Skip to content

feat: add 'gs ci merge-guard' to block out-of-order stacked PR merges#1153

Open
ed-irl wants to merge 4 commits into
ed-irl/restack-options-paramfrom
ci-merge-guard
Open

feat: add 'gs ci merge-guard' to block out-of-order stacked PR merges#1153
ed-irl wants to merge 4 commits into
ed-irl/restack-options-paramfrom
ci-merge-guard

Conversation

@ed-irl

@ed-irl ed-irl commented May 12, 2026

Copy link
Copy Markdown
Collaborator

Adds a gs ci merge-guard <number> command for forge CI/CD pipelines that fails when a change request's base branch is not trunk, preventing out-of-order merges in a stacked PR workflow.

merge-guard command

gs ci merge-guard <number> resolves the change, detects its trunk, and exits non-zero if the base branch is not trunk. Trunk is detected from the git-spice navigation comment on the PR, or overridden with --trunk. Unmanaged PRs (no navigation comment) are allowed through by default; --all blocks any PR whose base is not trunk. The new ci command group is registered under a CI group in the CLI.

Trunk metadata in navigation comments

To support detection, the navigation comment now embeds the trunk branch name via a trunk marker (<!-- gs:trunk main -->, or the Markdown link form for forges that use it). generateStackNavigationComment and updateNavigationComments take the trunk name, threaded through from h.Store.Trunk() in the submit handler. ExtractTrunkFromComment parses either marker form back out, and the previously unexported _navCommentRegexes is exported as NavCommentRegexes so merge-guard can reuse it to find navigation comments.

Tests

Unit tests cover ExtractTrunkFromComment (HTML, Markdown, missing, and full-comment round-trip) and the updated nav-comment generation. Script tests cover merge-guard for safe, blocked, deep-stack, --trunk override, unmanaged/--all, already-merged, closed, and not-found cases. Existing nav-comment golden files are updated to include the trunk marker.

@ed-irl

ed-irl commented May 12, 2026

Copy link
Copy Markdown
Collaborator Author

@ed-irl ed-irl requested a review from abhinav May 12, 2026 12:59
@abhinav abhinav force-pushed the ci-merge-guard branch 2 times, most recently from 2488f59 to 6391910 Compare May 23, 2026 22:05
@abhinav abhinav force-pushed the ci-merge-guard branch 3 times, most recently from 1b2630b to b25aab5 Compare May 31, 2026 19:53
Base automatically changed from branch-merge to main May 31, 2026 20:16
@abhinav

abhinav commented Jun 3, 2026

Copy link
Copy Markdown
Owner

@ed-irl is this intended as a guard in the merge command?
I don't think we need something like that?
merge only merges things that have trunk as base.
The original implementation had a bug where it would only guard the first branch in the stack.
Merged version fixes that.

@ed-irl ed-irl force-pushed the ci-merge-guard branch 2 times, most recently from 73e4a70 to 992b28b Compare June 15, 2026 09:51
@ed-irl ed-irl changed the title ci: add merge-guard command to block out-of-order stacked PR merges feat: add worktree management commands, per-worktree trunks, and worktree-aware filtering Jun 19, 2026
@ed-irl ed-irl changed the title feat: add worktree management commands, per-worktree trunks, and worktree-aware filtering feat: add 'gs ci merge-guard' to block out-of-order stacked PR merges Jun 19, 2026
ed-irl and others added 3 commits June 23, 2026 11:38
Introduces restack.Options{AutoResolve} and threads an opts *Options
parameter through the high-level restack entry points (RestackBranch,
RestackStack, RestackDownstack) and the merge/sync RestackHandler
interfaces, with all current callers passing nil.

This is foundational plumbing for the restack auto-resolve feature.
Landing it on a branch below the consuming stacks lets every branch
inherit the 3-arg signature, rather than the signature change living
on a branch parallel to its callers.
Add 'gs ci merge-guard' command that checks whether a PR is safe
to merge by verifying its base branch is trunk. Trunk is detected
from a new metadata marker embedded in navigation comments.

- Embed trunk metadata in nav comments (<!-- gs:trunk <name> -->)
- Export NavCommentRegexes and ExtractTrunkFromComment from submit
- Add --trunk override and --all flag for unmanaged PRs
- Wire forge.Repository as Kong singleton provider
@ed-irl

ed-irl commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator Author

@abhinav no, this is meant to be run in a Github action. This prevents people from hitting the "merge" button in github (or advises against it via a failed check anyways) if the target branch isn't the repo main branch.

@abhinav

abhinav commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Okay, I can see the argument for guarding against human error with an optional CI integration.

@ed-irl ed-irl changed the base branch from main to ed-irl/restack-options-param June 24, 2026 01:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants