rcmdnk's blog
Last update

20150225_werckerapp_200_200

RubyのBenchmarkを使ってOctopressのgenerateでどれ位時間がかかってるか測ってみるRubyのruby-profを使ってOctopressのgenerateでどれ位時間がかかってるか測ってみる とOctopressの時間が気になってきたので何とかしようと思って来たところですが、 今のところOctopress(Jekyll)を使う限りはどうしようもないみたいなので、 時間のかかる生成作業を別の所で行いたい、 ということでwercker というCIサービスを使ってみることにしました。

Sponsored Links

wercker

werckerTravis CIと同じ様な CI Webサービスで、 現在の所まだベータバージョンです。

werckerを選んだ理由はBitbucketに対応していることと、 GitHub、Bitbucket共にプライベートレポジトリを今のところ無料で取り扱う事が出来る事です。 (Travis CIはGitHubしか使えないのとプライベートレポジトリは有料。)

今回はBitbucketのプライベートレポジトリで管理しているOctopressのソース を取ってきてビルド(generate)してデプロイする、ということをしたいので werckerのこの特徴が必要になります。

今のところベータバージョンなので無料で使える機能、ということで いつ有料になるかはわからないところですが、 有料になったらなったで考えるということで。 (ブログを見る限り2012年位から始動してるみたいです。)

CI(継続的インテグレーション)サービスまとめ・14個! - atskimura-memo

これを見ると、他にも Magnum CI というのが同じように今のところ無料でBitbucketも使えてプライベートレポジトリも使えるみたいです 1

werckerとMagnum CIは殆ど同じ様な感じですが、 共通な点として

  • 無料でGitHub/Bitbucketのレポジトリを無制限に使える。プライベートレポジトリも無制限。
  • 無制限で共同作業者を加えられる。
  • ビルドの回数も無制限。
  • クレジットカードの登録の必要なし。

といった感じ。今のところ有料のサービスを入れてないので全体的に無制限。 (クレジットカード登録云々に関して両方共わざわざ書いてありますが、 最近Webサービスで無料登録だとしてもクレジットカードの登録をさせるものが 増えてるからなんでしょうか?)

ちょっと違うのが、

wercker:

  • 同時ビルドは2つまで。
  • 1つのビルドの最大実行時間は25分まで。

追記: 2015/06/16

どうも仕様の変更があったみたいで現在はステップの最大時間は60分になっています。

サイドバーのランダムリストのアップデート

下にあるno-response-timeout(デフォルト5min)は 何も出力が無かった場合にアボートする時間の設定で、 これ以外にcommand-timeoutという値が追加されていて、 これが1つのステップの最大時間になります。

デフォルトが25分で最大60分にまで延ばせる、とのこと。

これも各ステップの最大値なので、 ステップを分ければもっと長いことも1つのwerkerタスクで出来る(かも)。

追記ここまで

Magnum CI:

  • 同時ビルドは1つまで。
  • 1つのビルドの最大実行時間は30分まで。

ということで、ちょっとでも実行時間を長く確保したい場合には Magnum CIで複数ビルドを同時に行いたい場合にはwercker、的な。 (とは言っても5分の差なのでギリギリの物はそもそも失敗する可能性が大きいので 時間を短くする方法を探したほうが良いですが。)

ちなみに、werckerは”ワーカー(worker)”と読むのが正しいようです。

CircleCI導入したのでwerckerとの比較も含めてまとめ - 月曜日までに考えておきます

werckerでのアプリの作成

追記: 2017/01/19

アプリがDockerベースに変わっていて、現在のアプリの作成方法とか boxの設定値とかがこの頃とはちょっと違っています。

追記ここまで

取り敢えずwerckerにサクッとアカウントを作成して作業していきます。

werckerでは1つレポジトリに対する作業の管理のくくりをアプリケーションと言います。

アプリケーションの登録は ウェブインターフェース を使うか、 コマンドライン でも出来るようにPython製のコマンドが用意されています。

取り敢えずウェブでやれば簡単にできますが、 今回のアプリケーションとしては以下の様な流れ。

  • 左のタブからApps+Addを押すなどして作成画面へ移行。

weckeraddapps

  • Choose a Git provider: Bitcucketを選択。

weckerapp

  • Select a repository: Octopressのソースを置いてるレポジトリを選択。
  • Configure access: Add the deploy key to the selected repository for meを選択。
    • プライベートレポジトリを選択するとこれがrecommendされます。
    • パブリックレポジトリだとwercker will checkout the code without using an SSH keyがrecommendされます。

