@@ -195,9 +195,11 @@ func (v *Provider) SetClient(_ context.Context, run *params.Run, runevent *info.
195195 }
196196 v .apiURL = apiURL
197197
198- v .gitlabClient , err = gitlab .NewClient (runevent .Provider .Token , gitlab .WithBaseURL (apiURL ))
199- if err != nil {
200- return err
198+ if v .gitlabClient == nil {
199+ v .gitlabClient , err = gitlab .NewClient (runevent .Provider .Token , gitlab .WithBaseURL (apiURL ))
200+ if err != nil {
201+ return err
202+ }
201203 }
202204 v .Token = & runevent .Provider .Token
203205
@@ -211,6 +213,19 @@ func (v *Provider) SetClient(_ context.Context, run *params.Run, runevent *info.
211213 v .sourceProjectID = runevent .SourceProjectID
212214 }
213215
216+ // check that we have access to the source project if it's a private repo, this should only occur on Merge Requests
217+ if runevent .TriggerTarget == triggertype .PullRequest {
218+ _ , resp , err := v .Client ().Projects .GetProject (runevent .SourceProjectID , & gitlab.GetProjectOptions {})
219+ errmsg := fmt .Sprintf ("failed to access GitLab source repository ID %d: please ensure token has 'read_repository' scope on that repository" ,
220+ runevent .SourceProjectID )
221+ if resp != nil && resp .StatusCode == http .StatusNotFound {
222+ return fmt .Errorf ("%s" , errmsg )
223+ }
224+ if err != nil {
225+ return fmt .Errorf ("%s: %w" , errmsg , err )
226+ }
227+ }
228+
214229 // if we don't have sourceProjectID (ie: incoming-webhook) then try to set
215230 // it ASAP if we can.
216231 if v .sourceProjectID == 0 && runevent .Organization != "" && runevent .Repository != "" {
@@ -280,27 +295,35 @@ func (v *Provider) CreateStatus(_ context.Context, event *info.Event, statusOpts
280295 Context : gitlab .Ptr (contextName ),
281296 }
282297
283- // setCommitStatus attempts to set the commit status for a given SHA, handling GitLab's permission model.
284- // First tries the source project (fork), then falls back to the target project (upstream repo).
285- // This fallback is necessary because:
286- // - In fork/MR scenarios, the GitLab token may not have write access to the contributor's fork
287- // - This ensures commit status can be displayed somewhere useful regardless
288- // of permission differences
289- // Returns nil if status is set on either project, logs error if both attempts fail.
298+ // In case we have access, set the status. Typically, on a Merge Request (MR)
299+ // from a fork in an upstream repository, the token needs to have write access
300+ // to the fork repository in order to create a status. However, the token set on the
301+ // Repository CR usually doesn't have such broad access, preventing from creating
302+ // a status comment on it.
303+ // This would work on a push or an MR from a branch within the same repo.
304+ // Ignoring errors because of the write access issues,
290305 _ , _ , err := v .Client ().Commits .SetCommitStatus (event .SourceProjectID , event .SHA , opt )
291- if err == nil {
292- v .Logger .Debugf ("created commit status on source project ID %d" , event .SourceProjectID )
306+ if err != nil {
307+ v .Logger .Debugf ("cannot set status with the GitLab token on the source project: %v" , err )
308+ } else {
309+ // we managed to set the status on the source repo, all good we are done
310+ v .Logger .Debugf ("created commit status on source project ID %d" , event .TargetProjectID )
293311 return nil
294312 }
295313 if _ , _ , err2 := v .Client ().Commits .SetCommitStatus (event .TargetProjectID , event .SHA , opt ); err2 == nil {
296314 v .Logger .Debugf ("created commit status on target project ID %d" , event .TargetProjectID )
315+ // we managed to set the status on the target repo, all good we are done
297316 return nil
298317 }
299- v .Logger .Debugf (
300- "Failed to create commit status: source project ID %d, target project ID %d. " +
301- "If you want Gitlab Pipeline Status update, ensure your GitLab token has access " +
302- "to the source repository. Error: %v" ,
303- event .SourceProjectID , event .TargetProjectID , err )
318+ v .Logger .Debugf ("cannot set status with the GitLab token on the target project: %v" , err )
319+ // we only show the first error as it's likely something the user has more control to fix
320+ // the second err is cryptic as it needs a dummy gitlab pipeline to start
321+ // with and will only give more confusion in the event namespace
322+ v .eventEmitter .EmitMessage (v .repo , zap .InfoLevel , "FailedToSetCommitStatus" ,
323+ fmt .Sprintf ("failed to create commit status: source project ID %d, target project ID %d. " +
324+ "If you want Gitlab Pipeline Status update, ensure your GitLab token giving it access " +
325+ "to the source repository. %v" ,
326+ event .SourceProjectID , event .TargetProjectID , err ))
304327
305328 eventType := triggertype .IsPullRequestType (event .EventType )
306329 // When a GitOps command is sent on a pushed commit, it mistakenly treats it as a pull_request
0 commit comments