Skip to content

Release blocker check — 发稳定版前的 P0 门禁 #1

Release blocker check — 发稳定版前的 P0 门禁

Release blocker check — 发稳定版前的 P0 门禁 #1

name: Release blocker check — 发稳定版前的 P0 门禁
# Phase 7D:手动在发稳定版前运行。查 v0.56.x milestone 下是否有 open 的 P0 blocker。
# - open P0-crash-or-interrupt / P0-data-loss-risk → fail(不可发版)
# - open P1-* → 不 fail,列为 known issues 候选
# 只读 issue 元数据,不碰任何代码 / 不关闭任何东西。
on:
workflow_dispatch:
permissions:
issues: read
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v7
with:
script: |
const { owner, repo } = context.repo;
const { data: milestones } = await github.rest.issues.listMilestones({ owner, repo, state: 'open', per_page: 100 });
const ms = milestones.find((m) => m.title === 'v0.56.x Stability / Trust');
if (!ms) {
core.setFailed('❌ 未找到 milestone "v0.56.x Stability / Trust",发版门禁 fail-closed(不放行)。请确认 milestone 名称未被改名 / 关闭,或手动核对 P0 blocker 后再发版。');
return;
}
const issues = await github.paginate(github.rest.issues.listForRepo, {
owner, repo, state: 'open', milestone: String(ms.number), per_page: 100,
});
const onlyIssues = issues.filter((i) => !i.pull_request);
const P0 = ['P0-crash-or-interrupt', 'P0-data-loss-risk'];
const p0 = onlyIssues.filter((i) => i.labels.some((l) => P0.includes(l.name)));
const p1 = onlyIssues.filter((i) => i.labels.some((l) => /^P1-/.test(l.name)));
if (p1.length) {
core.warning(`P1 known-issues 候选(${p1.length},不阻塞发版,建议写进 Release Notes):\n` +
p1.map((i) => ` #${i.number} ${i.title}`).join('\n'));
}
if (p0.length) {
core.setFailed(`❌ 发现 ${p0.length} 个 open P0 blocker,不可发稳定版:\n` +
p0.map((i) => ` #${i.number} ${i.title}`).join('\n'));
} else {
core.info(`✓ milestone "${ms.title}" 下无 open P0 blocker,可继续发版流程。`);
}