@@ -49,14 +49,17 @@ export class Runner {
4949 return this . queue . getRunning ( ) ;
5050 } ;
5151
52+ getWaitingAndQueued = async ( ) => {
53+ const queued = await this . getQueue ( ) ;
54+ const waiting = await this . queue . getStatusesForWaitingRequests ( ) ;
55+ return [ ...queued , ...waiting ] ;
56+ } ;
57+
5258 moveFromQueueToRunning = async ( landRequestStatus : LandRequestStatus , lockId : Date ) => {
5359 const landRequest = landRequestStatus . request ;
5460 const running = await this . getRunning ( ) ;
5561 const runningTargetingSameBranch = running . filter (
56- build =>
57- build . request . pullRequest . targetBranch === landRequest . pullRequest . targetBranch &&
58- // Failsafe to prevent self-dependencies
59- build . request . pullRequestId !== landRequest . pullRequestId ,
62+ build => build . request . pullRequest . targetBranch === landRequest . pullRequest . targetBranch ,
6063 ) ;
6164 const maxConcurrentBuilds = this . getMaxConcurrentBuilds ( ) ;
6265 if ( runningTargetingSameBranch . length >= maxConcurrentBuilds ) {
@@ -76,9 +79,10 @@ export class Runner {
7679 landRequest . triggererAaid ,
7780 ) ;
7881 const commit = landRequest . forCommit ;
79- const isAllowedToLand = await this . client . isAllowedToLand (
82+ const isAllowedToLand = await this . isAllowedToLand (
8083 landRequest . pullRequestId ,
8184 triggererUserMode ,
85+ this . getRunning ,
8286 ) ;
8387
8488 // ToDo: Extra checks, should probably not be here, but this will do for now
@@ -108,10 +112,10 @@ export class Runner {
108112 return landRequest . setStatus ( 'aborted' , 'PR commit changed between landing and running' ) ;
109113 }
110114
111- if ( isAllowedToLand . errors . length > 0 ) {
115+ if ( isAllowedToLand . errors . length > 0 || isAllowedToLand . existingRequest ) {
112116 Logger . error ( 'LandRequest no longer passes land checks' , {
113117 namespace : 'lib:runner:moveFromQueueToRunning' ,
114- errors : isAllowedToLand . errors ,
118+ isAllowedToLand,
115119 landRequestStatus,
116120 pullRequestId : landRequest . pullRequestId ,
117121 landRequestId : landRequest . id ,
@@ -120,8 +124,12 @@ export class Runner {
120124 return landRequest . setStatus ( 'fail' , 'Unable to land due to failed land checks' ) ;
121125 }
122126
127+ const runningExceptSelf = runningTargetingSameBranch . filter (
128+ // Failsafe to prevent self-dependencies
129+ build => build . request . pullRequestId !== landRequest . pullRequestId ,
130+ ) ;
123131 const dependencies = [ ] ;
124- for ( const queueItem of runningTargetingSameBranch ) {
132+ for ( const queueItem of runningExceptSelf ) {
125133 if ( ( await queueItem . request . getFailedDependencies ( ) ) . length === 0 ) {
126134 dependencies . push ( queueItem ) ;
127135 }
@@ -492,19 +500,18 @@ export class Runner {
492500 const triggererUserMode = await permissionService . getPermissionForUser (
493501 landRequest . triggererAaid ,
494502 ) ;
495- const isAllowedToLand = await this . client . isAllowedToLand ( pullRequestId , triggererUserMode ) ;
503+ const isAllowedToLand = await this . isAllowedToLand (
504+ pullRequestId ,
505+ triggererUserMode ,
506+ this . getQueue ,
507+ ) ;
496508
497509 if ( isAllowedToLand . errors . length === 0 ) {
498- const queue = await this . getQueue ( ) ;
499- const existingBuild = queue . find (
500- q => q . request . pullRequestId === landRequest . pullRequestId ,
501- ) ;
502- if ( existingBuild ) {
510+ if ( isAllowedToLand . existingRequest ) {
503511 Logger . warn ( 'Already has existing Land build' , {
504512 pullRequestId,
505513 landRequestId : landRequest . id ,
506514 landRequestStatus,
507- existingBuild,
508515 namespace : 'lib:runner:checkWaitingLandRequests' ,
509516 } ) ;
510517 await landRequest . setStatus ( 'aborted' , 'Already has existing Land build' ) ;
@@ -633,6 +640,26 @@ export class Runner {
633640 }
634641 } ;
635642
643+ async isAllowedToLand (
644+ pullRequestId : number ,
645+ permissionLevel : IPermissionMode ,
646+ queueFetcher : ( ) => Promise < LandRequestStatus [ ] > ,
647+ ) {
648+ const isAllowedToMerge = await this . client . isAllowedToMerge ( pullRequestId , permissionLevel ) ;
649+ let existingRequest = false ;
650+ const queue = await queueFetcher ( ) ;
651+ for ( const queueItem of queue ) {
652+ if ( queueItem . request . pullRequestId === pullRequestId ) {
653+ existingRequest = true ;
654+ break ;
655+ }
656+ }
657+ return {
658+ existingRequest,
659+ ...isAllowedToMerge ,
660+ } ;
661+ }
662+
636663 getState = async ( requestingUser : ISessionUser ) : Promise < RunnerState > => {
637664 const requestingUserMode = await permissionService . getPermissionForUser ( requestingUser . aaid ) ;
638665 const [
0 commit comments