いけむランド

はてダからやってきました

野良のパッケージングを CI する仕組みをつくってみた

野良パッケージはあくまで手元でパッケージングできることを確認しているだけであり、手元の環境に依存したなにかがあると、他の人が同じレシピを使っても、パッケージングできない可能性がある。そこで CI 環境を用意してみた。

scallywag

元々 Cygwin 公式には各リポジトリの commit を hook して、パッケージング可能であるかを検証する scallywag という Web アプリがある。

こいつはキックされると、環境変数経由で渡された git repository を clone して、そこで cygport all を実行する。

ちなみに AppVayor の中で git して、別の repository の処理を動かすことが 利用規約 的に OK なのかはちょっと読み取れなかった...。(同じような CI である GitHub Actions の利用規約 では また、アクションは次の用途には使用しないでください。... gitHubアクションが使用されるリポジトリに関連するソフトウェアプロジェクトの製造、テスト、デプロイ、公開に関連しないその他の行為。 とあるため、大丈夫そうには見えるが...。)

パクる

そのような scallywag を参考に yacp を git clone して、同じことをするスクリプトをつくってみた。

github.com

この appveyor.yml を環境変数を渡して、キックする。(改行は読みやすくするために適当に入れている。)

$ curl \
    -H 'Authorization: Bearer ********' \
    -H "Content-Type: application/json" \
    -X POST https://ci.appveyor.com/api/builds -d '{
  "accountName":"fd00",
  "projectSlug":"galuf",
  "branch":"master",
  "environmentVariables":{
    "PACKAGE":"uriparser",
    "NEW_VERSION":"0.9.4",
    "CYGWIN_PACKAGES":"libgtest-devel,cmake,ninja"
  }
}'

実際の実行結果は以下の通りである。

ci.appveyor.com

最初に setup.exe で必要なパッケージをインストールする。今回、対象とする uriparsercmake (と ninja) をビルドツールとして使うため、それらをインストールするように環境変数経由で指定した。libgtest-devel も必要であるが、これは公式では配布されていないものであるため、S3 に置いておくことにした。(置き方については後述する。)

必要なパッケージのインストールが終わったら、本体である galuf.rb を起動する。

中では git clone するが、高速化のために sparsecheckoutpull 時の --depth オプション を使用している。

あとは cygport コマンドで実際にパッケージングをしてみて、成功したらディレクトリを tar.gz で固めて、アーティファクトとして、ダウンロードできるようにする。

S3

上述の通り、ビルドが他の野良のパッケージに依存している場合には、先にそのパッケージを setup.exe でインストールできる場所に公開しておく必要がある。

手元にある yacp のバイナリは計 8G くらいで、これを全部無料で簡単に公開できる場所というのはさすがに見当たらない。(きちんと探してないけど。)

また、以下の条件から、とりあえず S3 に置くことにした。

  • 元々ソースに同梱のデータが再配布禁止のため、結果的にバイナリパッケージも配布禁止になっているものがある。(これはバイナリパッケージから取り除けば、解決する気がするけど、めんどいので未着手。)
  • AppVeyor 以外からはアクセスできないようにしたい。(不特定多数にミラーとして使われると通信料で死ぬ。)

前者については必要なパッケージだけのツリーをつくって mksetupini すれば良いし、後者はバケットポリシーの設定で解決できる。

バケットポリシーの設定については以下を参照されたい。

future-architect.github.io

AppVeyor の IP アドレス群は以下で公開されている。

www.appveyor.com

これらの設定をしたバケットに必要なパッケージをアップロードする。

$ mksetupini -v --arch x86_64 --inifile ./x86_64/setup --okmissing required-package --releasearea .
$ zstd -f ./x86_64/setup
$ aws s3 sync x86_64 s3://bucket-for-appveyor/x86_64 --acl public-read --delete --exclude setup

動機

ビルドの依存関係が必要なのに書いてないという指摘があったため、今回これを構築するに至った。

github.com

前々から構想はあったが、あんまりやる気が出ないでいたため、放置してたが、これがいいきっかけになったという話です。