@@ -179,6 +179,12 @@ const startingOrInProgressPipelineStatuses = [
179179 PipelineStatus . Preparing ,
180180] ;
181181
182+ const incompletePipelineStatuses = [
183+ PipelineStatus . Failed ,
184+ PipelineStatus . Canceled ,
185+ PipelineStatus . Skipped ,
186+ ] ;
187+
182188const containsLabel = ( labels : string [ ] , label : BotLabels ) => labels . includes ( label ) ;
183189const containsAssignedUser = ( mergeRequest : MergeRequest , user : User ) => {
184190 const userIds = mergeRequest . assignees . map ( ( assignee ) => assignee . id ) ;
@@ -287,6 +293,16 @@ export const acceptMergeRequest = async (
287293 } ;
288294 }
289295
296+ // we are behind the target branch, rebase required
297+ if ( mergeRequestInfo . diverged_commits_count > 0 ) {
298+ console . log ( `[MR][${ mergeRequestInfo . iid } ] Branch has diverged commits` ) ;
299+ return {
300+ kind : AcceptMergeRequestResultKind . InvalidSha ,
301+ mergeRequestInfo,
302+ user,
303+ } ;
304+ }
305+
290306 if (
291307 mergeRequestInfo . head_pipeline !== null &&
292308 startingOrInProgressPipelineStatuses . includes ( mergeRequestInfo . head_pipeline . status )
@@ -311,6 +327,18 @@ export const acceptMergeRequest = async (
311327 } ;
312328 }
313329
330+ // the latest pipeline is incomplete / has failed
331+ if (
332+ mergeRequestInfo . head_pipeline !== null &&
333+ incompletePipelineStatuses . includes ( mergeRequestInfo . head_pipeline . status )
334+ ) {
335+ return {
336+ kind : AcceptMergeRequestResultKind . CanNotBeMerged ,
337+ mergeRequestInfo,
338+ user,
339+ } ;
340+ }
341+
314342 const useSquash = mergeRequestInfo . labels . includes ( config . SKIP_SQUASHING_LABEL )
315343 ? false
316344 : config . SQUASH_MERGE_REQUEST ;
@@ -342,7 +370,20 @@ export const acceptMergeRequest = async (
342370 ) ;
343371
344372 if ( response . status === 405 || response . status === 406 ) {
345- console . log ( `[MR][${ mergeRequestInfo . iid } ] ${ response . status } - cannot be merged` ) ;
373+ // GitLab 405 is a mixed state and can be a temporary error
374+ // as long as all flags and status indicate that we can merge, retry
375+ if ( mergeRequestInfo . merge_status === MergeStatus . CanBeMerged ) {
376+ console . log (
377+ `[MR][${ mergeRequestInfo . iid } ] ${ response . status } - cannot be merged but merge status is: ${ mergeRequestInfo . merge_status } ` ,
378+ ) ;
379+
380+ return {
381+ kind : AcceptMergeRequestResultKind . CheckingMergeStatus ,
382+ mergeRequestInfo,
383+ user,
384+ } ;
385+ }
386+
346387 return {
347388 kind : AcceptMergeRequestResultKind . CanNotBeMerged ,
348389 mergeRequestInfo,
0 commit comments