Skip to content

feat(promote): rejoin and clean up diverged envs on inbound promotion - #105

Merged
joshua-temple merged 1 commit into
mainfrom
feat/hotfix-rejoin-lifecycle
Jun 11, 2026
Merged

joshua-temple merged 1 commit into
mainfrom
feat/hotfix-rejoin-lifecycle

Conversation

@joshua-temple

Copy link
Copy Markdown
Collaborator

Problem

A hotfix diverges an environment onto an env/<name> integration branch with its own hotfix tag and release draft. Nothing yet ends that divergence: when a normal promotion brings a containing trunk SHA into the env, the divergence fields, branch, tags, and drafts were left behind, and there was no way to spot orphan env/* branches.

Fix

When a promotion into a diverged environment finalizes (the preflight patch-containment gate having already passed), the env rejoins trunk:

  • Clear ref / base_sha / patches on that env's state.
  • Delete the env/<env> integration branch on the remote.
  • Delete the hotfix tags for that base (vX.Y.Z-rc.N.hotfix.M) and their release drafts. The RC-shaped cleanup deliberately cannot see these, so they are collected explicitly.

The cleanup is gated on the env having been diverged and is injected through a LifecycleCleaner with a no-op default, so a normal promotion into a non-diverged environment touches none of the new logic. A new cascade status consistency subcommand flags env/* branches that have no matching manifest divergence (orphan integration branches).

Supporting internal/git helpers added: DeleteRemoteBranch, DeleteRemoteTag, ListRemoteBranches (all idempotent on already-absent refs).

Verification

  • go build ./...
  • go test ./... (1131 passing, 20 packages)
  • go test -race ./internal/promote/ ./internal/hotfix/ ./internal/git/ ./internal/status/
  • golangci-lint run ./internal/promote/... ./internal/release/... ./internal/hotfix/... ./internal/status/... (clean)

Coverage: focused unit tests for rejoin field-clearing, branch deletion, tag/draft cleanup, other-env preservation, the non-diverged negative path, and the orphan-branch consistency check, plus a full-lifecycle integration test against a real git repository and a release-stub server.

The act/gitea hotfix e2e scenarios (including rejoin/cleanup) are owned by the e2e harness unit and are intentionally deferred here; this PR's bar is unit plus scratch-repo plus release-stub integration coverage. Confined to internal/promote, internal/git, internal/hotfix, internal/status; internal/generate is untouched.

When a promotion into a diverged environment passes the patch-containment
gate and finalizes, the environment rejoins trunk: clear ref/base_sha/patches,
delete the env/<env> integration branch, and remove the hotfix tags and release
drafts minted for that base. Add a status consistency check that flags env/*
branches with no matching manifest divergence (orphan integration branches).

Cleanup is gated on prior divergence and injected through a no-op LifecycleCleaner,
so a normal promotion into a non-diverged environment touches none of it. Adds
git helpers for remote branch/tag deletion and remote branch listing.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
@joshua-temple
joshua-temple merged commit f76a0e8 into main Jun 11, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant