mcpField
M
motoko-github-ci-workflow

motoko-github-ci-workflow

github.com/research-agクラウド・DevOps035 回インストール9 週間前に更新
リポジトリ

motoko-github-ci-workflow について

motoko-github-ci-workflowは、MotokoプロジェクトのGitHub Actions CIを追加・更新するスキルです。プロジェクト構成と既存ツールを確認し、必要なテスト、ベンチマーク、フォーマット検査、ビルドを設定します。

主な機能

  1. 01Motokoの構成と既存CIの確認
  2. 02必要に応じたテストとベンチマーク設定
  3. 03Prettierのフォーマット検査
  4. 04キャニスターとサンプルのビルド
  5. 05PocketICとwasm-optのツールチェーン設定

活用シーン

  1. 01MotokoパッケージへのCI追加
  2. 02既存ワークフローのテスト不足の補完
  3. 03ベンチマーク実行環境の設定
  4. 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 組織の公開リポジトリをご覧ください。

前提条件

  • mops CLI(ローカル環境: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 を参照)。

仕組み

  1. リポジトリを分析する:
    • [package] が mops.toml にあるかどうかで Motoko パッケージかどうかを判定します。また、[canister] が mops.toml または dfx.json にあるかどうかで、カニスタープロジェクトかどうかを判定します。
    • テストを確認する:test/ ディレクトリと *.test.mo ファイルを探します。見つからない場合は、mops test の手順を含めないでください。
    • ベンチマークを確認する:bench/ ディレクトリと *.bench.mo ファイルを探します。見つからない場合は、mops bench の手順を含めないでください。
  2. 既存の CI を分析する:
    • .github/workflows/ にすでに CI ファイルがある場合は、使用されているツール(dfx、icp-cli、またはなし)を確認します。
    • リポジトリにテストやベンチマークがあるのに CI に含まれていない場合は、追加します。
  3. カニスターのビルドツールを選択する:
    • ライブラリパッケージの場合(カニスターがなく、カニスターのビルドツールを必要とするサンプルもない場合)は、dfx または icp-cli のインストールを完全に省略します。テストとベンチマークには引き続き moc(Motoko コンパイラー)が必要であり、通常は mops で管理されることに注意してください。
    • カニスターやサンプルを含む新規プロジェクトでは、新しく、より軽量な icp-cli を優先します。
    • 既存プロジェクトでは、既存のツールセット(dfx または icp-cli)を維持します。
    • 重要:dfx と icp-cli を同時にインストールしないでください。
  4. 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 を参照)。
  5. ワークフローファイルを作成または更新する:.github/workflows/ にある既存のワークフローファイル(例:pull_request_build.yml、test.yml、ci.yml)を特定します。ない場合は、.github/workflows/ci.yml を作成します。効率化のため、ジョブは並列実行するようにします。
  6. 並列ジョブを設定する:
    • test ジョブ:依存関係のインストール、mops test、mops bench を実行します。
    • fmt ジョブ:prettier のフォーマットチェックを実行します。
  7. ビルド手順を追加する:サンプルまたはカニスターがある場合は、選択したカニスターのビルドツールを使ってビルドする手順を追加します。

実装

ステップ 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

よくある落とし穴

  1. Node のバージョンが古い。 Prettier と一部の Motoko ツールには、比較的新しい Node.js バージョンが必要です。CI では常に latest、または少なくとも v22 を使用してください。

  2. ベンチマークには 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 のランタイムに関するものです。)

  3. pocket-ic のバージョン指定がない。 mops bench(または mops toolchain bin pocket-ic)が、ツールチェーンがバージョン指定されていないというエラーですぐに失敗する場合、mops.toml に [toolchain] pocket-ic がありません。dfx で回避しようとするのではなく、mops toolchain use pocket-ic <version> でバージョンを指定してください(エラーメッセージに具体的なバージョンが示されます)。

  4. [optimize] を指定せずにベンチマークを実行する。 mops.toml に [optimize] セクションがある場合に限り、mops bench は wasm-opt を実行します。これを省略すると、CI は最適化されていない Wasm の数値を問題なく報告しますが、その数値は本番環境に出荷されるものを反映していません。パッケージにベンチマークがあり、[optimize] がない場合は、「CI が成功する」ことを「CI が適切な測定をしている」ことと見なすのではなく、[toolchain] wasm-opt のバージョン指定とともに追加してください。手順 1 を参照してください。

  5. バージョンを表示しない。 mops と moc のバージョンを表示する手順を必ず含めてください。CI の問題のデバッグに役立ちます。

  6. 並列ジョブを使用しない。 同じジョブでフォーマットとテストを実行すると時間がかかります。ジョブを分けて、GitHub で並列実行されるようにしてください。

  7. テストがないのに mops test を含める。 パッケージに *.test.mo ファイルを含む test/ ディレクトリがあるか、必ず確認してください。ない場合は、CI の失敗を避けるために mops test のステップを省略してください。

  8. ベンチマークがないのに mops bench を含める。 パッケージに *.bench.mo ファイルを含む bench/ ディレクトリがあるか、必ず確認してください。ない場合は、mops bench のステップを省略してください。

  9. 古い mops のインストール方法。 npm i -g ic-mops や ZenVoich/setup-mops@v1 は避けてください。代わりに caffeinelabs/setup-mops@v1 を使用してください。

  10. ツールを同時にインストールする。 dfx と icp-cli の両方をインストールしないでください。どちらか一方だけを使用してください。

  11. 既存のテストを省略する。 既存の CI を更新する場合は、リポジトリにあるすべてのテストとベンチマークが実行されることを確認してください。

  12. 不要なツールのインストール。 ベンチマークなしで mops test のみを実行するライブラリパッケージには、dfx や icp-cli をインストールしないでください。パッケージにベンチマークがある場合は、pocket-ic が必須です(mops bench で使用できる唯一のランタイムです)。ベンチマークのジョブ内でのみ、mops toolchain bin pocket-ic を使ってインストールしてください([optimize] が設定されている場合は wasm-opt もインストールします)。mops bench を実行するためだけに dfx や icp-cli をインストールしないでください。

動作を確認する

  1. GitHub Actions タブを確認する。 test ジョブと fmt ジョブの両方が存在し、実行されていることを確認してください。
  2. ログを確認する。 mops install が依存関係を正しく取得し、mops bench が [toolchain] pocket-ic でバージョン指定された PocketIC に対して実行されることを確認してください(mops CLI v3.0.0 以降、--replica フラグはなくなりました)。mops.toml に [optimize] セクションがある場合は、wasm-opt のステップも実行されたことを確認してください。ベンチマーク結果の前に、その出力が表示されます。
  3. フォーマットを確認する。 ファイルを意図的に不正なフォーマットにして PR を作成し、想定どおり fmt ジョブが失敗することを確認してください。

コメント