CI & Actions
すべてのワークフローは .github/workflows/ に配置されています。以下のセクションでは、トリガー別にグループ化しています: git イベントでの自動実行、または workflow_dispatch とスケジュールによるメンテナー起動/アドバイザリワークフロー。
自動ワークフロー
品質ゲート (ci.yml)
master を対象とするすべてのPRと、master への信頼されたプッシュで実行されます。複数のマトリックスレッグを持つ複合ジョブです:
- fmt:
cargo fmt --all -- --check - history-guard: 完全な履歴を取得し、テスト対象のコミットを
origin/masterと照合します。プルリクエストでは明示的なgithub.event.pull_request.head.shaを使用し、信頼されたプッシュとマージキューの実行ではgithub.shaを使用します。このガードとそのフィクスチャテストは、空のgit merge-baseを拒否し、マージ後に graft された 2 つ目のルートによってgit blameが崩れるのを防ぎます。 - lint:
cargo clippy --workspace --exclude zeroclaw-desktop --all-targets --features ci-all -- -D warnings、続いてcargo doc --no-deps --workspace --exclude zeroclaw-desktop(rustdoc の警告は.cargo/config.tomlのbuild.rustdocflagsにより致命的なエラーとして扱われます。デスクトップはxtask build_api/ docs-deploy に合わせ、リントランナー上で GTK/glib-sysを避けるため除外されます)、さらにコメントの衛生チェックゲート - build: マトリックス:
x86_64-unknown-linux-gnu、aarch64-apple-darwin、x86_64-pc-windows-msvc - check:
zeroclaw-desktopを除くワークスペースに対して、警告を致命的エラーとして扱う3つのチェックを実行する:全機能、デフォルト機能なし、そして--all-targetsを指定したデフォルト機能。デフォルトの機能構成でテストターゲットをコンパイルするのは最後のチェックだけである - check-32bit: デフォルト機能なしの
i686-unknown-linux-gnu - bench: ベンチマークのコンパイルチェック
- テスト: Linux 上で、
scripts/ci/firmware_protocol_gate.shによるスタンドアロンのファームウェアプロトコルホストゲートとcargo nextest run --locked --workspace --exclude zeroclaw-desktopを実行し、設定書き込みの分離および Fluent のカバレッジ(ユーザー向け文字列をそのまま記述しないこと)に関するアーキテクチャガードも含める - parallel-runtime-test:
scripts/ci/parallel_runtime_test_gate.shに含まれる同一プロセスのランタイム/チャンネルテストを繰り返し実行するジョブ。関連するPRパスに対してはメインテストジョブと並列で実行され、masterへのプッシュおよびマージキューの実行時は無条件で実行されます - security:
cargo deny check - nix-eval: NixOS モジュールのアサーションを評価します(
nixos-module-evalflake チェック) - docs-style: Markdown lint、emダッシュの散文チェック、および
scripts/ci/docs_quality_gate.shとscripts/ci/docs_links_gate.shによる変更行のリンクゲート
fmt は安価なシリアルゲートとして最初に実行されます。その他のすべてのジョブは直接または推移的に needs: [fmt] を宣言し、フォーマットが通過した後にファンアウトします。CI Required Gate はすべての結果を集約します。ブランチ保護はこの複合ゲートジョブを固定します。これがグリーンになるまで PR はマージできません。master へのプッシュ実行は、後続の PR 実行のために信頼できる Rust キャッシュをシードしつつ、同じ品質シグナルを維持します。
フレッシュな必須 CI は通常、それが実際に実行する Cargo サーフェスの共有エビデンスです。同じ head、ターゲット、feature セットに対する同じ Cargo コマンドのローカル再実行は、重複した確信であり、より強い証明ではありません。追加の Cargo や Clippy を求める前に、変更されたサーフェスを現在のワークフローファイルと PR 上の実際のチェックと比較してください。追加の検証は、必須ゲートがレビュー対象を証明しない箇所に属します:
- プラットフォームはコンパイルチェックを受けましたが、テストは受けませんでした。
- プラットフォーム、crate、またはパスが必須の lint ジョブの範囲外です。
- デスクトップの変更ではデスクトップワークフローがトリガーされませんでした。
- リリースターゲットは PR マトリックスの範囲外であり、release/manual ワークフローでのみカバーされます。
- 失効、キャンセル、スキップ、または利用不可の CI は最新の証拠ではありません。
定義やインポートがフィーチャーによって条件付けされている場合は、その cfg 条件をすべての利用側と比較します。有効な構成と、関連する無効な構成をそれぞれ検証してください。フィーチャーを有効にした検証では利用側が引き続き動作することを確認でき、一方、ワークスペース全体での no-default-features チェックでは、未使用の非公開定義やインポートなど、警告を発生させる不一致を検出できます。この検証では --all-targets なしで cargo check を実行するため、テストターゲットは決してコンパイルされません。単なる test によって条件付けされたヘルパーで、その唯一の呼び出し元がフィーチャーの背後にある場合は、代わりに default-features/all-targets の検証段階で検出されます。必要な CI 構成のいずれでも変更された条件が検証されない場合は、対象を絞ったフィーチャーの組み合わせが引き続き必要です。
定期実行のプラットフォームテスト (platform-tests.yml)
軽量な Linux フォーマットチェックの後、macos-14 と windows-latest で cargo nextest run --locked --workspace --exclude zeroclaw-desktop --no-fail-fast を実行します。マトリックスの実行対象は次のとおりです:
platform-tests.yml自体を変更するプルリクエスト;- 手動ディスパッチ、および
- 毎晩 03:17 UTC に実行されるスケジュール。
ジョブでは continue-on-error を使用し、CI Required Gate には結果を渡しません。これらは移植性の証拠であり、マージ要件ではありません。通常のコード PR ではマトリックスは自動的に起動せず、特定のプラットフォームの検証が有用な場合は、メンテナーがブランチを対象に手動でディスパッチできます。ワークフローは通常の push または merge_group イベントでは実行されません。master 上での夜間実行および手動ディスパッチ実行では信頼できるキャッシュに書き込めますが、プルリクエストの実行では書き込めません。--no-fail-fast により、1 回の実行ですべてのプラットフォームの失敗を確認できます。
日次アドバイザリスキャン(daily-audit.yml)
毎日 09:00 UTC に依存関係ツリーに対して cargo deny check advisories を実行します。問題が見つかった場合は issue を作成します。脆弱性が報告されない限り、何も行われません。
日次 npm 監査 (daily-npm-audit.yml)
web/package-lock.json に対して毎日 09:23 UTC に npm audit --audit-level=high を実行します。コミット済みの web ロックファイルに高深刻度の npm アドバイザリが影響する場合、重複排除された security + dependencies の issue を 1 件作成します。
週次 Trivy イメージスキャン (trivy-scheduled.yml)
公開された dist および default-features の GHCR イメージを毎週土曜日にスキャンし、HIGH/CRITICAL の検出結果を SARIF として Security タブにアップロードします。スキャンはレポート優先(検出結果に対して exit-code: 0)ですが、想定されるイメージが見つからない場合は、欠落しているタグと所有元の公開ワークフロー名をエラーに示して、Trivy のセットアップ前にジョブを失敗させます。
週次 Scoop Bucket Canary (scoop-bucket-canary.yml)
毎週月曜日に、現在の安定版リリースに対する Scoop の公開フローをリハーサルします。最新の vX.Y.Z タグを解決し、pub-scoop.yml を dry_run: true と credential_canary: true の両方を指定して呼び出すため、何も書き込まずに実際の SCOOP_BUCKET_TOKEN を実際のバケットに対して使用して動作を検証します。
credential_canary はその契約におけるフェイルクローズ部分です。SCOOP_BUCKET_REPO または SCOOP_BUCKET_TOKEN が欠落していると実行は失敗し、設定済みの認証情報は git push --dry-run の認可プローブまで到達しなければなりません。dry_run: true だけを指定した汎用的な手動 pub-scoop.yml 実行は、マニフェスト生成に対しては引き続き許容的であり、認証情報を利用できない場合はそのプローブをスキップすることがあります。認証情報検証の証拠として汎用モードを使用しないでください。
これは SCOOP_BUCKET_TOKEN がアカウントに紐付いているために存在します。つまり、有効期限が切れ、所有者の ID に付与されたバケット上のコラボレーター権限が変更されると、書き込み権限をひそかに失います。どちらも実際に起きました。カナリアの前は、認証情報を使用していたのは公開後の scoop ジョブだけだったため、無効なトークンが発見されたのはリリースがすでに作成され、告知された後であり、バケットは手動で更新する必要がありました。
カナリアは認証情報の陳腐化を検出します。これは意図的にバケットを正しい状態に保つものではなく、Release Stableにも組み込まれていません。使用不能になったパッケージマネージャーの認証情報によって、リリースがブロックされたり遅延したりすることは決してあってはなりません。
Scoop バケットの整合性が保たれる仕組み
現在、自動書き込みを行うのはリリースパブリッシャーだけです:
pub-scoop.ymlはリリース時にプッシュされます。 Scoop ユーザーは、これが成功するとすぐに新しいバージョンを確認できます。リポジトリ間で使用するSCOOP_BUCKET_TOKENが必要で、ここが壊れやすい部分です。- メンテナーは失敗した push を復旧します。 トークンをローテーションまたは修復し、Scoop Bucket Canary をディスパッチしてフェイルクローズの
credential_canaryパスを通じて検証し、dry_run: falseでパブリッシャーを再実行して、バケットマニフェストにリリースバージョンが反映されたことを確認します。
bucket 側の Excavator が scoop-zeroclaw#1 で提案されています。そのワークフローがマージされ、bucket リポジトリで Actions にワークフローの読み取り/書き込み権限が付与され、メンテナーによるスモークテストで更新がコミットされることが確認されれば、認証情報に依存しない復旧レイヤーにできます。3 つすべての条件が満たされるまでは、失敗した publisher が自動復旧すると想定しないでください。
checkver と autoupdate のブロックは、計画中の Excavator パスですでに不可欠です。現在の push パスでも、scripts/release/scoop_metadata.sh を使用して autoupdate からリリース URL テンプレートを導出しているため、両方のパスで 1 つのマニフェスト契約を共有しています。これらのブロックを削除したり、dist/scoop/zeroclaw.json から手作業で取り除いたりしないでください。
PR パスラベラー (pr-path-labeler.yml)
変更されたファイルに基づいて、パスおよびスコープのラベルを自動的に適用します。PRのオープン、再オープン、およびPRブランチへのプッシュ更新のたびに実行されます。sync-labels: true が有効になっているため、.github/labeler.yml で定義されたラベルは、現在のPRファイルセットから再計算されます。
このワークフローは現在、risk:*、size:*、type:*、コントリビューター層、ステータス、解決状況、stale、pickup ラベルを適用しません。PR にパス/スコープラベルが欠落している場合は、.github/labeler.yml のパスが変更内容をカバーしているか確認してください。
Dependabot は独自の PR 用に .github/dependabot.yml で個別のラベル設定を持っています。Cargo の更新 PR は dependencies で始まり、GitHub Actions と Docker の更新 PR は ci と dependencies で始まります。
プロジェクトダッシュボードプランナー (project-dashboard-plan.yml)
手動で単一の issue 番号に対して実行します。issue の状態とラベルを読み取り、その issue に最も適合する既存の Project Status 値を提案するレポート専用のステップサマリーを書き込みます。
このワークフローは、issue イベントで自動的に実行されることはなく、ProjectV2 フィールドへの書き込み、issue の編集、ラベルの追加、コメントの投稿、PR の risk:*、size:*、type:* ラベルの再計算も行いません。ライブの ProjectV2 変更や自動的な issue イベント計画には、個別に承認されたフィールドマッピング、トリガーポリシー、プロジェクトスコープの認証情報が必要です。
PRタイトルの検証(pr-title.yml)
すべてのPRのopen/edit/synchronizeで実行されます。バリデータのユニットテスト(scripts/check-pr-title.test.sh)を実行し、PRタイトルをConventional Commits(scripts/check-pr-title.sh)に照らしてチェックします。
Pages に mdBook ドキュメントをデプロイ (docs-deploy.yml)
タグのプッシュ(および workflow_dispatch)でトリガーされ、バージョン管理されたドキュメントをビルドして gh-pages ブランチに公開します。バージョンの下限とブートストラップのルールについては、リリース Runbook → バージョン管理されたドキュメントのデプロイを参照してください。
Docker イメージ PR チェック (docker-image-pr.yml)
Docker イメージ、Compose、または release-Docker コンテキストファイルが変更された場合にのみ実行されます。デフォルトと Alpine を統合した Compose 構成を検証し、Compose のみの編集を超える変更がある場合は、デフォルトおよび Debian の事前ビルド済みスモークテスト用イメージとソース Dockerfile を push せずにビルドします。デフォルトおよび Alpine のソースイメージは linux/amd64 と linux/arm64 向けにビルドされ、Debian のソースイメージは linux/amd64 向けにビルドされます。Alpine と Debian の個別の linux/amd64 レーンでは plugins-wasm-runtime-only を有効にするため、各ビルダーコンテキストによって、プラグイン対応ソースビルドでリポジトリの WIT コントラクトを利用できることが継続的に確認されます。
全機能対応の Containerfile のソースイメージは、そのファイルまたは Docker ワークフローが変更された場合に linux/amd64 向けにビルドされます。分離されたキャッシュスコープを使用し、ロードもプッシュもされません。Alpine amd64 レーンでは両方のバイナリを実行し、マージ済みの Compose 構成を通じてビルド済みイメージを起動し、ゲートウェイのヘルスチェックとダッシュボードの各画面を検証します。Alpine arm64 レーンは、コンパイルとイメージの組み立てのみを対象とします。Compose のみの変更では、縮小した Alpine amd64 マトリックスを使用するため、関連のないイメージを再ビルドせずにランタイム契約を引き続き検証できます。すべてのジョブはリポジトリへの読み取り専用権限を持ち、レジストリへの書き込み権限はありません。
Docker 公開 (docker-publish.yml)
dev/ci/docker-tags.toml から生成された4バリアントのマトリックス(minimal、default-features、dist、all-features)をビルド、署名、スキャンします。人手で作成した v* タグによって、このワークフローが直接開始されます。workflow_dispatch で開始された安定版リリースは GITHUB_TOKEN を使用してタグを作成しますが、これによって別のタグプッシュイベントは発生しません。そのため、正規のリリースおよび Docker ジョブが成功した後、release-stable-manual.yml が不変のリリースタグで Docker Publish を同期的に呼び出します。
このマトリックスは、安定版リリースのビルド済み latest、バージョン付き、および debian イメージを置き換えるのではなく、補完するものです。2つのパスは異なるビルド入力を使用し、異なるタグを公開します。
Discord リリース (discord-release.yml)
安定版リリースが成功した後に実行されます。リリースノートをコミュニティの Discord に投稿します。
Tweet リリース (tweet-release.yml)
安定版リリースが成功した後に実行されます。アナウンス用のツイートを投稿します。
AUR の週次最新性チェック (aur-freshness-check.yml)
毎週月曜日に、公開されている zeroclawlabs AUR バージョンを GitHub の現在の安定版リリースと比較し、AUR が遅れている場合は失敗します。
AUR への公開は投げっぱなしです。pub-aur.yml が失敗すると再確認されないため、パッケージがひそかに遅れます。v0.8.4 の後に、まさにそれが起きました。aur.archlinux.org のメンテナンス期間がリリースと重なり、再試行されなかった1回の clone が The AUR is down due to maintenance で失敗し、パッケージは何の通知もないまま3週間遅れた状態になりました。公開処理では現在、アクティブな non-dry-run の公開を最大1件に制限し、短時間の停止を乗り越えられるよう再試行します。同じ concurrency group 内では、GitHub が先にキューへ入った実際の公開を後続の公開で置き換える場合がありますが、dry run では別のグループを使用します。すべての試行で正本となるパッケージ状態を再度 clone し、より新しい epoch:pkgver-pkgrel タプルをより古いもので置き換えることを拒否します。再試行予算でもすべての失敗をカバーすることはできないため、このチェックが、サイレントな取りこぼしや置き換えられた実行を可視化する最後の防波堤になります。
AUR RPC に到達できない場合、チェックは警告を出してパスし、失敗にはしません。AUR の停止は上流の可用性の問題であり、パッケージの陳腐化ではありません。次回のスケジュール実行で再チェックされます。陳腐化は持続するため、検出が遅れても問題ありませんが、他者のメンテナンスウィンドウについて毎週ページを送るのは適切ではありません。
ドキュメントは、master へのプッシュごとではなく、リリースパイプラインの一部としてビルドおよび公開されます。翻訳は、専用の翻訳キャッシュ PR、新しいロケール、リリース翻訳パスのためのローカル専用ワークフローです。通常の英語ドキュメント PR では、生成される .po の広範な変更を延期してもかまいません。コントリビューター向けのガイダンスについては Docs & Translations を、リリース手順については Release Runbook を参照してください。
手動およびアドバイザリワークフロー
月次の古いパッケージスキャン (monthly-outdated.yml)
毎月1日の09:00 UTCに定期的なスキャンを実行します。すべてのワークスペースメンバーに対して cargo outdated --workspace を実行します。古い依存関係が見つかると、dependencies-ラベル付きのイシューを作成します。権限: contents: read + issues: write。重複防止ガードにより、前回のイシューがまだオープンのままの場合に積み重なるのを防ぎます。
新しい issue の最初のトリアージ手順: 報告された古いクレートに semver 非互換のバンプがあるか、および利用側クレートの API が変更されたかどうかを確認する。バンプが軽微 (patch/minor) な場合は、短い依存関係のみの PR を作成する。アップグレードが semver 破壊によってブロックされている場合は、メモとブロックしているクレート名を添えて issue をクローズする。
クロスプラットフォームビルド (cross-platform-build-manual.yml)
リリースバイナリをフルターゲットマトリックス(Linux x86_64/aarch64 GNU および MUSL、armv7、arm ハードフロート、macOS Intel/ARM、Windows x86_64、aarch64-linux-android(NDK でビルド))向けにビルドする手動トリガー。タグ付け前に非 Linux ターゲットでブランチがクリーンにコンパイルされることを確認する際に使用してください。
各ディスパッチでは、ビルドとは独立して、小規模なリリースツールのスモークマトリックスも実行されます。この証跡だけが必要な場合は release_tools_only を設定します。その場合、web ジョブと release-build ジョブはスキップされます。信頼済みの GitHub ホスト型 Linux x86_64 では、スモークで固定された cross アーカイブをインストールし、cross と cross-util の両方を確認して、cross --version を記録します。信頼済みの GitHub ホスト型 Windows x86_64 では、安定版リリースワークフローと同じ Rust バージョンおよび Bash-to-Cargo のパス形状を使用し、その後 cargo-tauri.exe --version と cargo tauri --version の両方を記録します。各レッグでは、テストした正確なコミットとランナーのアーキテクチャを公開ジョブサマリーに記録します。スモークはリポジトリへの読み取り専用権限を使用し、公開ジョブ、環境、シークレット、アーティファクトのアップロードはありません。
MUSL ビルドレッグも cross を scripts/ci/install_release_tool.sh 経由でインストールします。このスクリプトは、ピン留めされた上流のリリースアセットを正確にダウンロードし、インストール前に SHA-256 を検証します。必須の Repository Structure ジョブは、ネットワーク呼び出しを行わずに、サポート対象のランナーとアセットのマッピングおよびスモークワークフローの契約をテストします。
クロスプラットフォーム Clippy (cross-platform-clippy.yml)
macOS aarch64 および Windows x86_64 ターゲットでの手動および週次スケジュールのアドバイザリ lint カバレッジ。各プラットフォームに --target を設定した必須の PR lint コマンドをミラーしますが、意図的に PR では実行されず、CI Required Gate の一部ではありません。
必須の Linux Clippy、非必須のクロスプラットフォーム Clippy、および対象を絞った Windows Clippy は scripts/ci/run_clippy.sh を呼び出します。このランナーは、サポート対象のコマンド形式、Cargo の終了ステータスの伝播、および共通の実行時間・キャッシュ・コンパイル回数・ダウンロード回数の診断を担当します。ワークフローファイルは引き続き、トリガー、ランナー、ツールチェーン、キャッシュ、タイムアウト、必須ゲートへの所属を担当します。
リリース安定版 (release-stable-manual.yml)
完全なリリースパイプラインを手動でトリガーします。すべてのターゲットをビルドし、GitHub Release を作成し、事前ビルド済みの latest、バージョン付き、および debian の Docker イメージを GHCR にプッシュし、リリースタグで生成された Docker バリアントマトリックスを呼び出し、Web サイトの再デプロイをトリガーし、配布サブワークフロー(Scoop、AUR、Discord、tweet)を呼び出します。Homebrew Core は独自の autobump サービスを通じて新しいリリースを検出します。2 つの環境ゲートでは実行途中でメンテナーの承認が必要です:github-releases(publish ジョブ)と docker。
ダウンロード可能なアセットは、GitHub がホストする Build Level 2 アテステーションを使用します。オフラインバンドルと信頼されたルートマテリアルは、1 つの検証アーカイブに含めて提供され、両方の SBOM 形式はリリースが作成される前にチェックサムが生成され、アテステーションされます。Cosign は引き続き GHCR イメージの署名に限定されます。
完全な手順については、リリースランブックを参照してください。
リリース専用のビルドツールは、実行のたびにソースからコンパイルするわけではありません。ワークフローは scripts/ci/install_release_tool.sh を介して、バージョンを固定した上流の cross と Tauri CLI のリリースバイナリをインストールします。このスクリプトは、ランナー固有の各アーカイブについてリポジトリで管理する SHA-256 を検証してから、バイナリを Cargo の bin ディレクトリに配置します。いずれかのツールを更新するには、そのバージョン、アセット名、チェックサムをまとめて更新し、その後 scripts/ci/install_release_tool.test.sh を実行する必要があります。
パッケージの公開者
それぞれは workflow_dispatch でバージョン入力とともにトリガーされます。また、公開が成功した後にリリースワークフローから呼び出されます。
| ワークフロー | 何をするものか |
|---|---|
pub-aur.yml | Arch User Repository の PKGBUILD を更新し、AUR にプッシュします。 |
pub-crates.yml | ワークスペースの連携リリースをパッケージ化して検証し、その後、crates-io 環境ゲートの下で依存関係順に crates.io へ公開します |
pub-scoop.yml | Windows用のScoopマニフェストを更新します |
Homebrew Core の公式自動更新サービスは、GitHub の安定版リリースを検出し、独立して formula の更新を作成します。プロジェクト所有の Homebrew publisher や fork token を復元しないでください。これは Homebrew の正式な自動化と重複します。
必要なシークレット
| シークレット | 使用される |
|---|---|
AUR_SSH_KEY | pub-aur.yml |
CARGO_REGISTRY_TOKEN | リポジトリシークレットは pub-crates.yml に明示的に渡され、保護された公開ジョブからのみ参照される。v0.8.5 では、zerorelay、zeroclaw-relay-proto、zeroclaw-tls に publish-new が必要で、後続の連携更新では publish-update が必要になる |
DISCORD_WEBHOOK_URL | discord-release.yml |
TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET, TWITTER_CONSUMER_API_KEY, TWITTER_CONSUMER_API_SECRET_KEY | tweet-release.yml |
SCOOP_BUCKET_TOKEN | pub-scoop.yml, release-stable-manual.yml, scoop-bucket-canary.yml; zeroclaw-labs/scoop-zeroclaw に限定し、Contents の読み取り/書き込み権限を持つ fine-grained PAT |
WEBSITE_REPO_PAT | release-stable-manual.yml(ウェブサイトリポジトリの再デプロイをトリガーします) |
GITHUB_TOKEN (自動) | コミットのプッシュ、PR の作成、または GHCR へのイメージのプッシュを行うすべてのワークフロー |
Docker イメージは自動的に提供される GITHUB_TOKEN を使用して GHCR にプッシュされ、別個のレジストリトークンはありません。CARGO_REGISTRY_TOKEN はリポジトリシークレットとして保存し、その名前付きシークレットだけを再利用可能なパブリッシャーにマッピングします。呼び出し先ワークフローがこれを参照するのは、取り消し不能な公開ステップのみです。このステップのジョブでは、crates-io 環境を通じた承認が必要です。トークンを使用しないプレフライトは、これを参照もエクスポートもしません。承認者が公開ジョブを開始できる前に、プレフライトで同じ不変のリリースコミットをパッケージ化します。
調整リリースセット内のほとんどの crate はすでに存在し、crates.io の trusted publishing の対象となっています。v0.8.5 リリースではさらに zerorelay、zeroclaw-relay-proto、zeroclaw-tls が作成されるため、そのブートストラップトークンには publish-new を含める必要があります。環境トークンは、このワークフローのすべての crate に trusted-publisher エントリが設定されるまで、引き続きブートストラップ経路となります。これらのエントリを設定したら、CARGO_REGISTRY_TOKEN を保持する代わりに、GitHub が OIDC ID を短期間有効なトークンと交換するようジョブを移行します。
現在、組織では Scoop バケットのデプロイキーが無効化されており、自動の GITHUB_TOKEN は別のリポジトリに書き込めません。SCOOP_BUCKET_TOKEN のスコープはバケットに限定し、メンテナーの広範な権限を持つ CLI トークンを再利用しないでください。パブリッシャーは git push --dry-run で書き込み権限を確認し、その後、実際の更新には同じ Git トランスポートを使用します。
SCOOP_BUCKET_TOKEN のローテーション
デプロイキーが利用できないため、この認証情報は個人アクセストークンであり、そのため独立した2つの障害モードがあります。どちらもリリースを失敗させたことがあります:
- トークンの有効期限が切れます。 Fine-grained PAT には最大有効期間が設定されているため、ほかに何も変更がなくても、これは一定のスケジュールで繰り返されます。
- 所有者の ID がバケットへの書き込み権限を失う。 トークンが有効なままでも、それに紐付くアカウントが
readコラボレーターにすぎない場合があります。この場合、remote: Permission to zeroclaw-labs/scoop-zeroclaw.git denied to <account>と HTTP 403 が返されます。これは認証エラーではないため、権限の問題なのにコードの問題のように見えます。
トークンは個人アカウントではなくZeroClaw-Botアカウントで管理し、リリース手順が1人のメンテナーの認証情報に依存しないようにします。ローテーションするには:
ZeroClaw-Botとして、リソース所有者をzeroclaw-labsに設定し、リポジトリアクセスを単一のリポジトリzeroclaw-labs/scoop-zeroclawのみに制限した、きめ細かい PAT を作成してください。リポジトリ権限 → コンテンツ: 読み取りと書き込みのみを付与してください。それ以外は何も設定しないでください。- org がトークンを承認したことを確認してください。組織をリソース所有者とするきめ細かい PAT は承認されるまで保留中のままであり、保留中のトークンは認証できますが push はできません。
ZeroClaw-Botがバケットに対するwrite権限をまだ持っていることを確認します:gh api repos/zeroclaw-labs/scoop-zeroclaw/collaborators/ZeroClaw-Bot/permission --jq '.role_name'。手順 1 ではリポジトリへのアクセスは付与されず、トークンが使用できる範囲を限定するだけです。トークンが所有者がすでに持っている権限を超えることはできません。- シークレットを設定します:
gh secret set SCOOP_BUCKET_TOKEN --repo zeroclaw-labs/zeroclaw。 - バケットに触れずに Scoop Bucket Canary をディスパッチして検証します。グリーンの実行により、新しいトークンで push できることが証明されます。
ローテーションする際は、有効期限を永続的な場所に記録してください。いずれにせよ、カナリアは期限切れのトークンを 1 週間以内に検出しますが、検出されるのはすでに機能しなくなった後です。
AURパッケージのオーナーシップ
プロジェクトが所有するパッケージは現在 zeroclawlabs で、zeroclaw-bot によってメンテナンスされています。正規名 zeroclaw パッケージはサードパーティのパッケージであり、AUR_SSH_KEY のローテーションによって引き継ぐことはできません。そのメンテナが引き続き非アクティブである場合は、pkgname またはワークフローのクローン対象を変更する前に AUR orphan-request プロセス に従ってください。所有権の移転後は、パッケージ名の変更またはマージをレビュー済みの 1 つの変更としてまとめて調整してください。
ビルドキャッシュの動作
ci.yml の Rust の比重が高いジョブのほとんどは、ローカルの ./.github/actions/rust-cache コンポジットを通じてキャッシュします。このコンポジットは、runner を選択するものと同じ CI_USE_BLACKSMITH トグルからキャッシュバックエンドを選択します。ジョブが Blacksmith runner 上で実行される場合は useblacksmith/rust-cache(Blacksmith NVMe sticky disk)、それ以外の場合は Swatinem/rust-cache が選択されます。トグルの true 以外の値(未設定を含み、すべての fork PR も含む)の場合は、GitHub-hosted runner 上の Swatinem/rust-cache にフォールバックするため、Blacksmith が無効でもキャッシュが失われることはありません。トグルにかかわらず、両方の action 参照がコンポジット内に存在するため、両方とも allowlist に残す必要があります。macOS と Windows の build leg は Swatinem/rust-cache のままで、fmt、nix-eval、docs-style ジョブ(いずれも workspace をコンパイルしない)は Rust キャッシュを使用しません。キャッシュ関連の flaky をトリアージするときは、これらの挙動を知っておくと役立ちます。
- キャッシュへの書き込みはマスターのみで行われます。
save-ifはgithub.ref == 'refs/heads/master'を条件としているため、PR の実行ではマスター由来のキャッシュを読み取りますが、更新は行いません。PR ブランチがブランチ固有のアーティファクトで共有キャッシュを汚染することはありません。masterへのpushトリガーによって、マージ後に信頼できるキャッシュ書き込みの実行がワークフローに提供されます。 - 失敗時にキャッシュが保存されます。 各ジョブには
cache-on-failure: trueが設定されているため、部分的な実行でも次の試行のキャッシュを有効にします。 - Windows ビルドキャッシュが有効になっています。 Windows ビルドレグは、Linux や macOS と同じ固定された Rust キャッシュアクションを実行します。Windows のキャッシュ動作が不安定になったり、リグレッションが発生したりした場合は、ワークフローの変更を元に戻し、失敗した restore/save の証跡をキャッシュの issue に記録してください。
- 増分コンパイルは無効化されています。 ワークフローレベルで
CARGO_INCREMENTAL: 0が設定されています。増分ビルドはキャッシュサイズを増大させ、部分的に古くなった条件の下で再現性のないアーティファクトを生成します。 cargo-denyとcargo-nextestは実行のたびに新規インストールされます。securityジョブではcargo install cargo-deny --lockedを実行し、Linux のtestジョブと、スケジュール実行されるplatform-tests.ymlの両方のレッグでは、get.nexte.stから適切なcargo-nextestバイナリを取得します。どちらのツールもキャッシュされないため、インストールごとに各ジョブに一定のコストが加わります。どちらかをtaiki-e/install-actionに切り替えればキャッシュできるようになりますが、現在この action は許可リストに含まれていません。
ゲートが赤になったとき
| 症状 | 最初に確認すべきこと |
|---|---|
uses: の参照が変更された後、Release Stable がジョブ数ゼロで startup_failure により停止する | 実行サマリーとリポジトリのActionsポリシーを確認してください。GitHubがselected-actionsの拒否を報告している場合は、変更されたrefを許可リストと比較し、拒否されたパターンのみを追加して、設定の反映を待ってから新しい実行をディスパッチしてください。それ以外の場合は、ワークフロー定義またはその他のリポジトリポリシーを調査してください。startup_failure だけでは原因を特定できません |
CI Required Gate 赤 | まず fmt、次に lint、続いて test、最後に build を実行します |
validate のリリースに失敗しました | Cargo.toml のバージョンがワークフローの入力と一致しない、またはタグが既に存在します |
| リリースビルドのステップが失敗しました | 特定のターゲットのジョブログ。Android は experimental であり、continue-on-error で実行されます。 |
| 環境ゲートがタイムアウトしました | ワークフロー実行ページからタイムアウトしたジョブのみを再実行する |
| 配布元のパブリッシャーに失敗しました | まず、対応するサブワークフローを手動で dry_run: true で再実行してください。 |
許可されたアクション
このリポジトリは selected モードで Actions を実行しており、この許可リストに含まれるアクションのみ実行できます。許可リストは厳格に保つ必要があります。新しいサードパーティ製アクションを追加する前には、メンテナーの明示的な承認が必要です。
すべてのサードパーティ参照は、末尾にバージョンコメントを付けた完全なコミット SHA に固定されています。以下のバージョン列には、そのコメントが記録されています。
| 対応 | 使用される | 目的 |
|---|---|---|
actions/checkout (v6.0.2) | ほとんどのワークフロー | リポジトリのチェックアウト |
actions/cache (v4.2.3, v5.0.5) | docker-image-pr.yml、tweet-release.yml | 汎用依存関係および Trivy データベースのキャッシュ |
actions/setup-node (v7.0.0) | ci-sbom.yml, ci.yml, cross-platform-build-manual.yml, daily-npm-audit.yml, pub-crates.yml, release-stable-manual.yml | npm SBOM の生成、Web テスト/監査、Web/デスクトップ ビルド用の Node ツールチェーン |
actions/upload-artifact (v7.0.1) | release-stable-manual.yml、cross-platform-build-manual.yml、docker-publish.yml、trivy-scheduled.yml | ビルド成果物と Trivy SARIF 引き継ぎ成果物をアップロードする |
actions/download-artifact(v8.0.1) | release-stable-manual.yml、cross-platform-build-manual.yml、docker-publish.yml | ビルド成果物と Trivy SARIF ハンドオフ成果物をダウンロード |
actions/attest (v4.2.2) | release-stable-manual.yml | リリースアセット向けに GitHub ホスト型の Build Level 2 プロベナンスを生成する |
actions/labeler (v6.1.0) | pr-path-labeler.yml | .github/labeler.yml からパス/スコープラベルを適用する |
dtolnay/rust-toolchain (stable, v1) | ci.yml, platform-tests.yml, pub-crates.yml, release-stable-manual.yml, cross-platform-build-manual.yml, cross-platform-clippy.yml, daily-audit.yml, docs-deploy.yml, codeql.yml | Rust ツールチェーンをインストールする |
Swatinem/rust-cache (v2.9.2) | ci.yml(./.github/actions/rust-cache の GitHub-hosted パス)、platform-tests.yml、pub-crates.yml、release-stable-manual.yml、cross-platform-build-manual.yml、cross-platform-clippy.yml、docs-deploy.yml | GitHub ホステッド ランナーでの Cargo のビルド/依存関係のキャッシュ |
useblacksmith/rust-cache (v3.0.1) | ci.yml(./.github/actions/rust-cache の Blacksmith パス) | Blacksmith の sticky disk での Cargo ビルド/依存関係キャッシュ。CI_USE_BLACKSMITH=true の場合にのみ選択 |
docker/setup-buildx-action (v3.11.1, v4.0.0) | release-stable-manual.yml、docker-publish.yml | Docker Buildx のセットアップ |
docker/login-action (v3.4.0, v4.1.0) | release-stable-manual.yml, docker-publish.yml, trivy-scheduled.yml | GHCR認証 |
docker/build-push-action (v6.18.0, v7.1.0) | release-stable-manual.yml、docker-publish.yml | マルチプラットフォームのイメージビルドとプッシュ |
sigstore/cosign-installer (v3.8.1) | release-stable-manual.yml、docker-publish.yml | キーレスなGHCRコンテナイメージ署名のためにcosignをインストールする |
anchore/sbom-action (v0.24.0) | release-stable-manual.yml | 各リリースごとに SPDX + CycloneDX の SBOM を生成する |
aquasecurity/trivy-action (v0.36.0) | docker-image-pr.yml, docker-publish.yml, trivy-scheduled.yml | コンテナの脆弱性スキャン(レポートのみ) |
github/codeql-action/upload-sarif (v3.36.2) | docker-publish.yml, trivy-scheduled.yml, ci-code-analysis.yml | Trivy と Semgrep の SARIF レポートを Security タブにアップロードする |
github/codeql-action/init (v3.36.2) | codeql.yml | CodeQL 分析(Rust および JS/TS)を初期化する |
github/codeql-action/analyze (v3.36.2) | codeql.yml | CodeQL SARIFをセキュリティタブにアップロードする |
GitHub Releaseそのものは、releaseアクションではなく、publishジョブ内のgh release createで作成されます。
同等の許可リストパターン(意図的に狭く保たれています):
actions/*
dtolnay/rust-toolchain@*
Swatinem/rust-cache@*
useblacksmith/rust-cache@*
docker/*
sigstore/cosign-installer@*
anchore/sbom-action@*
aquasecurity/trivy-action@*
github/codeql-action/upload-sarif@*
github/codeql-action/init@*
github/codeql-action/analyze@*
現在の有効なポリシーをエクスポートします:
sh
gh api repos/zeroclaw-labs/zeroclaw/actions/permissions
gh api repos/zeroclaw-labs/zeroclaw/actions/permissions/selected-actions
uses: アクションのソースを追加または変更するすべてのPRには、本文にホワイトリストの影響に関する注記を含める必要があります。広範なワイルドカードの例外を避け、確認済みの不足しているアクションに対してのみホワイトリストを拡張してください。
メンテナンスルール
CI Required Gateを決定論的で小さく保つ。ゲートにジョブを追加するには、明確な品質の根拠が必要。- すべてのサードパーティのアクション参照は、上記の許可リストポリシーに従って完全なコミット SHA に固定する必要があります。
ci.yml、dev/ci.sh、.githooks/pre-pushの整合性を保ってください。共通ゲートはscripts/ci/に配置し、各呼び出し元はコマンドをコピーするのではなくヘルパーを呼び出す必要があります。スタンドアロンのファームウェアプロトコルゲートについて、ドキュメント化されているローカルのエントリーポイントは./dev/ci.sh firmware-protocolです。scripts/ci/prepare_docker_context.sh、docker-image-pr.yml、およびrelease-stable-manual.yml内の Docker ジョブを揃えておくことで、リリースワークフローが公開するのと同じコンテキスト形状を PR の検証でも確認できるようにします。- リリースアテステーション、チェックサム、SBOM、または検証アーカイブのシーケンスを変更した後は
python3 scripts/ci/release_attestation_contract_test.pyを実行してください。 docs-styleゲートジョブはbash scripts/ci/docs_quality_gate.sh(markdown lint + emダッシュの文章チェック)とbash scripts/ci/docs_links_gate.sh(変更行のリンクゲート)を実行します。ドキュメントの変更をプッシュする前に、ローカルで両方のスクリプトを実行してください。
緊急ロールバック
もしホワイトリストがインシデント中に重要なアクションをロックアウトする場合:
- 一時的にActionsのポリシーを
allに戻します。 - 欠落しているエントリを特定した後、
selectedの許可リストを復元する。 - インシデントと最終的な許可リストの差分を記録します。
これは all モードへの唯一の正当な経路であり、インシデントを超えて存続させてはなりません。