Files
nixpkgs/ci/github-script/run
Wolfgang Walther 87d9b08ffb ci/github-script/prepare: identify real base branch
When a contributor mistakenly sets the wrong target branch for a Pull
Request, this can lead to bad consequences for CI. Most prominent is the
mass ping of codeowners, that is already handled in
`ci/request-reviews/verify-base-branch.sh`. But there are other things
that go wrong:
- After eval, a mass ping of maintainers would still be possible, in
theory. Practically, this doesn't happen, because we have a limit of 10
reviewer requests at the same time.
- This will most often contain a change to `ci/pinned.json`, thus the
full Eval matrix of all Lix/Nix versions will be run, burning a lot of
resources.
- The PR will be labelled with almost all labels that are available.

We can improve on the current situation with some API calls to determine
the "best" merge-base for the current PR. We then consider this as the
"real base". If the current target is not the real base, we fail the
prepare step, which is early enough to prevent all other CI from
running.
2025-08-24 18:09:08 +02:00

87 lines
2.7 KiB
JavaScript
Executable File

#!/usr/bin/env -S node --import ./run
import { execSync } from 'node:child_process'
import { closeSync, mkdtempSync, openSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { program } from 'commander'
import * as core from '@actions/core'
import { getOctokit } from '@actions/github'
async function run(action, owner, repo, pull_number, options = {}) {
const token = execSync('gh auth token', { encoding: 'utf-8' }).trim()
const github = getOctokit(token)
const payload = !pull_number ? {} : {
pull_request: (await github.rest.pulls.get({
owner,
repo,
pull_number,
})).data
}
process.env['INPUT_GITHUB-TOKEN'] = token
closeSync(openSync('step-summary.md', 'w'))
process.env.GITHUB_STEP_SUMMARY = 'step-summary.md'
await action({
github,
context: {
payload,
repo: {
owner,
repo,
},
},
core,
dry: true,
...options,
})
}
program
.command('prepare')
.description('Prepare relevant information of a pull request.')
.argument('<owner>', 'Owner of the GitHub repository to check (Example: NixOS)')
.argument('<repo>', 'Name of the GitHub repository to check (Example: nixpkgs)')
.argument('<pr>', 'Number of the Pull Request to check')
.option('--no-dry', 'Make actual modifications')
.action(async (owner, repo, pr, options) => {
const prepare = (await import('./prepare.js')).default
run(prepare, owner, repo, pr, options)
})
program
.command('commits')
.description('Check commit structure of a pull request.')
.argument('<owner>', 'Owner of the GitHub repository to check (Example: NixOS)')
.argument('<repo>', 'Name of the GitHub repository to check (Example: nixpkgs)')
.argument('<pr>', 'Number of the Pull Request to check')
.option('--no-cherry-picks', 'Do not expect cherry-picks.')
.action(async (owner, repo, pr, options) => {
const commits = (await import('./commits.js')).default
run(commits, owner, repo, pr, options)
})
program
.command('labels')
.description('Manage labels on pull requests.')
.argument('<owner>', 'Owner of the GitHub repository to label (Example: NixOS)')
.argument('<repo>', 'Name of the GitHub repository to label (Example: nixpkgs)')
.argument('[pr]', 'Number of the Pull Request to label')
.option('--no-dry', 'Make actual modifications')
.action(async (owner, repo, pr, options) => {
const labels = (await import('./labels.js')).default
const tmp = mkdtempSync(join(tmpdir(), 'github-script-'))
try {
process.env.GITHUB_WORKSPACE = tmp
process.chdir(tmp)
run(labels, owner, repo, pr, options)
} finally {
rmSync(tmp, { recursive: true })
}
})
await program.parse()