weckerconfigaccess

  • Setup your wercker.yml: 実行内容を指定するwercker.ymlを用意してくれます。 レポジトリの内容を見て適当な物を作ってくれるので、 それをコピーしてきてそれを元に自分の行いたいものを書いていきます。
  • Awesome! you are all done!: ここでFinishを押すとアプリケーションを作成しますが、 押す前にMake my app publicにチェックが入ってないことを確認しておきます。 公開したい場合にはチェックを入れますが、 今回はプライベートレポジトリからのプライベートなビルド、ということで非公開に。

weckerprivate

取り敢えずこれでアプリの作成は完了。

ssh鍵の作成

アプリケーション作成後、SettingsSSH keysから レポジトリへアクセスするためのSSH鍵を作成します。

weckersshkeys

名前は適当に与えて、鍵を作成すると、 上で、SSH鍵を使う設定を選んだ場合、 一番最初に作られる鍵(最初の1回だけ?)はそのまま指定したレポジトリ側へ登録されます。 また、この時(一番最初に)作られた秘密鍵の方はsshでのデフォルトの鍵として登録されるようです。

Bitbucketへ行ってみるとwerckerから登録された鍵が追加されているはずです。

bitbucketsshkeys

Bitbucket用の鍵が作成できたら、もう一つ、 GitHubへpushするための鍵を作成します。 今回はBitbucketからソースを取ってきて、最終的に GitHubのGitHub pagesへ公開するのでそのレポジトリへpushするための鍵です。

適当にgithub_key等という名前で鍵を作成して、 表示される公開鍵をコピーします。

こちらは手作業でGitHubの該当レポジトリへ行き、 レポジトリの設定からDeploy keysにこの公開鍵を登録します。

TOKENを使った方法もありますが、TOKENはアカウント全体への操作を可能するのに対し、 SSH鍵だとレポジトリ毎にも登録できるのでより安全です。 (werckerの場合だとさらに上のように鍵の管理も簡単です。)

デプロイの設定

次に、SettingsにあるDeploy targetsでデプロイの設定を行います。

Add deploy targetの中にはGitHubとかはないので、 Custom deployを選択して作成。

Deploy target nameはなんでも良いですが、 Auto deployauto deploy successful builds to branch(es)へチェックを入れ、 該当するブランチ名を登録します。

ここで、少し勘違いしてしまいましたが、 ここで登録するブランチ名はソースを取ってくる方のブランチ名です。 (今回の場合だと、Bitbucketにあるrcmdnk.github.comというレポジトリのsourceというブランチ。)

最初、デプロイ先のブランチ名を書いてて自動でデプロイが稼働しなくて困りました。。。

また、先ほど生成したGitHub pages用の鍵を使う準備もしておきます。 Auto deployのブランチの設定より更に下に、 Deploy pipelineという項目があり、Add new variableと言うボタンがあるかと思います。

ここで、SSH key pairを選んで、先ほどのgithub_keyという鍵を選択すると、 公開鍵の登録が出来ます。

werckerdeploy

Environment variableGITHUB_DEPLOY_KEYとでも入れておくと、 後でwercker.ymlの中で、GITHUB_DEPLOY_KEY_PUBLICGITHUB_DEPLOY_KEY_PRIVATE という値で参照できるようになります。

wercker.ymlの設定

ここまででwerckerサーバー側の設定は済んだので、 今度はソースのレポジトリ側へwercker.ymlを作成し、 実際に行いたいことを書いていきます。

wercker.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
box: wercker/rvm
no-response-timeout: 25
build:
    steps:
        # A step that executes `bundle install` command
        - bundle-install

        # A custom script step, name value is used in the UI
        # and the code value contains the command that get executed
        - script:
            name: Octopress generate
            code: |
                #sed -i"" "s/^tmp_dir.*/tmp_dir = \"$(echo $WERCKER_OUTPUT_DIR|sed "s/\//\\\\\//g")\"/" Rakefile
                #sed -i"" "s/^public_dir.*/public_dir = \"$(echo $WERCKER_OUTPUT_DIR|sed "s/\//\\\\\//g")\"/" Rakefile
                #sed -i"" "s/^destination:.*/destination: $(echo $WERCKER_OUTPUT_DIR|sed "s/\//\\\\\//g")/" _config.yml
                sed -i"" "s/^tmp_dir.*/tmp_dir = \".\/\"/" Rakefile
                sed -i"" "s/^destination:.*/destination: .\/public/" _config.yml
                rake integrate
                rake generate
deploy:
    steps:
        - script:
            name: Prepare .ssh directory
            code: mkdir -p "$HOME/.ssh"
        - create-file:
            name: Prepare ssh key
            filename: $HOME/.ssh/id_rsa
            overwrite: true
            hide-from-log: true
            content: $GITHUB_DEPLOY_KEY_PRIVATE
        - script:
            name: Set permissions for ssh key
            code: chmod 0400 $HOME/.ssh/id_rsa
        - script:
            name: Prepare gitconfig
            code: |
                git config --global user.email "rcmdnk@gmail.com"
                git config --global user.name "rcmdnk-wercker"
        - script:
            name: Deploy to github pages
            code: rake deploy["push_ex"]

