読者です 読者をやめる 読者になる 読者になる

えいのうにっき

主に Web 系技術ネタ。背景画像 is powered by grass-graph.shitemil.works

awesome_events の push-to-deploy はじめました(master / feature)

2014年のふりかえりエントリも書いたし、今年はもうブログ書かないと思った?…残念!むしろいろいろと遊んでみてるのでした!

ってことで、表題の件。

前提

awesome_events は、CircleCI による CI まではできているという状態。

awesome_events とは、"パーフェクト Ruby on Rails" のサンプルアプリケーションで、a-know は既に写経済み

パーフェクトRuby on Rails

パーフェクトRuby on Rails

今回やりたいこと

  • awesome_events の master ブランチに push が行われ、そのテストが通ったら、master ブランチがそのまま heroku にデプロイされるようにしたい
  • それと同様のことを、feature ブランチでも行いたい
    • feature ブランチの内容を、staging 環境(に見立てた heroku app)にデプロイしたい。

効果・効能

heroku への手動デプロイが不要になる。また、全ての変更を feature ブランチ(PR)を通して行うようにすれば、その変更を master ブランチにマージする前に heroku 環境で確認することができる。

つまり

CircleCIでfeature branchをHerokuに継続deploy - Masatomo Nakano Blog の記事の内容ができれば良い!

やったこと

まずは master ブランチ -> 本番用 heroku app、の実現

下準備

もちろん CircleCIでfeature branchをHerokuに継続deploy - Masatomo Nakano Blog を参考に。

deploy 用の shellscript が下記のようになっていたので、それぞれ手入れ。

  • 上記サイトの方のサイトから毎回 curl するようになっていた
    • 自分のところ(s3 に置いた)から curl するように
  • デプロイ先の heroku app が、何らかの organization に属する前提だった

あとこれも上記ブログには書かれているのだけど、

  • heroku への SSH key の登録
  • HEROKU_USERHEROKU_API_TOKEN を、CircleCIのEnvironment variablesに設定する(deploy script から参照される)

これらもやっておく必要がある。

heroku への SSH key の登録は、CircleCI の当該プロジェクト設定メニュー Continuous Deployment の heroku 項目から行えるのでそれで済ませちゃうのが一番簡単かな。

HEROKU_USER は heroku に登録されているメールアドレス、HEROKU_API_TOKEN は heroku の Manage Account > Account タブの下の方で見れる、API Key の値でおk。

上記のようなことを含めた対応は、全てこの PR にまとめてますので、よろしければ。

実際の動き

PR(ブランチ)に対しての CI は走るが、今回はまだ production 向けのデプロイしか準備してないので、CI が通ったからといってこの段階ではまだなにも行われない。

f:id:a-know:20141230130721p:plain

f:id:a-know:20141230130733p:plain

肝心なのは、これが master ブランチにマージされてからの動き。

実際にマージしてみると、まず master ブランチの CI が走る。これは今まで通り。

f:id:a-know:20141230131011p:plain

おお、deploy script が正常に走った…

f:id:a-know:20141230131038p:plain

いぇあ!deploy された!☆-(ノ゚Д゚)八(゚Д゚ )ノイエーイ

feature ブランチの内容を staging 用途の heroku app にデプロイする

考えなきゃいけないこと

