mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-01 14:34:42 +01:00
* feat(pr-wait): gstack-pr-wait event watcher (tstack pr-wait design port) and /land-and-deploy Step 3 wiring Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pr-wait): keep the result codes in lib/result-codes-release.ts so fixtures that copy the module list keep working Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(pr-wait): function declarations for the fake-gh helpers so the pregate TSX import scanner maps the lib files Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pr-wait): /ship review pass 1 — every check gates green, --timeout, bot identity, signal disposition Red Team and specialist findings on #3495, all fixed in the diff: - green gates on every check on the head, as gstack-ci-gate does, so land-and-deploy Step 2 and Step 3 can no longer disagree while a non-required check pends; required checks still gate before they appear - --timeout MINUTES (default 60, 0 = none) ends a watch that met nothing as PR_WAIT_BLOCKED naming the still-pending checks; restores Step 3's cap - a bot owns logins that start with its name (greptile-apps[bot]), not any login containing it; a failed gating-bot check is a failed check, never a completed review - ready: green alone when no gating bot is configured (pr_wait_gating_bots none no longer polls forever); held while merge state is UNKNOWN - BEHIND and DIRTY announced once per head, with the short head in the line - the bin installs no signal handlers: the synchronous loop never ran them and they made the process ignore SIGTERM/SIGINT; default disposition kills it at once and the next watcher takes over the dead pid's lock - a gh spawn timeout (ETIMEDOUT) is retried like any transient failure - a local fault (unwritable state root) is PR_WAIT_REFUSED exit 2, so exit 1 always carries a PR_WAIT_BLOCKED line - control characters in GitHub text never start a second event line Tests: 21 new cases including a real SIGTERM against the bin, gstack-config set-time validation and default parity, and the 14 state-matrix cells the state-machines specialist listed (gstack-state-matrix check: ok, 33/33). Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(pr-wait): /ship review pass 2 — advisory checks gate too, BEHIND keyed on the head, verdict survives a failed save - an advisory bot's review is never waited for, but its check gates like any other, so gstack-ci-gate (Step 2) and gstack-pr-wait --until green (Step 3) read the same check set with no exception - BEHIND and DIRTY are keyed on the head alone; the pass-1 key also held the base oid, so a base that kept moving re-announced BEHIND to a restarted watcher on every commit - finish() keeps the printed verdict's exit code when the state file cannot be written; the save error goes to stderr - PR_WAIT_BLOCKED and PR_WAIT_REFUSED summaries name every exit-1 and exit-2 path (--timeout, a local error); emitBots docstring matches the gating rule - CHANGELOG says what a timeout means at land-and-deploy Step 3: a STOP with the pending checks named, no wait-more question Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
33 lines
1.4 KiB
TypeScript
Executable File
33 lines
1.4 KiB
TypeScript
Executable File
#!/usr/bin/env -S bun --no-env-file --config=/dev/null
|
|
/**
|
|
* gstack-pr-wait — watch one pull request and print one line per real event.
|
|
*
|
|
* gstack-pr-wait <pr> [--repo owner/name] [--until green|ready|any-change] [--interval SECONDS] [--timeout MINUTES]
|
|
*
|
|
* Exit 0 when the --until condition is met or the PR merged, 1 when it needs
|
|
* action (PR_WAIT_BLOCKED), 2 on bad input, a duplicate watcher or a local
|
|
* error (PR_WAIT_REFUSED). The loop is synchronous (spawnSync, Bun.sleepSync),
|
|
* so signals keep their default disposition: Ctrl-C and kill end the process
|
|
* at once and the next watcher takes over the dead pid's lock. Review-bot lists: `gstack-config set pr_wait_gating_bots`
|
|
* and `pr_wait_advisory_bots`. Logic: lib/pr-wait.ts and lib/pr-wait-github.ts.
|
|
*
|
|
* Design ported from tstack's pr-wait (t3dotgg/tstack, MIT, Copyright (c) 2026
|
|
* Theo Browne; NOTICE.md). Docs: docs/troubleshooting.md#gstack-pr-wait
|
|
*/
|
|
import { spawnGh } from '../lib/ci-gate';
|
|
import { prWaitMain } from '../lib/pr-wait';
|
|
|
|
const code = prWaitMain(process.argv.slice(2), {
|
|
gh: spawnGh,
|
|
vars: process.env,
|
|
pid: process.pid,
|
|
now: () => Date.now(),
|
|
sleep: ms => Bun.sleepSync(ms),
|
|
out: text => process.stdout.write(text),
|
|
err: text => process.stderr.write(text),
|
|
pidAlive: pid => {
|
|
try { process.kill(pid, 0); return true; } catch (error) { return (error as NodeJS.ErrnoException).code === 'EPERM'; }
|
|
},
|
|
});
|
|
process.exit(code);
|