mcpField
G
github-actions-workflow-pro

github-actions-workflow-pro

github.com/bretfisherクラウド・DevOps2164 回インストール2 週間前に更新
リポジトリ

github-actions-workflow-pro について

GitHub Actionsのワークフローを作成、編集、監査するコーディングエージェント向けスキルです。最小権限、アクションの固定、保守しやすいYAML、検証を重視します。

主な機能

  1. 01編集前のリポジトリ規約確認
  2. 02最小権限の適用
  3. 03サードパーティアクションのコミットSHA固定
  4. 04ワークフローの高速化とキャッシュ
  5. 05既存ワークフローの監査と強化
  6. 06リポジトリスクリプトによる変更検証

活用シーン

  1. 01安全なCIワークフローの作成
  2. 02既存ワークフローのリスク確認
  3. 03遅いGitHub Actionsジョブの高速化
  4. 04コンテナイメージのビルドと公開ワークフローの準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bretfisher/skills --skill github-actions-workflow-pro

インストール後、Claude Code で/github-actions-workflow-proを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
audit.md
parallel-steps.md
security.md
speed.md
scripts/
run-stats.py
scan.sh
validate.sh

詳細

GitHub Actions ワークフロールール

リポジトリに明確に異なる慣例がある場合、またはユーザーが別のトレードオフを求めている場合を除き、編集するすべてのワークフローに、これらの既定ルールを先回りして適用してください。ワークフローはトークンを使って任意のコードを実行するため、最初の行からセキュリティを組み込み、ワークフローを保守し続けられるよう速度を重視します。

作業スタイル

  1. 変更する前に既存のワークフローファイルを確認し、新しい変更がリポジトリの命名、トリガー、シークレットに関する慣例に合うようにします。
  2. 正しい範囲で最小限の変更を優先し、すでに編集しているコードにある安全でない、または無駄の多いパターンは修正します。
  3. 事実は自分で調べます(アクションの SHA、必要な権限、ツールが OIDC をサポートしているかなど)。判断はユーザーに委ねます(手動トリガーの追加、レジストリの選択、環境の作成など)。それぞれユーザーに確認し、返答を待ちます。
  4. リポジトリからわからないシークレット名、環境名、パッケージ名、クラウドロールにはプレースホルダーを使い、引き渡し時にすべてのプレースホルダーを列挙します。

ワークフローの作成

  • リポジトリから推測します。ランタイムのバージョンはバージョンファイル(.nvmrc、.python-version、go.mod)または engines から、lint とテストのコマンドはスクリプトから確認します。
  • 再利用可能なワークフローには call-*.yaml または reusable-*.yaml という名前を付けます。
  • pinact を使い、サードパーティの uses: はそれぞれ -i '<action>' を付けてピン留めします。追加するアクションには @v<major> を指定し、scripts/scan.sh pinact run --update --min-age 7 -i '<action>' <file> を実行します。新しいコードには、少なくとも7日経過した最新リリースを使うためです。すでにタグ(@v4 など)を指定しているアクションには、--update を付けずに scripts/scan.sh pinact run --min-age 7 -i '<action>' <file> を実行します。--update を付けると最新のメジャーバージョンに更新され(v4 から v7 など)、メジャーバージョンの更新はユーザーが判断するためです。引き渡し時には、より新しいメジャーバージョンへの更新について質問します。対象範囲が重要です。ファイル全体に対する --update は、すでにピン留めされている行も更新しますが、ユーザーはそれを求めていません。編集対象のファイルでタグを指定している既存のアクションも、何を「ほかはすべてそのまま」とするかにかかわらず、ピン留めします。攻撃者が変更できるのはそのタグの行であるため、ピン留めして引き渡し時に明記します(下記の pinned を参照)。
  • Docker ビルドワークフロー、または独自のリンターがないリポジトリの lint ワークフローを作成する場合は、独自のワークフローを作る前に再利用可能なワークフローを提案し、ユーザーがすでに使っているものがあるか確認します。Bret のワークフローは https://github.com/BretFisher/docker-build-workflow と https://github.com/BretFisher/super-linter-workflow です。npm run lint などをすでに定義しているリポジトリでは、それを実行します。

