Fix pulls stuck open after a missed close webhook - #501
Draft
probablyian wants to merge 1 commit into
Draft
probablyian wants to merge 1 commit into
probablyian wants to merge 1 commit into
Conversation
A closed PR can stay on the board forever. Pulldasher finds out a pull closed from GitHub's pull_request webhook. If that delivery is lost, the pull's row keeps state 'open' until something else refreshes that pull. Nothing does on its own. The startup refresh only lists the pulls GitHub reports as open, and a closed pull is never in that list. https://github.com/iFixit/pulldasher/blob/f924c742c208c2e52ce568b4f0a4998c46693a9c/app.js#L96-L99 https://github.com/iFixit/pulldasher/blob/f924c742c208c2e52ce568b4f0a4998c46693a9c/lib/git-manager.js#L165-L171 On 2026-09-11 the board showed 312 open pulls, and 4 of them were already closed on GitHub, all on 2026-08-28 (times in UTC): iFixit/ops#765 merged 03:38 iFixit/ops#696 merged 03:51 iFixit/DocHarvestor#242 merged 03:53 iFixit/ifixit#64052 closed 16:27 I can't read the server logs. A pulldasher container on the host started at 17:35 that day, and the next pull to close after that (iFixit/fixbot#3276, 17:43) isn't stuck. Now openPulls() ends by loading every pull the DB holds as open and refetching each one the listing left out, which saves its real state. It skips repos whose listing failed, since a failed listing says nothing about which of their pulls closed. It runs once at startup, and from bin/refresh-open-pulls, which calls the same function. When nothing is stale it adds one DB query and no GitHub calls. Solutions considered: 1. Also re-check every hour. That clears a stuck pull without waiting for a restart; we went with startup only. 2. Schedule bin/refresh-all-pulls. It lists every pull ever opened in each repo, 36,659 in ifixit alone. Note: this doesn't cover a pull that closes while the startup refresh is still working through its listing. The refresh saves the state it listed, and DBPull.save() is a plain REPLACE, so if that write comes after the close webhook's write, the pull is open again. Claude-Session: https://claude.ai/code/session_01Jd4HCBx9fmiVVyuziBg1HQ
Member
Author
|
@jarstelfox I found one of my closed pulls listed in pulldasher and this was the result of the investigation. Any concerns with these changes? |
Member
|
@probablyian The only concern is I haven't merged #486 which is what cominor has been running |
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.
🤖
Closed PRs can stay on the board forever. Pulldasher finds out a PR closed when GitHub sends it a notification. If that notification is missed, for example while pulldasher is down, the PR stays open on the board. Restarting doesn't fix it, because the startup refresh only asks GitHub for open PRs.
On 2026-09-11 the board listed 312 open PRs, and 4 of them had closed on GitHub on 2026-08-28, including iFixit/ifixit#64052 under Dev Blocked. Now startup also re-checks each PR the database still has as open that GitHub didn't list, so those 4 leave the board once pulldasher restarts with this change.
Summary
app.jsfinishes the open-PR list,openPulls()loads every pull the DB holds as open and refetches the ones GitHub didn't list.bin/refresh-open-pulls: calls the same function, so running it by hand clears stuck pulls too.This doesn't cover a pull that closes during the startup refresh, which can be saved back as open; the commit message explains why. If loading open pulls from the DB fails,
bin/refresh-open-pullslogs it and still exits 0.The 4 stuck pulls (all closed 2026-08-28, times in UTC)
QA
npm teston Node 24 and confirmtest/stale-open-pulls.test.jspasses. CI only runs lint and build.https://claude.ai/code/session_01Jd4HCBx9fmiVVyuziBg1HQ