├── README.md ├── docker ├── Dockerfile ├── build.sh ├── jobs │ └── webapp-workflow │ │ └── config.xml ├── run.sh ├── server.xml └── tomcat-users.xml ├── flows └── cd-tomcat.groovy ├── jobs └── web-app-cd.xml └── src └── com └── cb ├── util └── BasicUtilities.groovy └── web └── Tomcat.groovy /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Jenkins Workflow 2 | 3 | This repository is created for this [post](http://udaypal.com/jenkins-workflow-getting-started/) 4 | 5 | # Docker setup 6 | 7 | To run this demo in docker you can run the following command 8 | 9 | `docker run -p 8080:8080 -p 8180:8180 -it uday/workflow-getting-started` 10 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | From uday/jenkins-base 2 | MAINTAINER Udaypal Aarkoti 3 | 4 | ENV JENKINS_HOME /var/lib/jenkins 5 | RUN mkdir -p "$CATALINA_HOME/jobs" 6 | 7 | ADD https://updates.jenkins-ci.org/latest/mock-security-realm.hpi /var/lib/jenkins/plugins/mock-security-realm.hpi 8 | ADD https://updates.jenkins-ci.org/latest/workflow-aggregator.hpi /var/lib/jenkins/plugins/workflow-aggregator.hpi 9 | ADD https://updates.jenkins-ci.org/latest/workflow-basic-steps.hpi /var/lib/jenkins/plugins/workflow-basic-steps.hpi 10 | ADD https://updates.jenkins-ci.org/latest/workflow-scm-step.hpi /var/lib/jenkins/plugins/workflow-scm-step.hpi 11 | ADD https://updates.jenkins-ci.org/latest/workflow-step-api.hpi /var/lib/jenkins/plugins/workflow-step-api.hpi 12 | ADD https://updates.jenkins-ci.org/latest/workflow-cps.hpi /var/lib/jenkins/plugins/workflow-cps.hpi 13 | ADD https://updates.jenkins-ci.org/latest/workflow-job.hpi /var/lib/jenkins/plugins/workflow-job.hpi 14 | ADD https://updates.jenkins-ci.org/latest/workflow-cps-global-lib.hpi /var/lib/jenkins/plugins/workflow-cps-global-lib.hpi 15 | ADD https://updates.jenkins-ci.org/latest/workflow-api.hpi /var/lib/jenkins/plugins/workflow-api.hpi 16 | ADD https://updates.jenkins-ci.org/latest/workflow-durable-task-step.hpi /var/lib/jenkins/plugins/workflow-durable-task-step.hpi 17 | ADD https://updates.jenkins-ci.org/latest/workflow-support.hpi /var/lib/jenkins/plugins/workflow-support.hpi 18 | ADD https://updates.jenkins-ci.org/latest/durable-task.hpi /var/lib/jenkins/plugins/durable-task.hpi 19 | ADD https://updates.jenkins-ci.org/latest/git-server.hpi /var/lib/jenkins/plugins/git-server.hpi 20 | ADD https://updates.jenkins-ci.org/latest/git-client.hpi /var/lib/jenkins/plugins/git-client.hpi 21 | ADD https://updates.jenkins-ci.org/latest/git.hpi /var/lib/jenkins/plugins/git.hpi 22 | ADD https://updates.jenkins-ci.org/latest/mailer.hpi /var/lib/jenkins/plugins/mailer.hpi 23 | ADD https://updates.jenkins-ci.org/latest/scm-api.hpi /var/lib/jenkins/plugins/scm-api.hpi 24 | ADD https://updates.jenkins-ci.org/latest/promoted-builds.hpi /var/lib/jenkins/plugins/promoted-builds.hpi 25 | ADD https://updates.jenkins-ci.org/latest/matrix-project.hpi /var/lib/jenkins/plugins/matrix-project.hpi 26 | ADD https://updates.jenkins-ci.org/latest/ssh-credentials.hpi /var/lib/jenkins/plugins/ssh-credentials.hpi 27 | ADD https://updates.jenkins-ci.org/latest/credentials.hpi /var/lib/jenkins/plugins/credentials.hpi 28 | 29 | ENV CATALINA_HOME /usr/local/tomcat 30 | ENV PATH $CATALINA_HOME/bin:$PATH 31 | RUN mkdir -p "$CATALINA_HOME" 32 | WORKDIR $CATALINA_HOME 33 | 34 | # see https://www.apache.org/dist/tomcat/tomcat-8/KEYS 35 | RUN gpg --keyserver pool.sks-keyservers.net --recv-keys \ 36 | 05AB33110949707C93A279E3D3EFE6B686867BA6 \ 37 | 07E48665A34DCAFAE522E5E6266191C37C037D42 \ 38 | 47309207D818FFD8DCD3F83F1931D684307A10A5 \ 39 | 541FBE7D8F78B25E055DDEE13C370389288584E7 \ 40 | 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 \ 41 | 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED \ 42 | 80FF76D88A969FE46108558A80B953A041E49465 \ 43 | 8B39757B1D8A994DF2433ED58B3A601F08C975E5 \ 44 | A27677289986DB50844682F8ACB77FC2E86E29AC \ 45 | A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 \ 46 | B3F49CD3B9BD2996DA90F817ED3873F5D3262722 \ 47 | DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 \ 48 | F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE \ 49 | F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23 50 | 51 | ENV TOMCAT_MAJOR 6 52 | ENV TOMCAT_VERSION 6.0.44 53 | ENV TOMCAT_TGZ_URL https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz 54 | 55 | RUN set -x \ 56 | && curl -fSL "$TOMCAT_TGZ_URL" -o tomcat.tar.gz \ 57 | && curl -fSL "$TOMCAT_TGZ_URL.asc" -o tomcat.tar.gz.asc \ 58 | && gpg --verify tomcat.tar.gz.asc \ 59 | && tar -xvf tomcat.tar.gz --strip-components=1 \ 60 | && rm bin/*.bat \ 61 | && rm tomcat.tar.gz* 62 | 63 | ADD tomcat-users.xml /usr/local/tomcat/conf/ 64 | ADD server.xml /usr/local/tomcat/conf/ 65 | ADD jobs /var/lib/jenkins/jobs 66 | ADD workflow-libs /var/lib/jenkins/workflow-libs 67 | 68 | ENV JAVA_HOME /usr/lib/jvm/jre 69 | RUN export JAVA_HOME=$JAVA_HOME 70 | 71 | RUN chown -R jenkins:jenkins /var/lib/jenkins/plugins 72 | RUN chown -R jenkins:jenkins /var/lib/jenkins/jobs 73 | CMD service jenkins start; bin/catalina.sh run; 74 | 75 | EXPOSE 8080 8180 76 | -------------------------------------------------------------------------------- /docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker build -t uday/workflow-getting-started . 4 | -------------------------------------------------------------------------------- /docker/jobs/webapp-workflow/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 110 | false 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /docker/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker run -p 8080:8080 -p 8180:8180 -it uday/workflow-getting-started 4 | -------------------------------------------------------------------------------- /docker/server.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 41 | 46 | 47 | 48 | 53 | 54 | 55 | 56 | 60 | 61 | 62 | 69 | 72 | 73 | 79 | 83 | 88 | 89 | 90 | 91 | 92 | 93 | 98 | 99 | 102 | 103 | 104 | 107 | 110 | 111 | 114 | 117 | 118 | 122 | 124 | 125 | 128 | 131 | 132 | 134 | 137 | 138 | 140 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /docker/tomcat-users.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /flows/cd-tomcat.groovy: -------------------------------------------------------------------------------- 1 | // Global Libraries 2 | 3 | // Tomcat library to deploy / undeploy to tomcat 4 | tomcat = new com.cb.web.Tomcat(hostname: "localhost", port: "8180", adminUser: "admin", adminPassword: "tomcat") 5 | 6 | // Simple utility 7 | util = new com.cb.util.BasicUtilities() 8 | 9 | // Local variables 10 | artifactName = 'webapp.war' 11 | artifact = "target/${artifactName}" 12 | 13 | // Closures to be executed by tomcat library to deploy/undeploy 14 | deployClosure = {war, url, id -> sh "curl --upload-file ${war} '${url}?path=/${id}&update=true'"} 15 | undeployClosure = {url, id -> sh "curl '${url}?path=/${id}'"} 16 | deployClosure.resolveStrategy = Closure.DELEGATE_FIRST 17 | undeployClosure.resolveStrategy = Closure.DELEGATE_FIRST 18 | 19 | // Execute the following steps on the master 20 | node('master') { 21 | git url: 'https://github.com/jenkinsbyexample/workflow-plugin-pipeline-demo.git' 22 | devQAStaging() 23 | } 24 | 25 | production() 26 | 27 | def devQAStaging() { 28 | 29 | // Execute maven build and archive artifacts 30 | stage 'Build' 31 | sh 'mvn clean package' 32 | archive artifact 33 | 34 | // TODO : Setup code coverage 35 | stage 'Code Coverage' 36 | echo 'Using Sonar for code coverage' 37 | 38 | // Run tests in parallel and publish report 39 | stage 'QA' 40 | 41 | parallel(longerTests: { 42 | runWithServer {url -> 43 | sh "mvn -f sometests/pom.xml test -Durl=${url} -Dduration=10" 44 | } 45 | }, quickerTests: { 46 | runWithServer {url -> 47 | sh "mvn -f sometests/pom.xml test -Durl=${url} -Dduration=5" 48 | } 49 | }) 50 | 51 | step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml']) 52 | 53 | // Assuming the tests above take a while (which is probably true in real world) 54 | // Setup a checkpoint so that if the build fails after the checkpoint, its possible 55 | // to restart the build from the checkpoint 56 | // NOTE: The try/catch block makes sure the build does not fail if checkpoint functionality 57 | // doesn't exist (because its available through CloudBees Jenkins Enterprise) 58 | try { 59 | checkpoint('Before Staging') 60 | } catch (NoSuchMethodError _) { 61 | echo 'Checkpoint feature available in Jenkins Enterprise by CloudBees.' 62 | } 63 | 64 | // Make sure only one build can enter this stage 65 | stage name: 'Staging', concurrency: 1 66 | 67 | // Deploy the artifact to Tomcat 68 | tomcat.deploy(artifact, 'staging', deployClosure) 69 | } 70 | 71 | def production() { 72 | 73 | // Wait for someone to validate that the deployment looks good. 74 | // Its also possible to add security here to make sure only people 75 | // With a specific role can resume the build from here 76 | input message: "Does ${tomcat.hostUrl}/staging/ look good?" 77 | 78 | try { 79 | checkpoint('Before production') 80 | } catch (NoSuchMethodError _) { 81 | echo 'Checkpoint feature available in Jenkins Enterprise by CloudBees.' 82 | } 83 | 84 | stage name: 'Production', concurrency: 1 85 | node('master') { 86 | sh "curl -I ${tomcat.hostUrl}/staging/" 87 | unarchive mapping: ['target/webapp.war' : 'webapp.war'] 88 | tomcat.deploy(artifactName, 'production', deployClosure) 89 | echo "Deployed to ${tomcat.hostUrl}/production/" 90 | } 91 | } 92 | 93 | // Simple utility function to run tests on tomcat at random url 94 | def runWithServer(body) { 95 | def id = util.random() 96 | tomcat.deploy(artifact, id, deployClosure) 97 | try { 98 | body.call "${tomcat.hostUrl}/${id}/" 99 | } finally { 100 | tomcat.undeploy(id, undeployClosure) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /jobs/web-app-cd.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | false 6 | 7 | 8 | 110 | false 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /src/com/cb/util/BasicUtilities.groovy: -------------------------------------------------------------------------------- 1 | package com.cb.util; 2 | 3 | def random() { 4 | UUID.randomUUID().toString() 5 | } 6 | -------------------------------------------------------------------------------- /src/com/cb/web/Tomcat.groovy: -------------------------------------------------------------------------------- 1 | package com.cb.web; 2 | 3 | class Tomcat implements Serializable { 4 | String hostname, port, adminUser, adminPassword, protocol = "http" 5 | 6 | def deploy(war, id, proc) { 7 | proc(war, deployUrl, id) 8 | } 9 | 10 | def undeploy(id, proc) { 11 | proc(undeployUrl, id) 12 | } 13 | 14 | def getHostUrl() { 15 | "${protocol}://${hostname}:${port}" 16 | } 17 | 18 | def getHostAccessUrl() { 19 | "${protocol}://${adminUser}:${adminPassword}@${hostname}:${port}" 20 | } 21 | 22 | def getManagerUrl() { 23 | "${hostAccessUrl}/manager" 24 | } 25 | 26 | def getDeployUrl() { 27 | "${managerUrl}/deploy" 28 | } 29 | 30 | def getUndeployUrl() { 31 | "${managerUrl}/undeploy" 32 | } 33 | 34 | String toString() { 35 | "\t** Tomcat : \n\t\thostname = " + hostname + 36 | "\n\t\tport = " + port + 37 | "\n\t\tadminUser = " + adminUser + 38 | "\n\t\tdeployUrl = " + deployUrl 39 | } 40 | } 41 | --------------------------------------------------------------------------------