Files
orca/.github/scripts/check-required-pr-context.mjs
T
Neil a7ae68fc6f ci: full checks on main pushes, changed-file lint on PRs, Slack alert when main breaks (#37282)
* ci: full checks on main pushes, changed-file lint on PRs, Slack alert when main breaks

PR Checks now also runs on every push to main, with each commit in its own
concurrency group so main runs never cancel one another. On a push the path
router gets an empty diff, which already fails closed to every job, and the
input-scoped steps (localization extraction, VM rollback replay, orcad smoke)
run in full. Advisory E2E lanes stay PR-only.

On PRs the per-file passes (root oxlint, JS-plugin oxlint, anti-slop, ast-grep
and oxfmt) check only the changed paths. Everything is checked when the diff
cannot be resolved, a lint toolchain input changes (oxlint/oxfmt/ast-grep
configs and plugins, package.json, the lockfile, .gitignore, pr.yml), or more
than 1500 paths change. Whole-program checks stay unscoped.

A new workflow follows completed main runs and posts to the release Slack
webhook only when main turns red, and once when it turns green again.

* ci: alert once per main health streak and tolerate a malformed Slack mapping
2026-11-01 20:30:03 -08:00

40 lines
1.6 KiB
JavaScript

import { readdirSync, readFileSync } from 'node:fs'
import { join } from 'node:path'
import { pathToFileURL } from 'node:url'
export function verifyRequiredPrContext(parseYaml) {
const directory = '.github/workflows'
const providers = readdirSync(directory)
.filter((file) => /\.ya?ml$/.test(file))
.flatMap((file) => {
const workflow = parseYaml(readFileSync(join(directory, file), 'utf8'))
return Object.entries(workflow.jobs)
.filter(([id, job]) => (job.name ?? id) === 'PR checks passed')
.map(([id, job]) => ({ owner: `${file}:${id}`, job }))
})
const owners = providers.map((provider) => provider.owner)
if (providers.length !== 1 || owners[0] !== 'pr.yml:verify') {
throw new Error(`Required PR context must belong only to pr.yml:verify; found ${owners}`)
}
const gate = providers[0].job
const condition = gate.if?.replace(/^\$\{\{\s*|\s*\}\}$/g, '').trim()
if (
condition !==
"!cancelled() && (github.event_name != 'pull_request' || github.event.pull_request.draft != true)"
) {
throw new Error('Required PR aggregate must run unless cancelled or the PR is a draft.')
}
if (gate['continue-on-error'] || gate.steps?.some((step) => step['continue-on-error'])) {
throw new Error('Required PR aggregate must not ignore failures.')
}
}
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
const yaml = globalThis.Bun?.YAML
if (!yaml) {
throw new Error('Run workflow context validation with the pinned Bun runtime.')
}
verifyRequiredPrContext(yaml.parse)
console.log('Required PR check context verified.')
}