Jenkins Workflow in 5 Minutes
This is a 5min guide about how to build a project from Git repo and deploy it to a server with Jenkins workflow.
To help you through, I will provide all the commands/VMs you need to run.
What You Need
- Vagrant >= 1.7
- Download a JDK (required by later steps)
- Check out https://github.com/ryan-ju/jenkins-workflow-in-5-minutes
- (Optional) Fork https://github.com/ryan-ju/resteasy-demo-01 and rename the
<groupId>
in pom.xml’s. Only required if you need to release a build. - (Optional) Create a Sonatype nexus account following instructions in Maven Release in 5 Minutes. If you don’t use nexus, make sure to configure the workflow to download the war file from somewhere else.
Project Structure
As you see, the pipeline is a relatively complex one, with branching (7) and human intervention (9).
Steps
Go to where you checked out the code. Read the README.md
files to see what you need to change. Then start the VMs by running
$ cd jenkins-vm
$ vagrant up
$ cd tomcat-vm
$ vagrant up
Once the VMs are up, open a browser and go to 192.168.2.4:8080
. You should see a job workflow-demo-01
. Click on it and click “configure”.
First change the “tomcat_username” and “tomcat_password” to the value you’ve configured for tomcat-vm.
Then modify the workflow script. The comments point out where the line corresponds to in the diagram.
node {
def mvnHome = tool 'Maven'
def devHost = '192.168.2.3'
def prodHost = '192.168.2.3'
dir('dev') {
stage 'Dev build'
# 1
git url: 'https://github.com/ryan-ju/resteasy-demo-01.git'
// Print version
def v = version()
if (v) {
echo "Building version ${v}"
}
# 2
sh "${mvnHome}/bin/mvn clean install"
stage 'Dev deploy'
# 3
deploy("resteasy-demo-01-server/target/resteasy-demo-01-*.war", devHost, "/dev")
}
dir('dev-test') {
stage 'Dev QA'
# 4
git url: 'https://github.com/ryan-ju/resteasy-demo-01-test.git'
# 5
sh "${mvnHome}/bin/mvn -Dhost=http://${devHost} -Dport=8080 -Dcontext=/dev/api clean install"
}
dir('dev') {
stage 'Upload artifact'
// Print version
def v = version()
if (v) {
echo "Uploading version ${v}"
}
# 6
sh "${mvnHome}/bin/mvn -Dmaven.test.skip=true -P nexus deploy"
}
# 7
if (release.toString().toBoolean()) {
dir('dev') {
stage 'Release build'
sh "git checkout master"
sh "git pull origin master"
def rv = releaseVersion()
# 8
sh "${mvnHome}/bin/mvn -P nexus -Darguments=\"-DskipTests\" release:prepare release:perform"
if (rv) {
// Ask for manual permission to continue
# 9
input "Ready to update prod?"
# 10
sh "curl -L -o resteasy-server.war https://oss.sonatype.org/service/local/repositories/releases/content/org/itechet/resteasy-demo-01-server/${rv}/resteasy-demo-01-server-${rv}.war"
# 11
deploy("resteasy-server.war", prodHost, "/resteasy")
} else {
error "Failed to get release version from pom.xml"
}
}
}
}
// Get version from pom.xml
def version() {
def matcher = readFile('pom.xml') =~ '<version>(.+)</version>'
matcher ? matcher[0][1] : null
}
// Get release version from snapshot pom.xml
def releaseVersion() {
def matcher = readFile('pom.xml') =~ '<version>(.+)-SNAPSHOT</version>'
matcher ? matcher[0][1] : null
}
// Deploy file to tomcat
def deploy(file, host, context) {
sh "curl -T ${file} -u \"${tomcat_username}:${tomcat_password}\" http://${host}:8080/manager/text/deploy?path=${context}&update=true"
}
Explanations
Jenkins workflow script is a DSL. The most important ones are:
node
keyword specifies a chunk of task that should be scheduled on a node. It comes with a workspace (you can’t specify it).
dir
keyword allows you to create a work dir under the node’s workspace.
stage
is used to control the concurrency of a section of code. For example, you only want one build to deploy to Tomcat at a time, so should set this value to 1.
input
asks for user intervention.
parallel
allows multiple actions to run in parallel.
sh
executes commands.
Output
At the moment, this is all the visualization you get:
Pretty ugly right? You’ll have to wait till the Cloudbees’ visualization plugin is open sourced, which will be early 2016.
Conclusion
Jenkins workflow is pretty painful to set up (totally my option, you’re welcome to disagree). The official tutorial doesn’t tell enough, neither does the Cloudbees doc. I personally found stackoverflow more informative.
To make matters worse, there are certain important features that are only available in Cloudbees enterprise, like workflow visualization and checkpoint (also, I still haven’t figured out how to wipe out the workspace, other than logging in and rm the whole dir. Indeed, such important functionality isn’t implemented yet!).
IMO, Jenkins workflow does work, but if you to make your life easier and have some fortune to spare, probably Cloudbees is a better choice to run Jenkins.
Next time I’ll have a look at GoCD, the new CD tool that’s getting lots of attention and is supposed to be much better.
Please leave a comment if you like this post or want anything improved.
References
Jenkins installation: https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+on+Ubuntu
Git integration: http://jakubstas.com/github-and-jenkins-integration/
Github plugin installation: https://www.cloudbees.com/blog/better-integration-between-jenkins-and-github-github-jenkins-plugin
Java keytool: https://docs.oracle.com/cd/E19159-01/819-3671/ablra/index.html
Tomcat 8 connector config: https://tomcat.apache.org/tomcat-8.0-doc/ssl-howto.html#Configuration
Jenkins workflow plugin tutorial: https://github.com/jenkinsci/workflow-plugin/blob/master/TUTORIAL.md
Jenkins workflow guide by Cloudbees: https://documentation.cloudbees.com/docs/cookbook/_continuous_delivery_with_jenkins_workflow.html
Written with StackEdit.