RubyのBenchmarkを使ってOctopressのgenerateでどれ位時間がかかってるか測ってみる、 Rubyのruby-profを使ってOctopressのgenerateでどれ位時間がかかってるか測ってみる とOctopressの時間が気になってきたので何とかしようと思って来たところですが、 今のところOctopress(Jekyll)を使う限りはどうしようもないみたいなので、 時間のかかる生成作業を別の所で行いたい、 ということでwercker というCIサービスを使ってみることにしました。
wercker
werckerは Travis CIと同じ様な CI Webサービスで、 現在の所まだベータバージョンです。
werckerを選んだ理由はBitbucketに対応していることと、 GitHub、Bitbucket共にプライベートレポジトリを今のところ無料で取り扱う事が出来る事です。 (Travis CIはGitHubしか使えないのとプライベートレポジトリは有料。)
今回はBitbucketのプライベートレポジトリで管理しているOctopressのソース を取ってきてビルド(generate)してデプロイする、ということをしたいので werckerのこの特徴が必要になります。
今のところベータバージョンなので無料で使える機能、ということで いつ有料になるかはわからないところですが、 有料になったらなったで考えるということで。 (ブログを見る限り2012年位から始動してるみたいです。)
これを見ると、他にも 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)”と読むのが正しいようです。
werckerでのアプリの作成
追記: 2017/01/19
アプリがDockerベースに変わっていて、現在のアプリの作成方法とか
box
の設定値とかがこの頃とはちょっと違っています。
追記ここまで
取り敢えずwerckerにサクッとアカウントを作成して作業していきます。
werckerでは1つレポジトリに対する作業の管理のくくりをアプリケーションと言います。
アプリケーションの登録は ウェブインターフェース を使うか、 コマンドライン でも出来るようにPython製のコマンドが用意されています。
取り敢えずウェブでやれば簡単にできますが、 今回のアプリケーションとしては以下の様な流れ。
- 左のタブからAppsの+Addを押すなどして作成画面へ移行。
- Choose a Git provider: Bitcucketを選択。
- 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されます。
- Setup your wercker.yml: 実行内容を指定するwercker.ymlを用意してくれます。 レポジトリの内容を見て適当な物を作ってくれるので、 それをコピーしてきてそれを元に自分の行いたいものを書いていきます。
- Awesome! you are all done!: ここでFinishを押すとアプリケーションを作成しますが、 押す前にMake my app publicにチェックが入ってないことを確認しておきます。 公開したい場合にはチェックを入れますが、 今回はプライベートレポジトリからのプライベートなビルド、ということで非公開に。
取り敢えずこれでアプリの作成は完了。
ssh鍵の作成
アプリケーション作成後、SettingsのSSH keysから レポジトリへアクセスするためのSSH鍵を作成します。
名前は適当に与えて、鍵を作成すると、 上で、SSH鍵を使う設定を選んだ場合、 一番最初に作られる鍵(最初の1回だけ?)はそのまま指定したレポジトリ側へ登録されます。 また、この時(一番最初に)作られた秘密鍵の方はsshでのデフォルトの鍵として登録されるようです。
Bitbucketへ行ってみるとwerckerから登録された鍵が追加されているはずです。
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 deployでauto 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という鍵を選択すると、 公開鍵の登録が出来ます。
Environment variableにGITHUB_DEPLOY_KEY
とでも入れておくと、
後でwercker.ymlの中で、GITHUB_DEPLOY_KEY_PUBLIC
、GITHUB_DEPLOY_KEY_PRIVATE
という値で参照できるようになります。
wercker.ymlの設定
ここまででwerckerサーバー側の設定は済んだので、 今度はソースのレポジトリ側へ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 |
|
こんな感じのwercker.ymlをOctopressのトップディレクトリに置いてあります。
Validate wercker.yml: http://devcenter.wercker.com/articles/werckeryml/validate.html
で文法を簡単にチェックすることが出来ます。
以下、各部分の大体の説明。
box
werckerではジョブの実行環境をboxと呼ばれる設定で管理しています。
上ではSetup your wercker.ymlで作られた物をそのまま使い、
rvm
用の
wercker/box-rvm
というboxを使っています。
boxはGitHub/Bitbucketに置かれたbox-XXX
というレポジトリ内の
wercker-box.ymlというファイルで定義されています。
中ではどのソフトのどのバージョンを使うか、等が定義されています
box: wercker/[email protected]
の様にすればその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.ymlとrun.shが用意されています。 wercker-step.ymlの方では名前やバージョンなどの定義が書いてあり、 run.shが実際に実行されるスクリプトです。
が上で使ってる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 targetsでAuto deployが指定されている場合に、 該当ブランチでビルドが成功した場合に実行されます。
もしくはビルド終了後、Webインターフェース等からデプロイを実行する事もできます。
書き方はbuild同様stepをリストする形です。
今回はcloneしてきたレポジトリとは別のレポジトリへpushするので、 GitHubの方のDeploy keysに指定したSSH鍵の登録を行います。
create-file
というstepで簡単にファイルを作成することが出来ますが、
ここで上で指定した$GITHUB_DEPLOY_KEY_PRIVATE
をid_rsaへ書き込んでいます。
また、gitのuser情報がないとpushするときに
*** Please tell me who you are.
Run
git config --global user.email "[email protected]"
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 [email protected]: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の中で
該当する[email protected]:...
の部分を
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: http://devcenter.wercker.com/articles/werckeryml/validate.html
で試してみても同じようなエラーが出ます。
もう一度werckerが作ってくれた物を取ってきてそのまま書いてみると上手く行きます。 同じような事を言ってる人も居たので 3、 どうもインデントの数は4つしか許されない様です。