ここまでで実施した production 用のものは簡単だ。なぜなら

  • デプロイ対象は master ブランチ固定
  • デプロイ先の heroku app も固定(awesome-events-production.herokuapp.com
    • 必要な configuration(環境変数とかアドオンとか) も既にされている前提で良いことが多い(と思う)

といった要因があるからだ。feature ブランチの内容を staging 用途の heroku app にデプロイするとなると、多分下記のようなことを考えなければならないはず。

  • デプロイ対象は master ブランチ以外の全てのブランチ
  • デプロイ先の heroku app は可変
    • app がひとつしかないと、いつ他者の feature ブランチの内容で deploy されてしまうかわからないので、デプロイ先としては複数あるべきだろう

ここらへん、上記ブログではどのように解決しているのか、も考えながらやってみたい。

“デプロイ対象は master ブランチ以外の全てのブランチ” の対処

これは簡単。circle.yml には下記のように記述ができるから、あとは CircleCI に頑張ってもらえば良い。

deployment:
  feature:
    branch: /^(?!^master$).+$/
    commands:
      - ./script/staging_deploy.sh

“デプロイ先の heroku app は可変” の対処

これをどのように実現しているかを確認するため、上述ブログで使用されているスクリプトを少し読んでみるとー。

#!/bin/bash -e

STAGING_APP_PREFIX="hoge-cms"
NUM_OF_STAGING_SERVERS=4

DEPLOY_SCRIPT=/tmp/deploy.$$.sh
curl https://quipper-deploy-support-tools.herokuapp.com/scripts/staging_deploy.sh.txt > ${DEPLOY_SCRIPT}
. ${DEPLOY_SCRIPT}

function prepare_for_staging_server() {
  heroku addons:add redistogo:nano || : # nothing if it's already installed
  heroku labs:enable user-env-compile
  heroku config:add \
      FOO=bar \
      BAZ=hoge
}

deploy

ふむ。

https://quipper-deploy-support-tools.herokuapp.com/scripts/staging_deploy.sh.txt の中身も見よう。

HEROKU_APP_NAME=`curl https://quipper-deploy-support-tools.herokuapp.com/apps --data "app=${STAGING_APP_PREFIX}&branch=${CIRCLE_BRANCH}&servers=${NUM_OF_STAGING_SERVERS}"`

…ん? デプロイ先 heroku app の名前を、どこぞの URL にリクエストすることで生成している?

試してみる。

$ curl https://quipper-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=test&servers=4"                        
hoge-staging-1%
$ curl https://quipper-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=test&servers=4"
hoge-staging-1%
$ curl https://quipper-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=piyo&servers=4"
hoge-staging-2%
$ curl https://quipper-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=huga&servers=4"
hoge-staging-3%
$ curl https://quipper-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=hoge&servers=4"
hoge-staging-4%
$ curl https://quipper-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=abc&servers=4"
hoge-staging-1%

おおおなるほど。すごい。 今回の用途でこれはちょっとオーバースペックな気もしたけど、便利なことには変わりないので、fork して自分の heroku app にデプロイして使うことにする。 (自分の heroku にデプロイする場合、mamcache の addon が必要 $ heroku addons:add memcachier 。要クレカ登録。)

$ curl https://shitemil-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=hoge&servers=4"
hoge-staging-1%
$ curl https://shitemil-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=hoge&servers=4"
hoge-staging-1%
$ curl https://shitemil-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=fuga&servers=4"
hoge-staging-2%
$ curl https://shitemil-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=piyo&servers=4"
hoge-staging-3%
$ curl https://shitemil-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=moga&servers=4"
hoge-staging-4%
$ curl https://shitemil-deploy-support-tools.herokuapp.com/apps --data "app=hoge&branch=poko&servers=4"
hoge-staging-1%

おk!

以上を踏まえてやってみる

今回も PR 作ったよ。だいぶ試行錯誤しちゃったけど。

  • feature ブランチをデプロイするための shellscript(scirpt/feature_deploy.sh。circle.yml で指定しているもの)を作成
  • その shellscript から curl して使用される script も、自分の管理下に配置してそれを用いるように修正
  • heroku app 名の生成をするための deploy tool も、自分のものを使うように変更

環境変数の設定も shellscript として書いてやらないといけないのがちょっともにょるけど、production 用のものではないし、目を瞑る。

ただ、今回のアプリケーションの場合 DB のマイグレーションが必要で、最初はそれを prepare_for_staging_server() の中で書いてやってたんだけど、それが呼ばれるのは git push の前なので、このままだと「rake がない(bundle install されてないよ)」と怒られてしまう。

なので、git push の後ろで setup_for_staging_server() を呼ぶように手を入れ、そこで heroku run rake db:migrate してやることにした。

  prepare_for_staging_server

  # https://github.com/quipper/deploy-support-tools/pull/5#issuecomment-36588889
  [[ ! -s "$(git rev-parse --git-dir)/shallow" ]] || git fetch --unshallow
  GIT_TRACE=1 git push -f heroku ${CIRCLE_SHA1}:refs/heads/master

+ setup_for_staging_server

  notify_all

実際の動き

ここまでできたら、最後に circle.yml に追記をして push。

この push により CI が走り、テストが問題なければ、staging 用途の heroku app が作成され、そこに feature ブランチの内容でデプロイされるはずだ。

f:id:a-know:20141230131915p:plain

CI が走り…

f:id:a-know:20141230131933p:plain

イェイ!ちゃんと staging 用途の heroku app が作成され、そこにデプロイされたね!

このままこの PR をマージすれば、master の CI が走り、テストOKならそのまま本番用の heroku app にデプロイされるはず。マージボタンポチー

f:id:a-know:20141230132029p:plain

グレイツ!!



follow us in feedly