ci: fail closed on draft admission state

This commit is contained in:
chichuan
2026-08-26 10:35:59 +08:00
parent 7913c3a720
commit d837da5f3a
5 changed files with 72 additions and 29 deletions
+24 -7
View File
@@ -12,12 +12,15 @@ permissions:
pull-requests: read
statuses: write
concurrency:
# State transitions for one PR supersede older policy evaluations. This
# prevents a stale Ready run from overwriting the fail-closed Draft status.
group: ai-behavior-${{ github.event_name == 'pull_request_target' && format('pr-{0}', github.event.pull_request.number) || format('push-{0}', github.sha) }}
cancel-in-progress: true
jobs:
ai-behavior-check:
name: AI Behavior
# Draft feedback is intentionally separate from all formal admission
# contexts. Re-evaluate the same head when ready_for_review is emitted.
if: ${{ github.event_name == 'push' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
@@ -50,23 +53,37 @@ jobs:
try {
const expectedHead = pullRequest.head.sha;
const expectedBase = pullRequest.base.sha;
const expectedDraft = pullRequest.draft;
const currentPull = async (phase) => {
const { data: pull } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number,
});
if (pull.head.sha !== expectedHead || pull.base.sha !== expectedBase) {
if (
pull.head.sha !== expectedHead ||
pull.base.sha !== expectedBase ||
pull.draft !== expectedDraft
) {
throw new Error(
`Pull request revision changed during ${phase}: ` +
`expected base/head ${expectedBase}/${expectedHead}, ` +
`got ${pull.base.sha}/${pull.head.sha}`
`Pull request identity changed during ${phase}: ` +
`expected base/head/draft ${expectedBase}/${expectedHead}/${expectedDraft}, ` +
`got ${pull.base.sha}/${pull.head.sha}/${pull.draft}`
);
}
return pull;
};
const before = await currentPull('pre-policy check');
if (before.draft) {
await setStatus('failure', 'Draft PR; mark Ready to run Code Admission');
core.setFailed(
'Draft pull requests are not eligible for Code Admission. ' +
'Mark the pull request ready to run all nine required contexts.'
);
return;
}
const labels = before.labels.map(({ name }) => name);
if (!labels.includes('ai-generated')) {
await setStatus('success', 'Not labeled ai-generated');
+3 -3
View File
@@ -21,9 +21,9 @@ concurrency:
jobs:
lint:
name: Lint
# Draft revisions use the isolated Draft CI workflow. Keeping the formal
# admission contexts absent prevents a fast preview on the same commit from
# being mistaken for the nine checks required after ready_for_review.
# Draft revisions use the isolated Draft CI workflow. Skip the heavy
# admission graph; the base-owned AI Behavior status fails Draft revisions
# so these successful skipped checks cannot authorize a merge.
if: ${{ github.event_name == 'push' || github.event.pull_request.draft == false }}
runs-on: ubuntu-latest
timeout-minutes: 10
+2 -2
View File
@@ -2,7 +2,7 @@ name: Draft CI
on:
pull_request:
types: [opened, synchronize, reopened, converted_to_draft, edited]
types: [opened, synchronize, reopened, ready_for_review, converted_to_draft, edited]
permissions:
contents: read
@@ -99,5 +99,5 @@ jobs:
run: |
printf '%s\n' \
'Draft Fast Gate is development feedback, not Code Admission.' \
'Mark this PR ready for review to run the nine required contexts.' \
'AI Behavior remains failed until this PR is Ready and fully admitted.' \
>> "$GITHUB_STEP_SUMMARY"