読者です 読者をやめる 読者になる 読者になる

CI で実行するスクリプトをリポジトリに含めるときに古いブランチでも実行できるようにする

CI で実行すべき処理をシェルスクリプトなどにしてリポジトリに含めておく、というのはまっとうな管理というかんじで望ましい。

とはいえ、新しく CI のジョブを追加するなどして新しいスクリプトリポジトリに追加した場合、追加するコミットが含まれていない古いブランチの扱いをどうするか、という悩みは尽きない。

作戦としては:

  • 古いブランチでは実行しない
  • ファイルが (ブランチにおいて) 存在すれば実行するし、なければべた書きしたシェルスクリプトを実行する

……という2つが考えられて、いままでは後者をとってきた。

しかし、メンテナンスすべきところが2つあると億劫だし、たまに修正が漏れたりする。

そこで、次のようなやりかたをとってみる:

  • ブランチにおいて存在したらそれを実行する
    • (これまで通り)
  • 存在しなければ、スクリプトが必ず存在するブランチから git-cat-file で内容を出力してパイプして実行する

「必ず存在するブランチ」とは、master など統合ブランチでもよいし、あるいはトピックブランチでもよい。
SHA1 で特定のコミットを指してもいいけど、リポジトリでバージョン管理したいという旨からするとブランチのほうが望ましいように思う。

具体的には以下のようなかんじ。

CI で実行したいスクリプト:

#!/bin/bash

set -e -u

carton install
carton exec -- prove t/

CI の設定 (シェルスクリプト):

ci_script=script/ci/run
if [[ -f $ci_script ]]; then
  bash $ci_script
else
  git cat-file blob origin/add-ci-script:$ci_script | bash -
fi

こうしておくと CI の設定は最小限度で済むし、基本的にそのブランチごとの最新のスクリプトが実行されるのでバージョン管理の恩恵が受けられる。
あと、細かい点ではあるけれどもパイプして実行しているのでごみを残さないのもよい (( ファイルを残しておくとうっかり同名のファイルをリポジトリに追加すると git-checkout に失敗してしまう ))。