motoko-github-ci-workflow について
motoko-github-ci-workflowは、MotokoプロジェクトのGitHub Actions CIを追加・更新するスキルです。プロジェクト構成と既存ツールを確認し、必要なテスト、ベンチマーク、フォーマット検査、ビルドを設定します。
主な機能
- 01Motokoの構成と既存CIの確認
- 02必要に応じたテストとベンチマーク設定
- 03Prettierのフォーマット検査
- 04キャニスターとサンプルのビルド
- 05PocketICとwasm-optのツールチェーン設定
活用シーン
- 01MotokoパッケージへのCI追加
- 02既存ワークフローのテスト不足の補完
- 03ベンチマーク実行環境の設定
- 04CIでのキャニスターやサンプルのビルド
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ research-ag/ motoko-skills --skill motoko-github-ci-workflowインストール後、Claude Code で/motoko-github-ci-workflowを入力して読み込まれたか確認します。
詳細
Motoko GitHub CI ワークフロー
これは何か
このスキルでは、Motoko プロジェクトの GitHub Actions CI ワークフローを追加または更新するための包括的な手順を提供します。mops、moc、prettier、icp-cli、dfx を使用した自動テスト、ベンチマーク、コードのフォーマット、ビルド(キャニスターまたはサンプル)を扱います。mops-package-maintenance スキルとの併用に最適です。
GitHub Actions の一般的な情報については、GitHub Actions Documentation を参照してください。Motoko 固有の例については、research-ag 組織の公開リポジトリをご覧ください。
前提条件
mopsCLI(ローカル環境:npm i -g ic-mops、CI:caffeinelabs/setup-mops@v1)node(最新の LTS を推奨。Prettier には少なくとも v22 が必要です)mops benchの実行に必要なpocket-ic。mops CLI v3.0.0 以降、dfx-replica のサポートはなくなりました。PocketIC はmops bench(およびレプリカテスト/--check-deploy)で使用できる唯一のランタイムであり、mops.tomlの[toolchain] pocket-ic = "<version>"で明示的に固定する必要があります(例:mops toolchain use pocket-ic 15.0.0)。固定しないと、mops benchはエラーで終了します。CI ではmops toolchain bin pocket-icを使って固定されたバイナリをインストールします(ステップ 1 を参照)。- 最適化済み(本番環境を想定した)Wasm を反映させるベンチマークには
wasm-optが必要です。mops bench/mops buildが Binaryen のwasm-optを実行するのは、mops.tomlに[optimize]セクションがある場合のみです。また、そのセクションにはpocket-icと同様に、明示的な[toolchain] wasm-opt = "<version>"の固定が必要です(ステップ 1 を参照)。
仕組み
- リポジトリを分析する:
[package]がmops.tomlにあるかどうかで Motoko パッケージかどうかを判定します。また、[canister]がmops.tomlまたはdfx.jsonにあるかどうかで、カニスタープロジェクトかどうかを判定します。- テストを確認する:
test/ディレクトリと*.test.moファイルを探します。見つからない場合は、mops testの手順を含めないでください。 - ベンチマークを確認する:
bench/ディレクトリと*.bench.moファイルを探します。見つからない場合は、mops benchの手順を含めないでください。
- 既存の CI を分析する:
.github/workflows/にすでに CI ファイルがある場合は、使用されているツール(dfx、icp-cli、またはなし)を確認します。- リポジトリにテストやベンチマークがあるのに CI に含まれていない場合は、追加します。
- カニスターのビルドツールを選択する:
- ライブラリパッケージの場合(カニスターがなく、カニスターのビルドツールを必要とするサンプルもない場合)は、
dfxまたはicp-cliのインストールを完全に省略します。テストとベンチマークには引き続きmoc(Motoko コンパイラー)が必要であり、通常はmopsで管理されることに注意してください。 - カニスターやサンプルを含む新規プロジェクトでは、新しく、より軽量な
icp-cliを優先します。 - 既存プロジェクトでは、既存のツールセット(
dfxまたはicp-cli)を維持します。 - 重要:
dfxとicp-cliを同時にインストールしないでください。
- ライブラリパッケージの場合(カニスターがなく、カニスターのビルドツールを必要とするサンプルもない場合)は、
mops.tomlを確認する:既存の[toolchain]セクションを読み取ります。mocとは異なり、パッケージにベンチマーク(またはレプリカテスト/--check-deploy)がある場合、pocket-icは省略できません。mops benchではバージョンの固定が必要です。[toolchain] pocket-icがなく、パッケージにベンチマークがある場合は、その旨をユーザーに伝え、CI が後で失敗しないようにバージョンを固定します(例:mops toolchain use pocket-ic <version>、例として15.0.0)。また、[optimize]も確認します。パッケージにベンチマークがあり、これがない場合は、ベンチマークの数値が最適化済み Wasm を反映するように追加し([toolchain] wasm-optのバージョン固定も追加します)、mops-package-maintenanceスキルがすでに実行されていれば、通常は設定済みです。その他の[toolchain]エントリとfilesフィールドには手を加えないでください(ステップ 1 を参照)。- ワークフローファイルを作成または更新する:
.github/workflows/にある既存のワークフローファイル(例:pull_request_build.yml、test.yml、ci.yml)を特定します。ない場合は、.github/workflows/ci.ymlを作成します。効率化のため、ジョブは並列実行するようにします。 - 並列ジョブを設定する:
testジョブ:依存関係のインストール、mops test、mops benchを実行します。fmtジョブ:prettierのフォーマットチェックを実行します。
- ビルド手順を追加する:サンプルまたはカニスターがある場合は、選択したカニスターのビルドツールを使ってビルドする手順を追加します。
実装
ステップ 1 — mops.toml を確認し、必要に応じて pocket-ic/wasm-opt を固定します
CI を追加する前に、mops.toml を読んでください。[toolchain] moc とその他のエントリは変更しないでください。
ベンチマークには pocket-ic が必須です(mops CLI v3.0.0 以降): dfx-replica のサポートは mops bench から完全に削除されました。PocketIC が唯一のランタイムになっており、[toolchain] でバージョンを固定する必要があります。固定していない場合、mops bench は修正方法(mops toolchain use pocket-ic <version>)を示すエラーを出して、直ちに失敗します。mops test では引き続き pocket-ic は不要です(Motoko インタープリターまたは WASI 経由で実行されます)。固定が必要なのは、パッケージにベンチマークまたはレプリカテストがある場合や、--check-deploy を使用する場合のみです。
現在の [toolchain] の内容に基づいて、使用する CI 戦略を決めます。
- パッケージにベンチマークがあり、
pocket-icがすでに[toolchain]で固定されている場合:CI でmops toolchain bin pocket-icを実行してインストールし、mops benchを実行します。正確なスニペットはステップ 2 のテンプレートと落とし穴 #2 を参照してください。 - パッケージにベンチマークがあり、
pocket-icが[toolchain]にない場合:固定しないと CI でmops benchが失敗することをユーザーに伝え、固定を追加します(mops toolchain use pocket-ic <version>— mops のエラーメッセージに具体的なバージョンが示されます。例:15.0.0)。filesフィールドとは異なり、これは手を加えずにそのままにしておくものではありません。固定されていないパッケージではmops benchを実行できません。 - ベンチマークがない場合:対応は不要です。
mops testにpocket-icは不要で、ベンチマークランタイムも必要ありません。
[optimize] と wasm-opt — ベンチマークでは最適化済みの Wasm を測定します。 mops bench が Binaryen の wasm-opt を実行するのは、mops.toml に [optimize] セクションがある場合のみです(空でもかまいません。その場合、デフォルトで level = "O3" が使用されます)。このセクションがないと、ベンチマークでは最適化されていないコードが気づかれないまま測定されます。pocket-ic と同様、[optimize] がある場合は [toolchain] wasm-opt を固定する必要があります。固定していないと、コンパイル前にビルドが失敗します。
- パッケージにベンチマークがあり、
[optimize]がすでに設定されている場合:mops benchの前にmops toolchain bin wasm-optを実行し、pocket-icとともに CI にインストールします。 - パッケージにベンチマークがあり、
[optimize]がない場合:上記のpocket-icの固定と同様に、[toolchain] wasm-optの固定(例:mops toolchain use wasm-opt <version>)と合わせて追加します。通常、メンテナンス作業ではmops-package-maintenanceスキルが対応しますが、まだ対応されていない場合はここで追加し、CI で最適化されていないコードのベンチマークが出力されないようにしてください。 - ベンチマークがない場合:対応は不要です。
また、mops.toml の [package] に files フィールドがあるか確認してください。ある場合は変更しないでください。files フィールドに対して気を利かせようとすると、予期しない副作用が発生する可能性があります。代わりに現在の設定をユーザーに伝え、重要なディレクトリ(examples/ など)が欠けているように見える場合や、サポートされていない拡張子が含まれている場合は警告してください(mops publish で許可されているのは .mo、.did、.md、.toml のみです)。
ステップ 2 — GitHub CI ワークフローを作成または更新します
.github/workflows/ に既存のワークフローファイルがあるか確認してください。ある場合は更新し、ない場合は .github/workflows/ci.yml を作成します。最新バージョンのアクション(例:actions/checkout@v6、actions/setup-node@v6)を使用し、タスクを並列化してください。
注:アクションの最新のメジャーバージョンを使用すると、最新の機能とセキュリティ更新を利用できます。
name: CI
on:
push:
branches: [main, master]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
jobs:
test:
name: Tests and Benchmarks
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: latest
- name: Install mops
uses: caffeinelabs/setup-mops@v1
- name: Make sure moc is installed
run: mops toolchain bin moc
- name: Show versions
run: |
mops --version
$(mops toolchain bin moc) --version
- name: Install dependencies
run: mops install
# Bench runtime: PocketIC is the only runtime `mops bench` supports
# (dfx-replica support was removed in mops CLI v3.0.0). `[toolchain]
# pocket-ic` must already be pinned in mops.toml (see Step 1) —
# `mops toolchain bin pocket-ic` downloads that pinned version.
# `mops bench` starts (and stops) PocketIC itself, so there is no
# separate "start" step. Omit both steps if the package has no
# benchmarks.
- name: Make sure pocket-ic is installed
run: mops toolchain bin pocket-ic
# Only if mops.toml has an [optimize] section (see Step 1) — it
# requires a [toolchain] wasm-opt pin, downloaded the same way.
# Omit this step if the package has no [optimize] section.
- name: Make sure wasm-opt is installed
run: mops toolchain bin wasm-opt
- name: Run tests
run: mops test # Omit this step if the package has no tests. Note: `mops test` does not use pocket-ic.
- name: Run benchmarks
run: mops bench # Omit this step if the package has no benchmarks.
fmt:
name: Formatting Check
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: latest
- name: Prettier Check
run: |
npm install prettier prettier-plugin-motoko --no-save
npx -y prettier --plugin prettier-plugin-motoko --check '**/*.{mo,json,md}'
ステップ 3 — サンプルと Canister を扱います(任意)
リポジトリに Canister のサンプル(または example)がある場合:
test ジョブ(または新しいジョブ)に、サンプルをビルドするステップを追加してください。プロジェクトですでに使用されているツールか、新しいプロジェクトでは icp-cli を使用します。ビルドが必要なサンプル/Canister がない場合は、このセクションを省略してください。
- name: Build examples
run: |
# Detect and build examples/example
EXAMPLES_DIR=""
if [ -d "examples" ]; then
EXAMPLES_DIR="examples"
elif [ -d "example" ]; then
EXAMPLES_DIR="example"
fi
if [ -n "$EXAMPLES_DIR" ]; then
cd "$EXAMPLES_DIR"
if [ -f "mops.toml" ]; then
mops install
fi
# Use icp if it exists, otherwise fallback to dfx if dfx.json is present
if [ -f "icp.yaml" ] && command -v icp >/dev/null; then
icp build --all
elif [ -f "dfx.json" ]; then
# Only run dfx build if dfx is already installed in this job
if command -v dfx >/dev/null; then
dfx build
fi
fi
cd ..
fi
リポジトリが Canister(パッケージではない)の場合:
プロジェクトが Canister の場合は、Canister をビルドし、必要に応じて .did ファイルを比較してください。
ツールをインストールする(いずれか 1 つを選択):
# Option A: For new projects or those already using icp
- name: Install icp-cli
run: npm i -g icp-cli
# Option B: For existing projects already using dfx
- name: Install dfx
uses: dfinity/setup-dfx@main
DID をビルドして比較する:
.did ファイルを比較するには、最新のインターフェースを確認するために didc が必要になることがよくあります。
- name: Build canisters
run: |
if [ -f "icp.yaml" ] && command -v icp >/dev/null; then
icp build
else
dfx build
fi
- name: Get didc
run: |
mkdir -p /home/runner/bin
release=$(curl --silent "https://api.github.com/repos/dfinity/candid/releases/latest" | awk -F\" '/tag_name/ { print $4 }')
curl -fsSL https://github.com/dfinity/candid/releases/download/$release/didc-linux64 > /home/runner/bin/didc
chmod +x /home/runner/bin/didc
echo "/home/runner/bin" >> $GITHUB_PATH
- name: Check Candid interface
run: |
# Compare generated .did with tracked .did
# e.g., didc check -s did/my_canister.did .dfx/local/canisters/my_canister/my_canister.did
didc check -s did/backend.did .dfx/local/canisters/backend/backend.did
ステップ 4 — エンドツーエンドテストを実行する
リポジトリにエンドツーエンドテスト(例:test/e2e など)が含まれている場合は、実行手順を追加します。通常、dfx と、起動中のローカルレプリカまたは pocket-ic が必要です。
- name: Run E2E tests
run: |
# Your E2E test command here
# e.g., npm run test:e2e
よくある落とし穴
-
Node のバージョンが古い。 Prettier と一部の Motoko ツールには、比較的新しい Node.js バージョンが必要です。CI では常に
latest、または少なくともv22を使用してください。 -
ベンチマークには
pocket-icツールチェーンの固定が必要です —dfxへのフォールバックはありません。 mops CLI v3.0.0 では dfx-replica のサポートが完全に削除されました(mops test/mops benchの--replicaフラグも削除されています。このフラグは 2.14 以降、非推奨でした)。現在、実行環境は PocketIC のみです。パッケージにベンチマークがある場合は、mops.tomlで[toolchain] pocket-icが固定されていることを確認し(設定されていない場合はmops toolchain use pocket-ic <version>で追加します。バージョンが固定されていないプロジェクトでは、必要な修正内容がエラーに正確に表示されます)、固定されたバイナリをインストールして bench を実行してください(mops benchを実行するジョブでのみ行います)。別途「start」手順を追加する必要はありません —mops benchが PocketIC 自体を起動(および停止)します。- name: Make sure pocket-ic is installed run: mops toolchain bin pocket-ic - run: mops bench注:
mops testはpocket-icを使用しません(Motoko インタープリターまたは WASI 経由で実行されます)。そのため、固定が関係するのはmops bench/レプリカテスト/--check-deployのみです。残っている
dfxのベンチマーク実行環境の手順を削除してください。dfx(dfinity/setup-dfx@main)をインストールしたり、mops benchの実行環境を用意する目的だけでdfx start --background --cleanを実行したりする既存のワークフローを更新する場合は、それらの手順を削除してください —mops benchでは何の効果もなく、pocket-icの固定の代わりにもなりません。# `mops bench` のためだけに存在する場合は、以下を削除してください — # dfx-replica のサポートは mops CLI v3.0.0 で削除されました: - name: Install dfx uses: dfinity/setup-dfx@main - name: Start dfx run: dfx start --background --clean(
dfxのインストールは、キャニスター/サンプルのビルドや E2E テストなど、ほかの用途では引き続き有効です。手順 3/4 を参照してください。この問題は、特にmops benchのランタイムに関するものです。) -
pocket-icのバージョン指定がない。mops bench(またはmops toolchain bin pocket-ic)が、ツールチェーンがバージョン指定されていないというエラーですぐに失敗する場合、mops.tomlに[toolchain] pocket-icがありません。dfxで回避しようとするのではなく、mops toolchain use pocket-ic <version>でバージョンを指定してください(エラーメッセージに具体的なバージョンが示されます)。 -
[optimize]を指定せずにベンチマークを実行する。mops.tomlに[optimize]セクションがある場合に限り、mops benchはwasm-optを実行します。これを省略すると、CI は最適化されていない Wasm の数値を問題なく報告しますが、その数値は本番環境に出荷されるものを反映していません。パッケージにベンチマークがあり、[optimize]がない場合は、「CI が成功する」ことを「CI が適切な測定をしている」ことと見なすのではなく、[toolchain] wasm-optのバージョン指定とともに追加してください。手順 1 を参照してください。 -
バージョンを表示しない。
mopsとmocのバージョンを表示する手順を必ず含めてください。CI の問題のデバッグに役立ちます。 -
並列ジョブを使用しない。 同じジョブでフォーマットとテストを実行すると時間がかかります。ジョブを分けて、GitHub で並列実行されるようにしてください。
-
テストがないのに
mops testを含める。 パッケージに*.test.moファイルを含むtest/ディレクトリがあるか、必ず確認してください。ない場合は、CI の失敗を避けるためにmops testのステップを省略してください。 -
ベンチマークがないのに
mops benchを含める。 パッケージに*.bench.moファイルを含むbench/ディレクトリがあるか、必ず確認してください。ない場合は、mops benchのステップを省略してください。 -
古い mops のインストール方法。
npm i -g ic-mopsやZenVoich/setup-mops@v1は避けてください。代わりにcaffeinelabs/setup-mops@v1を使用してください。 -
ツールを同時にインストールする。
dfxとicp-cliの両方をインストールしないでください。どちらか一方だけを使用してください。 -
既存のテストを省略する。 既存の CI を更新する場合は、リポジトリにあるすべてのテストとベンチマークが実行されることを確認してください。
-
不要なツールのインストール。 ベンチマークなしで
mops testのみを実行するライブラリパッケージには、dfxやicp-cliをインストールしないでください。パッケージにベンチマークがある場合は、pocket-icが必須です(mops benchで使用できる唯一のランタイムです)。ベンチマークのジョブ内でのみ、mops toolchain bin pocket-icを使ってインストールしてください([optimize]が設定されている場合はwasm-optもインストールします)。mops benchを実行するためだけにdfxやicp-cliをインストールしないでください。
動作を確認する
- GitHub Actions タブを確認する。
testジョブとfmtジョブの両方が存在し、実行されていることを確認してください。 - ログを確認する。
mops installが依存関係を正しく取得し、mops benchが[toolchain] pocket-icでバージョン指定された PocketIC に対して実行されることを確認してください(mops CLI v3.0.0 以降、--replicaフラグはなくなりました)。mops.tomlに[optimize]セクションがある場合は、wasm-optのステップも実行されたことを確認してください。ベンチマーク結果の前に、その出力が表示されます。 - フォーマットを確認する。 ファイルを意図的に不正なフォーマットにして PR を作成し、想定どおり
fmtジョブが失敗することを確認してください。