执行摘要
- 一句话:引入评论命令触发 Buildkite CI
- 推荐动作:该 PR 是 CI 流程的显著改进,安全设计细致(精确命令、权限控制、只检出默认分支),并配有完整测试。建议 CI 团队和架构师精读
run_ci_command.py 中的授权逻辑与 Buildkite 交互设计。
功能与动机
Replace label-driven full CI triggering with explicit PR comment commands so reviewers and authors can request CI only when needed.
实现拆解
- 新增工作流
run-ci-command.yml:监听 issue_comment 事件,匹配精确命令 /ci run 或 /ci retry,设置 per-PR 并发组。
- 新增核心脚本
run_ci_command.py:实现 GitHub 和 Buildkite API 客户端、命令解析、权限授权、创建构建/重试失败任务、活跃构建检查等逻辑。脚本依赖 Python 标准库,无外部包。
- 新增测试
test_run_ci_command.py:通过 FakeGitHub 和 FakeBuildkite 模拟网络调用,覆盖 15 个用例(精确命令匹配、权限边界、信任用户、活跃构建检测等)。
- 修改 CI 消息通知和 pre-commit 检查:更新
new_pr_bot.yml 和 pre-commit.yml 中的提示文本,标明新触发方式。
- 更新贡献文档
docs/contributing/README.md:说明新的 CI 触发流程。
关键文件:
.github/workflows/scripts/run_ci_command.py(模块 CI核心脚本;类别 infra;类型 infrastructure;符号 ApiError, HttpTransport, request, _error_message): 核心命令处理脚本,实现 GitHub API 交互、Buildkite 构建创建、权限检查等所有逻辑。
.github/workflows/scripts/test_run_ci_command.py(模块 CI测试;类别 test;类型 test-coverage;符号 make_pr, make_event, FakeGitHub, init): 完整的测试套件,15 个测试用例覆盖命令解析、权限授权、信任用户、活跃构建检测等场景,使用 fake 对象保证测试独立。
.github/workflows/run-ci-command.yml(模块 工作流定义;类别 infra;类型 infrastructure): GitHub Actions 工作流定义,配置触发器、并发组、权限和步骤,是 CI 命令的入口。
关键符号:authorize, has_trusted_approval, parse_command, create_build_payload, select_latest_build, is_active_build, is_build_for_pr, run, BuildkiteClient.list_builds, BuildkiteClient.create_build, BuildkiteClient.retry_failed_jobs
关键源码片段
.github/workflows/scripts/run_ci_command.py
核心命令处理脚本,实现 GitHub API 交互、Buildkite 构建创建、权限检查等所有逻辑。
class GitHubClient:
def __init__(
self,
token: str,
repository: str,
transport: HttpTransport | None = None,
) -> None:
if not token:
raise RuntimeError("GH_TOKEN is not set.")
self.owner, self.repo = repository.split("/", maxsplit=1)
self.transport = transport or HttpTransport()
# 固定请求头,符合 GitHub API 规范
self.headers = {
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"User-Agent": "vllm-ci-command",
"X-GitHub-Api-Version": "2022-11-28",
}
def authorize(
self,
actor: str,
*,
pr: dict[str, Any],
trusted_users: set[str],
) -> tuple[bool, str]:
permission = self.get_permission(actor)
if permission in TRUSTED_PERMISSIONS:
return True, f"permission: {permission}"
if actor == pr["user"]["login"]:
# 作者需要批准或 ready 标签
labels = {label["name"] for label in pr.get("labels", [])}
if READY_LABELS & labels:
return True, "author with ready label"
decision = self.get_review_decision(pr["number"])
if decision in ("APPROVED", "CHANGES_REQUESTED"):
return True, "author with approved PR"
return False, "author without approval or ready label"
if actor in trusted_users:
return True, "trusted user"
return False, "no valid permission"
.github/workflows/scripts/test_run_ci_command.py
完整的测试套件,15 个测试用例覆盖命令解析、权限授权、信任用户、活跃构建检测等场景,使用 fake 对象保证测试独立。
def make_pr(**overrides: Any) -> dict[str, Any]:
# 构造默认 PR 对象,可通过 overrides 覆写
pr = {
"base": {"ref": "main"},
"draft": False,
"head": {
"ref": "feature",
"repo": {"clone_url": "https://github.com/contributor/vllm.git"},
"sha": "0123456789abcdef",
},
"labels": [],
"number": 42,
"state": "open",
"user": {"login": "author"},
}
pr.update(overrides)
return pr
def make_event(command: str, actor: str = "reviewer") -> dict[str, Any]:
# 构造 issue_comment 事件负载
return {
"comment": {
"body": command,
"id": 99,
"user": {"login": actor},
},
"issue": {
"number": 42,
"pull_request": {},
},
}
class FakeGitHub:
# 模拟 GitHub API 客户端,所有方法直接返回预设数据
def __init__(self, *, permission="write", permissions=None, pr=None,
review_decision="REVIEW_REQUIRED", reviews=None):
self.comments = []
self.permission = permission
self.permissions = permissions or {}
self.pr = pr or make_pr()
self.reactions = []
self.review_decision = review_decision
self.reviews = reviews or []
def get_pr(self, number):
return self.pr
def get_permission(self, actor):
return self.permissions.get(actor, self.permission)
def get_review_decision(self, number):
return self.review_decision
def list_reviews(self, number):
return self.reviews
评论区精华
本 PR 未收到实质性 Review 评论(仅 claude[bot] 自动回复)。但 PR body 中详细阐述了安全设计与 Rollout 要求,包括精确命令匹配、per-PR 并发、仅检出默认分支、以及秘密变量配置步骤。
风险与影响
关联脉络
参与讨论