GitHub Actions で SATySFi の文書やパッケージの CI
これは SATySFi Advent Calendar 2019 6日目の記事です。 5日目はzr_tex8rさんによるSATySFiコード中で整数を16進数で書きたいでした。
3日目の記事では satysfi-docker の紹介をしましたが、今回は satysfi-docker と GitHub Actions を使って SATySFi パッケージや文書の CI をする例を紹介したいと思います。
GitHub Actions は最近正式版になった GitHub の機能で、GitHub の様々なイベント (リポジトリへのプッシュ、Pull Request、リリースの作成、などなど) に反応してワークフローと呼ばれる一連のタスクを実行できるというものです。
GitHub のサービスなだけあって GitHub との親和性は抜群で、CI サービスとしては後発なのでいろいろやりやすかったり (個人の感想です)、Microsoft パワーなのか CI サービスとしては利用制限が緩かったりします。
サンプルリポジトリ
こちらがサンプルコードが入ったリポジトリです。 簡単なものから少しだけ複雑なものまで5つの例を用意したので、順に説明していきます。
- 01-simple-example
- 02-library-example
- 03-submodule-example
- 04-satyrographos-example
- 05-custom-action-example
01-simple-example
一番簡単な例です。 doc.saty というファイルがあり、リポジトリへの push 毎にビルドできるか確認したいという状況です。 依存パッケージもなく、文書をあるバージョンの SATySFi でだけビルドできればいいならこの方法で十分だと思います。
name: build # ワークフローの名前は build (バッヂをつける際はこの名前で参照することになります) on: push # push 毎にワークフローを実行 jobs: # job 定義 build-simple-example: # job 定義の名前 runs-on: ubuntu-latest # ubuntu 環境で実行 steps: - uses: actions/checkout@v1 # ソースコードをチェックアウトしてくる # satysfi-docker を使ってビルド (この例くらいなら slim タグを使ったほうがいいですが簡単のため latest) - run: docker run --rm -v $(pwd):/satysfi amutake/satysfi satysfi doc.saty # 今回は 01-simple-example というディレクトリの下にあるのでその中でコマンドを実行 working-directory: ./01-simple-example - uses: actions/upload-artifact@master with: name: 01-simple-example # 01-simple-example という名前で、 path: 01-simple-example/doc.pdf # doc.pdf をアップロード
GitHub Actions ではジョブの中で普通に docker run
できるので、satysfi-docker の使い方の通りに satysfi を実行するだけです。
生成した PDF はアーティファクトとしてアップロード・ダウンロードできます。 勝手に zip 形式に圧縮されます。PDF はブラウザから確認できたら嬉しいのですがダウンロードして展開してとやらなければいけないのでちょっと面倒。
実行されたワークフローは Actions タブ から確認することができます。
↓ここからダウンロードできるようになります。
02-library-example
次は SATySFi のライブラリの CI をしたい例です。以下のような状況だと思ってください。
commands.satyh
をライブラリとして配布したいcommands.satyh
の使い方の説明ドキュメントdoc.saty
(この中でcommands.saty
を使っている) をテストとしてビルド・目視確認したい- ライブラリなので SATySFi の複数のバージョンで使えるか確認したい
この場合は下のようにするといいと思います。
build-library-example: runs-on: ubuntu-latest strategy: matrix: # 確かめたい SATySFi のバージョンを列挙 version: [0.0.3-slim, 0.0.3-dev2019.11.16-slim, nightly] steps: - uses: actions/checkout@v1 # matrix.version によってタグを指定 - run: docker run --rm -v $(pwd):/satysfi amutake/satysfi:${{ matrix.version }} satysfi doc.saty working-directory: ./02-library-example - uses: actions/upload-artifact@master with: name: 02-library-example_${{ matrix.version }} path: 02-library-example/doc.pdf
01-simple-example との差分は matrix
を使っている部分です。
GitHub Actions の matrix 機能を使って簡単に複数バージョンでのビルドができます。今回はバージョン0.0.3, 2019-11-16時点のスナップショット、nightly で確認しています。
そしてバージョンごとに成果物がアーティファクトとしてアップロードされます。
ライブラリのドキュメントや使用例のPDFはリポジトリに含めておきたい (つまり生成した PDF をリポジトリに push したい) ことが多いと思いますが、
その場合も、 github actions push to repo
とかで検索すればいろいろ出てくるので簡単に実現できると思います (試してはないですが…)。
03-submodule-example
以降の3つは依存パッケージがある場合の例です。 依存パッケージがある場合にビルドする方法はいくつかありますがこの例では submodule を使う方法を説明します。
build-submodule-example: runs-on: ubuntu-latest strategy: matrix: version: [0.0.3-dev2019.11.16-slim, 0.0.3-dev2019.07.14-slim] steps: - uses: actions/checkout@v1 with: submodules: recursive # submodules: recursive を指定することで submodule init --recursive をしてくれるようになる - run: docker run --rm -v $(pwd):/satysfi amutake/satysfi:${{ matrix.version }} satysfi doc.saty working-directory: ./03-submodule-example - uses: actions/upload-artifact@master with: name: 03-submodule-example_${{ matrix.version }} path: 03-submodule-example/doc.pdf
02-library-example との差分は checkout に submodules: recursive
を指定していることです。
あとは doc.saty から @import: ...
で読み込むと submodule にしたライブラリが使えるようになります。
この方法の利点としては、slim が使えるので CI も速い (ダウンロード時間が小さい) のと、ジョブ定義もシンプルに保てて手軽なことです。
ただ、文書を作成したい場合はこれでいいかもしれませんが、@import
を使っているため、ライブラリとして配布したい場合にこの方法を使うのは配布方法によっては微妙かもしれません (ライブラリの利用者にも submodule で recursive update してもらうことになるかも)。
04-satyrographos-example
こちらは依存パッケージを Satyrographos と opam を使ってインストールする例です。
build-satyrographos-example: runs-on: ubuntu-latest strategy: matrix: version: [0.0.3-dev2019.11.16] container: image: amutake/satysfi:${{ matrix.version }} # run で使うイメージを指定 steps: - uses: actions/checkout@v1 - run: | export HOME=/root # workaround eval $(opam env) opam update opam install satysfi-grcnum # opam で SATySFi のライブラリをインストール satyrographos install -library grcnum # Satyrographos で SATySFi のライブラリをインストール satysfi doc.saty working-directory: ./04-satyrographos-example - uses: actions/upload-artifact@master with: name: 04-satyrographos-example_${{ matrix.version }} path: 04-satyrographos-example/doc.pdf
差分は run
のところで、 opam と Satyrographos を使って SATySFi のライブラリ (ここでは satysfi-grcnum) をインストールしています。
また、 container
でジョブの中でコマンドを実行するコンテナイメージを指定しています。
こうしないと、
run: docker run --rm -v $(pwd):/satysfi amutake/satysfi:${{ matrix.version }} bash -c "opam update && opam install satysfi-grcnum && satyrographos install -library grcnum && satysfi doc.saty"`
と長々と書かなければならずちょっとだるいです。ただ GitHub Actions は環境変数 HOME
を上書きして走らせるため、 opam がインストールされてあるディレクトリに指定し直しています。
こういう感じで opam リポジトリに登録されている SATySFi のパッケージを使うことができます。
(なお、インストールするパッケージはワークフローの定義に直接書くのではなくパッケージ一覧を書いたファイルかなにかをリポジトリに入れておくのがいいと思います)
05-custom-action-example
SATySFi 用の Action を作って使う例です。 04-satyrographos-example は run にコマンドがベタ書きされていて見づらかったので、 Action としてモジュール化しています。
以下がジョブの定義になります。
build-custom-action-example: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - uses: ./.github/actions/satysfi with: main: ./05-custom-action-example/doc.saty # メインファイルを指定 packages: 'satysfi-fonts-theano satysfi-grcnum' # パッケージ一覧を指定 - uses: actions/upload-artifact@master with: name: 05-custom-action-example path: 05-custom-action-example/doc.pdf
.github/actions/satysfi
に Action の定義を入れておいて、ジョブの中からはそれを参照しています。
以下が Action の定義 (.github/actions/satysfi/action.yml
) です。いわゆる container action になっています。main
と packages
を受け取って、docker run の引数として与えています。
name: 'SATySFi' description: 'Build SATySFi file' inputs: main: description: 'Target file which will be built via SATySFi.' required: true packages: description: 'Space separated SATySFi packages which will be installed via opam & Satyrographos' required: false default: '' outputs: runs: using: docker image: Dockerfile args: - ${{ inputs.main }} - ${{ inputs.packages }}
以下が docker のエントリポイントとなるファイル (.github/actions/satysfi/entrypoint.sh
) です。
ここに、04-satyrographos-example に長々と書いていたコマンドの列を書いています。
#!/bin/sh -l main=$1 shift packages=$@ # workaround. GitHub Actions overwrites $HOME. export HOME=/root eval $(opam env) opam update opam install $packages satyrographos install satysfi $main
あとはsatysfi-docker をベースイメージにした Dockerfile を書いてやればそれで完了です。CI が走るたびにイメージがビルドされて Action が実行されます。
おわりに
この記事では、GitHub Actions を使って SATySFi のパッケージや文書の CI をする説明をしました。 GitHub Actions を使うと、依存ライブラリをインストールしつつ文書をコンパイルできたり、 matrix を使ってライブラリがサポートしたいバージョンで簡単に CI を走らせることができたりします。 ライブラリの信頼性を高めたり、複数人で文書を書く際には有効だと思うので、ぜひ使ってみてください。