Required changes from trunk 状态检查确保开放的拉取请求(pull requests)在合并之前包含来自 trunk 的最新必需的仓库级基础设施变更(例如 Node.js 升级等工具链更新,或仓库级的格式化和代码检查变更)。这可以防止基于较旧提交的拉取请求针对过时的工具链通过 CI,或重新引入旧风格的代码。
工作原理
一个可移动的 git 引用 refs/baselines/required-trunk-changes 指向每个开放拉取请求必须包含的最后一个 trunk 提交。当该提交是拉取请求头部的祖先时,检查通过;否则失败。在该引用不存在期间,不要求任何内容,一旦有操作为其打上标记,拉取请求即通过。在它消失之前写入的状态将保持原样,直到一次 scope: all 刷新重新访问它们。
基线仅通过维护者的明确意图移动,有两种方式:
- 合并带有
Require PR update标签的拉取请求,或者 - 以
mode: move-baseline调度Required changes from trunk工作流。
当基线移动时,每个开放的拉取请求最终都会显示其当前应有的判定结果。
该引用故意位于 refs/heads/ 和 refs/tags/ 之外:除非被明确要求,否则没有任何东西会获取它,因此它的移动永远不会干扰 git pull,不会启动任何工作流,且没有分支清理工具会移除它。git ls-remote origin 'refs/baselines/*' 会显示它指向的位置。
限制
- 每次刷新最多写入 300 个状态。移动操作会重写那些显示绿色的拉取请求,因此大型移动需要几次
trunk推送才能完成:因达到预算而停止的运行会说明这一点,下一次trunk推送或调度将从中断处继续。 - 从未收到状态的拉取请求显示为“Expected”,这也阻止了合并。其自身的下一次更新会赋予它真实的状态,但 Dependabot 拉取请求除外:Dependabot 触发的每次运行都获得只读令牌,因此这些请求需等待每日回填,后者会为仍未携带状态的请求打上标记。
- 如果在刷新运行期间拉取请求的头部发生移动,则该请求会被推迟处理,而不是在过期的头部上打标记。导致其移动的那次推送会报告自己的状态。
我的拉取请求有一个红色的“Required changes from trunk”状态。我该怎么做?
使用以下任一方法将您的分支更新至当前基线之后:
- 将最新的
trunk合并到您的分支中,或者 - 将您的分支变基(rebase)到最新的
trunk上。
推送更新会重新运行检查并将其变为绿色。失败的状态链接到了确切展示您的分支缺少内容的比较视图。
Require PR update 标签
提交者会将 Require PR update 标签应用于更改会使所有开放拉取请求失效的请求,例如工具链更新或仓库级格式化变更。当此类拉取请求合并时,基线会移动,所有开放拉取请求都必须更新。
维护者操作手册
Required changes from trunk 工作流暴露了一个 mode 调度输入:auto 的行为类似于 trunk 推送,仅在带标签的合并赢得资格时移动基线然后刷新;move-baseline 强制移动到当前的 trunk HEAD 然后刷新;refresh-pr-statuses 仅刷新开放拉取请求的状态,这是在中断运行后的重试路径。
scope 输入选择 mode: refresh-pr-statuses 覆盖哪些开放拉取请求:corrections 访问那些显示绿色的请求,这是向前移动唯一可能使其变红的请求;unstamped 访问那些尚未携带状态的请求,这是每日回填运行的目标;all 访问每一个开放拉取请求。另外两种模式自行选择范围:auto 对应 corrections,move-baseline 对应 all。
向后移动基线是一种例外情况。它可以使失败的拉取请求变绿,因此它在 all 范围内进行刷新,而 trunk 推送不会继续此操作。请使用 mode: refresh-pr-statuses 和 scope: all 重新调度,直到某次运行结束时呈绿色且无剩余项。即使某次运行推迟或失败了某个拉取请求,仍将其报告为已计入,因此它可以在呈红色时表示无剩余项。
初始设置
在完成以下一次性步骤之前,工作流不会阻塞任何内容,请按顺序执行:
- 创建
Require PR update标签。 - 让刷新在没有基线引用的情况下运行:使用
mode: refresh-pr-statuses和scope: unstamped进行调度。它写入的通过记录证明了令牌和权限在任何东西能够阻塞之前都已就绪。它会远早于触及每个拉取请求之前就因其写入预算而停止,这一步由第 4 步完成。 - 初始化基线:使用
mode: move-baseline调度工作流,这将把基线初始化为当前的trunkHEAD。若要在较早的提交处初始化,请直接将该提交推送到该引用:git push origin <sha>:refs/baselines/required-trunk-changes。 - 使用
mode: refresh-pr-statuses和scope: all重新调度,直到某次运行结束时呈绿色且无剩余项。第 3 步在通过直接推送初始化引用时不写入任何内容,因此第 2 步产生的通过记录也必须被重新访问,而不仅仅是那些仍未携带状态的拉取请求。 - 请求仓库管理员将
Required changes from trunk提交状态(来源:GitHub Actions)添加到 trunk 规则集的必要状态检查中。
规则集无法覆盖 refs/baselines/,因此拥有写权限的任何人都可以移动或删除该引用。除了强制移动外,工具只会对其进行快进(fast-forward),这也是修复指向非 trunk 位置的基线的方法;在这种状态下,刷新会通过它所触及的拉取请求而不是阻塞它们,并且已经写入的状态将保持不变,直到再次触及它们。要回滚检查,请将 Required changes from trunk 从必要状态检查中移除;现有状态立即变为信息性提示。
该工作流位于 .github/workflows/required-changes-from-trunk.yml 并运行 pr-baseline action,其文档全面涵盖了权限、速率限制和边缘情况。