-
Improvement
-
Resolution: Fixed
-
Minor
-
None
I brought this up in the hudson-dev mailing list, but wanted to followup and enter a JIRA ticket for more formal tracking.
I have a build job that takes a parameter - VERSION, which I expect to
be a 4 digit number, like 1.2.3.4
What I would like to do is derive a new parameter, BRANCH, which is
the first 3 digits, like 1.2.3.
I then hope to use new BRANCH parameter to be available from the view
configuration for a perforce job.
For example, my build job would define the Perforce view to be:
//SOME/ROOT/PATH/${BRANCH}/...
I thought I knew how to do this, writing a new BuildWrapper extension
plugin similar to SetEnv. The only difference I added was to supply
options fields for including support for regular expression pattern
matching and replacement. It worked really well, and various
buildsteps of the job were able to get access to my derived env
variable.
I discovered however that while perforce gets access to use the
original parameters as a macro when defining the view, it was failing
to resolve my derived variable.
Turns out the BuildWrapper is not hooked into the build until after the scm checkout phase occurs.
This enhancement request is to provide a hook for BuildWrapper to decorate build variables prior to the scm checkout phase.
I've played around with checking out the core and altering things to get it to work, but not sure how to formalize getting feedback and actually committing assuming it is approved.
Here's how I go things to work:
n the abstract BuildWrapper class, I created a new method –
public Map<String,String> decorateBuildVariables(AbstractBuild build,
Map<String,String> buildVariables)
Then, I modified the the AbstractBuild.getBuildVariables() method, as seen here:
public Map<String,String> getBuildVariables() {
Map<String,String> r = new HashMap<String, String>();
ParametersAction parameters = getAction(ParametersAction.class);
if (parameters!=null) {
// this is a rather round about way of doing this...
for (ParameterValue p : parameters)
}
// NEW CODE here to allow buildwrapers to alter build variables
if (project instanceof BuildableItemWithBuildWrappers)
{ BuildableItemWithBuildWrappers biwbw = (BuildableItemWithBuildWrappers) project; for (BuildWrapper bw : biwbw.getBuildWrappersList()) r = bw.decorateBuildVariables(this, r); }// END NEW CODE
return r;
}
After making these changes, I implemented my BuildWrapper extension to override the decorateBuildVariables() method and I was able to confirm that the perforce plugin was able to get access to my new build variables my plugin injected into the build.
As the default behavior of the BuildWapper just returns the supplied map, this results in backwards compatibility for those extensions already deriving from BuildWrapper.
This was the easiest way to introduce this functionality into hudson core. I don't have the experience within the hudson core codebase to know the implication of these changes.
One potential problem I see is that AbstractBuild.getBuildVariables() will call BuildWrapper.decorateBuildVariables(), passing an instance of itself in the parameters. This produces the danger that the called BuildWrapper might in its implementation turn around and re-call getBuildParameters(), thus setting up an infinite loop.
For my specific BuildWrapper extension I'm writing which needs to take advantage of these core changes, I don't need access to the Build instance and don't use it. I had only thrown it there thinking that its reasonable that someone might want to use some additional information from the build to derive new dynamic BuildVariables.