Community程式設計與開發github.com

land-renovate

批次合併 Renovate PR。遍歷當前儲存庫中所有由 Renovate 建立的 PR,將安全的 PR 核准並以 rebase-merge 方式合併,並處理衝突或真實失敗的情況。

land-renovate 是什麼?

此技能專為需要批次處理 Renovate 依賴更新 PR 的開發者設計,可自動遍歷並分類當前 GitHub 儲存庫中所有由 Renovate 建立的開放 PR。它會根據 PR 的狀態檢查、合併性及合併狀態,將每個 PR 歸類為 GREEN(可安全合併)、CONFLICTING(衝突)、REAL_FAILURE(真實失敗)或 HOLD(需人工判斷)。針對 GREEN 的 PR,它會自動核准並以 rebase-merge 方式合併;針對 CONFLICTING 的 PR,則會勾選 Renovate 的 rebase 核取方塊,觸發重新基底,並透過監控腳本等待檢查完畢。此技能完全依賴 gh CLI 操作遠端 PR,不涉及本地提交或自訂 PR 建立,支援 `gh` 和 Claude Code 等平台。其監控機制特別設計以處理 Renovate 重新基底後可能發生的多次提交(Renovate 推送修正,然後應用機器人再推送),確保僅在真正就緒時才給予 GREEN 判決,避免 gh pr checks --watch 的陷阱。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/langri-sha/skills/tree/main/land-renovate

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

land-renovate 是做什麼的?

遍歷當前儲存庫中所有開放的 Renovate PR 佇列,並合併安全的 PR: 依序列舉、分類、核准 + 以 rebase-merge 方式合併(依 PR 編號升序), 對其餘 PR 勾選 rebase 核取方塊以提示重新基底,並在遇到真實失敗或 HOLD 案例時乾淨地停止。

此技能完全透過 gh 操作現有的遠端 PR。它不會呼叫 /create-commit、/create-pr 或 /wrap,也不會在本機建立提交。

引數

引數預設值說明
limit=N30限制要遍歷的 PR 數量。
<pr-number>...所有 Renovate 建立的開放 PR以空格分隔的 PR 編號;僅對這些 PR 進行操作。

預設值:當前儲存庫(來自 gh repo view --json nameWithOwner)、Renovate 建立的開放 PR、 PR 編號升序排列、無標籤篩選。

工作流程

1. 解析儲存庫

REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)

2. 列舉 Renovate PR

列出所有開放的 Renovate 建立的 PR,從最舊(最小編號)開始:

gh pr list -R "$REPO" --author "app/renovate" --state open --limit 30 \
  --json number,title,mergeable,mergeStateStatus,statusCheckRollup

按 number 升序排序並依此順序遍歷。如果指定了明確的 PR 編號作為引數,則將集合限制為這些 PR。

注意: gh pr list 經常回傳 mergeable: UNKNOWN,因為 GitHub 會延遲計算可合併性。 對單一 PR 執行 gh pr view <n> --json mergeable 可以強制執行計算。當 PR 的 mergeable 為 UNKNOWN 時,請在分類前使用 gh pr view 重新讀取。

3. 分類每個 PR

使用 statusCheckRollup + mergeable + mergeStateStatus 來為每個 PR 分類:

分類信號動作
GREENrollup 中沒有 FAILURE/CANCELLED/TIMED_OUT,沒有任何待處理項目,mergeable=MERGEABLE核准 + rebase-merge(步驟 4)
CONFLICTINGmergeable=CONFLICTING 或 mergeStateStatus=DIRTY勾選 rebase 核取方塊(步驟 5),監控
REAL_FAILURErollup 中包含無法由升級後處理程序自動修復的 FAILURE跳過;留給人工處理
HOLD需要跨檔案協調(人工檢查清單 — 請見下方)呈現給人類;不要繼續進行

當 CheckRun 的 status != COMPLETED 或 StatusContext 的 state 為 PENDING/EXPECTED 時,rollup 中的檢查視為待處理。當 CheckRun.conclusion 為 FAILURE/CANCELLED/TIMED_OUT/ ACTION_REQUIRED/STARTUP_FAILURE,或 StatusContext.state 為 FAILURE/ ERROR 時,視為失敗。

