执行摘要
- 一句话:新增 rebase-required CI 检测模式
- 推荐动作:建议精读
action.yml 中的 shell 实现,了解 fail-open 设计、SHA 校验和 compare API 的使用。对于 CI 基础设施维护者有参考价值。
功能与动机
当主分支有重大更新(如 CUDA 版本升级)时,需要所有开放 PR rebase 后才能运行 CI,但维护者不希望完全暂停 CI。现有 full-pause 模式只能通过打开 issue #21065 完全阻止 CI,不够灵活。
实现拆解
- 解析 Issue Body 指令:修改
action.yml 中的 shell 脚本,使用 gh issue view 获取 issue #21065 的 state 和 body,并通过 grep/sed 提取第一个 MIN_BASE_SHA: <sha> 行。
- 校验 SHA 格式:对提取的 SHA 进行格式校验(7-40 位十六进制),不合法则忽略并输出 warning。
- 执行 Rebase 检查:当
MIN_BASE_SHA 非空时,使用 gh api /repos/$REPO/compare/$SHA...$HEAD 比较 PR 与 base commit 的关系。若状态为 behind 或 diverged 则报错退出;ahead/identical 则放行。
- 独立于 Issue 状态:无论 issue 是 open 还是 closed,只要 body 包含指令就强制执行 rebase 检查。
- 更新文档:在
MAINTAINER.md 中新增 「Rebase-Required Mode」章节,说明用法和注意事项。
关键文件:
.github/actions/check-maintenance/action.yml(模块 CI 动作;类别 infra;类型 infrastructure): 核心实现文件,新增 rebase-required 模式,修改了 action 的输入参数和运行步骤。
.github/MAINTAINER.md(模块 文档;类别 docs;类型 documentation): 更新维护手册,说明 rebase-required 模式的用法和注意事项。
关键符号:未识别
关键源码片段
.github/actions/check-maintenance/action.yml
核心实现文件,新增 rebase-required 模式,修改了 action 的输入参数和运行步骤。
# 核心步骤:解析 issue 并执行 rebase 检查(省略了前导部分)
runs:
using: composite
steps:
- name: Check maintenance mode
shell: bash
run: |
MAINTENANCE_ISSUE=21065
REPO="${{ github.repository }}"
PR_NUMBER="${{ github.event.pull_request.number }}"
PR_HEAD_SHA="${{ github.event.pull_request.head.sha }}"
# 如果 PR Test 在主分支运行,直接放行
if [[ "${PR_TEST_BYPASS_MAINTENANCE_ON_MAIN:-}" == "true" ]]; then
echo "✅ PR Test on main branch; bypassing all gates."
exit 0
fi
# 获取 issue 状态和 body(API 错误时允许 CI 继续)
ISSUE_JSON=$(gh issue view "$MAINTENANCE_ISSUE" --repo "$REPO" --json state,body 2>/dev/null || echo "")
ISSUE_STATE=$(printf '%s' "$ISSUE_JSON" | jq -r '.state // "UNKNOWN"')
ISSUE_BODY=$(printf '%s' "$ISSUE_JSON" | jq -r '.body // ""')
# 解析第一个 `MIN_BASE_SHA: <sha>` 指令
MIN_BASE_SHA=$(printf '%s' "$ISSUE_BODY" | tr -d '\r' | grep -iE '^[[:space:]]*`?MIN_BASE_SHA`?[[:space:]]*[:=]' | head -n1 | sed -E 's/.*[:=][[:space:]]*//; s/`//g' | awk '{print $1}')
# 校验 SHA 格式(7-40 位十六进制)
if [[ -n "$MIN_BASE_SHA" ]] && ! [[ "$MIN_BASE_SHA" =~ ^[a-fA-F0-9]{7,40}$ ]]; then
echo "::warning::Ignoring malformed MIN_BASE_SHA: $MIN_BASE_SHA"
MIN_BASE_SHA=""
fi
# Gate1:如果 issue OPEN 且没有设置 MIN_BASE_SHA → full-pause
if [[ "$ISSUE_STATE" == "OPEN" && -z "$MIN_BASE_SHA" ]]; then
echo "::error::Maintenance mode is active."
exit 1
fi
# Gate2:如果设置了 MIN_BASE_SHA → 执行 rebase 检查(无论 issue 状态)
if [[ -n "$MIN_BASE_SHA" ]]; then
COMPARE_URL="/repos/$REPO/compare/$MIN_BASE_SHA...$PR_HEAD_SHA"
COMPARE_STATUS=$(gh api "$COMPARE_URL" --jq '.status' 2>/dev/null || echo "UNKNOWN")
case "$COMPARE_STATUS" in
ahead|identical)
echo "✅ PR contains required base $MIN_BASE_SHA ($COMPARE_STATUS)."
;;
behind|diverged)
echo "::error::Rebase Required. Your PR does not contain $MIN_BASE_SHA (status: $COMPARE_STATUS)."
exit 1
;;
UNKNOWN)
echo "⚠️ API error during compare; fallthrough allowed."
;;
esac
fi
echo "✅ Maintenance gate(s) passed."
评论区精华
无实质审查讨论。作者在 PR 评论中自测了 16 种场景,并指出需调整逻辑使 rebase 检查独立于 issue 状态(todo 评论后通过第三个 commit 实现)。
风险与影响
- 风险:
- API 错误处理:GitHub API 调用(
gh issue view、gh api compare)可能因网络或权限返回非预期结果,action 采用 fail-open(错误时允许 CI 继续),可能降低安全性。
- SHA 解析局限:仅解析第一个
MIN_BASE_SHA 行,且不跳过 issue body 中的代码块,可能误匹配示例中的指令。
- 实时生效:设置
MIN_BASE_SHA 后,已运行的 CI 作业不受影响,但新启动的作业会立即被阻塞,可能造成维护者在调整期间需处理大量失败。
- 标签 bypass 作用范围:
bypass-maintenance 标签可绕过所有门控,若误用于非 CI 修复 PR,可能绕过 rebase 要求。
- 影响:影响所有使用 .github/actions/check-maintenance 的 workflow(如 pr-test.yml、nightly 等),无需额外配置即可获得 rebase 强制检查能力。团队需要知晓新的门控机制,并在 issue #21065 文档中明确何时使用。
- 风险标记:CI 流程变更, API 调用可能失败, SHA 解析可能误匹配, bypass 标签滥用风险
关联脉络
参与讨论