Skip to content

fix: drive hotfix finalize via trigger-capable state token merge#202

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

fix: drive hotfix finalize via trigger-capable state token merge#202
joshua-temple merged 1 commit into
mainfrom
fix/hotfix-finalize-trigger

Conversation

@joshua-temple

Copy link
Copy Markdown
Collaborator

Problem

The generated hotfix workflow gates its FINALIZE chain (context, build, deploy, finalize) on pull_request: closed into env/*. The apply job merged the clean cherry-pick resolution PR with gh pr merge --auto --squash under the default GITHUB_TOKEN. GitHub completes auto-merge as github-actions[bot], and merges authored by that token do not emit pull_request/push events (recursion suppression). So the finalize chain never ran and state.<env> was never recorded after any automated hotfix merge. The previous direct-merge fallback under GITHUB_TOKEN had the identical gap.

Fix

Merge the clean resolution PR in a dedicated step authenticated with the configured state token (config.GetStateToken(), the same trigger-capable token already used for state-write commits). A state-token-authored merge emits pull_request: closed, so the finalize chain runs. The step polls PR mergeability before merging, so a protected env branch with a required status check still gates the merge until the check is green; an unprotected branch reports mergeable on the first poll and merges immediately (subsuming the old fallback). On timeout it fails loudly. The conflict path (human merges via UI) is unchanged.

When no state_token is configured it defaults to GITHUB_TOKEN, documented in the step comment as the case where finalize will not fire; operators needing post-hotfix finalize must configure a trigger-capable token.

Verification

  • go build ./..., go test ./... (23 packages), golangci-lint run ./... all green.
  • TDD: failing test first (TestHotfixGenerator_CleanPathPATMerge asserting the merge step carries the state token, polls mergeability, and no longer uses gh pr merge --auto), then implementation to green.
  • e2e: the gitea-based harness cannot reproduce GITHUB_TOKEN trigger-suppression, so this is covered by generator-level assertions rather than a full e2e run.

The generated hotfix workflow merged the clean-cherry-pick resolution PR
with gh pr merge --auto under the default GITHUB_TOKEN. GitHub completes
auto-merge as github-actions[bot], and merges authored by that token do
not emit pull_request events, so the pull_request(closed) finalize chain
never ran and the target environment state was never recorded after an
automated hotfix.

Merge the clean resolution PR in a dedicated step authenticated with the
configured state token (the same trigger-capable token used for state
writes). The step polls PR mergeability before merging, so a protected
env branch with a required status check still gates the merge until the
check is green, and an unprotected branch merges on the first poll. A
state-token-authored merge emits pull_request(closed), so context,
build, deploy, and finalize run.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
@joshua-temple joshua-temple force-pushed the fix/hotfix-finalize-trigger branch from 4c72a20 to 1a2bf8c Compare June 17, 2026 06:39
@joshua-temple joshua-temple merged commit 6fa9c90 into main Jun 17, 2026
9 checks passed
@joshua-temple joshua-temple deleted the fix/hotfix-finalize-trigger branch June 17, 2026 12:52
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