既存ワークフローの監査

ユーザーからワークフローのレビュー、強化、セキュリティ保護、または高速化を依頼された場合や、CI の問題点を尋ねられた場合は、audit.md を読み、その手順に従います。リポジトリ内のすべてのワークフローを対象に、最近の実行履歴を最初に取得し(scripts/run-stats.py を使用。失敗状況と、ワークフロー、ジョブ、ステップを所要時間順に一覧化し、2分以上かかったすべてのステップに印を付けて、そのしきい値をユーザーに確認します)、続いてリンター(actionlint、zizmor、gasa)を実行します。指摘事項を正確性、ハードニング、速度、意見に分類し、最初に「まず行うこと」のリストを示し、レポートの受け取り方法をユーザーに確認します。

チェックリスト

作成または編集するすべてのワークフローで、以下を満たします。リンク先のリファレンスには各ルールとその理由の詳細が記載されています。要約だけでは不十分な箇所は、そちらを読んでください。

  • 最上位に permissions: {} を設定し、ジョブごとに 最小権限 を付与します。後続のステップでトークンを使ってプッシュする場合を除き、actions/checkout では persist-credentials: false を設定します。→ security.md
  • サードパーティーの uses: はすべて、完全なコミット SHA に 固定 し、行には # vX.Y.Z コメント以外を付けません(余分なテキストがあると Dependabot がコメントを更新できなくなります)。固定先は、リリースから少なくとも7日経過したものにします。pinact が固定と経過日数の確認を行います。同じオーナーの参照にはタグを使えます。@main のようなブランチ参照は置き換えます。また、固定先となるタグがアップストリームにない場合は、高リスクとして報告します。→ security.md
  • クラウドの認証情報には OIDC(id-token: write)を使い、クラウド認証情報のステップ(configure-aws-credentials)は npm ci、pip install、ビルドの各ステップの後に実行します。または、ビルドを id-token: write のない独立したジョブにします。インストールスクリプトは任意のコードを実行するため、そのコードの実行が完了するまで認証情報を与えないようにします(build-push-action の前にレジストリへログインするのは問題ありません。Dockerfile のインストール処理はランナー上ではなく BuildKit 内で実行されるためです)。サードパーティーのシークレットは、ジョブで指定するリポジトリ環境に保存します。→ security.md
  • PR のトリガーには pull_request を使います。pull_request_target は外部の PR がアクセスできない場合に限って使います。具体的には、プルリクエストへのアクセスが Collaborators のみに制限されたリポジトリ、または信頼されていないチェックアウトを権限付与なしの独立したジョブに隔離したプライベートリポジトリです。zizmor の dangerous-triggers はトリガー自体を警告するため、使用を継続する場合は理由を明記します。→ security.md
  • SHA の固定をリリースから一定期間遅らせて最新に保つ更新ボットは1つだけ使用します。Dependabot(.github/dependabot.yml)または Renovate(renovate.json、.github/renovate.json、.renovaterc およびそれらの .jsonc/.json5 形式)のどちらでも構いません。リポジトリにあるボットとその設定を確認し、不足しているものだけを提案します。どちらのファイルも存在しない場合は、設定ファイルを作成する前に、ユーザーがどちらのボットを希望するか尋ねます。組織でリポジトリ外の Renovate 設定を共有している可能性があり、ボットを2つ使うと重複した PR が作成されるためです。→ security.md
  • 置き換えられた 実行はキャンセルします。CI では、ワークフローと ref をキーとする concurrency に cancel-in-progress: true を設定します。デプロイとリリースのワークフローには、キャンセルしない独自のグループを設定します。→ speed.md
  • リント、型チェック、単体テストなどの低コストなジョブを最初に実行し、それぞれを並行して動かします。高コストなジョブは、それらを needs: で指定します。→ speed.md
  • 1つの低速なジョブ内で独立しているステップは、同時に実行します。parallel: ブロックを使うか、ジョブが起動するサービスには background: true と wait/cancel を使います。この4つのステップキーは2026年6月に追加されたもので、学習データより新しいため、記述する前に構文を確認してください。→ parallel-steps.md
  • キャッシュにはセットアップアクション(setup-node の cache: npm、setup-go、Buildx の type=gha)を使います。ネットワークに接続するジョブやデプロイを行うジョブには timeout-minutes を設定します。再利用可能なワークフローを uses: で呼び出すジョブには設定できないため、呼び出し先のワークフローに設定します。→ speed.md
  • シェル、coreutils、checkout がすでに必要とするもの(git、curl、tar)以外のツールを呼び出す run: ステップでは、そのツールを インストールアクション で導入します。たとえば azure/setup-kubectl、azure/setup-helm、hashicorp/setup-terraform があり、ツールを開発する組織が公開しているアクションを優先します。または、依存関係をなくします(yq による編集の代わりに helm --set を使うなど)。kubectl、helm、jq、yq、aws を PATH に追加するのはランナーイメージだけです。そのため、これらが存在する前提のステップは、セルフホストランナー、container: ジョブ、または act ではツールが見つからず、CI が実際に実行される環境でワークフローを使えなくなります。アクションの version: には特定のバージョンか latest を指定できます。リポジトリにどちらが必要かはユーザーが決めることなので、選択肢として提示し、現行イメージに含まれるソフトウェアを伝えます(runs-on ラベルのソフトウェア一覧は https://github.com/actions/runner-images#available-images にリンクされています)。代わりに決めないでください。監査では、これらをすべてのツールとステップを列挙した1件のグループ化された指摘としてまとめ、デプロイワークフローを6件ではなく1件の修正として示します。

保守しやすい YAML

  • 大文字やスペースを含む、わかりやすい name: の値を付けます。ワークフロー名は1~3語、ジョブ名は最大5語、ステップ名は最大10語にします。2つのテストジョブは、名前で区別できるようにします。リポジトリ内の他のワークフローとスタイルを合わせます。
  • 既存のワークフローを編集したり高速化したりしても、トリガーは維持します。push をデフォルトブランチに絞ると、オープンな PR がないブランチでは CI が実行されなくなります。その変更は適用せず、失われるものを明記したうえで質問として提示します。
  • 複数行の Bash ステップは set -euo pipefail から始めます。1行に詰め込まず、わかりやすい複数行にします。
  • コメントは、セキュリティ境界、わかりにくいトリガー、デプロイのゲートを示すために使います。YAML のキーは見ただけで意味がわかるようにします。
  • <name>.md の隣にある <name>.lock.yml は、コンパイル済みの GitHub Agentic Workflow です。編集するのは .md ファイルで、その後 gh aw compile を実行してロックファイルを再生成します。ロックファイルの1行目には DO NOT EDIT と記されており、手動で編集しても次回のコンパイルで上書きされます。2つのファイルの監査(古さの確認、再コンパイル)については、audit.md を参照してください。
  • 複数のワークフローまたはリポジトリで安定した動作を共有する場合は、再利用可能なワークフローを導入する価値があります。ワークフローが1つだけなら、インラインのままにします。

コンテナイメージ

イメージを公開するのは信頼できる参照(デフォルトブランチ、タグ、リリース)からの場合に限り、2つのジョブを使います。pull_request で実行されるビルドジョブには contents: read と push: false を設定し、デフォルトブランチまたはタグへの push で実行される公開ジョブだけに packages: write を設定します。権限はイベントに応じて変更できないため、push: ${{ github.event_name != 'pull_request' }} を設定した1つのジョブでは、同一リポジトリからのすべての PR 実行に packages: write が付与されてしまいます。ビルドジョブの push: にはリテラルの false を指定し、イベント式は使いません。信頼できる参照ではジョブ内の式が true になり、レジストリにログインしていないジョブで push が失敗し、公開ジョブが実行されなくなるためです。

  • docker/setup-buildx-action、続いてタグとラベル用の docker/metadata-action、最後に docker/build-push-action を使います。PR では metadata-action が semver タグではなく pr-N を生成します。これは意図した動作です。
  • リポジトリで別のレジストリが指定されていない限り、ghcr.io を使います。
  • cache-from: type=gha と cache-to: type=gha,mode=max を指定します。公開時は provenance: true と sbom: true も指定します。
  • ビルド後に続くデプロイジョブでは、ダイジェストを使ってイメージを参照します。次の3行を設定します。ビルド・プッシュのステップに id: build を設定し、ビルドジョブの outputs: に digest: ${{ steps.build.outputs.digest }} を記述し、デプロイのステップでは <registry>/<image>@${{ needs.build.outputs.digest }} を参照します。タグは使いません。タグはビルドからデプロイまでの間に再度 push できますが、ダイジェストはできません。そのため、スキャンとテストを通過した成果物が、そのままリリースされます。

検証

編集したすべてのファイルに対して scripts/validate.sh <file>... を実行します。1回の実行で actionlint、scan.sh 経由の zizmor(そのため、gh のログインで使われるトークンがコマンド、トレース、トランスクリプトに現れることはありません)、poutine、pinact run --check --verify-comment --min-age 7 --verify-min-age が実行されます。各ツールの検出内容は個別の見出しの下に表示され、最後に validate: clean または報告したツールの数が出力されます。報告された内容を修正し、検出事項がなくなるまで再度実行してください。これらのスキャナーは、セキュリティチェックリスト(権限、ピン留めとピン留め期間、persist-credentials、インジェクション、危険なトリガー、Dependabot のクールダウン)のほとんどをすでに確認するため、証拠となるのは自分で読むことではなく、スキャナーの結果です。gasa は API 経由で push 済みのリポジトリを監査するため、ローカルでの編集ではなく監査の手順に含めます。インストールされていないツールは absent と表示されます。その場合は、インストールする(brew install actionlint shellcheck zizmor poutine pinact)かスキップするかを質問し、回答を待ちます。検証がすべてクリーンになるか、未インストールのツールが名前とともに absent と報告された場合にのみ、作業を引き渡します。

完了条件

  • 編集したすべてのファイルについて、actionlint、zizmor、poutine、pinact --check がクリーンであること、またはそれぞれが見つからない場合はツール名を明記すること。残してよい報告は、pinact ではピン留めできないブランチ参照(上流での修正としてリリースへのタグ付けを記載し、未解決として一覧にする)と、明示した理由により維持する pull_request_target に対する zizmor の dangerous-triggers だけです。さらに、並列ステップ構文に対する actionlint の unexpected key "background"/step must run script with "run" も許容されます。これは古いスキーマによるものであり、ワークフローのエラーではありません(parallel-steps.md)。
  • すべてのジョブに permissions: ブロックがあり、ワークフローの先頭に permissions: {} があること
  • すべてのサードパーティの uses: が、バージョンコメント付きの完全な SHA であること。編集したファイル内でタグ指定されていたアクションも対象です。引き継ぎ時にはピン留めしたものをすべて列挙し、すでにピン留めされていた行の SHA とコメントは維持すること
  • すべてのプレースホルダーをユーザー確認用に一覧にすること。環境名、リージョン、ロール ARN、バケット、レジストリ、シークレット名が対象です
  • 引き継ぎ時に、適用した次の各デフォルトについて、適用した理由を一行で説明すること。最小権限のアクセス許可、SHA のピン留め、同時実行制御、キャッシュ、timeout-minutes、信頼できる参照からの公開、provenance/sbom、persist-credentials: false、set -euo pipefail。長い作業の最後に「各デフォルト」を記憶から思い出すと必ず一つ抜けるため、名前を列挙してください。理由では、それが何をするかではなく、ここでなぜ適用するのかを述べてください

コメント