Skip to content

fix: land hotfix merge on unprotected env branches#201

Merged
joshua-temple merged 1 commit into
mainfrom
fix/hotfix-automerge-unprotected
Jun 17, 2026
Merged

fix: land hotfix merge on unprotected env branches#201
joshua-temple merged 1 commit into
mainfrom
fix/hotfix-automerge-unprotected

Conversation

@joshua-temple

Copy link
Copy Markdown
Collaborator

Problem

The generated cascade-hotfix.yaml clean cherry-pick path merged with gh pr merge --auto --squash "$BRANCH". --auto calls GitHub's enablePullRequestAutoMerge mutation, which GitHub rejects when the target env branch has no protection rule (Protected branch rules not configured for this branch). Under set -e the step exited non-zero, the hotfix run failed, and the PR was left open. This breaks every adopter whose env branches are unprotected (branch protection is optional / plan-gated for OSS).

Every other PR-merge cascade emits is a plain gh pr merge --squash, which works unprotected. Only the hotfix path assumed protection.

Fix

Prefer auto-merge so required checks still gate the merge on protected branches, but fall back to an immediate squash merge when auto-merge cannot be enabled:

if ! gh pr merge --auto --squash "$BRANCH"; then
  echo "::notice::auto-merge unavailable (branch likely unprotected); merging directly"
  gh pr merge --squash --delete-branch "$BRANCH"
fi
  • Protected branch: --auto succeeds and waits for checks (unchanged).
  • Unprotected branch: --auto fails, fallback merges immediately. The hotfix lands either way.
  • The if ! guard keeps the failing attempt from tripping set -e.

The conflict-resolution path opens a PR for manual resolve and never auto-merges, so no change is needed there.

Verification

  • New unit test TestHotfixGenerator_CleanPathMergeFallback asserts the guarded --auto attempt and the direct-merge fallback. Confirmed red before the change, green after.
  • go build ./..., full go test ./... (1400 pass), golangci-lint run ./... (clean).
  • TestHotfixGenerator_Actionlint runs actionlint (with shellcheck) over the regenerated workflow; the new if/then/fi lints clean.

Note: the e2e hotfix harness reimplements apply+merge directly against gitea REST and never dispatches the generated gh pr merge shell, so the runnable proof of the emitted shell is the actionlint test plus the unit assertion. Live re-run on the unprotected 3env fleet to follow.

The clean cherry-pick path merged with `gh pr merge --auto`, which calls
GitHub's enablePullRequestAutoMerge mutation. GitHub rejects that mutation
when the target env branch has no protection rule, so the apply step exited
non-zero under set -e and left the hotfix PR open on unprotected branches.

Prefer auto-merge so required checks still gate the merge on protected
branches, but fall back to an immediate squash merge when auto-merge cannot
be enabled. The `if !` guard keeps the failing attempt from tripping set -e.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
@joshua-temple joshua-temple merged commit e6b85e1 into main Jun 17, 2026
7 checks passed
@joshua-temple joshua-temple deleted the fix/hotfix-automerge-unprotected branch June 17, 2026 04:10
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.

1 participant