fix: deduplicate managed PR comments created by concurrent Action runs#834
Merged
Merged
Conversation
GitHub Issues API has no conditional write support (no If-Match), so two concurrent runs that both see no managed comment will both call createComment, leaving a stale duplicate that subsequent runs never update or delete. Add deduplicateManagedComments() which fetches all managed comments for the user, deletes every one except the most-recently-created (highest id), and returns the survivor. updateMessage now calls this before deciding the action, and also calls it again after a successful createComment so that any duplicate added in the same race window is removed immediately. Extract applyCommentAction() to keep cyclomatic complexity inside the Biome limit and make the intent of each branch clearer.
🎉 Happy commit!
|
gh-counterPR gate
Repo dashboard
Reported by gh-counter |
Code Metrics Report
Details | | main (7382600) | #834 (03952c7) | +/- |
|---------------------|----------------|----------------|-------|
+ | Coverage | 99.1% | 99.1% | +0.0% |
| Files | 5 | 5 | 0 |
| Lines | 115 | 122 | +7 |
+ | Covered | 114 | 121 | +7 |
+ | Code to Test Ratio | 1:0.5 | 1:0.5 | +0.0 |
| Code | 1511 | 1598 | +87 |
+ | Test | 834 | 898 | +64 |
| Test Execution Time | 1s | 1s | 0s |Code coverage of files in pull request scope (100.0% → 100.0%)
Reported by octocov |
gh-build-size
Reported by gh-build-size |
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.
What changed
Added post-create deduplication to
updateMessageinsrc/github.tstoclean up managed PR comments that accumulate when two Action runs race.
New helpers
getAllManagedComments()— fetches all matching managed comments (byuser login +
COMMENT_MARKER), sorted by id ascending.deduplicateManagedComments()— callsgetAllManagedComments, deletesevery entry except the last (highest id), returns the survivor.
applyCommentAction()— extracted fromupdateMessageto keepcyclomatic complexity inside the Biome limit.
Changed behaviour
updateMessagenow:deduplicateManagedCommentsinstead ofgetManagedComment.If a previous race left more than one managed comment, the stale
duplicates are deleted before the current action is decided.
createComment, callsdeduplicateManagedCommentsagain so any duplicate created in the same window is removed
immediately.
Why
GitHub Issues API provides no conditional write mechanism (no If-Match
header). When two Action runs trigger on the same PR within milliseconds,
both call
listComments, both see no managed comment, and both callcreateComment. The second comment is then never updated or deleted byfuture runs because
find()always picks the first match.This fix cannot prevent the race (the API does not allow it), but it
resolves the stale-comment state eagerly on every subsequent run.
Verification
bun run lint— no issuesbun run build— build completebun run test— 46 passed (added 2 new tests covering thededuplication and post-create cleanup paths)
madge --circular src/— no circular dependency foundTrade-offs
listCommentscall aftercreateComment. Thisis a best-effort cleanup, not a hard guarantee; two runs that finish
their creates and re-fetches in an interleaved order could both decide
they are the winner and keep their own comment. In practice this window
is much smaller than the original race, and any remaining duplicate is
cleaned up on the very next run.
getAllManagedCommentsfetches up to 100 comments per call. PRs withmore than 100 comments could miss older managed comments, but this
matches the previous behaviour.