# PR #25586 完整报告

- 仓库：`sgl-project/sglang`
- 标题：ci: pr-states no longer overwrites running run state when label is removed
- 合并时间：2026-05-18 19:23
- 原文链接：http://prhub.com.cn/sgl-project/sglang/pull/25586

---

# PR 分析报告

## 执行摘要

本 PR 修复了 `pr-states.yml` 在标签移除时错误覆盖运行状态的 bug，通过识别 `unlabeled` 事件并引入预等待时间，确保正在运行的 CI 工作流链接不被丢失。同时重构了查询辅助函数，统一重试逻辑。变更仅涉及一个 CI 工作流文件，风险低，但提升了 CI 状态展示的准确性。

## 功能与动机

当 `run-ci` 标签从 PR 上移除时，原有的 `pr-states` 工作流会立即将 PR body 中的 CI 状态回退到 "Missing label" 或 "Not enabled"，即使此时仍有工作流在运行。这导致开发者丢失了正在运行的测试链接，造成困扰。PR 作者在描述中明确要求“keep the actual workflow run link in the PR body even after the gating label is removed”。

## 实现拆解

1. **事件识别**：新增 `justRemovedLabel` 标志，通过 `context.eventName === 'pull_request_target'` 且 `context.payload.action === 'unlabeled'` 判断。
2. **预等待配置**：定义 `LABEL_ON_PRESLEEP_MS`（3000ms）和 `LABEL_OFF_PRESLEEP_MS`（6000ms）常量，以应对 GitHub API 索引延迟。
3. **函数重构**：将原 `findRunWithRetry` 替换为更灵活的 `findRun`，接受 `{ preSleepMs, attempts, delayMs }` 参数，使所有查询路径统一。
4. **主逻辑调整**：根据是否标签移除和是否拥有标签，选择不同的预睡眠时间，然后调用 `findRun`。若返回正在运行的 `run`，则保留其链接与状态图标；仅当无运行且标签缺失时才显示 "Missing label"。

### `.github/workflows/pr-states.yml`

唯一变更文件，包含所有修复逻辑：标签移除事件识别、预等待常量、重构查询函数及主逻辑调整。

```javascript
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
const RETRY_ATTEMPTS = 3;
const RETRY_DELAY_MS = 6000;
const LABEL_ON_PRESLEEP_MS = 3000;
const LABEL_OFF_PRESLEEP_MS = 6000;

async function findRun(workflowFile, { preSleepMs = 0, attempts = 1, delayMs = 0 }) {
  // 可选预睡眠，等待 GitHub API 索引更新
  if (preSleepMs > 0) await sleep(preSleepMs);
  for (let i = 0; i < attempts; i++) {
    const run = await findRunBySha(workflowFile);
    if (run) return run;
    if (i < attempts - 1) await sleep(delayMs);
  }
  return null;
}

// 主 handler 中关键逻辑
const justRemovedLabel = context.eventName === 'pull_request_target' && context.payload.action === 'unlabeled';
let preSleep = 0;
if (justRemovedLabel) {
  preSleep = LABEL_OFF_PRESLEEP_MS; // 标签移除后，等待 6s
} else if (hasCI) {
  preSleep = LABEL_ON_PRESLEEP_MS; // 有标签时，等待 3s
}
const run = await findRun('pr-test.yml', {
  preSleepMs: preSleep,
  attempts: RETRY_ATTEMPTS,
  delayMs: RETRY_DELAY_MS
});
// 后续：如果 run 存在且正在运行，则保留其链接和图标；
// 否则根据标签存在与否显示对应文本

```

## 评论区精华

无可记录的 review 讨论，作者直接合并。Gemini Code Assist 尝试生成 review 但因文件类型未支持而跳过。

## 风险与影响

- **风险**：变更仅限 CI 工作流，无生产影响。主要风险是预等待时间可能不足导致竞态，但重试机制可降低概率。缺少自动化测试覆盖。
- **影响**：所有开发者将受益于更准确的 CI 状态展示；标签移除后不再丢失运行中的测试链接。无性能开销。

## 关联脉络

本 PR 属于 CI 基础设施的独立修复，与同期大量 scheduler 重构 PR（#25622~#25641）无关。它聚焦于 GitHub Actions 工作流的健壮性，没有跨 PR 的关联演进。