feat(merge_requests): add CancelAutoMerge

With CancelMergeWhenPipelineSucceeds, Go callers cannot tell if anything was cancelled. GitLab answers that endpoint with a small status object instead of the merge request. It also returns 201 when the merge request was not set to auto-merge. So the method returns an empty MergeRequest and no error in both cases.

GitLab 19.5 adds a new endpoint for this (gitlab-org/gitlab!255702 (merged)), and I added MergeRequests.CancelAutoMerge for it. It returns the merge request after the cancel. When there is no auto-merge to cancel, it returns an error with status 409. When the user is not allowed to cancel it, the status is 403.

API docs: https://docs.gitlab.com/api/merge_requests/#cancel-auto-merge

CONTRIBUTING says an issue is not needed for an MR like this, so I did not open one.

  1. I marked CancelMergeWhenPipelineSucceeds as deprecated ("in GitLab 19.5, use CancelAutoMerge instead"). GitLab deprecates the old route in the same release (gitlab-org/gitlab!255704 (merged)). Callers who still use it for GitLab before 19.5 will see a staticcheck warning.
  2. The old method works the same as before. I only fixed its doc comment. It said GitLab returns 406 when the merge request is not set to auto-merge, but GitLab returns 201 with an error status.

!3063 (closed) also changes MergeRequestsServiceInterface, so whichever MR lands second will conflict in the interface and its mock. Regenerating the mock fixes it.

How I tested

The endpoint changes a merge request, so I did not call it on gitlab.com. Instead I wrote a small Go program with a local test server that answers like the Rails code in gitlab-org/gitlab!255702 (merged). In the fake server, !1 is set to auto-merge and !2 is not.

On main, the program does not compile:

c.MergeRequests.CancelAutoMerge undefined (type gitlab.MergeRequestsServiceInterface has no field or method CancelAutoMerge)

On this branch:

server got: POST /api/v4/projects/group/app/merge_requests/1/cancel_auto_merge
CancelAutoMerge(!1): iid=1 title="Add feature" merge_when_pipeline_succeeds=false
server got: POST /api/v4/projects/group/app/merge_requests/2/cancel_auto_merge
CancelAutoMerge(!2): err=POST http://127.0.0.1:33331/api/v4/projects/group%2Fapp/merge_requests/2/cancel_auto_merge: 409 {message: 409 Conflict: Can't cancel the automatic merge} conflict=true
server got: POST /api/v4/projects/group/app/merge_requests/2/cancel_merge_when_pipeline_succeeds
CancelMergeWhenPipelineSucceeds(!2): err=<nil> iid=0

The last line is the old method on the same !2: no error and an empty merge request.

I added unit tests for the 201 case and the 409 case. The 409 test checks that HasStatusCode(err, http.StatusConflict) is true. I also added a test for the old method: when GitLab answers 201 with {"status":"error"}, it returns no error and an empty merge request.

$ go test -count=1 -run 'CancelAutoMerge|CancelMergeWhenPipelineSucceeds' -v .
--- PASS: TestCancelAutoMerge_Conflict (0.00s)
--- PASS: TestCancelMergeWhenPipelineSucceeds_ErrorStatus (0.00s)
--- PASS: TestCancelAutoMerge (0.00s)
PASS
ok  	gitlab.com/gitlab-org/api/client-go/v3	0.015s

gofumpt -l on the changed files, go build ./... and go vet . ./testing printed nothing. After rebasing on main, I ran the mockgen line for MergeRequestsServiceInterface again, and the mock had no diff.

The rest runs in the pipeline.

Implemented with AI assistance; I reviewed and tested the changes.

Edited by Hamza Hassanain

Merge request reports

Loading
Loading