船木俊介「デジタル進化論」

スーパーソフトウエア東京オフィス代表&キッズラインCTO

Wercker自動デプロイ、pull request - Webサービス開発フロー(6)

前回からの続き

7.Werckerで自動デプロイの設定

capコマンドを叩くことでデプロイする場合は以上で問題ありません。ただ、ここではWerckerを使用してGitHubにpushすると自動でデプロイまで行われるように設定します。

ローカル,GitHub,EC2,CIサービス(Wercker)と登場人物が多くて分かり難いですが、ポイントはWerckerがEC2にSSH接続できればいいというところです。先ほどローカルで~/.ssh/configで一時的に行った接続設定を、今度はWerckerに任せるイメージです。ここではEC2のpemkeyをそのまま使いますが、実際はデプロイユーザなどの設計を正しく行ってください。

WerckerでSettingsから「DEPLOY TARGETS」、「Add deploy target」から「custom deploy」を選択します。

aw5

Deploy target nameには「production」、auto deploy successful build toをチェックして、「master」を入力します。この設定で、masterブランチのビルドが成功した際に自動的にデプロイされるようになります。

aw6

Deploy piplineの「Add new variable」をクリックして、「WERCKER_PEM_KEY」を入力、TextにはEC2のpemkeyの内容をコピー&ペーストします。その下の「Protected」の項目はログなどに出力しないようにする設定ですので、必ずチェックを入れてください。

aw7

これで、wecker.ymlの中で$WERCKER_PEM_KEYという変数を使えるようになります。Werckerは、ビルド環境で一時的にpemkeyを作成してEC2に接続してデプロイを行います。

HipChatへの通知設定もここで行っておきましょう。HipChatのTokenは予め取得しておき、「PIPLINE」「Add new variable」でHIPCHAT_TOKENという変数を設定します。

aw8

wercker.yml

box: wercker/rvm

services:
    - wercker/mysql

# Build definition
# See the Rails section on the wercker devcenter:
# http://devcenter.wercker.com/articles/languages/ruby/settingup-rails4.html
# You will want to define your database as follows:
# services:
#   - wercker/postgresql
# See more about services on our devcenter:
# http://devcenter.wercker.com/articles/services/
build:
    steps:
        # Uncomment this to force RVM to use a specific Ruby version
        # - rvm-use:
        #       version: 2.1.5

        # A step that executes `bundle install` command
        - bundle-install

        # A step that prepares the database.yml using the database in services
        # - rails-database-yml
        - rails-database-yml:
            service: mysql

        # A custom script step, name value is used in the UI
        # and the code value contains the command that get executed
        - script:
            name: echo ruby information
            code: |
                echo "ruby version $(ruby --version) running"
                echo "from location $(which ruby)"
                echo -p "gem list: $(gem list)"

        # Add more steps here:
        # - script:
        #        name: rspec
        #        code: bundle exec rspec
        - script:
            name: Set up database
            code: RAILS_ENV=test bundle exec rake db:schema:load
        - script:
            name: Run rspec
            code: bundle exec rspec
    after-steps:
        - hipchat-notify:
            token: $HIPCHAT_TOKEN
            room-id: (HipChatのルームID)
            from-name: wercker
deploy:
    steps:
        - script:
            name: make .ssh directory
            code: mkdir -p "$HOME/.ssh"
        - create-file:
            name: write ssh key
            filename: $HOME/.ssh/id_rsa
            overwrite: true
            hide-from-log: true
            content: $WERCKER_PEM_KEY
        - script:
            name: set permissions for ssh key
            code: chmod 0400 $HOME/.ssh/id_rsa
        - cap:
            stage: production
            tasks: deploy
    after-steps:
        - hipchat-notify:
            token: $HIPCHAT_TOKEN
            room-id: (HipChatのルームID)
            from-name: wercker

編集したwercker.ymlをpushすると、ビルドからデプロイまで自動で行われます。

$ git add .
$ git commit -m 'edit wercker.yml'
$ git push -u origin master

aw10

これで完了。今回はWerckerを使用しましたが、CircleCIやJenkinsなどでも仕組みは同様です。

 

8.pull request

gitの格言

早めに、かつ頻繁にブランチを切りなさい

最後に、pull requestベースの開発の流れを見ていきます。変更のために、ブランチを切ります。

$ git checkout -b hotfix1
Switched to a new branch 'hotfix1'

例えば、一覧ページのタイトルが分かり難いので変更します。viewの文言を変更して、コミット&pushします。

$ git add .
$ git commit -m 'タイトル変更'
$ git push origin hotfix1

このブランチをmasterにマージしてもらうために、GitHubの画面でpull requestを作成します。

pr1

作成されたpull requestは、PMなどが確認して問題がなければマージします。

pr2

この段階で変更されたコードも確認します。

pr3

pull requestがmasterにマージされると、CIサービス(Wercker)はビルド、テスト、デプロイを自動的に行います。

pr4

サーバも更新されています。

pr5

masterを最新の状態にしておき、マージされて不要になったブランチは削除しておきます。

$ git checkout master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

$ git pull
$ git branch -d hotfix1
$ git push origin :hotfix1