fix(foreman): add payload.branchStrategy to stop stale revisions reverting merged work#1042
Conversation
…rting merged work A re-dispatch of the same issue (a review-feedback revision, or a repair re-dispatch) restored the prior attempt's branch via reviseFromBranch but never rebased it onto the current base. Its diff was computed against the old base, so opening/refreshing the PR reverted or deleted work merged since — the defilantech#1029 stale-branch overreach. Add an explicit payload.branchStrategy (enum reset|rebase, default reset): - reset (default): cut the working branch fresh from the CURRENT base, ignoring any prior attempt. A fresh issue-fix, retry, or repair re-dispatch redoes the work against latest base, so a stale branch can never drift from base and revert merged commits. - rebase: restore the prior attempt AND rebase it onto the current base (new repo.RebaseOntoBase; a conflict fails loud rather than reverting merged work), so an in-review PR revision carries its earlier commits forward on top of merged work. The WorkloadReconciler's review-feedback re-dispatch is the in-review revision path, so it now stamps branchStrategy=rebase; every other issue-fix defaults to reset. Branch ops only ever touch foreman-namespaced task branches, and the push remains force-with-lease (allowOverwrite) as the compare-and-swap backstop. Closes defilantech#1029 Signed-off-by: Jory Irving <jory.irving@stackadapt.com>
Defilan
left a comment
There was a problem hiding this comment.
Really solid, Jory, and it lines up exactly with the #1029 thread. Verified locally: RebaseOntoBase is safe (aborts + fails loud on conflict, no-op on empty upstream, injection guards consistent with the sibling helpers), the reset/rebase dispatch is correct, and backward-compat is clean (the only reviseFromBranch setter now stamps rebase, everything else defaults to reset). go build + go test ./pkg/foreman/agent/... ./api/... are green, and the real-git RebaseOntoBase tests confirm a replay onto an advanced base preserves merged work and carries the prior fix forward. Nice that it sets up the slicer repair re-dispatch to use reset for free.
One thing before it goes green: the chart CRDs are out of sync. branchStrategy landed in config/crd/bases/ but not charts/foreman/templates/crds/ — running make chart-crds && make foreman-chart-crds produces drift on both agentictasks and workloads, so the CRD Sync Check will fail. Run those and commit the chart CRD changes.
Heads up too: my #1037 adds the integrate/reconcile task kinds to the same two CRDs + agentictask_types.go, so whichever of us merges second will need a trivial rebase.
make chart-crds/foreman-chart-crds drift: branchStrategy landed in config/crd/bases but not charts/foreman/templates/crds, which the CRD Sync Check flags. Sync both agentictasks and workloads chart CRDs. Signed-off-by: Jory Irving <jory.irving@stackadapt.com>
|
Thanks for the careful review. Fixed the chart CRD drift in d5076c4 — ran Ack on #1037 — I'll take the trivial rebase on agentictask_types.go + the two CRDs if you merge that first. |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
Heads-up on the one red check — Run on Ubuntu (MicroShift via MINC, OpenShift SCC): it's an unrelated flake, not this change. It failed at |
What
Add an explicit
payload.branchStrategy(enumreset|rebase, defaultreset) that controls how an issue-fix task's working branch is cut relative to the current base, so a re-dispatch of the same issue can never revert already-merged work.Why
Fixes #1029
A re-dispatch of the same issue (a review-feedback revision, or the slicer's repair re-dispatch) restored the prior attempt's branch via
reviseFromBranchbut never rebased it onto the current base. Its diff was computed against the old base, so opening/refreshing the PR reverted or deleted work merged since — the stale-branch overreach from the issue.How
reset(default): cut the working branch fresh from the current base, ignoring any prior attempt. A fresh issue-fix, retry, or repair re-dispatch redoes the work against latest base — a stale branch can never drift from base and revert merged commits.rebase: restore the prior attempt and rebase it onto the current base (newrepo.RebaseOntoBase; a conflict fails loud rather than reverting merged work), so an in-review PR revision carries its earlier commits forward on top of merged work.WorkloadReconciler's review-feedback re-dispatch is the in-review revision path, so it now stampsbranchStrategy=rebase; every other issue-fix defaults toreset. This maps onto the reset=fresh/retry, rebase=in-review-revision split from the issue thread — a repair re-dispatch setsreset.foreman/<workload>/issue-Ntask branches (never human branches), and the push staysforce-with-lease(allowOverwrite) as the compare-and-swap backstop.CRD regenerated for both
AgenticTaskandWorkload(pipeline steps embed the payload).Checklist
repo.RebaseOntoBase(prior attempt replayed onto an advanced base preserves the merged file + carries the prior fix forward; empty-upstream no-op);setupTaskBranch(rebaserestores+rebases,resetignoresreviseFromBranchand cuts from base, missing-ref falls back)make testpasses locally — full suite green (controller envtest included) and in CI (Run on Ubuntu ✅)make lintpasses locally (0 issues)git commit -s) per DCOdescription+ Go doc comments)