Repository navigation
Merge run post-merge steps: delete the Issue branch, close the issue, survive failures and Ctrl-C - #98
Merged
Conversation
After the Self-merge, thirdshift deletes the Issue branch on origin and closes the issue if the merge did not, with a comment naming the PR and Base branch. Either step failing is a warning naming the manual fix; the Run still exits 0 as merged. An interrupt after the merge no longer matters, and a merge that reports failure but went through counts as a merge. The fake gh gains issue close, on-merge hooks and failure injection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Decide whether the merge closes the issue from GitHub's own rule (base is the default branch and the PR links the issue for closing), not from the issue's state a moment after the merge, which GitHub updates late. - Count a failed gh pr merge as a merge only if the PR merged at the watched head, inside github::merge. - Retry a post-merge step once if Ctrl-C killed its git or gh. - Match the Issue branch's exact ref on origin, keeping the push error. - Take the Base branch from the PR; tidy the test helpers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main's before-merge `gh fake on-merge <times>` hook keeps its name; this branch's after-merge hook becomes `gh fake after-merge`. A successful Self-merge in the new retry loop runs the post-merge steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Share one `pr_view` helper across the four `gh pr view` calls. - The manual issue-close hint says to run it only if the issue is still open, since thirdshift couldn't tell, and shell-quotes the comment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
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
A Self-merge now ends with the Issue branch gone from
originand the issue closed. Once the merge has happened, nothing turns the Merge run into a Failed run. It builds on main's retry loop for failed merges (#97).implement repair_loop.run → loop ensure_pr_ready_and_mergeable if interrupted → Failed run github::merge(head) + gh failed but PR merged at exactly `head` → still a merge + merged → after_merge # never fails the Run, ignores Ctrl-C + worktree.delete_from_origin # already gone (GitHub auto-delete) → fine + close_unless_merge_does + base is default branch && PR links the issue for closing → leave it to GitHub + issue still open → gh issue close --comment "Closed by #<pr>, merged into <base> by a thirdshift Merge run." + each step: retried once if Ctrl-C killed its git/gh + on failure: error line, then `warning: …, so <do> it by hand: <command>` + → Ok(pr.url): exit 0, URL on stdout, "PR <url> is merged" failed → round_after_failed_merge (main, unchanged)The fake
ghgains:issue close --commentandrepo view --json defaultBranchRefheadRefOidandclosingIssuesReferencesonpr viewgh fake after-merge,gh fake fails '<cmd> <sub>'andgh fake issue <n> <state>Main's before-merge
on-merge <times>hook keeps its name.github.rsgets a sharedpr_viewhelper for its fourgh pr viewcalls. The README documents the post-merge steps and the success-with-warnings outcome.Evidence
tests/merge_run.rsagainst the first cut of the code): the tests for branch deletion, issue close, warnings and Ctrl-C after the merge failed, e.g.origin_log("issue-7") == None→left: Some(["Add feature", "Initial commit"]).After (branch merged with current main):
cargo testpasses every suite, withmerge_runat 22/22, andcargo clippy --all-targetsandcargo fmt --checkare clean. The suite covers:develop, thirdshift closes the issue with the comment. Intomain, gh closes it and thirdshift makes nogh issue closecall, even when GitHub hasn't closed it yet when thirdshift checks.warning:line naming the manual commandgh pr mergethat errors after merging at the watched head counts as a merge. If it merged at another head, the Run is a Failed run.mainrather than readingissue-7on origin, since that branch is deleted.Merge Danger
Door: two-way
The code reverts cleanly. Runs made while it's live delete remote Issue branches and post issue comments. Those are one-way for the repos they touch, but they're what the issue asked for.
Blast Radius: Merge-runs
Only
thirdshift mergechanges. A plain Run never reaches this code. Each successful merge makes up to 3 extraghcalls.Unaddressed findings
Standards
github::mergeanddelete_from_originshare a "try, then check whether it happened anyway" shape. Skipped. There are only two copies, in different modules, and each checks something different.github::close_issue/delete_from_origin(Shotgun Surgery). Skipped. The hand-run commands differ on purpose: no--no-verify, and quoting for a shell. Deriving them from the internal calls would tie two different audiences together.github.rs(Feature Envy). Skipped. It's Self-merge policy built from twogithubqueries.github.rsstays a thinghwrapper, and the policy lives in one small function inrun.rs.&str/Stringfor commit SHAs and branches (Primitive Obsession). Skipped. It matches the rest of the codebase, and a SHA type belongs in its own change.merge_into_develop(&scenario, "")passes an emptythen. Skipped. The reviewer called it harmless, and the parameter is used by the other callers.Spec
retry_if_interrupted, and the fake's extra hooks. Kept. They serve "Ctrl-C decides the outcome by whether the PR merged" and "after it, thirdshift finishes these steps", and the tests need the hooks.git/gh, since they share thirdshift's process group. Partly addressed. A step that fails while the Run is interrupted is retried once, and both steps are idempotent. Children don't get their own process group, because that would also stop Ctrl-C from killing a hungghbefore the merge. The test harness signals only thirdshift, so the terminal case isn't tested.Addressed from this round: the shared
pr_viewhelper. The issue-close warning now says to close it only if it is still open, because thirdshift may not have been able to tell, and it shell-quotes the comment.Closes #92
🤖 Generated with Claude Code