github.com/engineyard/workflow-cli@v2.21.6+incompatible/Jenkinsfile (about) 1 def windows = 'windows' 2 def linux = 'linux' 3 def git_commit = '' 4 def git_branch = '' 5 def git_tag = '' 6 7 def getBasePath = { String filepath -> 8 def filename = filepath.lastIndexOf(File.separator) 9 return filepath.substring(0, filename) 10 } 11 12 def sh = { cmd -> 13 wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'XTerm']) { 14 sh cmd 15 } 16 } 17 18 def pscmd = { String cmd -> 19 "powershell -NoProfile -ExecutionPolicy Bypass -Command \"${cmd}\"" 20 } 21 22 def bootstrap = { String node -> 23 bootstrapCmd = node == windows ? bat(pscmd('.\\make bootstrap')) : make('bootstrap') 24 25 try { 26 bootstrapCmd 27 } catch(error) { 28 echo "bootstrap failed; wiping 'vendor' directory and trying again..." 29 retry(1) { 30 dir('vendor') { deleteDir() } 31 bootstrapCmd 32 } 33 } 34 } 35 36 // Disabling until we have a more sustainable Windows Jenkins Agent plan 37 // See https://github.com/deis/jenkins-jobs/issues/351 38 // node(windows) { 39 // def gopath = pwd() + "\\gopath" 40 // env.GOPATH = gopath 41 // def workdir = gopath + "\\src\\github.com\\deis\\workflow-cli" 42 // 43 // dir(workdir) { 44 // stage 'Checkout Windows' 45 // checkout scm 46 // stage 'Install Windows' 47 // bootstrap windows 48 // stage 'Test Windows' 49 // bat pscmd('.\\make test') 50 // } 51 // } 52 53 stage 'Git Info' 54 node(linux) { 55 checkout scm 56 57 git_branch = env.BRANCH_NAME 58 git_commit = sh(returnStdout: true, script: 'git rev-parse HEAD').trim() 59 git_tag = sh(returnStdout: true, script: 'git describe --abbrev=0 --tags').trim() 60 61 if (git_branch != "master") { 62 // Determine actual PR commit, if necessary 63 merge_commit_parents= sh(returnStdout: true, script: 'git rev-parse HEAD | git log --pretty=%P -n 1 --date-order').trim() 64 if (merge_commit_parents.length() > 40) { 65 echo 'More than one merge commit parent signifies that the merge commit is not the PR commit' 66 echo "Changing git_commit from '${git_commit}' to '${merge_commit_parents.take(40)}'" 67 git_commit = merge_commit_parents.take(40) 68 } else { 69 echo 'Only one merge commit parent signifies that the merge commit is also the PR commit' 70 echo "Keeping git_commit as '${git_commit}'" 71 } 72 } 73 } 74 75 def test_image = "quay.io/deisci/workflow-cli-dev:${git_commit.take(7)}" 76 def mutable_image = 'quay.io/deisci/workflow-cli-dev:latest' 77 78 node(linux) { 79 stage 'Build and push test container' 80 checkout scm 81 def quayUsername = "deisci+jenkins" 82 def quayEmail = "deis+jenkins@deis.com" 83 withCredentials([[$class: 'StringBinding', 84 credentialsId: 'c67dc0a1-c8c4-4568-a73d-53ad8530ceeb', 85 variable: 'QUAY_PASSWORD']]) { 86 87 sh """ 88 docker login -e="${quayEmail}" -u="${quayUsername}" -p="\${QUAY_PASSWORD}" quay.io 89 docker build \${DOCKER_BUILD_FLAGS} -t ${test_image} . 90 docker push ${test_image} 91 """ 92 93 if (git_branch == "master") { 94 sh """ 95 docker tag ${test_image} ${mutable_image} 96 docker push ${mutable_image} 97 """ 98 } 99 } 100 } 101 102 103 stage 'Lint and test container' 104 // TODO: re-parallelize these tasks when race condition is fixed. 105 node(linux) { 106 sh "docker run --rm ${test_image} lint" 107 } 108 node(linux) { 109 withCredentials([[$class: 'StringBinding', 110 credentialsId: '995d99a7-466b-4beb-bf75-f3ba91cbbc18', 111 variable: 'CODECOV_TOKEN']]) { 112 def codecov = "codecov -Z -C ${git_commit} -B ${branch_name}" 113 if (branch_name != "master") { 114 def branch_index = branch_name.indexOf('-') 115 def pr = branch_name.substring(branch_index+1, branch_name.length()) 116 codecov += " -P ${pr}" 117 } 118 sh "docker run -e CODECOV_TOKEN=\${CODECOV_TOKEN} --rm ${test_image} sh -c 'test-cover.sh && ${codecov}'" 119 } 120 } 121 122 stage 'Build and Upload Artifacts' 123 124 def old_gcs_bucket = "gs://workflow-cli" 125 def pr_gcs_bucket = "gs://workflow-cli-pr" 126 def master_gcs_bucket = "gs://workflow-cli-master" 127 128 def upload_artifacts = { String dist_dir, String auth_id, String bucket, boolean cache -> 129 def headers = "-h 'x-goog-meta-git-branch:${git_branch}' " 130 headers += "-h 'x-goog-meta-git-sha:${git_commit}' " 131 headers += "-h 'x-goog-meta-ci-job:${env.JOB_NAME}' " 132 headers += "-h 'x-goog-meta-ci-number:${env.BUILD_NUMBER}' " 133 headers += "-h 'x-goog-meta-ci-url:${env.BUILD_URL}'" 134 if(!cache) { 135 headers += ' -h "Cache-Control:no-cache"' 136 } 137 138 def script = "sh -c 'echo \${GCS_KEY_JSON} | base64 -d - > /tmp/key.json " 139 script += "&& gcloud auth activate-service-account -q --key-file /tmp/key.json " 140 script += "&& gsutil -mq ${headers} cp -a public-read -r /upload/* ${bucket}'" 141 142 withCredentials([[$class: 'StringBinding', 143 credentialsId: auth_id, 144 variable: 'GCSKEY']]) { 145 sh "docker run ${dist_dir} -e GCS_KEY_JSON=\"\${GCSKEY}\" --rm ${test_image} ${script}" 146 } 147 } 148 149 def mktmp = { 150 // Create tmp directory to store files 151 sh 'mktemp -d > tmp_dir' 152 def tmp = readFile('tmp_dir').trim() 153 echo "Storing binaries in ${tmp}" 154 sh 'rm tmp_dir' 155 return tmp 156 } 157 158 def version_flags = "-e REVISION=${git_commit.take(7)} -e GIT_TAG=${git_tag}" 159 160 parallel( 161 revision: { 162 node(linux) { 163 164 def flags = "" 165 if (git_branch != "master") { 166 echo "Skipping build of 386 binaries to shorten CI for Pull Requests" 167 flags += "-e BUILD_ARCH=amd64" 168 } 169 170 def tmp_dir = mktmp() 171 def dist_dir = "-e DIST_DIR=/upload -v ${tmp_dir}:/upload" 172 sh "docker run ${flags} ${version_flags} ${dist_dir} --rm ${test_image} make build-revision" 173 174 if (git_branch == "master") { 175 upload_artifacts(dist_dir, '6029cf4e-eaa3-4a8e-9dc7-744d118ebe6a', master_gcs_bucket, true) 176 } else { 177 upload_artifacts(dist_dir, '6029cf4e-eaa3-4a8e-9dc7-744d118ebe6a', pr_gcs_bucket, true) 178 } 179 sh "docker run ${dist_dir} --rm ${test_image} sh -c 'rm -rf /upload/*'" 180 sh "rm -rf ${tmp_dir}" 181 } 182 }, 183 latest: { 184 node(linux) { 185 if (git_branch == "master") { 186 def tmp_dir = mktmp() 187 def dist_dir = "-e DIST_DIR=/upload -v ${tmp_dir}:/upload" 188 sh "docker run ${dist_dir} ${version_flags} --rm ${test_image} make build-latest" 189 190 upload_artifacts(dist_dir, '6029cf4e-eaa3-4a8e-9dc7-744d118ebe6a', master_gcs_bucket, false) 191 sh "docker run ${dist_dir} --rm ${test_image} sh -c 'rm -rf /upload/*'" 192 sh "rm -rf ${tmp_dir}" 193 } else { 194 echo "Skipping build of latest artifacts because this build is not on the master branch (branch: ${git_branch})" 195 } 196 } 197 } 198 ) 199 200 stage 'Trigger e2e tests' 201 202 waitUntil { 203 try { 204 def chartRepoType = git_branch == "master" ? 'dev' : 'pr' 205 build job: 'workflow-chart-e2e', parameters: [ 206 [$class: 'StringParameterValue', name: 'WORKFLOW_CLI_SHA', value: git_commit], 207 [$class: 'StringParameterValue', name: 'ACTUAL_COMMIT', value: git_commit], 208 [$class: 'StringParameterValue', name: 'COMPONENT_REPO', value: 'workflow-cli'], 209 [$class: 'StringParameterValue', name: 'CHART_REPO_TYPE', value: chartRepoType], 210 [$class: 'StringParameterValue', name: 'UPSTREAM_SLACK_CHANNEL', value: '#controller']] 211 true 212 } catch(error) { 213 if (git_branch == "master") { 214 throw error 215 } 216 217 node(linux) { 218 withCredentials([[$class: 'StringBinding', credentialsId: '8a727911-596f-4057-97c2-b9e23de5268d', variable: 'SLACKEMAIL']]) { 219 mail body: """<!DOCTYPE html> 220 <html> 221 <head> 222 <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' /> 223 </head> 224 <body> 225 <div>Author: ${env.CHANGE_AUTHOR}<br/> 226 Branch: ${env.BRANCH_NAME}<br/> 227 Commit: ${env.CHANGE_TITLE}<br/> 228 <a href="${env.BUILD_URL}console">Click here</a> to view logs.</p> 229 <a href="${env.BUILD_URL}input/">Click here</a> to restart e2e.</p> 230 </div> 231 </html> 232 """, from: 'jenkins@ci.deis.io', subject: 'Workflow CLI E2E Test Failure', to: env.SLACKEMAIL, mimeType: 'text/html' 233 } 234 input "Retry the e2e tests?" 235 } 236 false 237 } 238 }