行動すれば次の現実

テック中心の個人ブログ

Heroku Pipelineでデプロイ作業がかなりラクになった

今まで同じコードベースを複数のアプリで別管理していたのですが、さすがに片手で数えられないアプリ数にもなると管理が辛くなってきたので、Heroku Pipelineを導入してみました。

実際に使用してみると、痒いところに手が届く素晴らしい機能だと感じたので紹介したいと思います。

ステージごとに「複数」のアプリを載せられる

Heroku PipelineではReview App、Staging、Productionの3つのステージが存在します。

Review AppにはPR単位の使い切りの一時的なアプリを載せて、StagingとProductionにはそれぞれ該当のアプリを登録します。

StagingとProductionそれぞれアプリは1つのみ載せられると勝手に思い込んでいましたが、複数のアプリを載せられるという仕様なのは「さすがHeroku」だと感じました。

例えばパッケージソフトを扱うシステムの場合、Staging環境に「開発用アプリ」「デモ用アプリ」、Productiion環境に「A社用アプリ」「B社用アプリ」のように複数のアプリを登録することが可能です。

「開発用アプリ」のスラグを一括で「A社用アプリ」「B社用アプリ」にプロモートすることができます。これによりリリース作業の煩わしさがなくなり、とても管理が楽になりました。

また、Herokuではプロモートやデプロイ時に実行される「リリースフェーズ」に特定のコマンドを発行することができます。

Procfileに以下のように「release」の定義をすることで、今までコマンドで直接叩いていたマイグレーションも自動化できるようになりました。 マイグレーションをし忘れるというリスクもなくなり至れり尽くせりです。

Procfile

release: bin/rails db:migrate
web: bundle exec puma -C config/puma.rb

自動テストがHeroku CIで簡単に実行できる

有料にはなりますが、Heroku CIを利用することでRSpecやRubocopなどのテスト環境を簡単に構築することができます。

CIツールというと有名所だとCircle CIなどがあります。Circle CIの場合、Docker上にテスト環境を構築してテストを実行する必要があります。

シンプルにRSpecとRubocopを実行したいだけでも、それなりに複雑なDockerの定義が必要になります。 (例えばimageを定義したり、dbを構築したり、各種ライブラリをインストールしたりなど)

Heroku CIの場合、Herokuのdyno上で実行されるため、Dockerの定義が必要ありません。そのため、設定ファイルはかなりシンプルな形式になります。

app.json

{
  "environments": {
    "test": {
      "addons": [
        "heroku-postgresql"
      ],
      "scripts": {
        "test": "bundle exec rubocop app && bundle exec rspec spec"
      }
    }
  }
}

ただし、複雑な自動テストをしたい場合にはHeroku CIは向いていないかもしれません。

例えば、数回に1回何らかの理由で失敗してしまうテストを抽出して、再テストするような自動化を構築する場合、これをHeroku CI再現させるのは難しいように感じました。 (そもそもそのようなテストがある事自体が問題なのですが。。)

Circle CIではworkflowという機能を使って、テストjobと再テストjobをコントロールして失敗したテストを再テストするということが可能ですが、Heroku CIでは一筋縄では実現できなそうでした。(もしかすると方法があるのかもしれませんが)

とはいえほとんどのケースはHeroku CIで実現できますので、一考の価値はあるかと思います。