まえがき
- NimのプロジェクトにGitHub Actionsを導入して自動テストする
- タグを切ったら自動でGitHub Releaseにリリースできるようにする
- YAML 1ファイルで構築する
やることの意義
- 自動テストすることで、既存の挙動の変化に早期に気付ける
- どの修正でバグったのかすぐに分かる
- 時間ロスを減らせる
- どのPCからでもリリースできるようになる
- ローカルでリリース用のコマンドをインストールして、TOKEN発行して、は手間がかかる
- ビルド方法やリリース方法を忘れたりする
- タグを切るだけでリリースできるようにすれば環境構築不要
- PCが変わってもアカウントがあればいつでもリリースできる
リポジトリ
以下のリポジトリで検証しました。
GitHub - jiro4989/nim_ci_sample
引数に数値を渡してFizzBuzzするだけのコマンドです。
1ファイルのYAMLで自動テスト、リリースするための手順
-
nimble init
したリポジトリに、以下のYAMLファイルを.github/workflows/main.yml
に保存する - YAMLファイル内の
nim_ci_sample
を自分のリポジトリ名(バイナリ名)に変更する - 終わり
name: build
on: [push]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
# - windows-latest
# - macOS-latest
env:
NIM_VERSION: 1.0.4
steps:
- uses: actions/checkout@v1
- name: Cache choosenim
id: cache-choosenim
uses: actions/cache@v1
with:
path: ~/.choosenim
key: ${{ runner.os }}-choosenim-${{ env.NIM_VERSION }}
- name: Cache nimble
id: cache-nimble
uses: actions/cache@v1
with:
path: ~/.nimble
key: ${{ runner.os }}-nimble-${{ hashFiles('*.nimble') }}
- uses: jiro4989/setup-nim-action@v1.0.1
with:
nim-version: ${{ env.NIM_VERSION }}
- run: nimble build -d:release -Y
- run: nimble test -Y
- run: nimble install -Y
- run: nim_ci_sample 10
- run: nimble doc --project --index:on -o:docs src/nim_ci_sample.nim
- name: Create artifact
run: tar czf nim_ci_sample_${{ runner.os }}.tar.gz README.md nim_ci_sample
- name: Release binary
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
with:
files: nim_ci_sample*.tar.gz
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
このYAMLの解説
一連のフロー
- git checkoutでリポジトリのソースを取得
- choosenimのソースをキャッシュする宣言
- nimbleのソースをキャッシュする宣言
- Nim 1.0.4のインストール
- 自作のGitHub Actionで実施
- Nim用のGitHub Actionsを作ってみた
nimble build
nimble test
nimble install
- インストールしたコマンドの実行
- ドキュメントの生成
- ※GitHub Pagesにリリースするのにはちょっと手間が必要なので今回は割愛
- リリースファイルの生成
- GitHub Releaseにリリース
テストとリリース実行のトリガー
テストはpushの都度実行される。
これはYAML先頭の on: [push]
の指定から。
タグを切った時だけリリースするのは、最後のRelease binary
のif: startsWith(github.ref, 'refs/tags/')
の指定。
コレがないとpushの都度リリースされてしまう。
リリース時のジョブのログは以下。
https://github.com/jiro4989/nim_ci_sample/commit/d4a7b526c7e0e597484cbc66235c2eba7fa78e13/checks?check_suite_id=345650672
リリースに必要なトークン
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
をリリース用に指定しているが、
これは別に自分で用意しなくてよい。
CIが実行される都度発行される揮発性の変数で、60分で無効になる。
バッジ
バッジも発行されるのでREADMEに書いとけば華やかになる。
https://github.com/jiro4989/nim_ci_sample/workflows/build/badge.svg
補足
-
nim_ci_sample
の部分がリポジトリ名 -
build
の部分はYAMLの先頭のname
キャッシュ
キャッシュも効くように設定している。
キャッシュしている間はコレくらいの規模なら 1分 でCIが終わる。
キャッシュのキーにそれぞれ以下のように指定している。
${{ runner.os }}-choosenim-${{ env.NIM_VERSION }}
${{ runner.os }}-nimble-${{ hashFiles('*.nimble') }}
この指定は、キャシュを特定のタイミングに使わないようにするためのもの。
使用しているactions/cache
は、キャッシュのキーが前ジョブのものと同じ間はキャッシュしていたものを使いまわし続けるみたい。
このキーを固定値にしていると、Nimのバージョンが変わったのにキャッシュが残り続けてバージョンが古いままになったり、
nimbleに依存パッケージを追加したのに毎回依存パッケージをダウンロードするようになったりする。
これを回避するために、choosenim
のキャッシュのキーにはNimのバージョン番号を含めるようにした。
これでNimのバージョン番号を変更したらキャッシュを使わずに新しくコンパイラをインストールするようになる。
nimble
のキャッシュのキーには、nimbleファイルのハッシュ値を含めるようにしている。
nimbleファイルが更新されると、nimbleファイルのハッシュも変わる。
すると、前のジョブでキャッシュしていたキャッシュのキーと不一致になるので、キャッシュが使われなくなる。
結果的に、新しくパッケージを取得して、それをキャシュする。
まとめ
以下の内容について書きました。
- 1ファイルのYAMLで自動テスト、リリースできる
- CI設定の解説
これで快適Nimライフが送れます。
Nimでの開発のお役に立てば幸いです。
以上です。