Pull RequestごとにStorybookがビルドされたら最高じゃね?

merpayでは積極的にStorybookを活用してコードと見た目の両方の観点でレビューを行なっていますが、Pull Requestが飛んでくるたびに該当ブランチをpullしてローカルでStorybookを起動するのが大変という運用上の問題を抱えていました。

そこでソリューションチームの協力のもと、PRが作成されるたびにCIからGAE上にユニークなpathをもったStorybookを配信する仕組みが導入されたのが先週のこと。とてもめでたい👏👏

f:id:andoshin11:20180407223751p:plain

これによってPRのデザインをチェックする時もURLをクリックするだけでよくなりました。

UI開発の概念がひっくり返るほど便利だったので、この仕組みをプライベートの開発でも導入したいと思います。

やりたいこと

  • Storybookをホスティングする環境(URLの共有だけで完結するもの)を作りたい
  • Pull Requestが作成されるごとに自動で新しいURLを発行したい
  • Pull Requestがクローズされたら上記の環境を自動で破壊したい

これらの要件を達成するため始めは社内のスクリプトを丸ごとパクろうかと思いましたが、プロジェクトごとにGCPを設定するのはなかなか大変なので別の方法を模索してみます。

Heroku Review Apps

Heroku Review Appsとは、Herokuにpipelineを設定することでPull Requestが作成されるたびに独自のステージング環境を作成してくれるものです。

さらにPull Requestがクローズされたらそのステージング環境を一定時間後に破棄してくれるなど、今回の要件にピッタリの機能が詰まっています。こいつを今回は使っていきましょう!

プロジェクトの立ち上げとStorybookの設定

いつものようにvue-cli 3.0でプロジェクトを立ち上げました。

gyazo.com

RouterやStoreの設定を自動でやってくれるのでいつも重宝しています。以下の記事を参考にしてこちらにStorybookを設定。

studio-andy.hatenablog.com

シュッとButton componentを作成します。

gyazo.com

GitHubレポジトリとHerokuアプリの作成

GitHubにレポジトリを作成して masterをpush。Heroku側でもアプリを作成して接続します

f:id:andoshin11:20180407230416p:plain

f:id:andoshin11:20180407230430p:plain

StorybookをビルドしてExpressで配信する

package.jsonにコマンドを一行追加。

"build-storybook": "build-storybook -c .storybook -o storybook-static"

このコマンドを実行することでStorybookが静的なページとしてビルドされますが、このままではHerokuで公開できません。

そこで今回はExpressをHeroku上で動かしてそこから配信してみようと思います。まずは Expressを追加。

$ yarn add express

server.jsを作成

// server.js
var express = require("express");
var path = require("path");
var serveStatic = require("serve-static");

app = express();
app.use(serveStatic(__dirname + "/storybook-static"));

var port = process.env.PORT || 5000;
app.listen(port);

そしてHerokuにデプロイする時に実行されるコマンドを package.jsonに追記します

"heroku-postbuild": "npm run build-storybook",
"start": "node server.js"

heroku-postbuildはHeroku上で自動で npm installが走ったあとに実行されるフックで、 startはデプロイ完了時にトリガーされるものです。

最後にHeroku上でAutomatic DeployをEnableにし、 masterブランチがpushされたら自動でデプロイが走るように設定します。

f:id:andoshin11:20180407232327p:plain

この状態で masterをpushもしくは手動デプロイし、ビルドされたStorybookが無事にExpressから配信されていることを確認

f:id:andoshin11:20180407232459p:plain

f:id:andoshin11:20180407232732p:plain

これで最新のStorybookがHerokuから配信されるようになりました🎉

Heroku Review Appsの設定

ここからはPRごとに配信を行うためにHeroku Review Appsの設定を行なっていきます。まずは "create new pipeline"で storybook-review-appという名前のpipelineを作成。(ここの名前は自由です)

f:id:andoshin11:20180407233016p:plain

f:id:andoshin11:20180407233200p:plain

そうするとpipelineの管理画面が出てくるので画面左端より "Enable Review Apps..."を選択

f:id:andoshin11:20180407233301p:plain

f:id:andoshin11:20180407233404p:plain

Enableにするとプロジェクト内で app.jsonファイルを作成するように言われます。 app.jsonの中身はGUIからポチポチ設定できるのですが、今回は特に触らなくて大丈夫です。Buildpackが nodejsになっていることだけ確認しておいてください。

f:id:andoshin11:20180407233719p:plain

f:id:andoshin11:20180407233731p:plain

最下部の "Commit to Repo"を押すとプロジェクトの masterブランチに自動で app.jsonがcommitされます(ちょっと気持ち悪い)

f:id:andoshin11:20180407234039p:plain

最後にReview Appの設定を行なって完了です。Destroyの期限は最長30日まで設定できますがとりあえず1日で問題ないでしょう。

f:id:andoshin11:20180407234149p:plain

PRを作成してみる

Heroku Review Appsがちゃんと動作するか実際にテストしてみましょう。ボタンの文言だけ変更する簡単なPRを作成

f:id:andoshin11:20180407234543p:plain

するとpipeline上で自動でアプリのビルドが始まります

f:id:andoshin11:20180407234524p:plain

ログも見れちゃう。

f:id:andoshin11:20180407234618p:plain

ビルド完了。

f:id:andoshin11:20180407234757p:plain

f:id:andoshin11:20180407234822p:plain

すごい!新しいバージョンが配信されてる!!

f:id:andoshin11:20180407234931p:plain

そしてPRのスレッド上にもデプロイが完了した旨の通知が届いています。これをSlackで受け取ったりすると良さそうですね。

f:id:andoshin11:20180407235044p:plain

URLもおしりにPRナンバーが付与されており、ユニークであることがわかります。

PRをクローズする

PRをマージしてクローズしてみました

f:id:andoshin11:20180407235201p:plain

f:id:andoshin11:20180407235449p:plain

一瞬で環境が消えた😲めっちゃ優秀

まとめ

Heroku Review Appsが予想の数段上を行く優秀さでした。これでいつでも開発メンバーやデザインチームの手を煩わせることなくレビューしてもらうことができます。Heroku自体にBasic認証などを設定しておけばプライベートプロジェクトでも大丈夫。

みなさんも(Herokuの無料枠に注意して)どんどんStorybookを育てていきましょう。今回のコードは下に貼っておきます。

github.com

P.S.

HerokuでNode.jsが動くならそもそも毎回静的ファイルをビルドしなくて良かった説ある...