fix(queue): elect the duplicate-winner from live sibling state, not the stale cache#1406
Merged
Merged
Conversation
…he stale cache The duplicate-cluster winner (#dup-winner) was elected from the stored open-PR cache (listOtherOpenPullRequests). That cache lags GitHub, so a sibling closed or merged on GitHub but still cached `open` kept "winning" the cluster — the real lowest-OPEN PR was treated as a loser, given the duplicate_pr_risk blocker, and one-shot auto-closed. Reconcile the cluster's open siblings against live GitHub state before the winner is elected: re-fetch the LIVE state of just the lower-numbered overlapping siblings (the only ones that can demote this PR) and drop any no longer open, so isDuplicateClusterWinner sees ground truth. Fail-open — a sibling is dropped only on a positive non-open confirmation, and the whole path is gated behind GITTENSORY_DUPLICATE_WINNER, so flag-off is byte-identical with no extra API calls. Adds fetchLivePullRequestState; covers both reconcile arms, the new helper's branches, and the previously-uncovered linkedIssueDuplicatePullRequestsForGate non-overlap arm.
Contributor
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1406 +/- ##
=======================================
Coverage 95.34% 95.34%
=======================================
Files 192 192
Lines 20752 20770 +18
Branches 7501 7508 +7
=======================================
+ Hits 19785 19804 +19
Misses 383 383
+ Partials 584 583 -1
🚀 New features to boost your workflow:
|
3 tasks
galuis116
pushed a commit
to galuis116/gittensory
that referenced
this pull request
Jul 18, 2026
Root cause traced as far as possible: release-please's own createReleases() (the step that actually tags a merged Release PR) sometimes finds nothing to tag, and createPullRequests() then aborts every subsequent run without ever completing the tag -- confirmed live across two separate linked-versions release cycles this session (JSONbored#7127, JSONbored#7133), both requiring a manual dispatch of each publish-*.yml workflow plus manually flipping the merged PR's autorelease:pending label. Matches multiple long-open, unresolved upstream issues (googleapis/release-please#1946/JSONbored#1444/JSONbored#1406), so it isn't something fixable from this repo's config alone. Adds a reconcile-stale-releases job that runs after every release-please attempt, independent of its outputs: compares each package's committed package.json version against what's actually live on npm, dispatches that package's publish workflow whenever they disagree (the same documented human-override path, automated), and flips any merged PR's autorelease label once every package is confirmed live -- unsticking release-please's own tracking for the next run. Also cleaned up one ancient, silently-stuck instance of the exact same bug (engine v1.0.0, autorelease:pending since long before this session).
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
The duplicate-cluster winner (
#dup-winner) was elected from the stored open-PR cache (listOtherOpenPullRequests), not live GitHub state. That cache lags GitHub, so a sibling that was closed/merged on GitHub but still cachedopenkept "winning" the cluster — the real lowest-OPEN PR was treated as a loser, given theduplicate_pr_riskblocker (defaultblock), and one-shot auto-closed. This is a destructive race (audit #15).The fix reconciles the cluster's open siblings against live GitHub state before the winner is elected, in
reconcileLiveDuplicateSiblings:fetchLivePullRequestState(GET /pulls/{n}), and drop any no longer open, soisDuplicateClusterWinnersees ground truth.reReviewStoredPullRequestand thepull_requestwebhook path) beforebuildPullRequestAdvisory, so the advisory'sduplicate_pr_riskfinding and the disposition agree.GITTENSORY_DUPLICATE_WINNER; flag-off (default) is byte-identical with no extra API calls.No GitHub issue — internal review-subsystem audit finding (#15). Self-contained behavioral fix to the live-merge / one-shot-close path.
Scope
src/) only —src/queue/processors.ts,src/github/backfill.tsui:openapiregen needed)wrangler.jsoncbinding/var, no UI changeValidation
npm run test:ci— green (4454 passed | 4 skipped)npm run test:coverage— every changed line and branch covered (verified againstcoverage/lcov.info), incl. the previously-uncoveredlinkedIssueDuplicatePullRequestsForGatenon-overlap armnpm audit --audit-level=moderate— 0 vulnerabilitiesnpm run typecheck/ui:typecheck— cleanreconcile-live-duplicate-siblings.test.ts(flag-off / no-issue / no-lower-sibling / cached-closed / live-closed-drop / live-open-keep / fail-open / multi-sibling / token-mint throws+succeeds),fetch-live-pr-state.test.ts, and addedlinkedIssueDuplicatePullRequestsForGatecases.Safety