├── Dockerfile ├── README.md ├── detect-projects.sh ├── job-dsl-authentication-example.groovy ├── job-dsl-example.groovy ├── job-dsl-simple-2.groovy ├── job-dsl-simple.groovy └── plugins.txt /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jenkins 2 | MAINTAINER Dennis Schulte mail@dennis-schulte.de 3 | 4 | USER root 5 | RUN apt-get update 6 | RUN apt-get install -y maven 7 | USER jenkins 8 | 9 | COPY plugins.txt /plugins.txt 10 | 11 | RUN /usr/local/bin/plugins.sh /plugins.txt 12 | RUN curl -L https://github.com/steve-jansen/job-dsl-plugin/releases/download/JENKINS-21750-pre-release/job-dsl-jenkins-21750.hpi -o /usr/share/jenkins/ref/plugins/job-dsl-jenkins.hpi; 13 | 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Installation 4 | 5 | ## Build and run Docker image 6 | 7 | ```shell 8 | docker build -t denschu/jenkins . 9 | docker run -p 8080:8080 -u root -v /opt/jenkins_home:/var/jenkins_home denschu/jenkins 10 | docker run -p 8080:8080 -u root -i -t -v /opt/jenkins_home:/var/jenkins_home denschu/jenkins bash 11 | ``` 12 | 13 | ## Open Jenkins UI in webbrowser 14 | 15 | On a Mac you can get the ip address with the following command: 16 | 17 | ```shell 18 | boot2docker ip 19 | ``` 20 | 21 | ```shell 22 | http://192.168.59.103:8080/ 23 | ``` 24 | 25 | ## Add Maven path in Jenkins configuration 26 | 27 | ```shell 28 | /usr/share/maven/ 29 | ``` 30 | 31 | ## Create Generator Job 32 | 33 | 1. Create a freestyle jenkins job and call it "job-generator" 34 | 2. Add build step "Process Job DSLs" 35 | 3. Select the radio button "Use the provided DSL script" 36 | 4. Copy the contents of "job-dsl-example.groovy" into the text field 37 | 5. Save 38 | 6. Run 39 | 40 | 41 | # Job Steps 42 | 43 | ## Build 44 | 45 | 1. Jenkins triggers build process on SCM commit 46 | 2. Execute normal build process 47 | 48 | ```shell 49 | mvn clean package 50 | ``` 51 | 52 | ## Release 53 | 54 | 1. User triggers Release-Build 55 | 2. Replace SNAPSHOT-Version in pom.xml 56 | 57 | ```shell 58 | mvn build-helper:parse-version versions:set -DnewVersion=${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.incrementalVersion}-${BUILD_NUMBER} 59 | ``` 60 | 61 | 2. Execute normal build process 62 | 63 | ```shell 64 | mvn clean package 65 | ``` 66 | 67 | 3. Deploy artifact to artifact repository 68 | 69 | ```shell 70 | mvn deploy 71 | ``` 72 | 73 | 4. Tag version in SCM 74 | 75 | ```shell 76 | mvn scm:tag 77 | ``` 78 | 79 | ## Deploy 80 | 81 | 1. Select a build/release 82 | 2. Promote the build to a defined promotion level 83 | 3. The corresponding deploy-job will be executed 84 | 85 | # Job DSL Examples 86 | 87 | ## Build/Release Job 88 | 89 | ```shell 90 | def repository = 'codecentric/spring-samples' 91 | def contentApi = new URL("https://api.github.com/repos/${repository}/contents") 92 | def projects = new groovy.json.JsonSlurper().parse(contentApi.newReader()) 93 | projects.each { 94 | def projectName = it.name 95 | job(type: Maven) { 96 | name("${projectName}") 97 | triggers { scm("*/5 * * * *") } 98 | scm { 99 | git { 100 | remote { 101 | url("https://github.com/codecentric/spring-samples") 102 | } 103 | createTag(false) 104 | } 105 | } 106 | rootPOM("${projectName}/pom.xml") 107 | goals("clean package") 108 | wrappers { 109 | preBuildCleanup() 110 | release { 111 | preBuildSteps { 112 | maven { 113 | mavenInstallation("Maven 3.0.4") 114 | goals("build-helper:parse-version") 115 | goals("versions:set") 116 | property("newVersion", "\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.incrementalVersion}-\${BUILD_NUMBER}") 117 | } 118 | } 119 | postSuccessfulBuildSteps { 120 | maven { 121 | goals("deploy") 122 | } 123 | maven { 124 | goals("scm:tag") 125 | } 126 | downstreamParameterized { 127 | trigger("deploy-application") { 128 | predefinedProp("STAGE", "development") 129 | } 130 | } 131 | } 132 | } 133 | } 134 | publishers { 135 | groovyPostBuild("manager.addShortText(manager.build.getEnvironment(manager.listener)[\'POM_VERSION\'])") 136 | } 137 | promotions { 138 | promotion("Development") { 139 | icon("star-red") 140 | conditions { 141 | manual('') 142 | } 143 | actions { 144 | downstreamParameterized { 145 | trigger("deploy-application","SUCCESS",false,["buildStepFailure": "FAILURE","failure":"FAILURE","unstable":"UNSTABLE"]) { 146 | predefinedProp("ENVIRONMENT","test-server") 147 | predefinedProp("APPLICATION_NAME", "\${PROMOTED_JOB_FULL_NAME}") 148 | predefinedProp("BUILD_ID","\${PROMOTED_NUMBER}") 149 | } 150 | } 151 | } 152 | } 153 | promotion("QA") { 154 | icon("star-yellow") 155 | conditions { 156 | manual('') 157 | upstream("Development") 158 | } 159 | actions { 160 | downstreamParameterized { 161 | trigger("deploy-application","SUCCESS",false,["buildStepFailure": "FAILURE","failure":"FAILURE","unstable":"UNSTABLE"]) { 162 | predefinedProp("ENVIRONMENT","qa-server") 163 | predefinedProp("APPLICATION_NAME", "\${PROMOTED_JOB_FULL_NAME}") 164 | predefinedProp("BUILD_ID","\${PROMOTED_NUMBER}") 165 | } 166 | } 167 | } 168 | } 169 | promotion("Production") { 170 | icon("star-green") 171 | conditions { 172 | manual('') 173 | upstream("QA") 174 | } 175 | actions { 176 | downstreamParameterized { 177 | trigger("deploy-application","SUCCESS",false,["buildStepFailure": "FAILURE","failure":"FAILURE","unstable":"UNSTABLE"]) { 178 | predefinedProp("ENVIRONMENT","prod-server") 179 | predefinedProp("APPLICATION_NAME", "\${PROMOTED_JOB_FULL_NAME}") 180 | predefinedProp("BUILD_ID","\${PROMOTED_NUMBER}") 181 | } 182 | } 183 | } 184 | } 185 | } 186 | } 187 | } 188 | 189 | ## Deploy Job 190 | 191 | job{ 192 | name("deploy-application") 193 | } 194 | ``` 195 | 196 | # Used Plugins 197 | 198 | ## Jenkins Plugins 199 | 200 | https://wiki.jenkins-ci.org/display/JENKINS/Release+Plugin 201 | https://wiki.jenkins-ci.org/display/JENKINS/Groovy+Postbuild+Plugin 202 | https://wiki.jenkins-ci.org/display/JENKINS/Promoted+Builds+Plugin 203 | https://wiki.jenkins-ci.org/display/JENKINS/Job+DSL+Plugin 204 | 205 | ## Maven Plugins 206 | 207 | http://mojo.codehaus.org/build-helper-maven-plugin/parse-version-mojo.html 208 | http://mojo.codehaus.org/versions-maven-plugin/set-mojo.html 209 | http://maven.apache.org/scm-archives/scm-LATEST/maven-scm-plugin/tag-mojo.html 210 | 211 | 212 | 213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /detect-projects.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # The Base URL to detect the projects from 4 | REPOSITORY=https://github.com/codecentric/spring-samples 5 | 6 | # Check access 7 | svn info ${REPOSITORY} 8 | if [ "$?" != "0" ]; then 9 | echo "Failed to connect to SCM" 10 | exit 1 11 | fi 12 | 13 | 14 | echo "Detecting projects in SCM Repository: " ${REPOSITORY} 15 | for project in $(svn ls ${REPOSITORY}/trunk); do 16 | echo "project: " ${project} 17 | done -------------------------------------------------------------------------------- /job-dsl-authentication-example.groovy: -------------------------------------------------------------------------------- 1 | def repository = 'codecentric/crossfire'; 2 | // See also https://developer.github.com/v3/#authentication 3 | def authString = ":".getBytes().encodeBase64().toString(); 4 | 5 | URLConnection connBranches = new URL("https://api.github.com/repos/${repository}/branches").openConnection(); 6 | connBranches.setRequestProperty("Authorization", "Basic ${authString}"); 7 | def branches = new groovy.json.JsonSlurper().parse(new BufferedReader(new InputStreamReader(connBranches.getInputStream()))); 8 | 9 | //Iterate over each Branch 10 | branches.each { 11 | def branchName = it.name 12 | 13 | URLConnection connProjects = new URL("https://api.github.com/repos/${repository}/contents?ref=${branchName}").openConnection(); 14 | connProjects.setRequestProperty("Authorization", "Basic ${authString}"); 15 | def projects = new groovy.json.JsonSlurper().parse(new BufferedReader(new InputStreamReader(connProjects.getInputStream()))); 16 | 17 | //Iterate over each Project inside the actual branch 18 | projects.each { 19 | def projectName = it.name 20 | def contentType = it.type 21 | //Include only directories 22 | if(contentType == "dir"){ 23 | //Search for Dockerfile 24 | boolean containsDockerfile = false; 25 | URLConnection connProject = new URL("https://api.github.com/repos/${repository}/contents/${projectName}?ref=${branchName}").openConnection(); 26 | connProject.setRequestProperty("Authorization", "Basic ${authString}"); 27 | def projectContents = new groovy.json.JsonSlurper().parse(new BufferedReader(new InputStreamReader(connProject.getInputStream()))); 28 | projectContents.each { 29 | if(it.name == "Dockerfile"){ 30 | containsDockerfile = true; 31 | } 32 | } 33 | //Generate project only for Docker projects 34 | if(containsDockerfile){ 35 | job(type: Maven) { 36 | name("${projectName}-${branchName}") 37 | triggers { scm("*/5 * * * *") } 38 | scm { 39 | git { 40 | remote { 41 | url("https://github.com/${repository}") 42 | } 43 | createTag(false) 44 | } 45 | } 46 | rootPOM("${projectName}/pom.xml") 47 | goals("clean package") 48 | wrappers { 49 | preBuildCleanup() 50 | release { 51 | preBuildSteps { 52 | maven { 53 | mavenInstallation("Maven 3.0.4") 54 | rootPOM("${projectName}/pom.xml") 55 | goals("build-helper:parse-version") 56 | goals("versions:set") 57 | property("newVersion", "\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.incrementalVersion}-\${BUILD_NUMBER}") 58 | } 59 | } 60 | postSuccessfulBuildSteps { 61 | maven { 62 | rootPOM("${projectName}/pom.xml") 63 | goals("deploy") 64 | } 65 | maven { 66 | goals("scm:tag") 67 | } 68 | } 69 | } 70 | } 71 | publishers { 72 | groovyPostBuild("manager.addShortText(manager.build.getEnvironment(manager.listener)[\'POM_VERSION\'])") 73 | } 74 | } 75 | } 76 | 77 | } 78 | 79 | } 80 | } -------------------------------------------------------------------------------- /job-dsl-example.groovy: -------------------------------------------------------------------------------- 1 | def repository = 'codecentric/spring-samples' 2 | def contentApi = new URL("https://api.github.com/repos/${repository}/contents") 3 | def projects = new groovy.json.JsonSlurper().parse(contentApi.newReader()) 4 | projects.each { 5 | def projectName = it.name 6 | job(type: Maven) { 7 | name("${projectName}") 8 | triggers { scm("*/5 * * * *") } 9 | scm { 10 | git { 11 | remote { 12 | url("https://github.com/codecentric/spring-samples") 13 | } 14 | createTag(false) 15 | } 16 | } 17 | rootPOM("${projectName}/pom.xml") 18 | goals("clean package") 19 | wrappers { 20 | preBuildCleanup() 21 | release { 22 | preBuildSteps { 23 | maven { 24 | mavenInstallation("Maven 3.0.4") 25 | rootPOM("${projectName}/pom.xml") 26 | goals("build-helper:parse-version") 27 | goals("versions:set") 28 | property("newVersion", "\${parsedVersion.majorVersion}.\${parsedVersion.minorVersion}.\${parsedVersion.incrementalVersion}-\${BUILD_NUMBER}") 29 | } 30 | } 31 | postSuccessfulBuildSteps { 32 | maven { 33 | rootPOM("${projectName}/pom.xml") 34 | goals("deploy") 35 | } 36 | maven { 37 | goals("scm:tag") 38 | } 39 | downstreamParameterized { 40 | trigger("deploy-application") { 41 | predefinedProp("STAGE", "development") 42 | } 43 | } 44 | } 45 | } 46 | } 47 | publishers { 48 | groovyPostBuild("manager.addShortText(manager.build.getEnvironment(manager.listener)[\'POM_VERSION\'])") 49 | } 50 | promotions { 51 | promotion("Development") { 52 | icon("star-red") 53 | conditions { 54 | manual('') 55 | } 56 | actions { 57 | downstreamParameterized { 58 | trigger("deploy-application","SUCCESS",false,["buildStepFailure": "FAILURE","failure":"FAILURE","unstable":"UNSTABLE"]) { 59 | predefinedProp("ENVIRONMENT","test-server") 60 | predefinedProp("APPLICATION_NAME", "\${PROMOTED_JOB_FULL_NAME}") 61 | predefinedProp("BUILD_ID","\${PROMOTED_NUMBER}") 62 | } 63 | } 64 | } 65 | } 66 | promotion("QA") { 67 | icon("star-yellow") 68 | conditions { 69 | manual('') 70 | upstream("Development") 71 | } 72 | actions { 73 | downstreamParameterized { 74 | trigger("deploy-application","SUCCESS",false,["buildStepFailure": "FAILURE","failure":"FAILURE","unstable":"UNSTABLE"]) { 75 | predefinedProp("ENVIRONMENT","qa-server") 76 | predefinedProp("APPLICATION_NAME", "\${PROMOTED_JOB_FULL_NAME}") 77 | predefinedProp("BUILD_ID","\${PROMOTED_NUMBER}") 78 | } 79 | } 80 | } 81 | } 82 | promotion("Production") { 83 | icon("star-green") 84 | conditions { 85 | manual('') 86 | upstream("QA") 87 | } 88 | actions { 89 | downstreamParameterized { 90 | trigger("deploy-application","SUCCESS",false,["buildStepFailure": "FAILURE","failure":"FAILURE","unstable":"UNSTABLE"]) { 91 | predefinedProp("ENVIRONMENT","prod-server") 92 | predefinedProp("APPLICATION_NAME", "\${PROMOTED_JOB_FULL_NAME}") 93 | predefinedProp("BUILD_ID","\${PROMOTED_NUMBER}") 94 | } 95 | } 96 | } 97 | } 98 | } 99 | } 100 | } 101 | 102 | 103 | job{ 104 | name("deploy-application") 105 | } -------------------------------------------------------------------------------- /job-dsl-simple-2.groovy: -------------------------------------------------------------------------------- 1 | job(type: Maven) { 2 | name("${projectName}") 3 | triggers { scm("*/5 * * * *") } 4 | scm { 5 | git { 6 | remote { 7 | url("https://github.com/codecentric/spring-samples") 8 | } 9 | } 10 | } 11 | goals("clean package") 12 | } -------------------------------------------------------------------------------- /job-dsl-simple.groovy: -------------------------------------------------------------------------------- 1 | job{ 2 | name("transaction-service") 3 | } -------------------------------------------------------------------------------- /plugins.txt: -------------------------------------------------------------------------------- 1 | scm-api:0.2 2 | git-client:1.13.0 3 | git:2.3.2 4 | groovy-postbuild:2.2 5 | script-security:1.5 6 | promoted-builds:2.19 7 | maven-plugin:2.8 8 | mailer:1.12 9 | release::2.4.1 10 | dashboard-view::2.9.4 11 | javadoc:1.3 12 | parameterized-trigger:2.25 13 | --------------------------------------------------------------------------------