Gitlab CI - 部署到 Heroku 和 运行 迁移

Gitlab CI - deploy to Heroku and run migrations

我在 gitlab.com 上托管了一个 Rails 应用程序,我正在按照以下指南将其配置为部署到 heroku:http://docs.gitlab.com/ce/ci/examples/test-and-deploy-ruby-application-to-heroku.html。它工作正常。

我的问题是,每次部署到 heroku 时如何 运行 迁移?通过 CLI 部署时,我通常会这样做:

git push heroku master && heroku run rake db:migrate

但是使用 gitlab-ci.yml 我不知道该怎么做...

此答案中的信息可能已过时。请查看下面的两个答案,并记得为最新的答案投票以帮助未来的访问者。

这是我的示例 .yml,它运行我的测试然后推送到 Heroku 阶段(用于主分支推送)或生产(用于标签推送)

image: "ruby:2.3"

test:
  script:
  - apt-get update -qy
  - apt-get install -y nodejs
  - gem install bundler
  - bundle install -j $(nproc) --without production
  - bundle exec rails db:create RAILS_ENV=test
  - bundle exec rails db:migrate RAILS_ENV=test
  - bundle exec rails RAILS_ENV=test

staging:
  type: deploy
  environment: staging
  script:
  - gem install dpl
  - dpl --provider=heroku --app=$HEROKU_STAGING_APP_NAME --api-key=$HEROKU_API_KEY
  - "curl -n -X POST https://api.heroku.com/apps/$HEROKU_STAGING_APP_NAME/ps -H \"Accept: application/json\" -H \"Authorization: Bearer ${HEROKU_API_KEY}\" -d \"command=bundle exec rails db:migrate\""
  only:
  - master

production:
  type: deploy
  environment: production
  script:
  - gem install dpl
  - dpl --provider=heroku --app=$HEROKU_PRODUCTION_APP_NAME --api-key=$HEROKU_API_KEY
  - "curl -n -X POST https://api.heroku.com/apps/$HEROKU_PRODUCTION_APP_NAME/ps -H \"Accept: application/json\" -H \"Authorization: Bearer ${HEROKU_API_KEY}\" -d \"command=bundle exec rails db:migrate\""
  only:
  - tags

如果您希望能够在您的 GitLab CI 进程中使用 Heroku CLI 的全部功能(包括如果由于任何原因迁移失败则构建失败),您也可以尝试这种方法这将安装 Heroku CLI 并将 Heroku 命令的状态代码传送回 GitLab,当然还有命令行输出。在命令行上使用没有凭据的 heroku run 需要将 HEROKU_API_KEY 环境变量设置为可以访问相关应用程序的密钥。

before_script:
  - echo "deb http://toolbelt.heroku.com/ubuntu ./" > /etc/apt/sources.list.d/heroku.list
  - wget -O- https://toolbelt.heroku.com/apt/release.key | apt-key add -
  - apt-get update
  - apt-get install -y heroku-toolbelt
  - gem install dpl

stages:
  - deploy

test_on_heroku:
  type: deploy
  script:
    - dpl --provider=heroku --app=my_heroku_app --api-key=$HEROKU_API_KEY
    - heroku run <your command here> --exit-code --app my_heroku_app

我实际上 运行 我在 Heroku 实例上的测试可以肯定,环境是完全一样的。这就是它真正派上用场的地方。

要更新@huesforalice 的答案,这也适用于新的 Heroku CLI,它于 2016 年 11 月取代了 Heroku Toolbelt:

before_script:
  - apt-get update
  - apt-get install apt-transport-https
  - echo "deb https://cli-assets.heroku.com/branches/stable/apt ./" > /etc/apt/sources.list.d/heroku.list
  - wget -O- https://cli-assets.heroku.com/apt/release.key | apt-key add -
  - apt-get update
  - apt-get install -y heroku
  - gem install dpl

staging:
  type: deploy
  variables:
    HEROKU_API_KEY: $HEROKU_STAGING_API_KEY
  script:
    - dpl --provider=heroku --app=$HEROKU_STAGING_APP --api-key=$HEROKU_STAGING_API_KEY
    - heroku run rails db:migrate --exit-code --app $HEROKU_STAGING_APP
  only:
    - master

production:
  type: deploy
  variables:
    HEROKU_API_KEY: $HEROKU_PRODUCTION_API_KEY
  script:
    - dpl --provider=heroku --app=$HEROKU_PRODUCTION_APP --api-key=$HEROKU_PRODUCTION_API_KEY
    - heroku run rails db:migrate --exit-code --app $HEROKU_PRODUCTION_APP
  only:
    - tags

进一步改进@huesforalice 和@Jimmy Bosse 的答案 - 如果你想

  • 避免将 Heroku CLI 安装放在全局 before_script 但仅在部署阶段使用它
  • 同时,避免将安装片段复制粘贴到不同的阶段

您可以使用 YAML 锚点来 DRY up

before_script:
  # the global before_script
  - gem install bundler --no-document
  - bundle check || bundle install --jobs $(nproc)

.deployment_before_script: &deployment_before_script
  before_script:
    - echo "deb http://toolbelt.heroku.com/ubuntu ./" > /etc/apt/sources.list.d/heroku.list
    - wget -O- https://toolbelt.heroku.com/apt/release.key | apt-key add -
    - apt-get update
    - apt-get install -y heroku-toolbelt
    - gem install dpl

# other stages...

staging:
  stage: deploy
  <<: *deployment_before_script
  script:
    - dpl --provider=heroku --app=$HEROKU_APP_STAGING --api-key=$HEROKU_API_KEY_STAGING
    - heroku run bundle exec rails db:migrate --exit-code --app $HEROKU_APP_STAGING
  only:
    - master

production:
  stage: deploy
  <<: *deployment_before_script
  script:
    - dpl --provider=heroku --app=$HEROKU_APP_PRODUCTION --api-key=$HEROKU_API_KEY_STAGING
    - heroku run bundle exec rails db:migrate --exit-code --app $HEROKU_APP_PRODUCTION
  when: manual
  only:
    - tags