genesis-cicd について
genesis-cicdは、genesis monorepo向けのCIワークフローを生成するスキルで、Railway、Kubernetes、Overwatcherのデプロイ方式に対応します。サービスのテスト、イメージビルド、公開、デプロイ条件を整えるチーム向けに、方式別のルールと検証手順を備えています。
主な機能
- 01GitHub ActionsのCIワークフローを1つ生成
- 02Railway、Kubernetes、Overwatcherの構成
- 03サービス別テストとイメージビルド依存関係
- 04ブランチとデプロイのゲート設定
- 05ワークフローと前提条件の検証
活用シーン
- 01genesis monorepoへのCI追加
- 02serverとwebの独立したビルド経路の設定
- 03Kubernetesのイメージ公開とHelmデプロイ準備
- 04Overwatcherのイメージデプロイワークフロー設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ lwlee2608/ genesis --skill genesis-cicdインストール後、Claude Code で/genesis-cicdを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
kubernetes.mdREADME.mdreference.md詳細
genesis-cicd
genesis モノレポに .github/workflows/ci.yml を 1 つ追加します。Railway と Overwatcher のテンプレートは reference.md に、Kubernetes のテンプレートは外部の lwlee2608/release-manifest アクションを使用する kubernetes.md にあります。
- Kubernetes:
changes -> resolveの後、独立したserver -> build-server-imageとweb -> build-web-imageの経路がpublish -> deployで合流します。 - Overwatcher:
changesの後、独立したserver -> build-server-imageとweb -> build-web-imageの経路を実行します。外部デプロイには両方のビルドの成功が必要です。 - Railway:
changes -> server/web。
質問の流れ
- まず引数を読みます。
railway/kubernetes/overwatcherは CD の対象、main-prod/release-prodはブランチモデル、sticky-diskは Blacksmith の有料 Docker キャッシュを選択します。不足している情報だけを尋ねます。 - 残りの質問は、1 回の AskUserQuestion 呼び出しで尋ねます。
- CD の対象:
railway (Recommended)|kubernetes|overwatcher(Docker Compose を実行する VM に、Overwatcher GitHub App がデプロイ) - ブランチモデル:
main = production (Recommended)|main = staging, release = production - Docker レイヤーキャッシュ。
kubernetes/overwatcherの場合のみ:GitHub Actions cache (Recommended)— 無料 |Blacksmith sticky disk— $0.50/GB/month。RUN --mount=type=cacheも永続化されます
- CD の対象:
- 書き始める前に、対象の前提条件を解決します。 Kubernetes の場合はチャートを調べ、不足している GCP プロジェクト、クラスターのロケーション、名前空間、リリース名、環境値ファイルのパスを確認します。タグのみのイメージ構築ではなく、完全なダイジェスト参照にチャートが対応していることを必須とします。標準のスキャフォールドには Helm チャートがありません。チャートがない場合は、別の前提条件として作成するか、別の対象を選ぶかを確認して作業を止めます。公開済みの
lwlee2608/release-manifestのコミットを確認し、両方のアクションをそのコミットに固定します。利用可能になるまでは、バージョンを捏造せず、依存関係のブロッカーとして報告します。生成するワークフローにデプロイ用のプレースホルダーを残してはいけません。 - 1 文で確認してから、作成します。 例:「kubernetes、main→staging / release→prod、GCR、GHA キャッシュ — 続行しますか?」
ルール
-
まず対象プロジェクトを読みます。 サービスディレクトリ名、サーバーの Makefile にある
make test、Web 側のpackageManager: pnpm@…とpnpm-lock.yamlを確認します。pnpm/action-setupのpackage_json_fileにはサービス内のファイルを設定します。defaults.run.working-directoryはアクションには適用されません。Kubernetes の場合は、公開するイメージと照合し、Chart.yaml、環境値ファイル、両方のイメージ参照キーを検証します。project-00を残してはいけません。 -
ワークフローファイルは 1 つにし、ジョブは
needs:でつなぎます。workflow_runで連鎖させる 2 つ目のワークフローでは Actions のグラフが分断され、head_shaを渡さない限りデフォルトブランチの先端をチェックアウトし、同じコミットに対する push と PR の実行の両方で起動します。キャンセルするのは、後続に置き換えられる PR の実行だけです。無関係な push が関連するビルドをキャンセルしたり、保留中のビルドに取って代わったりしないよう、push の実行にはそれぞれ異なるコンカレンシーグループを割り当てます。Kubernetes の公開処理はリリーストラックごとに、Helm ジョブはデプロイ対象ごとに直列化し、実行中のジョブはキャンセルしません。
github.run_numberはワークフロー単位のため、各トラックの公開は 1 つのワークフローが担当します。公開とデプロイは別々の操作であり、アクションはデプロイ順序を保証しません。 -
サービスごとにテストジョブを 1 つ設けます。 Railway/Overwatcher と Kubernetes の PR では、
changes(dorny/paths-filter)を使ってテストスイートを絞り込みます。contents: readとpull-requests: readを付与し、base: ${{ github.ref }}を使用します。サービスの変更ではそのサービスのスイートを実行し、ci.ymlの変更では両方を実行します。ドキュメントはワークフローのトリガーではなく、これらのジョブのフィルターで除外します。paths:とpaths-ignore:の両方を使うと、必須の PR チェックが保留状態のままになることがあります。changesはデプロイ対象との関連性も報告するため、実際のチャート/値ファイルのパスと共有入力を含めます。Kubernetes の push では、失敗したビルド後に未公開のまま残っている変更も含め、resolveが要求するイメージをすべてテストします。明示的なジョブの状態ゲートを設定し、resolveが意図的にスキップされた場合も PR テストを実行できるようにします。 -
テストがスキップされたことだけでなく、関連性と前提条件の成功を基準に後続作業を制御します。 Overwatcher は、関連する場合、またはリリースの push ごとに、独立した
build-server-imageジョブとbuild-web-imageジョブで両方のイメージをビルドします。それぞれに必要なのはchangesと各自のテストスイートだけです(サーバーでは任意のストアテストも必要です)。ベースの関連性判定とリリーステストのスキップポリシーは維持してください。テストスイートまたはイメージのビルドに失敗しても、もう一方のイメージの処理はブロックされませんが、外部デプロイには両方のイメージジョブの成功が必要です。Kubernetes は対象となるすべての push でresolveを実行し、呼び出し元で計算されたフィンガープリントをそのトラックの公開済みベースラインと比較して、要求されたイメージのみをビルドします。各イメージジョブには、もう一方のテストスイートの成否にかかわらず、解決処理と自身のテストスイートの成功が必要です。publishには、変更検出と解決処理の成功、関連性(ビルドが要求されていること、デプロイ対象の変更があること、またはリリースの push であること)、要求された各イメージジョブの成功、要求されていない各イメージジョブのスキップ状態が必要です。ビルドが要求されていない場合は両方のイメージジョブをスキップします。Helm の変更とリリースの push では、保持された参照を引き続き公開します。テストスイートの失敗前にもう一方のイメージが push 済みとなる場合がありますが、公開はブロックされます。任意のストアテストがゲートするのはbuild-server-imageのみです。publish では、そのビルドの成功を通じてストアテストの成功を確認します。deployには公開の成功が必要です。PR から公開やデプロイを行わないでください。 -
ブランチモデル:
main-prod:push: branches: [main]+pull_request。release-prod:push: branches: [main, release]+pull_request。Kubernetes では、main にstaging、release にproductionを使用します。main を release にマージすると、release のコミットから変更されたイメージが自動でテスト・ビルドされ、本番環境にデプロイされます。変更されていない本番用ダイジェストは保持されます。手動ディスパッチ、source-release、ステージングイメージの昇格は追加しません。Railway/Overwatcher では、ベースのリリーステストポリシーを維持してください。保護された main のツリーが正常にテスト済みであることを確認した後にのみスキップし、それ以外の場合はリリースの push ですべてのテストスイートを実行します。リリースの push をパスフィルターで制限しないでください。
-
CD の対象:
railway:イメージビルドジョブなし、デプロイジョブなし。Railway は push 時に Dockerfile からビルドします。release-prodでは、本番環境のブランチをrelease、ステージング環境のブランチをmainに設定します。Wait for CI とサービスの監視パスは個別に設定してください。GitHub ジョブがスキップされたというだけでは、Railway のデプロイは抑制されません。昇格の例外については、リファレンスのチェックリストを参照してください。kubernetes:ベースの GHCR ワークフローに Helm の末尾部分を足すのではなく、Kubernetes のリファレンス全体を使用します。イメージは GCR に保存し、マニフェストはアプリケーションリポジトリの GitHub Release アセットに保存します。トラックを考慮するdeployジョブでは、成功した publish アクションのmanifest出力から取得した完全なダイジェスト参照を両方指定して Helm を実行します。main-prodでは main を本番環境の対象とし、release-prodでは main をステージング環境、release を本番環境の対象とします。本番環境の承認ゲートを維持してください。overwatcher:イメージは GHCR に保存し、デプロイジョブはありません。また、リファレンスに従ってdocker-compose.prod.ymlと.env.exampleも作成してください。genesis のスキャフォールドには本番用 compose がありません。owctl のセットアップにはoverwatcherスキルを使用します。サービスの Workflow フィールドをci.ymlに設定してください。Overwatcher がデプロイするのは、サービスのブランチで正常に完了した実行のみです。イメージジョブが失敗すると実行全体が失敗し、何も変更しない実行では、変更のないブランチタグが再取得されます。
-
共有の
latestは絶対にデプロイしないでください。 Overwatcher はサービスごとに固定タグをデプロイするため、compose ではデプロイ対象のブランチタグを固定します。イメージジョブでは、追跡可能性と手動ロールバックのために SHA タグも引き続き push します。Kubernetes では、一意な実行/試行ビルドタグは push にのみ使用し、その後repository@sha256:...を記録・デプロイします。フィンガープリントには、サービスのコンテキスト全体、ワークフロー、すべてのビルド入力と引数を含めます。サーバーのCOMMIT_SHAには安定したビルド入力コミットを使用し、それをフィンガープリントに含めます。現在の、無関係なワークフローの SHA は使用しません。コンテキスト全体を対象とするドキュメントは再ビルドを引き起こす場合がありますが、ビルド入力の範囲外にあるルートのドキュメントは再ビルドを引き起こしません。廃止された Python リリースマネージャーを生成プロジェクトにコピーしないでください。 -
Blacksmith ランナー:
server、build-server-image、および両方のイメージビルド対象におけるbuild-web-imageではblacksmith-4vcpu-ubuntu-2404を、それ以外ではblacksmith-2vcpu-ubuntu-2404を使用します。cacheを有効にしたまま、上流のactions/setup-go/actions/setup-nodeを使用してください。Blacksmith は GitHub キャッシュ API を透過的に高速化します。useblacksmith/setup-*ラッパーは非推奨です。 -
Docker レイヤーキャッシュ:ユーザーが
sticky-diskを選択した場合を除き、イメージごとに 1 つのスコープでtype=ghaを使用します。useblacksmith/setup-docker-builderとuseblacksmith/build-push-actionは、GB 単位で課金されるスティッキーディスク上でビルダーを維持します。ユーザーが選択していない場合、「高速化」のためにこれらを追加してはならず、1 つのジョブで 2 つの方式を混在させてはなりません。Kubernetes と Overwatcher では、各イメージジョブのビルダーを置き換え、<app>-serverと<app>-webという別々のスティッキーキャッシュキーを使用します。ジョブゲートがあるため、ステップごとに要求されたイメージの条件を指定する必要はありません。 -
シークレットをコミットしてはなりません。 GHCR では、
build-server-imageとbuild-web-imageのみにpackages: writeを付与し、GITHUB_TOKENを使用します。テストジョブは読み取り専用のままにします。Kubernetes では、contents: writeはpublishのみに付与し、解決にはcontents: readが必要です。GCR/GKE には、ユーザーがリポジトリの設定で追加するサービスアカウント JSON が必要です。Kubernetes のレジストリ認証ジョブでは、JSON ではなくスカラー形式のダイジェストをエクスポートします。複数行のシークレットマスキングによって、JSON のジョブ出力が抑制されることがあります。新しくビルドした参照はpublishのimagesステップで組み立てます。保持された参照は publish アクションから提供されます。
検証手順
- Blacksmith の許可済みセルフホストランナーラベルを設定して、
actionlint .github/workflows/ci.ymlを実行します。YAML パーサーは構文チェックの代替手段にすぎず、Actions の式や依存関係は検証できません。actionlint を利用できなかった場合は、その旨を報告してください。 grep -n project-00 .github/workflows/ci.ymlの結果が空であることを確認します。- 同じ手順をローカルで実行します:
go vet ./... && make test、pnpm install --frozen-lockfile && pnpm lint && pnpm build。 - 選択した対象の単一のジョブグラフを検証します。Kubernetes の PR テストは resolve がスキップされても動作する必要があります。また、書き込み/デプロイを行うすべてのジョブがスキップされる必要があります。実際に Actions の実行を確認していない場合は、ライブ環境で検証済みと主張してはなりません。
- Kubernetes:ブートストラップが両方のイメージをビルドし、それぞれのイメージが、もう一方を待たずに各自のテストスイート後に開始されることを検証します。server のみの変更では web が保持されます。Helm のみの変更では両方のイメージジョブがスキップされますが、保持されたダイジェストを使って publish/deploy が実行されます。無関係なプッシュでは、ビルド失敗後に未公開の変更が再試行されます。健全な状態でのルートドキュメントのみの main へのプッシュでは、両方のイメージジョブがスキップされ、publish/deploy も実行されません。要求されたテストスイートまたはビルドが失敗/キャンセルされた場合、もう一方のイメージがプッシュ済みでも公開はブロックされます。スカラー形式のダイジェスト出力と publish 側での JSON 組み立て、イメージごとに分離されたキャッシュを使う両方のキャッシュ方式、ならびに server のビルドと公開のみをブロックし、web はブロックしないオプションのストアゲートを確認します。
- Kubernetes の
release-prod:main を release にマージすると、本番ベースラインが自動的に使用され、要求された release ブランチのイメージがテスト/ビルドされ、公開済みの両方のダイジェストがデプロイされます。新しいイメージがない場合のリリース経路と、公開/Helm の失敗からの復旧をkubernetes.mdで確認します。 - Railway/Overwatcher:Overwatcher の両方のイメージを SHA でビルドすることや、外部の no-op/デプロイ設定を含め、参照元の動作チェックを維持します。それぞれのイメージが、もう一方を待たずに各自のテストスイート後に開始されることを検証します。テストスイートまたはビルドの失敗、あるいはオプションのストア障害は、もう一方のイメージの経路をブロックしませんが、デプロイはブロックします。PR/no-op のスキップ、チェックが意図的にスキップされるリリースビルド、イメージごとに分離されたキャッシュを確認します。GitHub のジョブスキップから外部 CD の動作を推測してはなりません。
よくある注意点
- Kubernetes のビルドで前回のコミットとの差分だけを使う — 失敗したビルドでの変更が、次の無関係なプッシュで見えなくなります。公開済みのマニフェストと比較してください。
- 要求されたテストのスキップを許容する — スキップは、依存関係の失敗ではなく、意図的に既存のイメージを維持することを意味する必要があります。
- Kubernetes で両方のイメージに現在の SHA を設定してデプロイする — 変更のないイメージは、現在のコミットのタグではなく、以前のダイジェストを維持します。
- PR でワークフローレベルの
paths:またはpaths-ignore:を使う — 必須の PR チェックが報告されず、マージがブロックされます。 - ワークフローの成功をイメージが公開された証拠とみなす — no-op や PR の実行は、イメージのジョブがスキップされても成功することがあります。Kubernetes の Helm のみの場合や、新しいイメージがないリリースのプッシュでは、両方のイメージのジョブがスキップされても、維持された参照が公開されることがあります。
- Railway または Overwatcher 用のデプロイジョブを書く — どちらも独自にデプロイするため、helm/ssh ジョブを追加すると競合します。
- Web で
npm ciを使う —pnpm-lock.yamlを無視します。 - サーバーと Web で同じ
type=ghaスコープを共有する — それぞれのビルドが、もう一方のレイヤーを削除します。