github-branch-policy
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGitHub Branch Policy
GitHub 分支策略
Overview
概述
Run a repeatable audit for GitHub branch policy safety and Actions workflow hygiene. Validate ruleset enforcement, required checks, workflow registration integrity, and branch cleanup behavior that commonly break CI and auto-merge.
针对GitHub分支策略安全性和Actions工作流合规性执行可重复的审计。验证规则集执行情况、必要检查、工作流注册完整性以及通常会导致CI和自动合并失败的分支清理行为。
Use This Skill When
适用场景
Apply this skill for requests like:
- "Audit branch protection/rulesets on this repo."
- "Check whether auto-merge and branch cleanup are configured correctly."
- "Find ghost workflows or stale branches causing Actions failures."
- "Why are we getting ?"
Cannot update this protected ref - "Make sure branch policy matches solo-developer expectations."
在以下场景中使用此技能:
- "审计此仓库的分支保护/规则集。"
- "检查自动合并和分支清理配置是否正确。"
- "查找导致Actions失败的幽灵工作流或陈旧分支。"
- "为什么我们会收到错误?"
Cannot update this protected ref - "确保分支策略符合独立开发者的预期。"
Prerequisites
前置条件
- authenticated for the target repo (
gh+reposcopes).workflow - available.
jq - Target repository known as , or current directory is a checked-out repo with a GitHub remote.
OWNER/REPO
- 已针对目标仓库完成认证(需
gh+repo权限范围)。workflow - 已安装工具。
jq - 目标仓库格式为,或当前目录是已检出的带有GitHub远程仓库的本地仓库。
OWNER/REPO
Quick Setup
快速设置
bash
OWNER_REPO="${OWNER_REPO:-$(gh repo view --json nameWithOwner -q .nameWithOwner)}"
OWNER="${OWNER_REPO%/*}"
REPO="${OWNER_REPO#*/}"
DEFAULT_BRANCH="$(gh repo view "$OWNER_REPO" --json defaultBranchRef -q .defaultBranchRef.name)"
echo "Auditing $OWNER_REPO (default: $DEFAULT_BRANCH)"bash
OWNER_REPO="${OWNER_REPO:-$(gh repo view --json nameWithOwner -q .nameWithOwner)}"
OWNER="${OWNER_REPO%/*}"
REPO="${OWNER_REPO#*/}"
DEFAULT_BRANCH="$(gh repo view "$OWNER_REPO" --json defaultBranchRef -q .defaultBranchRef.name)"
echo "Auditing $OWNER_REPO (default: $DEFAULT_BRANCH)"Audit Checklist
审计检查清单
1. Repository merge settings are compatible with policy
1. 仓库合并设置与策略兼容
Verification:
bash
gh api "repos/$OWNER/$REPO" \
--jq '{allow_auto_merge,allow_squash_merge,allow_merge_commit,allow_rebase_merge,delete_branch_on_merge,default_branch}'Pass criteria:
- when auto-merge is expected.
allow_auto_merge: true - Merge methods match branch rules (for example, squash-only policy -> squash enabled).
- unless intentionally disabled.
delete_branch_on_merge: true
Remediation:
- Enable auto-merge at repo level.
- Align repo merge methods with ruleset .
allowed_merge_methods - Enable delete-on-merge, or document why not.
验证命令:
bash
gh api "repos/$OWNER/$REPO" \
--jq '{allow_auto_merge,allow_squash_merge,allow_merge_commit,allow_rebase_merge,delete_branch_on_merge,default_branch}'通过标准:
- 当需要自动合并时,。
allow_auto_merge: true - 合并方式与分支规则匹配(例如,仅 squash 策略需开启 squash 合并)。
- ,除非有明确理由关闭该功能。
delete_branch_on_merge: true
修复措施:
- 在仓库级别启用自动合并。
- 对齐仓库合并方式与规则集的。
allowed_merge_methods - 启用合并后删除分支功能,或记录关闭理由。
2. Active ruleset applies to default branch and enforces PR + required checks
2. 活跃规则集应用于默认分支并强制执行PR与必要检查
Verification:
bash
gh api "repos/$OWNER/$REPO/rulesets" \
--jq '.[] | {id,name,enforcement,target,include:(.conditions.ref_name.include // []),rules:[.rules[].type]}'
gh api "repos/$OWNER/$REPO/rulesets" \
--jq '.[] | select(.enforcement=="active") | .rules[] | select(.type=="pull_request" or .type=="required_status_checks")'Pass criteria:
- At least one active branch ruleset applies to (or equivalent explicit default branch include).
~DEFAULT_BRANCH - Ruleset includes and
pull_request.required_status_checks - Optional hardening like ,
required_linear_history,non_fast_forwardis intentional.deletion
Remediation:
- Enable or create a default-branch ruleset.
- Add missing and
pull_requestrules.required_status_checks
验证命令:
bash
gh api "repos/$OWNER/$REPO/rulesets" \
--jq '.[] | {id,name,enforcement,target,include:(.conditions.ref_name.include // []),rules:[.rules[].type]}'
gh api "repos/$OWNER/$REPO/rulesets" \
--jq '.[] | select(.enforcement=="active") | .rules[] | select(.type=="pull_request" or .type=="required_status_checks")'通过标准:
- 至少有一个活跃分支规则集应用于(或等效的显式默认分支包含规则)。
~DEFAULT_BRANCH - 规则集包含和
pull_request规则。required_status_checks - 可选的强化规则如、
required_linear_history、non_fast_forward是有意配置的。deletion
修复措施:
- 启用或创建默认分支规则集。
- 添加缺失的和
pull_request规则。required_status_checks
3. Required check contexts match real check names
3. 必要检查上下文与实际检查名称匹配
Verification:
bash
gh api "repos/$OWNER/$REPO/rulesets" \
--jq '.[] | .rules[] | select(.type=="required_status_checks") | .parameters.required_status_checks[].context'
gh pr list --state all --limit 20 --json number \
--jq '.[0].number' | xargs -I{} gh pr view {} --json statusCheckRollupPass criteria:
- Required contexts exactly match real checks reported on PRs (case-sensitive), e.g. ,
ci,Vercel.Vercel Preview Comments
Remediation:
- Update required check contexts in the ruleset to match actual check names.
验证命令:
bash
gh api "repos/$OWNER/$REPO/rulesets" \
--jq '.[] | .rules[] | select(.type=="required_status_checks") | .parameters.required_status_checks[].context'
gh pr list --state all --limit 20 --json number \
--jq '.[0].number' | xargs -I{} gh pr view {} --json statusCheckRollup通过标准:
- 必要检查上下文与PR上显示的实际检查名称完全匹配(区分大小写),例如、
ci、Vercel。Vercel Preview Comments
修复措施:
- 更新规则集中的必要检查上下文,使其与实际检查名称一致。
4. Solo-dev compatibility: CODEOWNERS review not forced (if desired)
4. 独立开发者兼容性:未强制CODEOWNERS审核(如有需求)
Verification:
bash
gh api "repos/$OWNER/$REPO/rulesets" \
--jq '.[] | {name, pull_request_rules:[.rules[] | select(.type=="pull_request") | .parameters.require_code_owner_review]}'Pass criteria:
- For solo-maintainer repos, is
require_code_owner_reviewunless intentionally required.false
Remediation:
- Set where solo-dev flow is desired.
require_code_owner_review: false
验证命令:
bash
gh api "repos/$OWNER/$REPO/rulesets" \
--jq '.[] | {name, pull_request_rules:[.rules[] | select(.type=="pull_request") | .parameters.require_code_owner_review]}'通过标准:
- 对于单人维护的仓库,为
require_code_owner_review,除非有意强制开启。false
修复措施:
- 在需要独立开发者工作流的仓库中设置。
require_code_owner_review: false
5. Actions policy allows the workflow dependencies you actually use
5. Actions策略允许实际使用的工作流依赖
Verification:
bash
gh api "repos/$OWNER/$REPO/actions/permissions" \
--jq '{enabled,allowed_actions,sha_pinning_required}'
gh api "repos/$OWNER/$REPO/actions/permissions/selected-actions" \
--jq '{github_owned_allowed,verified_allowed,patterns_allowed}'Pass criteria:
- If , all actions used by workflows are explicitly allowed (or covered by allowed classes).
allowed_actions: selected - If SHA pinning is required, actions are pinned.
Remediation:
- Add missing action patterns to selected-actions policy.
- Pin unpinned actions.
- Prefer minimal/no third-party actions for sensitive auto-merge workflows.
验证命令:
bash
gh api "repos/$OWNER/$REPO/actions/permissions" \
--jq '{enabled,allowed_actions,sha_pinning_required}'
gh api "repos/$OWNER/$REPO/actions/permissions/selected-actions" \
--jq '{github_owned_allowed,verified_allowed,patterns_allowed}'通过标准:
- 如果,则工作流使用的所有操作都已被明确允许(或属于允许的类别)。
allowed_actions: selected - 如果要求SHA固定,则所有操作都已固定版本。
修复措施:
- 向选中操作策略添加缺失的操作匹配规则。
- 为未固定版本的操作添加SHA固定。
- 对于敏感的自动合并工作流,优先使用最少或不使用第三方操作。
6. Auto-merge workflow registration is clean (no ghost duplicates)
6. 自动合并工作流注册干净(无幽灵重复项)
Verification:
bash
gh api "repos/$OWNER/$REPO/actions/workflows" \
--jq '.workflows[] | [.id,.name,.path,.state] | @tsv' | sort
gh workflow list --allPass criteria:
- Exactly one active registration for the canonical auto-merge workflow path.
- Legacy/stale registrations are disabled or removed.
Remediation:
- Disable stale workflow IDs:
bash
gh workflow disable <workflow_id>- Keep a single canonical filename on default branch.
验证命令:
bash
gh api "repos/$OWNER/$REPO/actions/workflows" \
--jq '.workflows[] | [.id,.name,.path,.state] | @tsv' | sort
gh workflow list --all通过标准:
- 标准自动合并工作流路径仅有一个活跃注册项。
- 遗留/陈旧的注册项已被禁用或删除。
修复措施:
- 禁用陈旧工作流ID:
bash
gh workflow disable <workflow_id>- 在默认分支上保留单个标准文件名。
7. Auto-merge workflow trigger and runtime behavior are reliable
7. 自动合并工作流触发与运行行为可靠
Verification:
bash
AUTO_WF="Enable PR Auto-Merge" # adjust if needed
gh workflow view "$AUTO_WF" --yaml | sed -n '1,220p'
gh run list --workflow "$AUTO_WF" --limit 20 \
--json databaseId,event,status,conclusion,headBranch,createdAtDeep check for suspicious runs:
bash
RUN_ID="<id>"
gh run view "$RUN_ID" --json event,conclusion,jobsPass criteria:
- Trigger is intentionally chosen (is preferred for base-branch controlled auto-merge orchestration;
pull_request_targetcan be valid if branch consistency is guaranteed).pull_request - Recent PR-event runs execute real jobs.
- No repeating failures with event + zero jobs + missing logs (ghost workflow symptom).
push
Remediation:
- Move to a stable default-branch workflow file.
- Prefer for auto-merge orchestration logic that should not depend on PR-branch workflow file presence.
pull_request_target - Disable stale workflow registrations.
验证命令:
bash
AUTO_WF="Enable PR Auto-Merge" # 按需调整
gh workflow view "$AUTO_WF" --yaml | sed -n '1,220p'
gh run list --workflow "$AUTO_WF" --limit 20 \
--json databaseId,event,status,conclusion,headBranch,createdAt深度检查可疑运行:
bash
RUN_ID="<id>"
gh run view "$RUN_ID" --json event,conclusion,jobs通过标准:
- 触发方式经过合理选择(是基于主分支控制的自动合并编排的首选;如果能保证分支一致性,
pull_request_target也可使用)。pull_request - 近期PR事件的运行能执行实际任务。
- 没有重复出现事件+零任务+无日志的失败情况(幽灵工作流的特征)。
push
修复措施:
- 将工作流文件迁移到稳定的默认分支。
- 对于不依赖PR分支工作流文件存在的自动合并编排逻辑,优先使用。
pull_request_target - 禁用陈旧的工作流注册项。
8. Cannot update this protected ref
diagnostics for branch-update workflows
Cannot update this protected ref8. 分支更新工作流的Cannot update this protected ref
错误诊断
Cannot update this protected refVerification:
bash
gh workflow list --all
gh run list --workflow "Auto Update PR Branches" --limit 20Pass criteria:
- Workflow either:
- updates eligible PR branches successfully, and
- handles protected/fork branches gracefully without failing the whole run.
Remediation:
- In update-branch loops, continue on protected/fork failures.
- Skip PR heads that are protected or not writable.
- Treat this error as per-PR conditional failure, not a global workflow failure.
验证命令:
bash
gh workflow list --all
gh run list --workflow "Auto Update PR Branches" --limit 20通过标准:
- 工作流需满足以下任一条件:
- 成功更新符合条件的PR分支,并且
- 能优雅处理受保护/分叉分支,不会导致整个运行失败。
修复措施:
- 在分支更新循环中,遇到受保护/分叉分支失败时继续执行。
- 跳过受保护或不可写的PR头部分支。
- 将此错误视为单个PR的条件性失败,而非全局工作流失败。
9. Branch cleanup strategy is in place
9. 已配置分支清理策略
Verification:
bash
gh api "repos/$OWNER/$REPO" --jq '{delete_branch_on_merge}'
gh api "repos/$OWNER/$REPO/actions/workflows" \
--jq '.workflows[] | {name,path,state}'Pass criteria:
- , or equivalent cleanup workflow exists and is active.
delete_branch_on_merge: true
Remediation:
- Enable delete-on-merge.
- Add/repair cleanup workflow if additional cleanup behavior is required.
验证命令:
bash
gh api "repos/$OWNER/$REPO" --jq '{delete_branch_on_merge}'
gh api "repos/$OWNER/$REPO/actions/workflows" \
--jq '.workflows[] | {name,path,state}'通过标准:
- ,或存在等效的活跃清理工作流。
delete_branch_on_merge: true
修复措施:
- 启用合并后删除分支功能。
- 如果需要额外的清理行为,添加或修复清理工作流。
10. No stale branches from merged/closed PRs
10. 无来自已合并/关闭PR的陈旧分支
Verification:
bash
gh api "repos/$OWNER/$REPO/branches" --paginate --jq '.[].name' | sort -u > /tmp/live-branches.txt
gh pr list --state merged --limit 500 --json headRefName --jq '.[].headRefName' | sort -u > /tmp/merged-pr-branches.txt
gh pr list --state closed --limit 500 --json headRefName,mergedAt \
--jq '.[] | select(.mergedAt==null) | .headRefName' | sort -u > /tmp/closed-pr-branches.txt
cat /tmp/merged-pr-branches.txt /tmp/closed-pr-branches.txt | sort -u > /tmp/candidate-stale-branches.txt
comm -12 /tmp/live-branches.txt /tmp/candidate-stale-branches.txtPass criteria:
- Intersection output is empty, excluding intentional long-lived branches.
Remediation:
- Delete confirmed stale branches:
bash
git push origin --delete "<branch>"验证命令:
bash
gh api "repos/$OWNER/$REPO/branches" --paginate --jq '.[].name' | sort -u > /tmp/live-branches.txt
gh pr list --state merged --limit 500 --json headRefName --jq '.[].headRefName' | sort -u > /tmp/merged-pr-branches.txt
gh pr list --state closed --limit 500 --json headRefName,mergedAt \
--jq '.[] | select(.mergedAt==null) | .headRefName' | sort -u > /tmp/closed-pr-branches.txt
cat /tmp/merged-pr-branches.txt /tmp/closed-pr-branches.txt | sort -u > /tmp/candidate-stale-branches.txt
comm -12 /tmp/live-branches.txt /tmp/candidate-stale-branches.txt通过标准:
- 交集输出为空,排除有意保留的长期分支。
修复措施:
- 删除确认的陈旧分支:
bash
git push origin --delete "<branch>"11. Rulesets are primary policy; legacy protection is not conflicting
11. 规则集为主要策略;遗留保护规则无冲突
Verification:
bash
gh api "repos/$OWNER/$REPO/rulesets" --jq 'length'
gh api "repos/$OWNER/$REPO/branches/$DEFAULT_BRANCH/protection" 2>/dev/null | jq '.'Pass criteria:
- Rulesets are primary mechanism.
- Legacy branch protection is absent or intentionally non-overlapping.
- If branch protection endpoint returns 404 while rulesets exist, that is expected.
Remediation:
- Consolidate policy into rulesets.
- Remove redundant legacy branch protection after parity validation.
验证命令:
bash
gh api "repos/$OWNER/$REPO/rulesets" --jq 'length'
gh api "repos/$OWNER/$REPO/branches/$DEFAULT_BRANCH/protection" 2>/dev/null | jq '.'通过标准:
- 规则集是主要的策略机制。
- 遗留分支保护规则不存在或有意不重叠。
- 如果规则集存在时,分支保护接口返回404,属于正常情况。
修复措施:
- 将策略整合到规则集中。
- 在验证功能一致后,移除冗余的遗留分支保护规则。
Optional Smoke Test (recommended for auto-merge incidents)
可选冒烟测试(建议在自动合并故障时使用)
- Create a temporary PR from a throwaway branch.
- Confirm auto-merge was enabled:
bash
gh pr view <pr_number> --json autoMergeRequest- Confirm auto-merge workflow run event/job execution:
bash
gh run list --workflow "Enable PR Auto-Merge" --limit 5- Close PR and delete branch.
- 从临时分支创建一个测试PR。
- 确认自动合并已启用:
bash
gh pr view <pr_number> --json autoMergeRequest- 确认自动合并工作流的运行事件/任务执行:
bash
gh run list --workflow "Enable PR Auto-Merge" --limit 5- 关闭PR并删除分支。
Report Format
报告格式
markdown
undefinedmarkdown
undefinedBranch Policy Audit Report
分支策略审计报告
- Repository: OWNER/REPO
- Default branch: <branch>
- Timestamp (UTC): <iso8601>
- Overall status: PASS | NEEDS_ACTION | BLOCKED
- 仓库:OWNER/REPO
- 默认分支:<branch>
- 时间戳(UTC):<iso8601>
- 整体状态:通过 | 需要处理 | 阻塞
Findings
检查结果
- [SEV-<1-3>] <check name> - <pass/fail summary> Evidence: <key command output summary> Remediation: <next action>
- [严重程度-<1-3>] <检查名称> - <通过/失败摘要> 证据:<关键命令输出摘要> 修复措施:<下一步操作>
Actions Taken
已执行操作
- <action performed or "none">
- <执行的操作或"无">
Follow-up
后续跟进
- <required human decision or "none">
undefined- <需要人工决策或"无">
undefinedGuardrails
注意事项
- Do not delete branches until confirmed stale and unprotected.
- Do not disable workflows blindly; verify canonical registration first.
- Treat on workflow runs as likely ghost/stale registration evidence.
push + 0 jobs + no logs - Prefer deterministic evidence over assumptions.
gh api - If permissions are insufficient, report missing scope/permission and continue with remaining checks.
- 确认分支为陈旧且不受保护后再删除。
- 不要盲目禁用工作流;先验证标准注册项。
- 将工作流运行中的视为幽灵/陈旧注册项的可能证据。
push + 0 jobs + 无日志 - 优先使用确定性的证据,而非假设。
gh api - 如果权限不足,报告缺失的权限范围并继续执行剩余检查。