RedmineのtrunkのDockerイメージを毎日自動でビルドする

なんとなくやってみた。リポジトリはhttps://github.com/vzvu3k6k/docker-library-redmine/にある。

Docker official imageのhttps://github.com/docker-library/redmineをベースにしている。このリポジトリの機能のうち、今回やりたいことに関係するのは以下の2つ。

Dockerfileを生成するために*.templateupdate.shを編集する

オリジナルのリポジトリではRedmine 3.4とRedmine 4.0に対応するためにテンプレートを使っている。今回はtrunkだけに対応すればいいのでテンプレートは不要だが、4.0-stableや3.4-stableのブランチにもそのうち対応したくなるかもしれないので元の仕組みをそのまま残している。

update.shの書き換えは特に書くほどのこともない。

*.templateはRedmineのソースのtarballをダウンロードする処理をsvnでcheckoutする処理に置き換えた。いくつか引っかかったことがあるのでメモしておく。

中間証明書問題

https://svn.redmine.org/は中間証明書を提供していないらしく、svn coするとエラーになる。

HTTPSを諦めてHTTPを使う、証明書の検証をスキップする、証明書を自分でインストールするなどの対応が必要。今回は 証明書をインストールすることにした。agileware-jp/redmine-plugin-orb#8の実装内容を使わせてもらっている。

元の実装では証明書の受け渡しにprocess substitutionを使っているが、DockerfileRUNはデフォルトでは/bin/shなのでこの機能が使えなかった。

The default shell on Linux is ["/bin/sh", "-c"]

Docker Documentation

参考: https://stackoverflow.com/q/41354864

最新のリビジョン

「リビジョン番号を指定しないときには最新のリビジョンを取得する」という動きにしたかったが、SVNで最新のリビジョンを表すにはどうしたらいいのかわからなくて困った。

パースできないリビジョン番号を指定したときに出てくるエラーメッセージ(Syntax error in revision argument)でsvnのソースをgrepして、svn_opt_parse_revision_to_rangeparse_one_revrevision_from_wordという感じで関数をたどってみて、headという文字列でいけることが分かった。

あとから急に思いついて「svn revision format」でググってみたらドキュメントがあっさりでてきた。

http://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html

よく見たらsvn help coでも普通に説明されていた。

.travis.ymlを編集する

Dockerイメージのテスト

docker-library/official-imagesにはDockerイメージが意図通りに動くかどうかざっくりテストする仕組みがあって、docker-library/redmineもそのテストを利用している。テストコードはすべてofficial-imagesリポジトリに入っていて、~/official-images/test/run.shにイメージ名を渡すとそのイメージを対象にしたテストが実行される。このとき、特に設定しなければイメージ名のネームスペースを無視してくれるので、vzvu3k6k/redmineというようなイメージ名にしておけば何も手を加えなくてもdocker-library/redmineのイメージと同じテストが実行される。これはとても助かった。

フェーズ間で情報を受け渡す

TravisCIのジョブはいくつかのフェーズに分かれている(参照: https://docs.travis-ci.com/user/job-lifecycle/)。今回はそれぞれのフェーズで以下のような処理をしている。

before_scriptフェーズで定義した環境変数はscriptフェーズからは参照できるが、deployフェーズからは参照できなかった。

フェーズごとに最新のリビジョン番号を取り直せばだいたいうまくいくが、何度もSVNサーバーにリクエストを送りたくはないし、ジョブの実行中にコミットがあるとイメージの中身とタグがずれてしまう可能性がある。

TravisCI側では特に解決策を提供していないようなので、値をファイルに書き出しておくことにした。デフォルトではdeployフェーズの前にgit stash --allでファイルがリセットされるので設定で無効にしておく必要がある。(参照: https://docs.travis-ci.com/user/deployment#uploading-files-and-skip_cleanup

シェルスクリプト

細かいところでいろいろ詰まって調べた。

感想など