HOLD 檢查清單(人工判斷 — 非硬編碼)

HOLD 檢測是 AI 代理所做的判斷,而不是自動化規則。當隔離合併某個 PR 會破壞位於另一個檔案中的內容時, 將該 PR 視為 HOLD 候選者,例如:

  • terraform-version 固定版本不符 — Terraform 提供者/CLI 升級需要在其他地方更新對應的固定版本(例如 .terraform-version、CI 工作流程或 required_version 限制),然後才能安全合併。
  • schema 升級需要程式碼編輯 — 依賴項升級的新的主要版本變更了手寫程式碼仍依賴的 schema/類型;升級後鉤子無法產生程式碼編輯。
  • 任何變更日誌中要求進行升級後作業無法執行的協調編輯的升級。

當 PR 看起來像 HOLD 時,將其呈現給使用者並詢問 — 不要自動合併,也不要勾選 rebase 核取方塊。繼續遍歷佇列的其餘部分。

4. 核准 + 合併 (GREEN)

gh pr review "$PR" -R "$REPO" --approve \
  --body "LGTM — 作為 Renovate 批次上線的一部分自動核准。"
gh pr merge "$PR" -R "$REPO" --rebase --delete-branch

5. 勾選 rebase 核取方塊 (CONFLICTING)

翻轉 Renovate 的 rebase 核取方塊,以便它重新基底分支,然後監控:

body=$(gh pr view "$PR" -R "$REPO" --json body -q .body)
new=$(printf '%s' "$body" | sed 's|^\( *\)\- \[ \] <!-- rebase-check -->|\1- [x] <!-- rebase-check -->|')
printf '%s' "$new" | gh pr edit "$PR" -R "$REPO" --body-file - >/dev/null

在勾選核取方塊之前,先擷取當前 head SHA 作為基準線,然後執行監控(步驟 6), 這樣您就可以區分重新基底與起始狀態:

BASELINE=$(gh pr view "$PR" -R "$REPO" --json headRefOid -q .headRefOid)

永遠不要在 REAL_FAILURE 上勾選 rebase 核取方塊 — 這會浪費 Renovate 的資源並隱藏真正的問題。

6. 監控直到穩定

附帶的 scripts/monitor-renovate-pr.sh 腳本會輪詢單一 PR,直到其檢查穩定, 並輸出一個由 AI 代理透過監控工具使用的判決。

