From 4ead05efba80ca2bfc9f7c6658e85316104a1190 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 31 Jul 2026 23:28:27 +0000 Subject: [PATCH] ci: backport sync-agent-instructions.yml and dependabot.yml to main Bring main's copies to parity with develop's current content ahead of the GitHub default-branch switch to main. sync-agent-instructions.yml finishes #518, which retargeted the sync-claude-md/sync-apm-skills jobs at develop (explicit ref: develop checkout, base: develop) and added a sync-rulesets job, but only ever landed on develop's copy. GitHub Actions resolves schedule/default-ref workflow_dispatch triggers from the default branch's copy of the workflow file, so main's stale pre-#518 copy (base: main, no explicit ref) would otherwise run once main becomes the default branch. dependabot.yml drops the stale pre-bun-migration npm ecosystem entry (package-lock.json no longer exists, #353) and switches the Python ecosystem from pip to uv, matching develop. GitHub reads dependabot config from the default branch, so this would otherwise regress the moment main becomes default. release.yml needs no change: main's copy already has the fixed daily cadence, --no-ci, and develop-derived commit prep from #521-#527. Refs #626, #518 --- .github/dependabot.yml | 20 +-- .github/workflows/sync-agent-instructions.yml | 130 ++++++++++++++++-- 2 files changed, 126 insertions(+), 24 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 42737abf..792e32a0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -23,22 +23,16 @@ updates: timezone: "Asia/Tokyo" target-branch: develop - - package-ecosystem: npm - directory: / - groups: - npm: - patterns: - - "*" - schedule: - interval: daily - time: "19:00" - timezone: "Asia/Tokyo" - target-branch: develop + # NOTE: JavaScriptパッケージ管理をnpmからbunへ移行(#353)したため、`npm`エコシステムの + # 対象ファイル(package-lock.json)は存在しない。`package-ecosystem: bun`は + # Dependabotがサポートしない値でスキーマ検証に失敗するため使用できない(#367で確認済み)。 + # bunがサポートされるまでJS依存のDependabot自動更新は一時停止し、`bun update`を手動/別途の + # 仕組みで運用する。 - - package-ecosystem: pip + - package-ecosystem: uv directory: / groups: - pip: + uv: patterns: - "*" schedule: diff --git a/.github/workflows/sync-agent-instructions.yml b/.github/workflows/sync-agent-instructions.yml index f34526a7..a6235d2b 100644 --- a/.github/workflows/sync-agent-instructions.yml +++ b/.github/workflows/sync-agent-instructions.yml @@ -4,12 +4,21 @@ # # 目的 (Purpose): # --------------- -# エージェント指示を上流から追従させる2つの独立したジョブを持つ。 +# エージェント指示を上流から追従させる3つの独立したジョブを持つ。 # - sync-claude-md: 正本リポジトリ tvna/claude-md の CLAUDE.md を取得し、 # 本リポジトリの CLAUDE.md (コミット済み実ファイル) へ追従させる。 # - sync-apm-skills: apm.yml にピン留めした obra/superpowers / # tvna/clairvoyance の上流コミットを検知し、pin 更新・再デプロイ・ # マニフェスト再生成を行う。 +# - sync-rulesets: 正本リポジトリ tvna/claude-md の +# .github/rulesets/all-branches.json (全ブランチforce-push禁止、汎用的) +# のみを取得し、本リポジトリへ追従させる。取得後、command-ghostwriter +# 固有のローカル追加 (refs/heads/chore/sync-* の除外——本ワークフロー自身の +# sync-*ジョブがPRブランチ更新のたびに強制更新するため、force-push禁止rule +# から除外する必要がある) を毎回自動で再適用する (#503)。人間の記憶に頼らず +# 上流ドリフトで消えないようにするため、コピー後に決定的に付け直す。 +# main.json はcommand-ghostwriter固有のrequired_status_checksを含む +# ローカル正本のため同期対象外 (構造が変わった場合は人間が見て判断する)。 # いずれも差分があれば PR を作成/更新する (レビュー必須・自動マージしない)。 # # 方式の根拠 (Rationale): @@ -18,14 +27,23 @@ # に含まれない) ため、CLAUDE.md はコミット済み実ファイルとして同期する。 # - PR は GITHUB_TOKEN ではなく GitHub App トークン (actions/create-github-app-token) # で作成する。GITHUB_TOKEN で作った PR は on: pull_request を発火させず必須CIが -# 永久 pending となり `mergeable_state: blocked` に陥る (PR #510)。App トークンなら -# App bot 名義の Verified コミットとなり、下流 CI も発火する。上流 tvna/claude-md と -# 同じ方式・同じ GitHub App を用いる (Issue #511)。 +# 永久 pending となり `mergeable_state: blocked` に陥る (PR #464, #510)。App トークン +# なら App bot 名義の Verified コミットとなり、下流 CI も発火する。上流 +# tvna/claude-md と同じ方式・同じ GitHub App を用いる (Issue #511)。3ジョブ +# (sync-claude-md, sync-apm-skills, sync-rulesets) 全てが同じPR作成パターンを +# 使うため、同じバグクラスを抱える。3ジョブとも同時にApp token化する。 # - secret `AUTOMATION_APP_ID` / `AUTOMATION_APP_PRIVATE_KEY` に上流と同じ App の # App ID / PEM 秘密鍵を登録し、App を本リポジトリにインストールしておくこと # (権限: Contents=write, Pull requests=write, Issues=write)。 # - create-pull-request の sign-commits: true により、ローカル git commit ではなく # GitHub API 経由でコミットを作成し、App トークンで Verified 署名済みコミットとする。 +# - PR は develop へ向ける (base: develop)。dependabot (4エコシステム全て +# target-branch: develop) や通常のfeature/fix PR (claude/* ブランチ) と揃え、 +# develop で進行中の作業に指示・skill更新・ruleset更新を即座に反映するため。 +# main は develop→main のバージョンゲート付きリリース昇格時にのみ追従する +# (Issue #518)。schedule/workflow_dispatch トリガーの既定checkoutは default +# branch (main) になるため、checkout に明示的な `ref: develop` が必須 (これが +# ないと diff/commit の基準ブランチが main のままずれる)。 # - sync-apm-skills は上流の既定ブランチ最新コミットを REST API やフル checkout # ではなく `git ls-remote HEAD` で取得する (GitHub API のレート制限を回避)。 # - apm.yml の2依存が同時に更新されていても PR は1本にまとめる @@ -37,6 +55,7 @@ # 関連 (Reference): # ----------------- # - Issue #427, #467 (CLAUDE.md 同期), #480 (apm スキル上流追従), #446 (apm バージョンアップ, 別スコープ) +# - Issue #503 (main保護ruleset整備), #511 (App tokenへの移行), #518 (PR ターゲットを develop へ変更) # - 設計書 docs/superpowers/specs/2026-06-13-claude-md-master-sync-design.md # - 設計書 docs/superpowers/specs/2026-07-02-sync-apm-skills-upstream-update-design.md # ============================================================ @@ -65,15 +84,17 @@ jobs: pull-requests: write steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Check out this repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: develop - name: Check out master CLAUDE.md - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: repository: tvna/claude-md ref: main @@ -98,7 +119,7 @@ jobs: with: token: ${{ steps.app-token.outputs.token }} sign-commits: true - base: main + base: develop branch: chore/sync-claude-md delete-branch: true commit-message: "chore: sync CLAUDE.md from tvna/claude-md (#427)" @@ -127,12 +148,14 @@ jobs: APM_SHA256: a0b896e8cbdd10441125e989aa19d180c62052eda7c8aa850feb367805d1256f steps: - name: Harden Runner - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit - name: Check out this repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: develop - name: Detect upstream apm dependency updates id: detect @@ -213,7 +236,7 @@ jobs: with: token: ${{ steps.app-token.outputs.token }} sign-commits: true - base: main + base: develop branch: chore/sync-apm-skills delete-branch: true commit-message: "chore: sync apm skill dependency pins from upstream (#480)" @@ -226,3 +249,88 @@ jobs: Review required; do not auto-merge. Refs #480 + + sync-rulesets: + name: Sync all-branches ruleset from tvna/claude-md + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: write + pull-requests: write + steps: + - name: Harden Runner + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 + with: + egress-policy: audit + + - name: Check out this repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: develop + + - name: Check out upstream all-branches.json + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: tvna/claude-md + ref: main + sparse-checkout: .github/rulesets/all-branches.json + sparse-checkout-cone-mode: false + path: .upstream-claude-md + + - name: Copy upstream all-branches.json and reapply local exclude + run: | + set -euo pipefail + python3 -c " + import json + + with open('.upstream-claude-md/.github/rulesets/all-branches.json', encoding='utf-8') as fp: + ruleset = json.load(fp) + + # Local addition, not present upstream: command-ghostwriter's own + # sync-* jobs (this workflow) force-update their PR branch on every + # run via peter-evans/create-pull-request, which the upstream + # non_fast_forward rule would otherwise block. Re-apply it after + # every upstream copy so it survives drift (#503). + exclude = ruleset['conditions']['ref_name']['exclude'] + pattern = 'refs/heads/chore/sync-*' + if pattern not in exclude: + exclude.append(pattern) + + with open('.github/rulesets/all-branches.json', 'w', encoding='utf-8') as fp: + json.dump(ruleset, fp, indent=4, sort_keys=True) + fp.write('\n') + " + rm -rf .upstream-claude-md + + - name: Mint GitHub App token + id: app-token + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + app-id: ${{ secrets.AUTOMATION_APP_ID }} + private-key: ${{ secrets.AUTOMATION_APP_PRIVATE_KEY }} + + - name: Create or update pull request + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 + with: + token: ${{ steps.app-token.outputs.token }} + sign-commits: true + base: develop + branch: chore/sync-rulesets + delete-branch: true + commit-message: "chore: sync all-branches ruleset from tvna/claude-md (#503)" + title: "chore: sync all-branches ruleset from tvna/claude-md" + body: | + Automated sync of `.github/rulesets/all-branches.json` from the + master repository [`tvna/claude-md`](https://github.com/tvna/claude-md) (`main`). + + The local exclude pattern `refs/heads/chore/sync-*` (needed so this + workflow's own sync-* PR branches aren't blocked by the force-push + ban) is re-applied automatically after copying from upstream; it + should be present in the diff below. If it is missing, the + re-apply step has a bug and this PR should not be merged as-is. + + `.github/rulesets/main.json` is intentionally NOT synced here: it + carries command-ghostwriter-specific `required_status_checks` and + is a local source of truth. Review required; do not auto-merge. + + Refs #503