jenkins convert to pipeline plugin

I needed to convert a freestyle job to a pipeline job for “Automating your Ci/CD Stack with Java and Groovy” Hands On Lab at Oracle Code One. It’s a really simple project, but it is still a pain to convert by hand.

I had read about the Convert to Pipeline plugin so decide to give it a shot. It’s easy enough to install a plugin.

Generated Pipeline

Below is what got generated. While I’d like to assume that credentials binding isn’t in wide use, that one didn’t surprise me. In hindsight, it makes sense because the credentials binding would need to wrap the Gradle block. I was surprised that Gradle wasn’t supported.

I am glad that the tool leaves comments for what you need to do by hand.

// Powered by Infostretch 

timestamps {

node () {

	stage ('osprey - Checkout') {
 	 checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '', url: 'https://github.com/boyarsky/OracleCodeOne2018-HOL-Automating-Stack-Groovy.git']]]) 
	}
	stage ('osprey - Build') {
 	
// Unable to convert a build step referring to "org.jenkinsci.plugins.credentialsbinding.impl.SecretBuildWrapper". Please verify and convert manually if required.
// Unable to convert a build step referring to "hudson.plugins.gradle.Gradle". Please verify and convert manually if required.
		// JUnit Results
		junit 'osprey-project/build/test-results/test/*.xml' 
	}
}
}

Using the pipeline generator

On the pipeline job, you can click the “pipeline syntax” link. It opens a new browser tab with a pull down for common pipeline operations.

Credentials

I choose “withCredentials”, entered the variable names and selected the credential from the pull down. Then I clicked “Generate Pipeline Script” and got:


withCredentials([usernamePassword(credentialsId: 'nexus', passwordVariable: 'nexusPassword', usernameVariable: 'nexusUserName')]) {
// some block
}


Gradle

That brings us to Gradle. As far as I can tell, there are only objects for Gradle if you are using Artifactory. I am using the gradle wrapper though, so I followed the advice of this Stack Overflow post and just called gradlew.


withCredentials([usernamePassword(credentialsId: 'nexus', passwordVariable: 'nexusPassword', usernameVariable: 'nexusUserName')]) {
  sh "./osprey-project/gradlew clean build -b osprey-project/build.gradle -PnexusBaseUrl=http://nexus:8081 -PnexusUserName=${nexusUserName} -PnexusPassword=${nexusPassword}"
}

I decided to separate the publish step into a different stage and rename the stages as well.  Resulting in:


// Powered by Infostretch 

timestamps {

node () {

	stage ('Checkout') {
 	 checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: '', url: 'https://github.com/boyarsky/OracleCodeOne2018-HOL-Automating-Stack-Groovy.git']]]) 
	}
	stage ('Build') {
	    
	   withCredentials([usernamePassword(credentialsId: 'nexus', passwordVariable: 'nexusPassword', usernameVariable: 'nexusUserName')]) {
          sh "./osprey-project/gradlew clean build -b osprey-project/build.gradle -PnexusBaseUrl=http://nexus:8081 -PnexusUserName=${nexusUserName} -PnexusPassword=${nexusPassword}"
       }

		// JUnit Results
		junit 'osprey-project/build/test-results/test/*.xml' 
	}
	
	stage ('Publish') {
	    
	   withCredentials([usernamePassword(credentialsId: 'nexus', passwordVariable: 'nexusPassword', usernameVariable: 'nexusUserName')]) {
          sh "./osprey-project/gradlew publish -b osprey-project/build.gradle -PnexusBaseUrl=http://nexus:8081 -PnexusUserName=${nexusUserName} -PnexusPassword=${nexusPassword}"
       }
	}
}
}

Note: My actual build file was bigger. The parts outside the pipeline (ex: project security settings) got preserved.

a rant about jenkins script security

I’m working on the lab for my Automating Your CI/CD Stack with Java and Groovy Oracle Code One session. And of course I tripped over Jenkins Script Security plugin.

I don’t need script security. I’m running a lab. But you can’t turn off that feature. Sigh.

I can run this code from the scripting console as an admin. I can also run it from within a job using the embedded Groovy console option. If I try to pull the same code from GitHub and run it from the same job as a Groovy script, I can’t. Script security views the SAME script to be more dangerous because I put it in source control.

import jenkins.model.Jenkins

def instance = Jenkins.getInstance()
def realm = Jenkins.getInstance().securityRealm

I can think of three ways to “solve” the problem that Cloudbees created.

Option 1: Deal with script security

I can configure script security to allow these signatures. However, this does not make things more secure. I want these to be available to admins not for general use. So approving them or whitelisting them is the wrong decision. (Ok. It doesn’t matter here since this is just a lab. But in this hypothetical use case…)

Option 2: Authorized Build plugin

There’s an authorize project plugin that lets you run the build as an admin. I didn’t try it, but it appears to provide a decent workaround to this problem. (I’m trying to minimize setup)

Option 3: Just run the code through the Groovy console

I’m going with this. Up to 50 people are going to be doing this manually in a lab. Copy/paste is the easiest solution.

good security – warnings in project

Cloudbees puts out security alerts frequently for Jenkins. We didn’t patch at CodeRanch for a while and then it got overwhelming. I wanted to get the latest JUnit plugin today. After upgrading to the latest Jenkins core, I went to manage Jenkins and saw this.

I was pleased. The product itself reminded me that we should check our security settings. It also reminded of all the security alerts that we missed.

We are now up to date (as of this moment) and it took less than hour. If I wasn’t counting the Jenkins core install and test, it would have been even less.