Skip to content

Commit 54fa71f

Browse files
committed
fix: skip MR comment for non-permission errors
Signed-off-by: ab-ghosh <[email protected]>
1 parent 565420c commit 54fa71f

File tree

2 files changed

+86
-17
lines changed

2 files changed

+86
-17
lines changed

pkg/provider/gitlab/gitlab.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,12 +318,25 @@ func (v *Provider) CreateStatus(_ context.Context, event *info.Event, statusOpts
318318
v.Logger.Debugf("created commit status on source project ID %d", event.TargetProjectID)
319319
return nil
320320
}
321-
if _, _, err2 := v.Client().Commits.SetCommitStatus(event.TargetProjectID, event.SHA, opt); err2 == nil {
321+
_, _, err2 := v.Client().Commits.SetCommitStatus(event.TargetProjectID, event.SHA, opt)
322+
if err2 == nil {
322323
v.Logger.Debugf("created commit status on target project ID %d", event.TargetProjectID)
323324
// we managed to set the status on the target repo, all good we are done
324325
return nil
325326
}
326-
v.Logger.Debugf("cannot set status with the GitLab token on the target project: %v", err)
327+
v.Logger.Debugf("cannot set status with the GitLab token on the target project: %v", err2)
328+
329+
// Only fall back to creating MR comments if either error is a permission issue (401/403).
330+
// For other errors (e.g., state transition errors like "Cannot transition status via :run from :running"),
331+
// the status might already be set, so we should not create a comment.
332+
isPermErr := func(e error) bool {
333+
return e != nil && (strings.Contains(e.Error(), "401") || strings.Contains(e.Error(), "403"))
334+
}
335+
if !isPermErr(err) && !isPermErr(err2) {
336+
v.Logger.Debugf("skipping MR comment as error is not a permission issue")
337+
return nil
338+
}
339+
327340
// we only show the first error as it's likely something the user has more control to fix
328341
// the second err is cryptic as it needs a dummy gitlab pipeline to start
329342
// with and will only give more confusion in the event namespace

pkg/provider/gitlab/gitlab_test.go

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ func TestCreateStatus(t *testing.T) {
258258
},
259259
},
260260
{
261-
name: "commit status fails on both projects but continues",
261+
name: "commit status fails on both projects with non-permission error skips MR comment",
262262
wantClient: true,
263263
wantErr: false,
264264
fields: fields{
@@ -270,10 +270,50 @@ func TestCreateStatus(t *testing.T) {
270270
},
271271
event: &info.Event{
272272
TriggerTarget: "pull_request",
273-
SourceProjectID: 404, // Will fail
274-
TargetProjectID: 405, // Will fail
273+
SourceProjectID: 400, // Will fail with 400 (not permission error)
274+
TargetProjectID: 405, // Will fail with 400 (not permission error)
275275
SHA: "abc123",
276276
},
277+
postStr: "", // No MR comment expected for non-permission errors
278+
},
279+
},
280+
{
281+
name: "permission error 403 on source creates MR comment",
282+
wantClient: true,
283+
wantErr: false,
284+
fields: fields{
285+
targetProjectID: 100,
286+
},
287+
args: args{
288+
statusOpts: provider.StatusOpts{
289+
Conclusion: "success",
290+
},
291+
event: &info.Event{
292+
TriggerTarget: "pull_request",
293+
SourceProjectID: 403, // Will fail with 403 Forbidden
294+
TargetProjectID: 400, // Will fail with 400 (not permission error)
295+
SHA: "abc123def",
296+
},
297+
postStr: "has successfully",
298+
},
299+
},
300+
{
301+
name: "permission error 401 on source creates MR comment",
302+
wantClient: true,
303+
wantErr: false,
304+
fields: fields{
305+
targetProjectID: 100,
306+
},
307+
args: args{
308+
statusOpts: provider.StatusOpts{
309+
Conclusion: "success",
310+
},
311+
event: &info.Event{
312+
TriggerTarget: "pull_request",
313+
SourceProjectID: 401, // Will fail with 401 Unauthorized
314+
TargetProjectID: 400, // Will fail with 400 (not permission error)
315+
SHA: "abc123ghi",
316+
},
277317
postStr: "has successfully",
278318
},
279319
},
@@ -315,31 +355,47 @@ func TestCreateStatus(t *testing.T) {
315355
// Mock source project commit status endpoint
316356
sourceStatusPath := fmt.Sprintf("/projects/%d/statuses/%s", tt.args.event.SourceProjectID, tt.args.event.SHA)
317357
mux.HandleFunc(sourceStatusPath, func(rw http.ResponseWriter, _ *http.Request) {
318-
if tt.args.event.SourceProjectID == 404 {
319-
// Simulate failure on source project
358+
switch tt.args.event.SourceProjectID {
359+
case 400:
360+
rw.WriteHeader(http.StatusBadRequest)
361+
fmt.Fprint(rw, `{"message": "400 Bad Request"}`)
362+
case 401:
363+
rw.WriteHeader(http.StatusUnauthorized)
364+
fmt.Fprint(rw, `{"message": "401 Unauthorized"}`)
365+
case 403:
366+
rw.WriteHeader(http.StatusForbidden)
367+
fmt.Fprint(rw, `{"message": "403 Forbidden"}`)
368+
case 404:
320369
rw.WriteHeader(http.StatusNotFound)
321370
fmt.Fprint(rw, `{"message": "404 Project Not Found"}`)
322-
return
371+
default:
372+
rw.WriteHeader(http.StatusCreated)
373+
fmt.Fprint(rw, `{}`)
323374
}
324-
// Success on source project
325-
rw.WriteHeader(http.StatusCreated)
326-
fmt.Fprint(rw, `{}`)
327375
})
328376
}
329377

330378
if tt.args.event.TargetProjectID != 0 {
331379
// Mock target project commit status endpoint
332380
targetStatusPath := fmt.Sprintf("/projects/%d/statuses/%s", tt.args.event.TargetProjectID, tt.args.event.SHA)
333381
mux.HandleFunc(targetStatusPath, func(rw http.ResponseWriter, _ *http.Request) {
334-
if tt.args.event.TargetProjectID == 404 {
335-
// Simulate failure on target project
382+
switch tt.args.event.TargetProjectID {
383+
case 400, 405:
384+
rw.WriteHeader(http.StatusBadRequest)
385+
fmt.Fprint(rw, `{"message": "400 Bad Request"}`)
386+
case 401:
387+
rw.WriteHeader(http.StatusUnauthorized)
388+
fmt.Fprint(rw, `{"message": "401 Unauthorized"}`)
389+
case 403:
390+
rw.WriteHeader(http.StatusForbidden)
391+
fmt.Fprint(rw, `{"message": "403 Forbidden"}`)
392+
case 404:
336393
rw.WriteHeader(http.StatusNotFound)
337394
fmt.Fprint(rw, `{"message": "404 Project Not Found"}`)
338-
return
395+
default:
396+
rw.WriteHeader(http.StatusCreated)
397+
fmt.Fprint(rw, `{}`)
339398
}
340-
// Success on target project
341-
rw.WriteHeader(http.StatusCreated)
342-
fmt.Fprint(rw, `{}`)
343399
})
344400
}
345401

0 commit comments

Comments
 (0)