madt_finish/merge masks real Gitea merge errors as a "transient flake" and auto-retries non-retryable ones #456
Labels
No labels
breaking
bug
documentation
enhancement
epic
good first issue
help wanted
refactoring
resolution/duplicate
resolution/invalid
resolution/wontfix
security
severity/critical
severity/high
severity/low
severity/medium
status/abandoned
status/blocked
status/needs-decision
status/needs-info
status/needs-verification
testing
upstream
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
sixfold-space/madtea#456
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
On a merge failure,
madt_finishandmadt_prs action=mergereport a generic message like:and auto-retry (4 attempts). But the underlying Gitea error is specific and actionable, and several are NOT retryable:
This branch is already included in the target branch. There is nothing to merge.There is no key available to sign this commit.This branch is out-of-date with the base branch.Retrying these never succeeds, and the "transient flake" relabel hides the real cause from the user.
Concrete incident
A
madt_finishreturned HTTP 500 on merge - but the merge had actually SUCCEEDED server-side (the commit and itsCloses #Ntrailers landed on the default branch; the linked issues closed). madtea reported the finish as failed. A retry then created a REDUNDANT PR for a branch already in the target. Merging that PR failed with the real error "nothing to merge", which madtea again reported as a generic "try again later" flake and retried.Asks
Landed in PR #463 - all three asks: verbatim surfacing (the real Gitea body, no "transient flake" relabel), non-retryable classification (already-included / nothing-to-merge, no-signing-key, and out-of-date-with-base break immediately, no retry), and the post-5xx landed re-check (a merge that landed server-side reports success and opens no duplicate PR; the check gates every retry).
One refinement I want your call on. I put "out-of-date with the base branch" in the non-retryable set per the list in this issue, so it now fails verbatim. But the existing behind-base 405 path returns the same verbatim cause PLUS a ReconcileSteer - the copy-pasteable update-branch-and-remerge remedy - and out-of-date has exactly that remedy: updating the branch is the fix. So today the out-of-date failure is less actionable than the behind-base one.
I recommend adding the ReconcileSteer to the out-of-date verbatim failure: keep it non-retryable (no blind retry, no silent auto-merge of a tree the local gate did not validate) but hand the caller the update-branch remedy, so it reaches parity with the behind-base path. The other non-retryable reasons (nothing-to-merge, no-signing-key) stay bare - no update remedy applies to them. Say the word and I will add it.
(The alternative - route out-of-date to auto-update-and-remerge like a transient - reverses the non-retryable classification here and would silently merge a tree the local gate did not validate. I would not, but the call is yours.)
Decided: add the ReconcileSteer remedy to the out-of-date-with-base failure, keeping it non-retryable.
The out-of-date failure now returns the verbatim Gitea cause PLUS the copy-pasteable update-branch-and-remerge block, matching the behind-base 405 path (
internal/service/workflow/merge.go, where behind-base already attaches ReconcileSteer). It stays in the non-retryable set (internal/gitea/client_errors.go): no blind retry, and no auto-merge of a tree the local gate did not validate. Nothing-to-merge and no-signing-key stay bare, since no update remedy applies to them.The three original asks landed in PR #463; this closes the one refinement. Ready to build.