Tuesday, December 18, 2018

Jenkins 7: Pipeline Support

Next step in our Jenkins tutorials is to add support for pipeline builds.

Jenkins Tutorials

For a list of all jenkins related tutorials see Jenkins Tutorials Overview.

Source code for this tutorial is available on github as a single zip archive, as a Team Project Set or you can browse the files online.

Step 1: Adjusting the code

Good news first: our code (including jelly) from the previous tutorial is ready to be used in pipeline without change. There are some considerations to be taken when writing pipeline plugins, but we already took care of this.

In pipeline each build step needs a name to be addressed. By default this would be the class name and a call would look like this:
step([$class: 'HelloBuilder', buildMessage: 'Hello from pipeline'])

When using the @Symbol annotation on the Descriptor we can provide a nicer name for our build step.

Step 2: Adding dependencies to the execution environment

Our current test target does not support pipeline jobs as we did not add the right dependencies to the pom file so far. We will first see how to add dependencies in general, in the next step we will fix the build afterwards.

To add support for pipeline, add following definition to your pom.xml:
 <dependencies>
  <dependency>
   <groupId>org.jenkins-ci.plugins.workflow</groupId>
   <artifactId>workflow-aggregator</artifactId>
   <version>2.6</version>
   <scope>test</scope>
  </dependency>
 </dependencies>

We always need groupId, artifactId and a version. To get these parameters you would typically look up a plugin on the Jenkins plugin site. Locate the link to the source code (Github) and open the pom.xml of the corresponding plugin. There you will find definitions for groupId and artifactId.

Available versions can be found on the Jenkins Artifactory server (we added this server to our pom already). There navigate to the public folder, then follow the structure down, first opening folder from the groupId followed by the artifactId. For the pipeline dependency we would open public/org/jenkins-ci/plugins/workflow/workflow-aggregator. Latest version at the time of writing is 2.6.

Setting the scope to test means that we do not have a build dependency on the plugin. Instead we need it only deployed and enabled on our test instance.

When adding build dependencies you should run
mvn -DdownloadSources=true -DdownloadJavadocs=true -DoutputDirectory=target/eclipse-classes eclipse:eclipse
like we did in the first tutorial. It will update the .classpath file in your eclipse project, automatically adding required libraries to the build path. Take care that also the .project file gets rewritten!

Step 3: Dependency Resolution

We added our dependency, so everything should be done, right?
Wrong! The maven-enforcer-plugin verifies plugin dependencies for us and will detect some incompatibilities, eg:
Require upper bound dependencies error for org.jenkins-ci.plugins:script-security:1.39 paths to dependency are:
+-com.codeandme:builder.hello:1.0-SNAPSHOT
  +-org.jenkins-ci.plugins.workflow:workflow-aggregator:2.6
    +-org.jenkins-ci.plugins.workflow:workflow-support:2.20
      +-org.jenkins-ci.plugins:script-security:1.39
and
+-com.codeandme:builder.hello:1.0-SNAPSHOT
  +-org.jenkins-ci.plugins.workflow:workflow-aggregator:2.6
    +-org.jenkins-ci.plugins.workflow:workflow-durable-task-step:2.22
      +-org.jenkins-ci.plugins:script-security:1.39
and
+-com.codeandme:builder.hello:1.0-SNAPSHOT
  +-org.jenkins-ci.plugins.workflow:workflow-aggregator:2.6
    +-org.6wind.jenkins:lockable-resources:2.3
      +-org.jenkins-ci.plugins:script-security:1.26
...
This is one of multiple dependency conflicts detected. It seems that maven at first resolves the dependency with the lowest version number. As some plugins need a newer version, we need to resolve the dependency by our own.

The simplest way I found is to check for the highest version of the required plugin (in the upper case: script-security) and add it to our dependencies sections in the pom.xml file. I was hoping for some maven help on this process, but failed. So I ended up adding required dependencies manually until the build was satisfied.

You might run into other build problems, eg after adding a test dependency to the symbol-annotation plugin, my build started to fail, not being able to resolve Symbol.class anymore. Reason is that symbol-annotation is actually a build dependency rather than a test dependency. By binding it to the test scope only we broke the build.

Once you sorted out all dependencies (see resulting pom.xml) your test instance will be able to run pipeline jobs.

Step 4: Testing the Build Step in Pipeline

On your test instance create a new Pipeline and add following script:
node {
    stage('Greetings') {
        greet buildDelay: 'long', buildMessage: 'Hello pipeline build'
    }
}
Coding the command line for our build step can either be done manually or by using the Pipeline Syntax helper. The link is available right below the Script section in your job configuration. Jenkins makes use of our previous jelly definitions to display a visual helper for the Hello Build step. We may set all optional parameters on the UI and let Jenkins create the command line to be used in the pipeline script.

1 comment: