- 后端
- 云原生
- 运维
- 虚拟化
- 人工智能
- AI 应用
【免费下载链接】cloudpods
开源、云原生的多云管理及混合云融合平台
Cloudpods 仓库的 scripts/README.md 介绍了一组辅助 GitHub CI 机器人工作的脚本,用于在人工 code review 完成之后,安全、可控地给 Pull Request(PR)打标签并完成合并。本文以该文档为骨架,结合 scripts/approve.sh、scripts/approve_all.sh、scripts/lgtm.sh 及同目录下的配套脚本源码,逐一解析其检查项、标签协同机制与批量合并流程,帮助维护者理解这套 PR 合并工具链的工作原理与正确使用方式。
辅助脚本一览
围绕"给 PR 打标签 + 合并"这一目标,文档主体涉及三个脚本:
| 脚本 | 作用 | 用法 |
|---|---|---|
| approve.sh | 完成 4 项前置检查后,对单个 PR 打/lgtm、/approve标签以触发合并 | ./scripts/approve.sh <PRN> [check_reviewers] |
| approve_all.sh | 批量合并"master 主 PR + 各分支 cherry pick PR"这一整组 PR | ./scripts/approve_all.sh <PRN> |
| lgtm.sh | 给一个 PR 打上lgtm标签 | ./scripts/lgtm.sh <PRN> |
此外,scripts/label.sh 是被lgtm.sh和approve.sh复用的底层"打标签"原语,scripts/advchecks.py 负责 reviewer 审批核对,scripts/cherry_pick_pull.sh 则负责生成被approve_all.sh识别的 cherry pick PR。这些脚本都依赖hubCLI 与python,通过 GitHub REST API 与仓库交互。
approve.sh:合并前的四项前置检查
文档定义的检查项
approve.sh 是整套工具链的核心。文档明确列出了执行合并前的 4 项检查:
- 该 PR 的状态为
open; - 该 PR 的
mergeable状态为true(如果有冲突,则mergeable=false); - 该 PR 的所有 CI 检查都通过;
- 如果命令行第二个参数
check_reviewers为非空字符串,则还会检查是否所有 requested reviewers 都/lgtm了这个 PR。
同时文档特别强调:执行脚本之前,请确认已经人肉 review 过代码。脚本只是为了方便合并、并确保合并前没有忽略检查,并不是为了替代人工 code review。
检查流程的源码实现
从 approve.sh 的函数实现看,四项检查对应如下调用链(均基于hub api访问 GitHub API):
检查一:PR 状态。pr_state()请求repos/{owner}/{repo}/pulls/$PRN,解析state字段;若不是open则直接退出(exit 0,属于无需处理的正常结束)。
检查二:mergeable 轮询。mergeable()并非只查一次——GitHub 在计算合并状态期间会返回mergeable: null,因此脚本使用while true循环,直到取到true(成功)或false(冲突,退出码 1),见 mergeable 轮询逻辑。
检查三:CI check-runs 全绿。last_commits()先拉取 PR 的提交列表,并用一段 awk 把提交顺序反转(最新提交在前);然后last_check()对最新一个有检查结果的提交请求check-runs接口(注意使用了application/vnd.github.antiope-preview+json这个 API 预览版本头),逐条解析conclusion字段。只要有任何一条不是success就中止;如果所有提交都查不到检查结果(CHECKED为空),说明 CI 尚未跑完,脚本会提示"give up and try later"。相关实现见 提交与检查解析 和 结果判定循环。
检查四:reviewer 审批核对。只有当第二个参数非空时才执行:脚本先把 PR 详情与全部 issue 评论分别落盘到临时文件,再交给 advchecks.py 做比对,失败则退出(见 reviewer 检查调用)。
标签如何"驱动"合并
检查全部通过后,脚本并不直接调用 merge API,而是按顺序给 PR 发两条"指令性"评论并轮询标签落库:先label "$PR" "/lgtm" "lgtm",再label "$PR" "/approve" "approved"(见 打标签流程)。label()的内部机制是:向 PR 发一次评论(如/lgtm),然后每隔 1 秒轮询一次issues/$PRN/labels,最多等 30 秒;整个流程最多重试 3 轮。从源码结构看,这种"发评论—等标签"的异步协同表明:真正给 PR 打上lgtm、approved标签的是仓库配套的 CI 机器人,而合并动作也由机器人在看到approved标签后触发——脚本本身只负责检查与下"指令"。
advchecks.py:reviewer 审批核对逻辑
advchecks.py 是一个独立的 Python 校验器,输入为两个 JSON 文件:PR 详情与 PR 评论列表。其核对规则是:
- 从 PR 详情的
requested_reviewers字段提取全部被指派的 reviewer(以login(id)标识); - 从评论中筛选正文精确等于
/lgtm的评论,得到已表态的评审者集合; - 若没有任何 reviewer 被指派,直接以非零码退出("No reviwer is assigned");
- 若还有 reviewer 未
/lgtm,打印缺勤名单("Reviewers xxx needs /lgtm")并以非零码退出。
这保证了approve.sh <PRN> check_reviewers场景中"所有指派评审者均已认可"这一语义被严格验证,而不是仅凭评论数量判断。
approve_all.sh:批量合并主 PR 与 backport 组
文档语义
approve_all.sh 用于"合并一组 PR":这组 PR 由 master 上的主 PR 和 backport 到各个分支的 cherry pick PR 组成。文档规定:对 master 上的 PR 做全部 4 项检查,对其他(cherry pick)PR 只做前 3 项检查。
实现细节
脚本的执行逻辑与文档一一对应(见 approve_all.sh 主流程):
- 以
per_page=1000拉取仓库最近一页全部 PR,提取每个 PR 的number与title; - 用标题匹配
Automated cherry pick of #<PRN>:找出所有与主 PR 关联的 cherry pick PR; - 循环调用
approve.sh依次合并:第一遍调用时传入REVIEWER_CHECK=yes(对应 master 主 PR 的 4 项检查),合并成功后将REVIEWER_CHECK置空,后续 cherry pick PR 即只执行前 3 项检查;任一 PR 合并失败则整体中止(exit 1)。
值得注意的一个边界情况:脚本把PRN自身放在组首,因此即使匹配不到任何 cherry pick PR,也等价于对主 PR 执行完整的approve.sh流程。
cherry_pick_pull.sh:cherry pick PR 组从何而来
approve_all.sh依赖的Automated cherry pick of #PRN:标题格式,来自同目录的 cherry_pick_pull.sh。该脚本脱胎于 Kubernetes 社区的 cherry-pick 工具(文件头注明 Copyright 2015 The Kubernetes Authors),其用法为:
./scripts/cherry_pick_pull.sh <remote branch> <pr-number>...例如./scripts/cherry_pick_pull.sh upstream/release-3.14 12345会把 PR #12345 摘取到upstream/release-3.14分支并自动开 PR。关键行为(均可在 cherry_pick_pull.sh 中确认):
- 新建分支名形如
automated-cherry-pick-of-#12345-<target-branch>-<timestamp>(分支命名); - 下载
https://github.com/<org>/<repo>/pull/<pr>.patch后以git am -3应用,冲突时会暂停并等待人工在另一窗口解决后确认继续; - 自动创建的 PR 正文首行即
Automated cherry pick of #<pr1> #<pr2>(PR 描述生成),这正是approve_all.sh的标题匹配模式所依赖的约定; - 支持环境变量:
DRY_RUN跳过 push 与建 PR(只把 cherry pick 留在本地分支)、UPSTREAM_REMOTE(默认upstream)、FORK_REMOTE(默认origin)、GITHUB_USER(必填,PR 来源用户名/组织); - 脚本要求
hub版本不低于 2.13.0,且工作区必须干净、无进行中的git rebase/git am。
至此形成一条完整链路:cherry_pick_pull.sh在多个 release 分支上产生同标题族的 PR →approve_all.sh按主 PR 号一次性合并整族 PR。
lgtm.sh 与 label.sh:标签自动化的底层原语
lgtm.sh 自身只有一行核心逻辑:$CUR_DIR/label.sh $PRN /lgtm lgtm。它把"给 PR 打 lgtm 标签"统一委托给 label.sh,后者的完整用法是:
./scripts/label.sh <pr_number> <msg> <label>即向 PR 发送评论msg,并轮询等待标签label出现,重试与轮询策略与approve.sh内置的label()完全一致(3 轮 × 30 秒)。这说明仓库内的标签体系遵循同一模式:脚本只发指令评论,标签由 CI 机器人异步添加,lgtm.sh则是该模式最轻量的入口。
同目录的其他辅助脚本
除文档列出的三个脚本外,scripts/目录还有两个轻量工具,与 CI 机器人协同生态相关:
- comment.sh:向指定 PR 发送一条或多条评论(
comment.sh <PRN> <msg>...),是approve.sh/label.sh中评论逻辑的独立版本; - webhook.py:一个基于标准库的调试用 HTTP 服务,默认监听
0.0.0.0:20888,原样打印 POST 请求体及X-Yunion-Event请求头并返回{"result":"ok"},适合在本地验证 webhook 投递链路。
使用前提与注意事项
- 运行环境:脚本假定当前目录是目标仓库的 git 检出,并依赖
hub(hub api repos/{owner}/{repo}/...需要 hub 依据仓库 origin 解析 owner/repo)与python可用; - 平台前提:整套工具面向 GitHub 工作流(
hub api、GitHub check-runs API、cherry-pick patch 下载地址等),迁移到其他代码托管平台时需要重写 API 调用层; - 职责边界:
approve.sh的 4 项检查(open 状态、无冲突、CI 全绿、reviewer 认可)是"防遗漏"机制,文档明确要求执行人工 review 之后再执行脚本,脚本不替代人肉 code review; - CI 未完成时的表现:检查三项依赖 PR 最新提交上的 check-runs,若 CI 尚未开始,脚本会明确提示稍后再试而非误合并;
- 批量合并的原子性:
approve_all.sh在组内任一 PR 检查失败时立即退出,已合并的 PR 不回滚,因此建议在 CI 状态稳定后再执行批量操作。
从 scripts/README.md 到各脚本源码可以看出,这套工具的设计思路是"检查在客户端、动作经机器人":脚本承担确定性检查与指令下发,标签与合并由 CI 机器人闭环执行,从而在保留人工 review 责任的同时,把重复性的状态核对与批量 backport 合并交给可复核的自动化流程。
- 后端
- 云原生
- 运维
- 虚拟化
- 人工智能
- AI 应用
【免费下载链接】cloudpods
开源、云原生的多云管理及混合云融合平台
相关推荐
JVM Profiler实战案例:如何定位和解决HDFS NameNode性能瓶颈
JVM Profiler实战案例:如何定位和解决HDFS NameNode性能瓶颈 HDFS NameNode作为分布式文件系统的核心组件,其性能直接影响整个集
Apache Arrow 开发者工具实战:PR 自动合并脚本与 Docker 集成测试完全指南
Apache Arrow 开发者工具实战:PR 自动合并脚本与 Docker 集成测试完全指南 本篇指南围绕 Apache Arrow 仓库 dev/READM
数据工程大数据序列化数据分析ZenlessZoneZero-OneDragon PR 收尾指南:把已开 PR 推到「完善可合并」的完整流程
ZenlessZoneZero OneDragon PR 收尾指南:把已开 PR 推到「完善可合并」的完整流程 导读 本指南围绕 ZenlessZoneZero
桌面应用RPA计算机视觉
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考