くりにっき

フルスタックキュアエンジニアです

Wercker使っててClassic stackからWorkflowに移行した

以前構築していた Wercker のCI環境をClassic stack(古いCI環境)からworkflow(一番CI環境)に移行したのでメモ

前提

sue445.hatenablog.com

手順

Classic stackからDocker stackを経由してworkflowに移行します。一気にClassicからworkflowまでいけないこともないのですが、Classic stackとDocker stackの互換性がないのと、一度workflowにしたらClassicに戻せないので途中でDocker stackに移行するのがいいと思います

Classic stackからDocker stackに移行

Classic stack だとCI環境に Wercker Registry のboxを使いますが、Docker stackだとDockerのイメージを使うのでそのための移行です

wercker.ymlの差分はこんな感じ

-box: sue445/rvm-vagrant-digitalocean@1.1.1
 +box: drecom/centos-ruby:2.3.1

あとはbox内で行ってたVagrant周りのセットアップをスクリプトに移動してました。

Vagrant込のDockerfile作ってもよかったのですが、あまりオレオレイメージを作りたくなかったので既存のイメージを使う形にしました。(Vagrant本体とVagrantプラグインのインストールで20秒くらいだったのでまあ許容範囲かなと)

ハマったこと1. Vagrant の synced folderでエラーになるようになった

エラーの内容メモるの忘れたので詳しい状況は覚えてないですが、rsyncでエラーになるようになりました(使ってたイメージとの相性?)

調べても長引きそうだったし今回のケースだとローカルからsshごしにitamaeとserverspecを実行する関係でsynced folderは不要だったので無効化して逃げました。。。

     if ENV["WERCKER"] == "true"
+      override.vm.synced_folder ".", "/vagrant", disabled: true
       provider.ssh_key_name = "wercker-#{ENV['WERCKER_GIT_REPOSITORY']}"
       override.ssh.private_key_path = "~/.ssh/id_rsa.vagrant"
     else

ハマったこと2. Dockerの中でネストして bundle exec するとエラーになる

このissueと同じ現象でした

github.com

自分の場合 bundle exec rake itamae:$HOST の中で

sh "bundle exec itamae ssh --host=#{host} --vagrant --node-yaml=recipes/node.yml recipes/install.rb"

のようなrake taskを実行するとvagrantが見つからないみたいなエラーになったので、bundle exec の中で bundle exec を呼ばないようにしました

-      sh "bundle exec itamae ssh --host=#{host} --vagrant --node-yaml=recipes/node.yml recipes/install.rb"
 +      sh "itamae ssh --host=#{host} --vagrant --node-yaml=recipes/node.yml recipes/install.rb"

この時点の差分

https://github.com/sue445/itamae-plugin-resource-encrypted_remote_file/pull/7/files

stackを切り替える

Settings -> Options -> Infrastructure stack よりプルダウンを切り替えてSwitch。

f:id:sue445:20160802015207p:plain

ボタン押すだけなら何か合ってもまだClassicに戻ってこれます

修正をpushする

stackを切り替えた後に修正したやつをpushしないと正常にビルドされないので注意

Docker stackからworkflowに移行

メールフォームから随時申請します

Docker stackを有効にすると上の方にWorkflowsって出てるのでそれをクリック

f:id:sue445:20160802020307p:plain

Request this app to be migrated to workflows のボタンをクリック

f:id:sue445:20160802020405p:plain

メールフォームから申請

UserIDとApplicationIDは入力済みの状態なのであとはメールアドレスを入れるだけ(任意)

f:id:sue445:20160802020613p:plain

メール送ってからWorkflowに移行されるまでに4〜5日くらいかかりました

メールフォームでメールアドレスを書いておけば移行後にメールが送られてくるのですが、メールの文面だけだとどのアプリに対して移行が完了したのか分かりません。

f:id:sue445:20160802020903p:plain

1つだけ申請してるのであればいいのですが、自分の場合5つくらい同時に移行依頼出したのでgmailエイリアスで区別できるようにしました

