mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-12 19:44:48 +01:00
docs: ship-policy and troubleshooting match the shipped train commands
Step 14.5 documentation audit: the stack-tests naming rule is bun's own (.test, _test, .spec, _spec); prune --stale deletes every merged or closed PR's screen/<pr>-* branch; verify --post-merge takes the full SHA and counts commit statuses; train watch --free-timeout and ready --dispatch-ci --timeout defaults; PENDING/UNKNOWN/INCOMPLETE screen verdicts; QUEUE_SCREEN_STALE_REF's Meaning no longer contradicts its Fix; one sentence each for the new QUEUE_NOT_READY, QUEUE_TRAIN_UNTRUSTED and QUEUE_TRAIN_PENDING triggers. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
94f06fb2b2
commit
7ae2f64c69
2 files changed
+65
-39
No files matched your search
+29
-19
@@ -195,14 +195,15 @@ of them with the run URL (`PREGATE_CLEARED: <lane> <url>`; a lane of another
|
||||
workflow stays uncleared and is named in the refusal), and then reads the head
|
||||
as usual, which passes because the dispatched check runs attach to the commit;
|
||||
the `ci-hint:` line then says those non-pull_request runs count. A red run
|
||||
clears no lane and refuses (`QUEUE_NOT_READY`); a fork head is never dispatched
|
||||
here (`QUEUE_TRAIN_UNTRUSTED`). By hand the same four steps are `gh workflow
|
||||
clears no lane and refuses (`QUEUE_NOT_READY`); a run still going at `--timeout`
|
||||
(default 2700 s) is `QUEUE_TRAIN_PENDING`, and rerunning the command keeps
|
||||
waiting; a fork head is never dispatched here (`QUEUE_TRAIN_UNTRUSTED`). By hand the same four steps are `gh workflow
|
||||
run <wf> --ref <branch>`, wait, `gstack-pregate clear --remote <lane> --run-url
|
||||
<run>`, rerun `ready`. The `ci-hint:` line is advisory text for the lane;
|
||||
nothing parses it. `ready --screen` on such a PR has no merge ref to screen,
|
||||
so it builds the scratch merge described below (`SCREEN_MERGE:`, pushed as
|
||||
`screen/<pr>-<head12>`) and screens that; only a real conflict with the base
|
||||
is `QUEUE_SCREEN_STALE_REF`. A CHANGELOG-only conflict is screenable, and a
|
||||
(or a remote whose refs cannot be listed) is `QUEUE_SCREEN_STALE_REF`. A CHANGELOG-only conflict is screenable, and a
|
||||
lane whose skill's own paid cases ran focused may still READY with `--no-screen`.
|
||||
|
||||
`ci:` counts the latest run per check (one app's check name), as GitHub's
|
||||
@@ -420,8 +421,8 @@ lagging or unfetchable merge ref (GitHub stops recomputing it while the PR
|
||||
conflicts with the base, CHANGELOG-only conflicts included) is replaced by a
|
||||
scratch merge of the head onto the base, pushed as `screen/<pr>-<head12>`
|
||||
(the `SCREEN_MERGE:` line says which); a screen dispatched on a stale ref would
|
||||
plan no cases and report success. Only a real conflict with the base is
|
||||
`QUEUE_SCREEN_STALE_REF`. A finished screen that planned no cases (no
|
||||
plan no cases and report success. Only a real conflict with the base (or a
|
||||
remote whose refs cannot be listed) is `QUEUE_SCREEN_STALE_REF`. A finished screen that planned no cases (no
|
||||
`paid-plan` artifact, which a superseded run never uploads, or a plan manifest
|
||||
with nothing planned) is never followed as a screen: `ready --screen`
|
||||
dispatches a fresh one and `train build` prints `SCREEN: #<n> run <id> planned
|
||||
@@ -554,13 +555,15 @@ repair. When verify confirms the repair merged, it prints `FREEZE: cleared`
|
||||
and `NEXT:` builds a train of the PRs still unmerged.
|
||||
|
||||
**5b. Coordinator: after the merge.** `gstack-ship-queue verify --post-merge
|
||||
<sha> [--timeout <s>]` watches every check run attached to the merged commit
|
||||
(the push workflows: free tests, the Windows subset, the main backstop) until
|
||||
none is still running, prints one `CHECK: <name> <conclusion>` per check and
|
||||
<sha> [--timeout <s>]` (the merged commit's full 40-character SHA) watches
|
||||
every check run attached to it (the push workflows: free tests, the Windows
|
||||
subset, the main backstop) and every commit status until none is still
|
||||
running, prints one `CHECK: <name> <conclusion>` per check and
|
||||
`POST_MERGE: <sha12> green|red|pending|none (passed= failed= pending= skipped=)`.
|
||||
Green needs at least one completed check and no failure; `neutral` and
|
||||
`skipped` (the backstop superseding itself) count as skipped. A failure is
|
||||
`QUEUE_POST_MERGE_RED` naming the checks; a timeout (default 2700 s) is
|
||||
`skipped` (the backstop superseding itself) count as skipped; a pending
|
||||
commit status keeps the commit pending and a failed one makes it red. A
|
||||
failure is `QUEUE_POST_MERGE_RED` naming the checks; a timeout (default 2700 s) is
|
||||
`QUEUE_TRAIN_PENDING` with the same command as `NEXT:`. It keeps no process
|
||||
state, so rerunning it after a machine restart continues the watch.
|
||||
|
||||
@@ -569,9 +572,10 @@ deletes the `train/<nonce>` branches of merged, superseded and dropped trains
|
||||
(`WOULD-DELETE:`, `DELETED:`, `GONE:`). `train prune --stale` also settles a
|
||||
`merging` or `green` train whose every PR is MERGED or CLOSED on GitHub (its
|
||||
PRs landed through another train or by hand): it logs each PR's state on a
|
||||
`STALE:` line, marks the record `stale`, deletes its branch and any
|
||||
`screen/<pr>-*` scratch branches of those PRs; a train with an OPEN PR is kept
|
||||
(`KEEP: … still needs the train`). `train forget --train <nonce> | --receipt
|
||||
`STALE:` line, marks the record `stale` and deletes its branch; a train with an
|
||||
OPEN PR is kept (`KEEP: … still needs the train`). The same run deletes every
|
||||
`screen/<pr>-*` scratch branch whose PR is MERGED or CLOSED and keeps one whose
|
||||
PR is still OPEN. `train forget --train <nonce> | --receipt
|
||||
<pr>@<sha> [--dry-run]` removes one record (a settled train with its attempts,
|
||||
or one READY receipt) from local state and from `refs/notes/gstack-trains`
|
||||
with an exact lease on the notes ref, printing `FORGET:` then `FORGOTTEN:`; a
|
||||
@@ -588,14 +592,19 @@ dispatch), waits for the pending run by polling gh, reads the verdict and
|
||||
prints the last step's `NEXT:`. It never dispatches anything the record would
|
||||
not dispatch on its own, so rerunning it after an interruption continues from
|
||||
the record (`WATCH:` lines say what it did; a timeout, default 7200 s, is
|
||||
`QUEUE_TRAIN_PENDING` with the same command as `NEXT:`).
|
||||
`QUEUE_TRAIN_PENDING` with the same command as `NEXT:`; `--free-timeout <s>`,
|
||||
default 2700, bounds the wait for the free tests).
|
||||
|
||||
**Screens are read from the run.** `ready --screen` and `verify --pr <n>
|
||||
--screen` read a dispatched screen's verdict from the run's own artifacts
|
||||
(`gate-binding-a<attempt>`, `report-verdict-a<attempt>`), never from a lane's
|
||||
prose, and record it in the READY receipt (`screen.verdict`): `SCREEN_VERDICT:
|
||||
#<n> run <id> GREEN|RED|NOT-RUN|INCOMPLETE [red=…] [flaky=…]` plus one
|
||||
`FLAKY:` line per rule-16 flaky case. A RED screen refuses `ready` under
|
||||
`FLAKY:` line per rule-16 flaky case. `PENDING` is a run still going,
|
||||
`UNKNOWN` one the queue cannot read, and `INCOMPLETE` a finished run that bound
|
||||
no verdict (its report job did not finish): `ready --screen` dispatches afresh
|
||||
instead of following it, `verify --screen` refuses it (`QUEUE_PROOF_MISSING`)
|
||||
and `train build` seats the pin unscreened, as for `NOT-RUN`. A RED screen refuses `ready` under
|
||||
either choice and is never re-dispatched at the same merge SHA
|
||||
(`QUEUE_SCREEN_RED`); a run that concluded success with no slice (its route
|
||||
job found the head superseded or the plan selected nothing) is `NOT-RUN`:
|
||||
@@ -605,13 +614,14 @@ unscreened with a `SCREEN: … counted as not-run` line. When GitHub's
|
||||
`refs/pull/<n>/merge` lags the PR head or is missing, `ready --screen` plans
|
||||
the screen on a scratch merge of the head onto the base, pushed as
|
||||
`screen/<pr>-<head12>` (`SCREEN_MERGE:` names it; `prune --stale` deletes it
|
||||
once the PR merged); only a real conflict with the base is
|
||||
`QUEUE_SCREEN_STALE_REF`.
|
||||
once the PR merged or closed); only a real conflict with the base (or a remote
|
||||
whose refs cannot be listed) is `QUEUE_SCREEN_STALE_REF`.
|
||||
|
||||
**Stacked tests before the gate.** `train build --prs … --dry-run --stack-tests
|
||||
[--stack-tests-command "<cmd>"]` runs each PR's new test files (added relative
|
||||
to the base, under a test directory or named `*.test.*`/`*.spec.*`) on the
|
||||
integrated prefix that includes it, T<k>, in a scratch worktree, and prints
|
||||
to the base, with a name ending in `.test`, `_test`, `.spec` or `_spec` and a
|
||||
JS or TS extension, bun's own rule, so a helper or fixture under `test/` is not
|
||||
one) on the integrated prefix that includes it, T<k>, in a scratch worktree, and prints
|
||||
`STACK_TESTS: #<pr> T<k> <n> new test file(s) pass|FAIL (<files>)` or `no new
|
||||
test files`. A failure is `QUEUE_TRAIN_STACK_RED` (nothing written, pushed or
|
||||
dispatched): the tests pass on the PR head alone only because nothing before
|
||||
|
||||
+36
-20
@@ -3818,7 +3818,9 @@ time; `gstack-ship-policy validate` prints `MIN_READER:` for exactly that.
|
||||
coordinator could misread: the working tree has uncommitted tracked changes,
|
||||
HEAD is not the PR's pushed head (read through `gh pr view`), CI at that
|
||||
exact head is not green (failed, pending or unreadable), or the pregate result
|
||||
is missing, failed or recorded on another tree (`PREGATE_STALE`).
|
||||
is missing, failed or recorded on another tree (`PREGATE_STALE`). Under
|
||||
`--dispatch-ci` it is also a dispatched workflow run that concluded red (a red
|
||||
run clears no pregate lane) or a `gh workflow run` that failed.
|
||||
|
||||
**Fix.** Commit and push, wait for CI on that head, rerun
|
||||
`gstack-pregate run --allow-repo-commands` when the tree changed, then rerun
|
||||
@@ -3908,7 +3910,8 @@ a `train` block with `min_gstack_version` on the base branch first
|
||||
|
||||
**Meaning.** A pinned PR's head repository is not the base repository. The
|
||||
train branch and its dispatches run with repository secrets, so fork work
|
||||
never rides a train.
|
||||
never rides a train. `ready --dispatch-ci` refuses a fork head for the same
|
||||
reason and dispatches nothing.
|
||||
|
||||
**Fix.** Run the printed `train build --prs <list without it>`; the fork PR
|
||||
stays on the trusted-branch path.
|
||||
@@ -3972,7 +3975,11 @@ one-PR train.
|
||||
### `QUEUE_TRAIN_PENDING`
|
||||
|
||||
**Meaning.** The train's run (free tests, the full gate or the bisect) has
|
||||
not finished, so there is no verdict yet.
|
||||
not finished, so there is no verdict yet. The same code covers a `train watch`
|
||||
that reached its timeout, `verify --pr <n> --screen` on a screen run still
|
||||
going, `verify --post-merge` on checks that have not settled, and a
|
||||
`ready --dispatch-ci` workflow run still going at its `--timeout`; each prints
|
||||
the command to rerun as `NEXT:`.
|
||||
|
||||
**Fix.** Rerun the printed `NEXT:` command later. Nothing is dispatched again
|
||||
while a run is pending.
|
||||
@@ -4110,10 +4117,14 @@ to fix this: the stamp comes only when the slot is called.
|
||||
<a id="queue-screen-stale-ref"></a>
|
||||
### `QUEUE_SCREEN_STALE_REF`
|
||||
|
||||
**Meaning.** `gstack-ship-queue ready --screen` dispatches the screen against
|
||||
GitHub's `refs/pull/<n>/merge`, and that ref is missing or still merges an
|
||||
older head than the PR's pushed head. GitHub stops recomputing the merge ref
|
||||
while the PR conflicts with the base (a CHANGELOG-only conflict after a stamp
|
||||
**Meaning.** `ready --screen` refuses with this code when the PR conflicts with
|
||||
the base beyond the CHANGELOG and the stamp files (the message lists the
|
||||
conflicting paths) or when it cannot list the remote's refs. A missing or
|
||||
lagging merge ref alone no longer refuses (see Fix). The rest of this
|
||||
paragraph is why such a ref cannot be screened directly: `ready --screen`
|
||||
dispatches the screen against GitHub's `refs/pull/<n>/merge`, and that ref can
|
||||
be missing or still merge an older head than the PR's pushed head. GitHub
|
||||
stops recomputing the merge ref while the PR conflicts with the base (a CHANGELOG-only conflict after a stamp
|
||||
counts), so a screen dispatched there checks out the old merge, sees itself
|
||||
superseded, plans 0 cases and reports success. GSTA-95 hit this on #3431:
|
||||
`ready` printed `SCREEN_DISPATCH:` as if a screen ran. `ready` now compares
|
||||
@@ -4129,10 +4140,10 @@ read (`… paid-plan artifact has expired`, `… manifest.json is unreadable`, a
|
||||
unreadable run or artifact list, an unreadable repository slug, or a READY
|
||||
whose run id is not a number) keeps the slot screened and prints
|
||||
`SCREEN: #<n> <reason>; counted as screened, unverified`; `ready --screen`
|
||||
follows such a run. When `ready` cannot list the remote's refs or fetch the
|
||||
merge ref at all, it refuses with the same code and a `could not list …` or
|
||||
`could not fetch …` message whose NEXT line says to check the remote, not to
|
||||
resolve a conflict.
|
||||
follows such a run. When `ready` cannot list the remote's refs, it refuses with
|
||||
the same code and a `could not list …` message whose NEXT line says to check
|
||||
the remote, not to resolve a conflict; a merge ref that lists but cannot be
|
||||
fetched is replaced by the scratch merge described under Fix.
|
||||
|
||||
**Fix.** Since the scratch-merge screen landed, a lagging merge ref is no
|
||||
longer a refusal: `ready --screen` builds the merge of the PR head onto
|
||||
@@ -4142,8 +4153,10 @@ base's side, the CHANGELOG merges by section), pushes it as
|
||||
`SCREEN_MERGE: scratch merge …`. The code now means a real conflict: the
|
||||
message lists the conflicting paths. Resolve those with the base branch,
|
||||
push, and run `gstack-ship-queue ready --pr <n> --screen` again. A
|
||||
CHANGELOG-only or stamp-file-only conflict never refuses. `train prune
|
||||
--stale` deletes the scratch branches of merged or closed PRs.
|
||||
CHANGELOG-only or stamp-file-only conflict does not refuse, unless the PR's
|
||||
CHANGELOG drops or renames a released heading (the message then names the
|
||||
CHANGELOG). `train prune --stale` deletes the scratch branches of merged or
|
||||
closed PRs.
|
||||
|
||||
<a id="queue-screen-red"></a>
|
||||
### `QUEUE_SCREEN_RED`
|
||||
@@ -4172,8 +4185,9 @@ the flaky cases are listed for the ledger and need no rerun.
|
||||
### `QUEUE_TRAIN_STACK_RED`
|
||||
|
||||
**Meaning.** `gstack-ship-queue train build --dry-run --stack-tests` ran a PR's
|
||||
new test files (files the PR adds relative to the base under a test directory
|
||||
or named `*.test.*` / `*.spec.*`) on the integrated prefix that includes it,
|
||||
new test files (files the PR adds relative to the base whose name ends in
|
||||
`.test`, `_test`, `.spec` or `_spec` plus a JS or TS extension, bun's own
|
||||
rule; a helper or fixture under `test/` is not one) on the integrated prefix that includes it,
|
||||
T<k> (the base plus every slot up to and including that PR), in a scratch
|
||||
worktree, and they failed. The `STACK_TESTS: #<pr> T<k> <n> new test file(s)
|
||||
FAIL (<files>): <failing assertion>` line names the files and the runner's
|
||||
@@ -4191,11 +4205,13 @@ other than `bun test`; the files are appended to the command.
|
||||
<a id="queue-post-merge-red"></a>
|
||||
### `QUEUE_POST_MERGE_RED`
|
||||
|
||||
**Meaning.** `gstack-ship-queue verify --post-merge <sha>` watched the check
|
||||
runs attached to a commit the train merged onto the base branch (the push
|
||||
workflows: free tests, the Windows subset, the main backstop) until none was
|
||||
still running, and at least one concluded `failure`, `timed_out`,
|
||||
`cancelled` or another non-success. A `neutral` or `skipped` check (the
|
||||
**Meaning.** `gstack-ship-queue verify --post-merge <sha>` (the full 40-character
|
||||
SHA) watched the check runs attached to a commit the train merged onto the
|
||||
base branch (the push workflows: free tests, the Windows subset, the main
|
||||
backstop) and its commit statuses until none was still running, and at least
|
||||
one check concluded `failure`, `timed_out`, `cancelled` or another non-success,
|
||||
or a commit status failed (the message then says a commit status, not a check
|
||||
run). A `neutral` or `skipped` check (the
|
||||
backstop superseding itself when main moved on) is counted as skipped, never
|
||||
red. The command keeps no process state: it polls gh until the checks settle
|
||||
or `--timeout` (default 2700 s) passes, prints `POST_MERGE: <sha12>
|
||||
|
||||
Reference in new issue
Block a user