ci: fail closed on draft admission state
This commit is contained in:
@@ -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');
|
||||
|
||||
@@ -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,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"
|
||||
|
||||
Reference in New Issue
Block a user