fix(ci): resolve triggered-integration-test base SHA live from refs/heads/main - #62
Merged
nerdalert merged 2 commits intoAug 14, 2026
Conversation
…eads/main The "Verify PR merge checkout" step in triggered-integration-test.yaml compared the PR merge ref's base parent against `base_sha`, which was read from `gh api pulls/<n>` -> `.base.sha`. That REST field is only refreshed by GitHub on PR synchronize events (e.g. a push to the head branch) and can lag main's actual tip by hours once a PR sits idle while main advances. Meanwhile `refs/pull/<n>/merge` is kept continuously current against main, so the two values can disagree even with no race at all, failing the check with "Checked-out merge does not combine the expected base and PR head" (observed on run 31811278059 testing PR praxis-proxy#59: cached base_sha pointed at a main commit that was already superseded by 282a337 seven hours earlier). Resolve `base_sha` live via `git ls-remote refs/heads/main` in the same "Resolve source" step that resolves the merge ref, instead of trusting the cached PR resource field, so both values are re-derived consistently with each other. Signed-off-by: Jordi Gil <jgil@redhat.com>
Contributor
Author
|
@nerdalert PTAL |
praxis-bot
reviewed
Aug 14, 2026
praxis-bot
left a comment
There was a problem hiding this comment.
PR Review
Summary: Fixes spurious CI verification failures by resolving base_sha live from refs/heads/main via git ls-remote instead of relying on the GitHub REST API's .base.sha field, which can lag by hours.
Overall: Correct fix for a real problem. The change is well-motivated, well-documented, and preserves all existing safety checks. One suggestion to further tighten the consistency guarantee.
| Severity | Count |
|---|---|
| Medium | 1 |
Addresses grid#62 review feedback (praxis-bot): the merge-ref and refs/heads/main resolutions were two sequential `git ls-remote` calls, leaving a window for main to advance between them -- the same class of staleness bug this PR fixes, just with a much narrower race window. Combine both into a single `git ls-remote` invocation so both SHAs are resolved from the same server-side view, making them atomically consistent with each other instead of merely "re-derived the same way." Signed-off-by: Jordi Gil <jgil@redhat.com>
nerdalert
approved these changes
Aug 14, 2026
nerdalert
pushed a commit
that referenced
this pull request
Aug 16, 2026
…st (#67) resolve-source's "Verify PR merge checkout" step compares the checked-out merge commit's parents against a live-resolved base_sha (fixed in #62), but the checked-out commit itself still came from GitHub's refs/pull/<n>/merge -- a commit GitHub computes and caches asynchronously. Per GitHub's own changelog ("Changes to test merge commit generation for pull requests", 2026-02-19), that ref is only regenerated on a push to the PR branch, a merge-base change, or a 12h max-age timer, and viewing the PR no longer forces a refresh. Live reproduction against PR #63 right after #62 merged: the ref stayed stale for 49+ minutes, including after an explicit mergeable recheck, which would fail "Verify PR merge checkout" with a "base changed" error for a transient, unrelated-to-the-PR reason (see grid#66). Stop depending on that ref. resolve-source already resolves head_sha (PR API) and base_sha (live refs/heads/main) as pinned commit SHAs -- construct the merge locally from those two SHAs with `git merge --no-ff` instead, in both resolve-source (to fail fast on real conflicts before the 120-minute glb-e2e job) and glb-e2e's checkout (to get the actual tested tree). Pinning author/committer identity and date makes the merge commit fully deterministic, so both jobs independently arrive at the identical SHA despite running on separate runners with no shared git state -- verified live: two independent fresh-clone reconstructions of PR #63's merge (base 7ebabdb.., head 50720c9..) produced the exact same commit SHA (6df4a70a..). fetch-depth changes from 2 to 0 (full clone) for the shared checkout step, since `git merge` needs enough history to find the true merge-base between base_sha and head_sha, which a shallow clone cannot guarantee for a PR that is many commits behind main. Fixes grid#66 Signed-off-by: Jordi Gil <jgil@redhat.com>
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.
Summary
triggered-integration-test.yaml's "Verify PR merge checkout" step compares the PR merge ref's base parent againstbase_sha, previously sourced fromgh api pulls/<n>→.base.sha. That REST field only refreshes on PR synchronize events (e.g. a push to the head branch), so it can lagmain's actual tip by hours once a PR sits idle whilemainadvances — whilerefs/pull/<n>/mergestays continuously in sync withmain. This mismatch fails the check withChecked-out merge does not combine the expected base and PR headeven with no genuine race.base_shapointed at amaincommit that had already been superseded ~7 hours earlier.base_shalive viagit ls-remote refs/heads/main, in the same "Resolve source" step and right alongside therefs/pull/<n>/mergeresolution, instead of trusting the cached PR resource field, so both values are derived consistently with each other.Test plan
actionlintclean on the modified workflowyamllintshows no new warnings (only pre-existing line-length warnings across the file)make lint(clippy + fmt + machete) passes locallyTriggered Integration Testagainst an open PR to confirm "Verify PR merge checkout" now passes