Skip to content

fix(reset): retry reset push on non-fast-forward, re-applying the baseline - #361

Merged
joshua-temple merged 1 commit into
mainfrom
fix/reset-push-nonff-retry
Jun 25, 2026
Merged

joshua-temple merged 1 commit into
mainfrom
fix/reset-push-nonff-retry

Conversation

@joshua-temple

Copy link
Copy Markdown
Collaborator

Problem

cascade reset --state --push did a plain git push with no retry, so a concurrent write to main rejected it non-fast-forward. This surfaced as the keystone failure in the 4env validation-fleet lifecycle, whose first step seeds dev state via reset --push; rollback and merge_queue then failed downstream because state never seeded. Every other state writer (orchestrate, promote, finalize) already self-heals via a fetch/reset/reapply retry loop; reset was the one path missing it.

Fix

On a rejected push, commitAndPush() now resolves the current branch, fetches and hard-resets onto origin, re-parses the freshly fetched manifest so trunk-owned config survives, re-applies the state baseline (reset still wins on the state and latest-release sections), recommits, and retries. Bounded at 3 attempts with a 2s backoff, all git scoped to the repo path. DryRun, no-push, and no-change paths are unchanged.

Test

TestCommitAndPush_RecoversFromNonFastForward: a second clone pushes a concurrent promote that advances origin/main, so the reset's plain push is rejected non-fast-forward; asserts reset self-heals and origin HEAD carries neither the seed nor the concurrent writer's state while trunk config survives. Red before, green after, passes under -race.

Verification

go build ./...; full go test ./... (1776 pass); golangci-lint run ./internal/reset/... clean.

…eline

cascade reset --state --push did a plain git push with no retry, so a concurrent write to main rejected it non-fast-forward (observed as the keystone failure in the 4env validation-fleet lifecycle, which seeds state via reset --push). Every other state writer already self-heals via fetch/reset/reapply; reset was the gap. On rejection the push now resolves the branch, fetches and hard-resets onto origin, re-parses the freshly fetched manifest so trunk-owned config survives, re-applies the state baseline, recommits, and retries (bounded 3 attempts, 2s backoff). Reset still wins on the state and latest-release sections. DryRun, no-push, and no-change paths are unchanged.

Signed-off-by: Joshua Temple <joshua.temple@stablekernel.com>
@joshua-temple
joshua-temple force-pushed the fix/reset-push-nonff-retry branch from 29ac23f to 3d9bfe1 Compare June 25, 2026 19:16
@joshua-temple
joshua-temple enabled auto-merge (squash) June 25, 2026 19:17
@joshua-temple
joshua-temple merged commit f09da24 into main Jun 25, 2026
13 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