我有一个带有Jenkinsfile的Rails应用程序,我想设置它以便首先将构建部署到分段,然后如果我对结果感到满意,它可以在生产时构建。
我已经设置了2个Heroku实例,myapp-staging
和myapp-production
。
我的Jenkinsfile有一个看起来像的节点块:
node {
currentBuild.result = "SUCCESS"
setBuildStatus("Build started", "PENDING");
try {
stage('Checkout') {
checkout scm
gitCommit = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
shortCommit = gitCommit.take(7)
}
stage('Build') {
parallel 'build-image':{
sh "docker build -t ${env.BUILD_TAG} ."
}, 'run-test-environment': {
sh "docker-compose --project-name myapp up -d"
}
}
stage('Test') {
ansiColor('xterm') {
sh "docker run -t --rm --network=myapp_default -e DATABASE_HOST=postgres ${env.BUILD_TAG} ./ci/bin/run_tests.sh"
}
}
stage('Deploy - Staging') {
// TODO. Use env.BRANCH_NAME to make sure we only deploy from staging
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'Heroku Git Login', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD']]) {
sh('git push https://${GIT_USERNAME}:${GIT_PASSWORD}@git.heroku.com/myapp-staging.git staging')
}
setBuildStatus("Staging build complete", "SUCCESS");
}
stage('Sanity check') {
steps {
input "Does the staging environment look ok?"
}
}
stage('Deploy - Production') {
// TODO. Use env.BRANCH_NAME to make sure we only deploy from master
withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'Heroku Git Login', usernameVariable: 'GIT_USERNAME', passwordVariable: 'GIT_PASSWORD']]) {
sh('git push https://${GIT_USERNAME}:${GIT_PASSWORD}@git.heroku.com/myapp-production.git HEAD:refs/heads/master')
}
setBuildStatus("Production build complete", "SUCCESS");
}
}
我的问题是:
这是正确的方法吗?还是有其他一些最佳做法?例如,我需要两个Jenkins管道,还是一个项目管道呢?
如何根据我所处的阶段使用Jenkins的BRANCH_NAME变量进行动态更改?
提前致谢!
答案 0 :(得分:1)
对于第一个问题,使用一个Jenkinsfile来描述完整的项目管道是可取的。它将流程的描述保存在一个地方,并在一个UI中显示流程流,因此Jenkins文件在这方面看起来很棒。
对于第二个问题,您可以根据分支在if
条件中包装步骤。所以如果你想,比如说,跳过prod部署以及询问用户是否暂存看起来没问题的步骤(因为你不打算进行prod部署)如果分支不是master,那么这将有效。
node('docker') {
try {
stage('Sanity check') {
if (env.BRANCH_NAME == 'master') {
input "Does the staging environment look ok?"
}
}
stage('Deploy - Production') {
echo 'deploy check'
if (env.BRANCH_NAME == 'master') {
echo 'do prod deploy stuff'
}
}
} catch(error) {
}
}
我从你的管道中删除了一些没有必要来展示这个想法的东西,但我也解决了看起来像两个问题的东西。 1)你似乎在脚本和声明性管道之间混合隐喻。我认为你正在尝试使用脚本管道,所以我完全编写了脚本。这意味着你不能使用steps
。 2)您的try
缺少catch
。
在一天结束时,UI对于这个解决方案来说有点奇怪,因为所有步骤都会在所有情况下都显示出来,并且它们只会显示为绿色,就像它们通过并执行他们所说的那样做(它看起来像是部署到prod,即使在非主分支上)。据我所知,在脚本管道方面没有办法解决这个问题。使用声明性管道,您可以使用when
执行相同的条件逻辑,并且UI(至少是蓝海UI)实际上了解您的意图并以不同方式显示它。
玩得开心!