こんな感じのwercker.ymlをOctopressのトップディレクトリに置いてあります。

Validate wercker.yml で文法を簡単にチェックすることが出来ます。

以下、各部分の大体の説明。

box

werckerではジョブの実行環境をboxと呼ばれる設定で管理しています。 上ではSetup your wercker.ymlで作られた物をそのまま使い、 rvm用の wercker/box-rvm というboxを使っています。

boxはGitHub/Bitbucketに置かれたbox-XXXというレポジトリ内の wercker-box.ymlというファイルで定義されています。 中ではどのソフトのどのバージョンを使うか、等が定義されています

box: wercker/rvm@2.4.0

の様にすればそのboxのレポジトリの該当のタグのものを使うことも出来ます。

環境の基本はUbuntu 12.04で、 wercker/box-default で定義されています。

wercker.ymlでboxを定義するとこのdefaultに加える形で環境を構築します。

boxは自分でも作ることが出来、 werckerでないユーザーのものも 色々とあります

基本的にはwerckerがレポジトリをチェックして用意してくれたものを使えばOKだと思います。

no-response-timeout: 25

ジョブ全体では25分まで最大使うことが出来るのですが、 デフォルトだと5分間何も出力がないと強制的に終了させられてしまいます。

これを避けるためには定期的に何か出力するようなプログラムにしておくか、 werckerの設定でこれを引き伸ばすことも出来ます。 no-response-timeoutの値がこの時間(分数)を決めるので 上の様に25分を指定しておけば実質的にこの出力なしによる強制終了は 無効にすることが出来ます。

build

実際にビルドやテストなどを行う箇所です。 stepsという値に実行コマンドを与えていきます。

与えるものは step と呼ばれるものです。 これもGitHub/Bitbucketのレポジトリで定義されていて step-XXXという名前のレポジトリを使います。

中にはwercker-step.ymlrun.shが用意されています。 wercker-step.ymlの方では名前やバージョンなどの定義が書いてあり、 run.shが実際に実行されるスクリプトです。

wercker/step-bundle-install

が上で使ってるbundle-installですが、 run.sh は基本的にはbundle installを実行するためのものです。

中で $WERCKER_BUNDLE_INSTALL_PATH等の環境変数を使っていますが、 これは

steps:
    - bundle-install:
        path: /path/to/install

みたいにするとWERCKER+step name+val nameみたいな値として run.shの中で使える様になります。 (逆にrun.shの中の値を変更したい場合にはこんな感じでWERCKERとステップ名を 除いた部分を設定してあげればOK。)

wercker/bundle-installでも同じですが、 werckerがユーザーとして所有して居る物はユーザー部分を取り除いて レポジトリのstep-を除いた部分だけで設定できる様です。

stepの中にはscriptという特殊なstepがあり、これを使うと 通常のコマンドが使えます。

nameで実行するコマンド群の名前(実行結果の表示に使われる)、 codeで実行するコマンド群を指定します。

code: command

の様に1つのコマンドを指定するか、

code: |
    command1
    command2

の様にcode: |に続いて以下に複数のコマンドを書くことも可能。

また、if文とか使って複数行に分けて書きたいときは

code: >
    if [ $a -eq 1 ];then
    echo "one"
    fi

みたいに書くことも出来ます。

上のbundle-installも取ってきたソースのトップディレクトリで installコマンドを実行したいだけなら

steps:
    - script:
        name: Install gems
        code: bundle install

としても同じことです。

上でやってることはまず、 octogray ではpublicディレクトリなどをtmp_dirで指定されたディレクトリ以下に置いていて 2、 これが外部のディテクトリになってwerckerでの環境だと上手く使えないので、 Octopressのディレクトリ内にpublic_deployディレクトリを置くようにしています。

Rakefileや_config.ymlの中で設定してるもので変更が必要な場合は適時。

後は一応rake installしてからrake generateしています。

deploy

こちらはDeploy targetsAuto deployが指定されている場合に、 該当ブランチでビルドが成功した場合に実行されます。

もしくはビルド終了後、Webインターフェース等からデプロイを実行する事もできます。

書き方はbuild同様stepをリストする形です。

今回はcloneしてきたレポジトリとは別のレポジトリへpushするので、 GitHubの方のDeploy keysに指定したSSH鍵の登録を行います。

create-fileというstepで簡単にファイルを作成することが出来ますが、 ここで上で指定した$GITHUB_DEPLOY_KEY_PRIVATEid_rsaへ書き込んでいます。

