Heroku Pipelineを使ってみる


本記事はHeroku Advent Calendar 2015 10日目の記事です。
[前記事](http://qiita.com/yo-iida/items/27af229aa6037790df97)からの続きでPipelineについて書いていきます。

Pipelineはどういう機能か一言でいうと、
「GitHubを用いた開発フローに最適化された、環境ごとのアプリケーションのデプロイおよび管理機能」
です。

コード管理とアプリケーションの環境をうまく紐付けて開発コストやデプロイのコストを削減しようという背景があるようです。

この記事ではパイプラインで実際になにができるのかを紹介していきます。

まずはざっとおさらいです。

パイプラインは次の3つの環境を管理できます。

* development
* staging
* production

さらに、特別な環境としてreview appを持っています。
review appはPullRequest(以下PR)ごとのアプリケーションです。

Herokuでは`git push heroku master`時にHeroku上にスラグを作成します。
スラグはソースコードを圧縮したアプリケーションの元になるパッケージです。

パイプラインはこのスラグのフローを管理します。
パイプラインの環境は必ずすべて使う必要はありません。
今回の例ではstagingとproductionを主に使うフローを紹介します。
パイプラインの特徴的な機能は、後段の環境にアプリケーションを反映(promote)する機能です。
stagingで確認ができたアプリケーションをproductionに反映したい場合、productionにデプロイを実行するのがこれまでの方法ですが、パイプラインを使うとスラグをproductionに反映するので通常のデプロイより圧倒的に早く、間違いが起こりません。
複数の本番環境にたいしても同様に実行することができます。

では実際にパイプラインを構成していきます。

# 1. パイプラインに登録するアプリケーションを作成する
まずはパイプラインに登録するアプリケーションを作る必要があります。
パイプラインはスラグのフローを管理する機能なので、スラグを動かすアプリケーション自体は必要な分だけ個別に作る必要があります。
ただし、review appはPRごとに自動で作成されるので必要ありません。
ここではstagingとproductionのみ作成します。

* yo-paipu(production用)
* yp-paipu-stg(staging用)

としました。

# 2. パイプラインを作成する
![add pipeline.png](https://qiita-image-store.s3.amazonaws.com/0/69774/d63fbad9-8d20-b384-bd14-abc54be49c75.png "add pipeline.png")

`Create new pipeline`をクリックします。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/69774/bf65a2c4-b9d2-9a39-e2db-2dc5a52c54b7.png "2.png")

するとこのような画面になります。
Pipeline informationにはパイプラインの名前を入力します。(yo-paipuとしました)
つぎにAdd appsから追加するアプリケーションを選択します。
先ほど作成した二つのアプリケーションの名前を入れると選択できるようになります。
また、それらをdevelopment、staging、productoinのどれに該当させるのかも選択できるようになるので設定します。

設定が完了してCreate Pipelineをクリックするとパイプラインが構成され下記のように表示されます。

![4.png](https://qiita-image-store.s3.amazonaws.com/0/69774/dc94baef-55e1-0953-46d8-d65b01a92b67.png "4.png")

ダッシュボードでは下記のように表示されているはずです。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/69774/08d9cee5-925a-b05c-2c53-521b76e5cd59.png "3.png")

# 3. GitHub連携する
PipelineはGitHubと連携して使うことが奨励されています。（しなくても使えないことはないですが）
なぜなら、PRごとのreview appの自動生成や、PRマージ時に自動でpromoteさせる機能があるからです。

今回のブランチ運用は、

* staging - developブランチ(default)
* production - masterブランチ
* review app - feature-nブランチ

としてみます。

GitHub連携はアプリケーションのDeployタブから行います。
Connect to GitHubで検索するとヒットしたリポジトリが表示されますので該当リポジトリをConnectします。

![5.png](https://qiita-image-store.s3.amazonaws.com/0/69774/7852d882-da3f-6481-25b3-af14f06f8f95.png "5.png")

ついでに自動デプロイも設定しておきましょう。

![11_autodeploy.png](https://qiita-image-store.s3.amazonaws.com/0/69774/25b58919-1c5a-eda4-fe3a-53d5567ed90b.png "11_autodeploy.png")

これで、feature-nブランチからdevelopにPRがマージされたときに自動的にstagingに反映されます。

production環境はリポジトリの連携はしますが、productionへの反映は任意のタイミングで行いたいので自動デプロイははずしておきます。

# 4.review appを有効にする。
review appはPRごとのアプリケーションを作成できるパイプラインにおける特別な環境です。
チーム開発する際には新しく追加する機能を事前にオーナーに確認するケースがあると思いますが、並行開発するブランチが増えるほどこれを用意するのは困難になります。
そんな状況を解決してくれるのがreview appです。
この機能を有効にしておくとPRを作った段階で自動的にアプリケーションが作成されます。しかもこのアプリケーションは通常のアプリケーションと同じ扱いですので、追加課金の心配もありません。
PRがマージされると自動で削除してくれる便利なものです。
有効化の手順は以下です。
パイプラインを開くと下記のような画面が表示されています。

![6.png](https://qiita-image-store.s3.amazonaws.com/0/69774/7bc96ad3-a852-23f0-f7ab-a6b796fa67a8.png "6.png")

Enable Review Appsをクリックします。

![7.png](https://qiita-image-store.s3.amazonaws.com/0/69774/8cbb4635-e533-6133-7933-456199668fc7.png "7.png")

するとこのような画面が開きます。
review appにはapp.jsonが必要なのでリポジトリにコミットを作成するよ、と言っています。
review appは自動的にアプリケーションを作成する機能なので、その際の設定をapp.jsonに書いてルートに置いておくと、Herokuがそれにしたがってreview appを作成してくれる、というわけです。

Create an app.json Fileをクリックするとapp.jsonの設定値を入力する画面になります。

![9.png](https://qiita-image-store.s3.amazonaws.com/0/69774/8ab7e652-29c8-04e7-df26-3b79bc560441.png "9.png")

![10.png](https://qiita-image-store.s3.amazonaws.com/0/69774/e806c81c-e28e-b43b-dab0-eda75e739d54.png "10.png")

コミットされてしまいますが、後からでも普通に変更をコミットすれば変更可能です。
DBを利用する場合は最低でも下記のように記載しておけば動きます。

```app.json
{
  "name": "yo-paipu",
  "description": "pipeline test",
  "env": {
  },
  "addons": [
    "heroku-postgresql:hobby-dev"
  ],
  "scripts": {
   "postdeploy": "bundle exec rake db:migrate"
  }
}

```

![8.png](https://qiita-image-store.s3.amazonaws.com/0/69774/b1f9f18e-fdfb-2d40-bb65-8326eafb5eca.png "8.png")

PRのたびに自動でreview appを作成にチェックをいれてEnableをクリックします。

![11.png](https://qiita-image-store.s3.amazonaws.com/0/69774/997129bd-9c89-722d-7617-183b0730bf96.png "11.png")

このような画面になれば有効化されています。

ここでとりあえず普通にstagingにアプリケーションをmanual deployして動作することを確かめておきましょう。
(別途`heroku run bundle exec rake db:migrate`等が必要な場合もあります)

# 5.PR→マージでstagingに自動デプロイ
さて、準備ができたので、PRを作ります。
今回は`rails g scaffold`でマイグレーションが必要なページ追加を行いました。

![add products by yo iida · Pull Request  2 · yo iida yo paipu.png](https://qiita-image-store.s3.amazonaws.com/0/69774/f31d5bcc-72eb-b046-92d0-f3f3d7cb4446.png "add products by yo iida · Pull Request  2 · yo iida yo paipu.png")


こんなかんじで、
`yo-iida deployed to yo-paipu-stg-pr-2 2 minutes ago`
と出ていますね。
PRを作るとHerokuが自動的にアプリケーションを立ち上げて、PRのほうにもこのようにメッセージを出してくれます。

![13.png](https://qiita-image-store.s3.amazonaws.com/0/69774/067c37d3-a19a-8797-0ff9-cfa4829b4b1a.png "13.png")

パイプラインのほうはこのような表示になります。
stagingとreview appを実際に開いてみると確かに差分を確かめることができました。

では、PRをマージします。

![14.png](https://qiita-image-store.s3.amazonaws.com/0/69774/e9ba342a-bb54-4fb4-ab4d-0253b6b4b3e1.png "14.png")

GitHubのほうでマージすると、パイプラインのほうで自動でビルドが始まります。
完了したらアプリケーションを開いてみましょう。

ここで、ひとつ気づくことがあるかもしれません。
stagingは手動でマイグレーションを実行しないとアプリケーションが正常に動作しません。

実は、review appはmigrationを自動で実行してくれていました。
app.jsonはreview appだけのものなのです。。
これはapp.jsonに書いたscriptsで指定したものが実行されています。

# 6. 反映(promote)
stagingに一通りの変更がマージされたらproductionに反映しましょう。

![15.png](https://qiita-image-store.s3.amazonaws.com/0/69774/7bfde9d0-5ec3-1d89-1b3c-4560363a4838.png "15.png")

stagingに現れたPromote to productionをクリックします。

![16.png](https://qiita-image-store.s3.amazonaws.com/0/69774/3ab774bf-e862-8a36-9bac-af081f8a1ba2.png "16.png")

Promoteボタンをクリックすると、即座にproductionに反映されます。

察しのいい人はわかると思いますが、実はここでもマイグレーションを手動で実行する必要があります。

残念ながらパイプラインはスラグのフローを管理するだけなので、review app以外の環境ではビルド時やpromote時のスクリプトの実行はサポートされていません。
スクリプトの実行は手動でやるかCI側から無理やりherokuコマンドを叩くようにするとか何か別の方法を考える必要がありそうです。

しかしながら、スラグの反映はとても早く終わります。（ほんの数秒）
通常のデプロイとは異なるのであえて`promote`という言葉を使っているのかなと思いました。

いろいろと注意点はありましたが、パイプラインを利用するための一通りの流れは以上になります。

# さいごに
一通り使ってみて、パイプラインは、開発フローとコード管理と環境（ステージ）をうまく結びつけたとても可能性のある機能だなと思いました。
review appからの本番反映までのフローは本当に便利でわかりやすいですよね。
ただ、上記でも書いているようにpromote時にマイグレーション等を実行できないのはデプロイ自動化において非常にネックです。
また、環境ごとにアプリケーションを用意できるのはよいですが、production以外は普通は非公開で運用する前提があるので、ダッシュボードからIP制限をかけられるようにできるとよいな、、とか
BETA版の機能なので今後の展開に期待です。