Parameter Passing in a Build Flow

This article walks through passing parameters and environment variables between Jenkins Build Flow jobs. It includes concrete examples for routing deployment context through retries, parallel test jobs, and rescue steps.

Coveros Staff

September 30, 2014

As a direct followup to my previous , I thought the discussion of passing parameters in a build flow might be useful.

Let’s start with our previous example.  I’ve created a build flow that deploys an application and runs Front-End, Back-End and Integration Tests against that application in parallel.  In addition, we’ve added several features in the build flow to ensure that when that we easily recover from failures.

//Try to deploy the application up to three times
 retry (3) {
      build (“DeployMyApplication”)
 }
guard {
      //Try the following: Setup the DB à Test the application à Scorch the DB
      build (“SetupTestData”)
      //Run the tests in parallel
      parallel (
          { build (“RunFrontEndTests”) },
          { build (“RunBackEndTests”) },
          { build (“RunIntegrationTests”) }
     )
      build (“ScorchMyApplicationDB”)
 } rescue {
      //On failure, pull the application log, snapshot the DB and Scorch the DB
      build (“PullApplicationLogs”)
      build (“SnapshotTheDB”)
      build (“ScorchMyApplicationDB”)
      build (“FailTheFlow”)
 }

Passing Parameters in a Flow

Let’s assume that we have various servers available to deploy our application to and perhaps for our Deployment and test flow we want to pass the IP of the server we want interact with to various jobs.  The parameter we want passed to is called “ServerIP”.  Our flow would change a bit to look like the following:

//Try to deploy the application up to three times
 retry (3) {
      build (“DeployMyApplication”, ServerIP: "127.0.0.1")
 }
guard {
      //Try the following: Setup the DB à Test the application à Scorch the DB
      build (“SetupTestData”, ServerIP: "127.0.0.1")
//Run the tests in parallel
      parallel (
          { build (“RunFrontEndTests”, ServerIP: "127.0.0.1") },
          { build (“RunBackEndTests”, ServerIP: "127.0.0.1") },
         { build (“RunIntegrationTests”, ServerIP: "127.0.0.1") }
     )
     build (“ScorchMyApplicationDB”, ServerIP: "127.0.0.1")
} rescue {
      //On failure, pull the application log, snapshot the DB and Scorch the DB
      build (“PullApplicationLogs”, ServerIP: "127.0.0.1")
      build (“SnapshotTheDB”, ServerIP: "127.0.0.1")
      build (“ScorchMyApplicationDB”, ServerIP: "127.0.0.1")
      build (“FailTheFlow”)
}

We could now create flows for each of our servers to run tests against our applications.

Using Parameters and Environment Variables in a Flow

Obviously, I can easily see an area where we might want to use this one flow against various environments so that we could test an application on various environments concurrently.  In this case, we would take in a parameter in our build flow that we can later pass into the jobs called in our flow.   Let’s assume, that our parameter passed to the build flow has the exact same name as the parameter we are passing to our jobs in the flow (in this case “ServerIP”).  Our build flow might change a bit to look like the following

/Try to deploy the application up to three times
retry (3) {
      build (“DeployMyApplication”, ServerIP: PARAMS["ServerIP"])
}
guard {
      //Try the following: Setup the DB à Test the application à Scorch the DB
      build (“SetupTestData”, ServerIP: PARAMS["ServerIP"])
     //Run the tests in parallel
      parallel (
          { build (“RunFrontEndTests”, ServerIP: PARAMS["ServerIP"]) },
          { build (“RunBackEndTests”, ServerIP: PARAMS["ServerIP"]) },
          { build (“RunIntegrationTests”, ServerIP: PARAMS["ServerIP"]) }
     )
     build (“ScorchMyApplicationDB”, ServerIP: PARAMS["ServerIP"])
} rescue {
      //On failure, pull the application log, snapshot the DB and Scorch the DB
      build (“PullApplicationLogs”, ServerIP: PARAMS["ServerIP"])
      build (“SnapshotTheDB”, ServerIP: PARAMS["ServerIP"])
      build (“ScorchMyApplicationDB”, ServerIP: PARAMS["ServerIP"])
      build (“FailTheFlow”)
}

Now let’s also assume that there is some information want to pass on to one of our jobs that is currently an environment variable. A common variable I use is the BUILD_NUMBER so that it can be referenced in log output that is provided to developers and CI Engineers to trace problems back to a particular build flow.  If we were to use that example we might pass an environment variable from the flow to the “PullApplicationLogs” job.  that particular change might look like the following:

build (“PullApplicationLogs”, ServerIP: PARAMS["ServerIP"], BuildFlowID: ENV["BUILD_NUMBER"])

Hope you found this practical walk-through of the build flow useful for your CI needs!

Coveros Staff

Coveros Staff

This post represents the collective insights of the Coveros team. Our staff consists of software experts who bring deep experience in secure agile development, DevOps, testing, and software quality. Over the past 20 years, Coveros has trained more than 30,000 professionals and worked with half of the Fortune 100 companies on mission-critical software development challenges. We draw on this extensive experience to share practical insights, proven strategies, and real-world solutions that help organizations build better software faster and more securely.