www.ajaxtower.jp

が、エイリアスつけたメアドには移行完了メールが届かなかったのでダメかもしれない。*1

Workflowの設定

Settings -> Workflow

Pipeline

最初に下の方のPipelineを追加します

f:id:sue445:20160811002149p:plain

YML Pipeline nameがymlのkeyの名前でNameがWerckerで実際に表示される名前(werckerのビルドURLにも使われる)。特にこだわりがなければ両方同じでいいと思います

f:id:sue445:20160811002324p:plain

追加後に Report to SCM にチェックを入れないとPullRequestでビルドステータスが出ません

f:id:sue445:20160811002452p:plain

こういうの

f:id:sue445:20160811002614p:plain

Workflow

[+] の部分をクリックしてポチポチ登録します f:id:sue445:20160811002700p:plain

全てのブランチでビルド実行したければ * でいいと思います。(デプロイだとmaster指定とかになりそう)

f:id:sue445:20160811002819p:plain

Workflowの特徴

  • Workflow内のPipelineがそれぞれ完全に1つのDockerコンテナとして独立している
    • 各Pipelineの冒頭で docker pull してる
    • 1つ目のPipelineでbundle installしてキャッシュを作り、2つ目のPipelineでそのgemを使ってテストを実行というのはできない
    • Pipeline間でステータスを引き継がせる方法はなさそう
  • ymlのマージ機能*2 が使えるので、stepの共通化ができます
default: &default
    after-steps:
        - script:
            name: set variables
            code: |
                # NOTE: override .ruby-version in pretty-slack-notify
                export RBENV_VERSION=2.3.1
        - script:
            name: remove all vms
            code: vagrant destroy -f

        - wantedly/pretty-slack-notify:
            webhook_url: $SLACK_WEBHOOK_URL
            username: wercker_build

build-centos70:
    <<: *default  # 上で定義したafter-stepsが使えるようになる
    steps:
        - script:
            name: setup
            code: ./ci/setup.sh

        - bundle-install:
            jobs: 4

        - script:
            name: build CentOS 7.0
            code: ./ci/build.sh centos70

build-debian8:
    <<: *default  # 上で定義したafter-stepsが使えるようになる
    steps:
        - script:
            name: setup
            code: ./ci/setup.sh

        - bundle-install:
            jobs: 4

        - script:
            name: build Debian 8
            code: ./ci/build.sh debian8

Workflowのメリット

ビルド結果が見やすいってのがあります

それぞれのpipelineのコンソールログが完全に分かれているのでビルドが失敗してもログから調査しやすいです

また、ビルドが失敗した時に任意のpipelineをリトライできるってのも地味に嬉しい

たまたま build-debian8 だけ調子悪くてビルドがこけたので再実行した図

f:id:sue445:20160811003409p:plain

Workflowのデメリット

  • Pipelineの依存関係をウェブでポチる必要があるのが難点
    • GUIで操作できるのは見やすいんですが、個人的にはwercker.ymlで完結してほしかった感はある
  • Pipelineの枝分かれができるのは便利だが、合流することができない
    • 例:枝分かれしたPIpelineが全部終わった時に通知用のPipelineを1つだけ実行

上記デメリットを解消できるという点では個人的には GitLab CIが一番理想に近いと思ってます

tech.drecom.co.jp

まとめ

Dockerfile用意すれば自分の好きな環境を使ってビルドできるし、Travis CIやCircle CIと違って複雑なビルドが書けるのでWercker割とおすすめです

おまけ

移行対象のリポジトリが多すぎて Trello進捗管理していました。便利

f:id:sue445:20160810084301p:plain

1つだけ移行不要にしているのは https://github.com/sue445/wercker-box-rvm-vagrant-digitalocean の動作確認用です

*1:単に一度に申請したのが多すぎただけ説ある

*2: http://magazine.rubyist.net/?0012-YAML#l17