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  }