scripts/monitor-renovate-pr.sh <pr-number> <repo> <baseline-head-sha-short>
  • 每 45 秒(可透過 POLL_INTERVAL 覆蓋)輪詢 gh pr view --json headRefOid,mergeable,mergeStateStatus,statusCheckRollup,並僅在簽名 ${head:0:9}|<mergeable>:<state>|ok=N pend=M fail=K 變更時輸出一行。
  • 一旦 head 已離開基準線、沒有待處理的檢查,且簽名在連續兩次輪詢中保持穩定,則發出判決。
  • 最終的 stdout 行是以下之一:
    • GREEN: #<n> ready to merge → 返回步驟 4 核准 + 合併。
    • NOT-GREEN: #<n> settled failures=X mergeable=Y state=Z → 重新分類;它現在是 REAL_FAILURE 或 HOLD。
  • 可選環境變數:POLL_INTERVAL(秒,預設 45)、MAX_POLLS(在 N 次輪詢後放棄,0 = 無限制;耗盡時發出 NOT-GREEN: #<n> timeout ...)。

為什麼使用輪詢迴圈而不是 gh pr checks --watch

gh pr checks <n> --watch 對於一個已經可以合併且僅在執行檢查的 PR 來說很好, 但對於此技能所針對的重新基底路徑,它會產生誤導:

  • 它在過時的 head 上以綠色退出。 剛勾選 rebase 核取方塊後,PR 的_當前_檢查已經處於終端狀態——它們在重新基底前的(衝突)head 上通過了。--watch 看到「沒有待處理的檢查」,並立即回傳成功,甚至在 Renovate 重新基底之前。而 head moved off baseline 條件正是為了防止這種虛假的綠色。
  • 它只知道檢查,不知道可合併性。 GREEN 判決需要 mergeable=MERGEABLE + mergeStateStatus=CLEAN,而 CONFLICTING 是透過這些欄位_檢測_的——gh pr checks 從不回傳這些欄位。一次 gh pr view 輪詢就可以一次涵蓋兩者。
  • head 可以移動兩次(Renovate 推送,然後應用程式機器人進行升級後推送)。這兩者之間存在一個時間窗口,其中已知的檢查暫時完成;--watch 可以在這個間隙退出。而「沒有待處理且兩次輪詢穩定」的保護可以安全度過這個間隙。

7. 預期的重新基底後提交鏈

在勾選 rebase 核取方塊後(或 Renovate 自行重新基底),GREEN 上線通常會經歷以下鏈條——了解它就能判斷監控的變動是預期的,而不是失敗:

  1. Renovate 推送一個新的 head,作為 renovate[bot]。
  2. pull_request 工作流程觸發。check.yml 的升級後步驟執行 eslint --fix、prettier --write、vitest --update、projen 和 beachball 變更條目。
  3. 如果升級後步驟產生了差異,則 commit-upgrade-changes 作業會透過 actions/create-github-app-token@v2 鑄造一個應用程式權杖,並將修正推送為 <app-slug>[bot]。該機器人推送會重新觸發 pull_request 工作流程,因此 head 會第二次移動,檢查會重新執行。
  4. 最終就緒狀態:mergeable=MERGEABLE、mergeStateStatus=CLEAN、所有檢查 SUCCESS/SKIPPED。

由於 head 可以移動兩次(Renovate,然後應用程式機器人),監控是根據「head 離開基準線 + 沒有待處理 + 兩次穩定輪詢」來決定判決,而不是根據它看到的第一個推送。

停止條件

  • 沒有剩餘的 GREEN PR — 完成。
  • REAL_FAILURE — 跳過它,繼續下一個 PR;永遠不要自動重新基底 REAL_FAILURE。
  • HOLD 候選者 — 將其呈現給人類決定;不要自動合併。
  • 使用者取消。

限制

  • 提交主題不得包含問題/PR 參考(專案規則)。此處不適用於合併遠端 PR,但如果此技能將來擴展為建立本機提交,請將參考保留在主題之外——將它們放在正文中。請參閱 /create-commit。
  • 永遠不要在 REAL_FAILURE 上勾選 rebase 核取方塊。
  • 永遠不要自動合併 HOLD 候選者。
  • HOLD 檢測是人工檢查清單,而不是硬編碼規則。識別上述類別並呈現候選者;不要嘗試自動化決策。

測試筆記

乾運作分類

列舉並查看分類桶,不進行任何實際操作:

gh pr list -R "$REPO" --author "app/renovate" --state open \
  --json number,title,mergeable,mergeStateStatus,statusCheckRollup \
  | jq -r '.[] | "\(.number)\t\(.mergeable)\t\(.mergeStateStatus)\t\(.title)"'

為每個 PR 新增一個 rollup 摘要,以找出待處理/失敗的檢查:

gh pr list -R "$REPO" --author "app/renovate" --state open \
  --json number,statusCheckRollup \
  | jq -r '.[] | "\(.number)\t" + ([.statusCheckRollup[] | .conclusion // .state] | join(","))'

監控冒煙測試

針對一個已知的 PR 執行監控,使用虛擬的基準線 SHA(這樣 head 已經算作「已移動」), 並使用短間隔來觀察狀態行和最終判決:

POLL_INTERVAL=2 MAX_POLLS=4 \
  scripts/monitor-renovate-pr.sh <known-pr> "$REPO" deadbeef0

您應該會看到每個簽名變更對應一行狀態行,然後是 GREEN: / NOT-GREEN: 判決。 將 PR 的真實 head 作為基準線傳遞,則可以測試無重新基底路徑:head 從不移動, 因此它永遠不會穩定,並且執行會在 MAX_POLLS 超時時結束。

不涵蓋的範圍

  • 硬編碼的 HOLD 檢測規則(從上述人工檢查清單開始;稍後擴展)。
  • 將此技能連接到任何協調層。

相關技能