Carton考2014
こうするのがいいかなーと思ってる。経緯は端折って大枠だけ。Webアプリケーションプロジェクトの場合です。
cpanfileちゃんと書いてコミット
今やどこでもやってますね。scan-prereqs-cpanfile
も便利です。
開発者は各自carton install
でモジュールをインストール。プロジェクトごとにPerlをビルドしたりしてる場合は、cpanm --installdeps .
でも別に良い。
CI環境でcpanfile.snapshotを作る
CI環境は必ず以下のとおりとする。
- 本番環境と同じアーキテクチャ
- 本番環境と同じバージョンのPerl
- まっさらな状態(Globalに何のモジュールも入っていない)
CIにcarton install
もさせて、必要なモジュールをlocal/に入れてテストさせる。毎回サラからcarton install
してたら時間かかるので、git pull; carton install
とかで良い。
それでテスト回して、通ったらcpanfile.snapshotを自動コミットさせる。
追記:@soh335 先生に教えてもらったのですが、local/をサラにしないと、cpanfile.snapshotが変になることがあるようで、cpanfile.snapshot作ってコミットさせる処理はテスト回すジョブとは別のジョブにしたほうが良さそう。
サラなPerlが必須なのは以下の理由。
- cpanfileへの依存モジュールの書き漏れを防ぐ(CIで気付ける)
- グローバルにインストールされているモジュールに因ってインストールされるモジュールが変わってしまうことがある
ちなみにCartonはバージョン1以降は、0.x系と違ってグローバルなモジュールも見るようになっています。(lib::core::onlyを使ってない)
開発者は手元ではcpanfile.snapshotを更新してはならない
% git skip-worktree cpanfile.snapshot
とかやっておくと良さそう。
本番環境では carton install --deployment
CIでテスト通ったのと同じ構成のモジュールがインストールされるので安心。
carton execは使わないでラッパーシェルを使う
carton exec
と同じような環境変数を設定してくれるラッパーシェルを書いて、carton exec
の代用とする。一番シンプルな形だと以下の様な感じ。
#!/bin/sh
set -e
export PATH="local/bin:/opt/perl-5.18/bin:$PATH"
export PERL5LIB="local/lib/perl5"
exec "$@"
その他プロジェクト固有の環境変数とか、プロジェクトディレクトリへのcd
とか設定したい項目をこのシェルの中に入れ込んでおくと良い。本番兼CI用のラッパーシェルはちゃんとリポジトリにコミットしておくこと。以下の様な感じ。
% cat env-exec
#!/bin/sh
set -e
cd $(dirname $0)
export USER=app
export HOME=/home/$USER
export PLACK_ENV=production
export PATH="local/bin:/opt/perl-5.18/bin:$PATH"
export PERL5LIB="lib:local/lib/perl5"
exec "$@"
これは
% /path/to/env-exec perl ...
とかやって使う。prove
とかplackup
とかcarton install
とかもこれを噛ます。
これは、carton exec
が結構起動コストが掛かる(carton check
的なこともやってる)のでバッチ等では気になるので避けたいとか、どうせperl起動するときにラッパーシェルを噛ませるので、その中でcarton exec
がやってくれるような環境変数設定処理も一緒に書いておけばいいじゃんという感じです。
ちなみに、CI環境でcpanfile.snapshot作るとかは今のプロジェクトではやってないので誰か試してみてください。