-
Notifications
You must be signed in to change notification settings - Fork 0
[WRONG BRANCH] Require trusted GitHub Actions ci check before marking contributor PRs ready
#270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -841,16 +841,14 @@ jobs: | |
| checklistComplete = readiness.present && readiness.complete; | ||
| } | ||
|
|
||
| // The bot verifies the checklist claims it can check itself. The | ||
| // local-CI box is an author attestation only — fork contributors | ||
| // cannot start repository CI (a maintainer has to) — so the gate | ||
| // never disproves it; head-drift still resets every box after a | ||
| // new push. The latest-dev box only counts while the head is at | ||
| // most READINESS_LATEST_DEV_BEHIND_MAX commits behind the base; | ||
| // the findings box only counts while every Codex/CodeRabbit | ||
| // review thread on the PR is resolved. A disproved claim unchecks | ||
| // that box and keeps the PR a draft, exactly like a head-drift | ||
| // reset. | ||
| // The bot verifies the three checklist claims it can check itself. | ||
| // The CI box only counts when the head's `ci` check (the repo's | ||
| // documented "CI passed" signal) is green; the latest-dev box only | ||
| // counts while the head is at most READINESS_LATEST_DEV_BEHIND_MAX | ||
| // commits behind the base; the findings box only counts while every | ||
| // Codex/CodeRabbit review thread on the PR is resolved. A disproved | ||
| // claim unchecks that box and keeps the PR a draft, exactly like a | ||
| // head-drift reset. | ||
| let claimViolations = []; | ||
| let claimNotice = []; | ||
| if ( | ||
|
|
@@ -859,7 +857,52 @@ jobs: | |
| !headDrifted && | ||
| failures.length === 0 | ||
| ) { | ||
| let ciGreen = false; | ||
| try { | ||
| // GitHub Actions' immutable App ID. Name alone is not evidence: | ||
| // any installed app can publish a check called `ci`. | ||
| const githubActionsAppId = 15368; | ||
| const { data: checksData } = | ||
| await github.rest.checks.listForRef({ | ||
| owner, | ||
| repo, | ||
| ref: pr.head.sha, | ||
| app_id: githubActionsAppId, | ||
| check_name: "ci", | ||
| filter: "latest", | ||
| per_page: 100 | ||
| }); | ||
| const checkRuns = Array.isArray(checksData.check_runs) | ||
| ? checksData.check_runs | ||
| : []; | ||
| const ciChecks = checkRuns.filter( | ||
| check => | ||
| check.name === "ci" && | ||
| check.app?.id === githubActionsAppId | ||
|
Comment on lines
+878
to
+881
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For a contributor PR that changes AGENTS.md reference: AGENTS.md:L218-L224 Useful? React with 👍 / 👎. |
||
| ); | ||
| // The readiness claim requires positive CI evidence. A missing, | ||
| // pending, unsuccessful, foreign, or conflicting aggregate | ||
| // check must fail closed. The exact app/name/latest query should | ||
| // be tiny; if GitHub reports more rows than this response holds, | ||
| // treat the truncated evidence as unreadable rather than paging | ||
| // through an endpoint whose filters already select the latest run. | ||
| ciGreen = | ||
| Number.isSafeInteger(checksData.total_count) && | ||
| checksData.total_count === checkRuns.length && | ||
| ciChecks.length > 0 && | ||
| ciChecks.every( | ||
| check => | ||
| check.status === "completed" && | ||
| check.conclusion === "success" | ||
| ); | ||
| } catch (error) { | ||
| core.warning( | ||
| `Could not list checks for the readiness claim check: ${error.message}` | ||
| ); | ||
| ciGreen = false; | ||
| } | ||
| claimViolations = readinessClaimViolations({ | ||
| ciGreen, | ||
| behindBase, | ||
| behindUnknown: ancestryLookupFailed | ||
| }); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
enforce-targetjob declares onlycontents: writeandpull-requests: writeat lines 143–146; because job-level permissions set every omitted scope tonone, this newchecks.listForRefrequest lacks the requiredchecks: readpermission. On every completed contributor checklist the request therefore fails,ciGreenremains false, and the fail-closed path permanently unticks the CI box instead of ever marking the PR ready. Addchecks: readto this job's permissions.AGENTS.md reference: AGENTS.md:L218-L224
Useful? React with 👍 / 👎.