Repository navigation
Fix the base fetch so a rewind cannot abort the job (#807) - #25
Merged
Merged
Conversation
`git fetch origin main:refs/remotes/origin/main` without `+` only updates the ref as a fast-forward. actions/checkout leaves that ref at the tip it saw, so a push whose base is not a descendant of it made the step die with `! [rejected] ... (non-fast-forward)` before lint and the suite ran. Fetch with an explicit force refspec instead. The fetch still fails loudly when the base cannot be fetched, and the merge-base and rev-parse checks stay, so the arch-docs check never runs against an unverified base. `.github/scripts/fetch-base.test.mjs` reads the real step out of the action and runs it against a scratch repository: a base older than the checkout ref must not abort, a base that cannot be fetched must fail, and the refspec must stay forced.
Birfy
force-pushed
the
fix/807-fetch-base-refspec
branch
from
October 23, 2026 05:11
265ec44 to
717d635
Compare
Owner
Author
|
Verdict: PASS at 717d635 Ran:
What I checked:
Non-blocking:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reproduce
At
61a6af6f, onBirfy/FlyBot: a push tomainkilled theFetch origin/main for arch-docs checkstep of.github/actions/flybot-tests/action.ymlbefore lint and the suite ran (run39898972351, job120235871280):Local reproduction of the same ordering, no network: bare
originwithAthenBonmain; depth-1 clone (what checkout leaves behind,refs/remotes/origin/mainatB);mainmoved back toA; then the step's fetch. Unforced, it is refused andset -euo pipefailaborts the job:Forced, the same step completes in 235 ms and resolves the base to the commit it fetched:
What changed
.github/actions/flybot-tests/action.yml: the base fetch is nowgit fetch --no-tags --depth=1 origin +main:refs/remotes/origin/main, with a three-line comment saying why the+is required. Nothing else in the step moves:set -euo pipefailstays, the--deepen/--unshallowfallbacks stay, the fetch is not wrapped in|| true, andgit merge-base origin/main HEADplusgit rev-parse --verify origin/main^{commit}still verify the base beforearch-docsuses it..github/scripts/fetch-base.test.mjs(new): the check the issue asks for, run by the existingnode --test ".github/scripts/*.test.mjs"step. It reads the actualrun:block out of the action (no copy of the command in the test) and runs it as bash in a scratch repository. Three tests: the refspec stays forced and the fetch is not swallowed while both verification lines stay; a base older than the checkout ref does not abort the step and the resolved base is the fetched commit; a base that cannot be fetched fails the job instead of passing on the stale ref.git fetchcall sites:action.yml:50-51(--deepen) and:54(--unshallow, thenorigin mainas an argument) never update a named ref — they writeFETCH_HEADonly — so there is no ref-forwarding risk there.live-e2e.yml:35andnightly.yml:36usefetch-depth: 0and no fetch of their own. Repository-wide grep forgit fetchfinds no other ref-updating call.What I ran
At this tip
717d63547308931e605c77be49093d026833945d, one commit onmain10e26bb6(diff:action.yml+4/−1,fetch-base.test.mjs+110):node --test .github/scripts/fetch-base.test.mjs→ 3/3 pass.node --test ".github/scripts/*.test.mjs"(git onPATH) → 245/245 pass, 0 skipped.node .github/scripts/testing-layers.mjs --check→319 test file(s) in 12 workflow(s), every test file and workflow classified; no manifest edit was needed because.github/scripts/*.test.mjsalready covers the new file.node .github/scripts/changelog.mjs check→6 fragment(s) … are well formed(no fragment added: this changes no user-visible behaviour).Test, run 39904363604): all 9 checks success,tests-okgreen. In theubuntu-latestlog the fixed step isFetch origin/main for arch-docs check→ success,* [new branch] main -> origin/main, then base10e26bb6eabd0a8abf9fa2520dd3446160e6cc9b, and the job continues intoLint(green) and the suite.package: "Tests of the repo scripts (risk tier, labels)" and "Lint the workflows (actionlint)" both success;plugins (social),plugins (tree),plugins (timeline)success.Red without the source change
Each kill condition from the issue, applied to the action and run against the new test:
main:refs/remotes/origin/main→ 1 pass / 2 fail:the refspec needs+: checkout leaves the ref at the tip, so an older base is a non-fast-forward, and the runtime test aborts with the verbatim! [rejected] main -> origin/main (non-fast-forward).+main:… || true→ 1 pass / 2 fail:a failed base fetch must fail the job, not be swallowed, and the missing-base test fails withthe step must fail when the base cannot be fetched— with|| truethe step passes against the stale ref, which is the failure mode the issue calls worse than red.git merge-base origin/main HEAD >/dev/nullandgit rev-parse --verify origin/main^{commit}→ 2 pass / 1 fail:the base must stay verified.Not run
actionlintlocally: this machine cannot reachgithub.com:443, so the pinned1.7.7release cannot be downloaded here. It ran in fork CI at this tip (step 12, success), which is the evidence used above.corelint,build-client --check, plugin suites: untouched paths, no code change undercore/orplugins/.Risk
refs/remotes/origin/mainwhen the run's base is older than the ref checkout left behind. That ref is used in this job only by thearch-docscheck (merge-base, then its owndiffagainstorigin/main), so what the check needs is exactly the fetched base — and the existingmerge-base/rev-parselines still refuse a base that does not containHEAD, and a missing base still fails the job.mainis genuinely force-pushed backwards, the base fetch now succeeds where it used to abort; the followinggit merge-base origin/main HEADis what decides, so the outcome is a real red inarch-docs, not a silent pass.packagejob, about 0.6 s total.Fixes ThinkFlowLab#807
Tip SHA: 717d635