また、gitのuser情報がないとpushするときに

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident <ubuntu@wercker.(none)> not allowed

文句を言われて失敗するので適当な情報を入れておきます。

最後にデプロイしてるところではpush_exを使ってますが、 これは Octopressのpublic/_deployディレクトリの変更 の所で作ったタスクで 毎回レポジトリをinitしてリモートレポジトリを一から上書きするタスクです。

もし、通常のpushを使ってる場合で_deployディレクトリがソースに含まれないような場合、 一度

code: git clone git@github.com:rcmdnk/rcmdnk.github.io.git _deploy

の様な作業を入れてレポジトリを用意する必要があります。

取り敢えず以上用意して、wercker.ymlをレポジトリのトップディレクトリに追加して pushすればビルドが走り、deployまでしてくれます。

その他感想とか気になったこととか

  • $WERCKER_OUTPUT_DIR

ビルドが終わるとdeployで作業を行うためのpackageを作成して保存します。 この際、$WERCKER_OUTPUT_DIRで設定されているディレクトリに何かしらの ファイルなどが加えられていればこのディレクトリが保存され、 deploy時にこのディレクトリを取ってきて作業を行うことになります。

もしこのディレクトリが空の場合、ビルド時に最初に取ってきたレポジトリの ディレクトリをそのまま保存してdeployでも使います。

上の作業ではdeploy時にもrakeコマンドとかを使いたかったので build時と同じ環境にするため $WERCKER_OUTPUT_DIRを使わずOctopressのディレクトリ内に publicを作って作業しています。

もし、ビルドしたpublicディレクトリをそのままGitHub pagesへ繋げて pushするような作業を作るならpublic$WERCKER_OUTPUT_DIRにしてしまってdeploy時にはそれだけを使う、 ということも可能です。 (lvivier/step-gh-pages等、 それ用のstepもあるので簡単に出来ます。)

$WERCKER_OUTPUT_DIRにしたい場合には中に/が含まれてるので sedとかで変換する場合には注意して上のコメントになってる所みたいな感じにエスケープしてあげる必要があります。

  • submoduleを入れてる場合には注意が必要

werckerに限らないですが、上の作業ではBitbucketの特定レポジトリ用に作った SSH鍵を使っているので、 submoduleとしてGitHubの他のレポジトリとかを使ってたりして、 それをsshプロトコルで取ってきたりしてると認証が通らず失敗します。

なので、取り敢えず.gitmodules.git/configの中で 該当するgit@github.com:...の部分を https://github.com/...へと変更しておきました。 (実際にはさらに.themes/octogray/.gitmodules.git/modules/.themes/octogray/configも変更。)

  • 反応は結構早い

Travis CIとかと比べてもpushしてからの反応が早い気がします。

  • ビルドが途中で止められない?

Webやコマンドをみてもビルドを途中で止める方法が分かりませんでした。 普通に安定して使う分には余り問題無いですが、 一度に走らせられる物が2ジョブまでなので ちょっと間違えてすぐに次の物を試したい、みたいなときにはちょっと不満があります。

  • Gitのバージョンが1.7.9.5でちょっと古い

    git branch -u …

みたいなことをすると-uオプションなんてない、と言われてしまう。 Gitの新しいバージョンに依存するようなコマンドを使いたい場合には boxで新しいGitをインストールするものを選択(あれば)するなり作るなりするか stepの途中でインストールするなりする必要があります。

  • YAMLのインデントが必ず4つ必要

最初に用意してもらえるwercker.ymlのインデントが4つだったので それをインデントだけ2つにして送ってみたところ

Setting up environment...
Setup environment failed:
Invalid wercker.yml:

Please make sure the indentation and syntax of your wercker.yml file is correct.
See the wercker dev center for examples and more information: http://devcenter.wercker.com/articles/werckeryml

build/steps/1 is not of required type.

こんな感じのエラーが。 Validate wercker.yml で試してみても同じようなエラーが出ます。

もう一度werckerが作ってくれた物を取ってきてそのまま書いてみると上手く行きます。 同じような事を言ってる人も居たので 3、 どうもインデントの数は4つしか許されない様です。

Sponsored Links
  1. CloudBees も無料で300分まで、とありますが、HPを見る限りではコレはなくなったのか 今はEnterprise Trial、と言うのがあるだけです。

  2. Octopressのpublic/_deployディレクトリの変更

  3. Middleman 製の GitHub Pages サイトを Wercker で自動デプロイ - Qiita

Sponsored Links

« Rubyのruby-profを使ってOctopressのgenerateでどれ位時間がかかってるか測ってみる Firefoxのスタートページがマルウェアに汚染されたみたいになってびっくりした »