Tuesday, December 6, 2011

Passing upstream parameters to downstream builds in Jenkins

Jenkins has cool Pipeline plugin, which helps to create build pipelines, that for example, can organize and visualize deployment process. Plugin is very cool and looks great, but lacks few basic features, like passing generated parameters or variables from upstream builds to downstream.
For example, I wanted to pass SVN revision number into downstream builds.
Fortunately it is easy to do it with little hacking. Here is what I did.
  1. Add Groovy plugin.
  2. Add new build step Execute system Groovy script, now it is possible to hook into Jenkins internals.
  3. Then just add Groovy script there:
import hudson.model.*
def thr = Thread.currentThread()
def build = thr?.executable
build.addAction(new ParametersAction(new StringParameterValue('SVN_UPSTREAM', build.getEnvVars()['SVN_REVISION'])))


What this script does it just creates new parameter and adds SVN_REVISION from environment variables there. And pipeline can pass parameters with this mechanism to downstream builds (all of them).
Easy!

4 comments:

  1. Did this really work for you?

    I get "Null value not allowed as an environment variable: SVN_UPSTREAM"

    I could not access the upstream SVN value in the downstream.

    ReplyDelete
  2. You should be able to use it like $SVN_UPSTREAM.
    For example in command:
    /opt/grails-1.3.7/bin/grails cluster-deploy test $SVN_UPSTREAM

    It also is shown in Jenkins Parameters menu.

    ReplyDelete
  3. multiple params:

    import hudson.model.*
    def build = Thread.currentThread().executable
    def params = [
    new StringParameterValue('UPSTREAM_SVN_REVISION',build.getEnvVars()['SVN_REVISION']),
    new StringParameterValue('UPSTREAM_BUILD_NUMBER',build.getEnvVars()['BUILD_NUMBER']),
    new StringParameterValue('UPSTREAM_BUILD_ID',build.getEnvVars()['BUILD_ID']),
    new StringParameterValue('UPSTREAM_JOB_NAME',build.getEnvVars()['JOB_NAME']),
    ]
    build.addAction(new ParametersAction(params))

    ReplyDelete
    Replies
    1. is Groovy installation needed to run above script ?
      i get below error

      Building remotely on DP_SLAVE in workspace /u01/jenkins/workspace/test
      [test] $ groovy /u01/jenkins/workspace/test/hudson2231928367288528411.groovy
      FATAL: command execution failed
      java.io.IOException: Cannot run program "groovy" (in directory "/u01/jenkins/workspace/test"): java.io.IOException: error=2, No such file or directory
      at java.lang.ProcessBuilder.start(ProcessBuilder.java:475)
      at hudson.Proc$LocalProc.(Proc.java:244)
      at hudson.Proc$LocalProc.(Proc.java:216)
      at hudson.Launcher$LocalLauncher.launch(Launcher.java:773)
      at hudson.Launcher$ProcStarter.start(Launcher.java:353)
      at hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:998)
      at hudson.Launcher$RemoteLaunchCallable.call(Launcher.java:965)
      at hudson.remoting.UserRequest.perform(UserRequest.java:118)
      at hudson.remoting.UserRequest.perform(UserRequest.java:48)
      at hudson.remoting.Request$2.run(Request.java:326)
      at hudson.remoting.InterceptingExecutorService$1.call(InterceptingExecutorService.java:72)
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
      at java.util.concurrent.FutureTask.run(FutureTask.java:166)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
      at java.lang.Thread.run(Thread.java:679)
      Caused by: java.io.IOException: java.io.IOException: error=2, No such file or directory
      at java.lang.UNIXProcess.(UNIXProcess.java:164)
      at java.lang.ProcessImpl.start(ProcessImpl.java:81)
      at java.lang.ProcessBuilder.start(ProcessBuilder.java:468)
      ... 15 more
      Build step 'Execute Groovy script' marked build as failure
      Finished: FAILURE

      Delete