部署到Heroku升级,然后使用Jenkins进行生产

时间:2017-06-17 08:10:44

标签: ruby-on-rails heroku jenkins

我有一个带有Jenkinsfile的Rails应用程序,我想设置它以便首先将构建部署到分段,然后如果我对结果感到满意,它可以在生产时构建。

我已经设置了2个Heroku实例,myapp-stagingmyapp-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");
  }
}

我的问题是:

  1. 这是正确的方法吗?还是有其他一些最佳做法?例如,我需要两个Jenkins管道,还是一个项目管道呢?

  2. 如何根据我所处的阶段使用Jenkins的BRANCH_NAME变量进行动态更改?

  3. 提前致谢!

1 个答案:

答案 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)实际上了解您的意图并以不同方式显示它。

玩得开心!