@@ -27,6 +27,7 @@ const WAIT_TIME_SINGLE_APPROVAL = 24 * 7;
2727const GITHUB_SUCCESS_CONCLUSIONS = [ 'SUCCESS' , 'NEUTRAL' , 'SKIPPED' ] ;
2828
2929const FAST_TRACK_RE = / ^ F a s t - t r a c k h a s b e e n r e q u e s t e d b y @ ( .+ ?) \. P l e a s e 👍 t o a p p r o v e \. $ / ;
30+ const FAST_TRACK_MIN_APPROVALS = 2 ;
3031const GIT_CONFIG_GUIDE_URL = 'https://github.com/nodejs/node/blob/99b1ada/doc/guides/contributing/pull-requests.md#step-1-fork' ;
3132
3233export default class PRChecker {
@@ -138,7 +139,7 @@ export default class PRChecker {
138139 const { requestedChanges, approved } = reviewers ;
139140 const labels = pr . labels . nodes . map ( ( l ) => l . name ) ;
140141
141- const isFastTracked = labels . includes ( 'fast-track' ) ;
142+ let isFastTracked = labels . includes ( 'fast-track' ) ;
142143 const isCodeAndLearn = labels . includes ( 'code-and-learn' ) ;
143144 const isSemverMajor = labels . includes ( 'semver-major' ) ;
144145
@@ -168,6 +169,7 @@ export default class PRChecker {
168169 }
169170 }
170171
172+ let fastTrackAppendix = '' ;
171173 if ( isFastTracked ) {
172174 const comment = [ ...this . comments ] . reverse ( ) . find ( ( c ) =>
173175 FAST_TRACK_RE . test ( c . bodyText ) ) ;
@@ -183,14 +185,15 @@ export default class PRChecker {
183185 r . user . login !== pr . author . login &&
184186 collaborators . includes ( r . user . login . toLowerCase ( ) ) ) . length ;
185187
186- if ( requester === pr . author . login && approvals < 2 ) {
187- cli . error ( 'The fast-track request requires' +
188- " at least two collaborators' approvals (👍)." ) ;
189- return false ;
190- } else if ( approvals === 0 ) {
191- cli . error ( 'The fast-track request requires' +
192- " at least one collaborator's approval (👍)." ) ;
193- return false ;
188+ const missingFastTrackApprovals = FAST_TRACK_MIN_APPROVALS - approvals -
189+ ( requester === pr . author . login ? 0 : 1 ) ;
190+ if ( missingFastTrackApprovals > 0 ) {
191+ isFastTracked = false ;
192+ fastTrackAppendix = ' (or 0 hours if there ' +
193+ `${ missingFastTrackApprovals === 1 ? 'is' : 'are' } ` +
194+ `${ missingFastTrackApprovals } more approval` +
195+ `${ missingFastTrackApprovals === 1 ? '' : 's' } (👍) of ` +
196+ 'the fast-track request from collaborators).' ;
194197 }
195198 }
196199
@@ -211,10 +214,12 @@ export default class PRChecker {
211214 if ( timeLeftMulti === 0 ) {
212215 const timeLeftMins =
213216 this . waitTimeMultiApproval * 60 - minutesFromCreateTime ;
214- cli . error ( `This PR needs to wait ${ timeLeftMins } more minutes to land` ) ;
217+ cli . error ( `This PR needs to wait ${ timeLeftMins } ` +
218+ `more minutes to land${ fastTrackAppendix } ` ) ;
215219 return false ;
216220 }
217- cli . error ( `This PR needs to wait ${ timeLeftMulti } more hours to land` ) ;
221+ cli . error ( `This PR needs to wait ${ timeLeftMulti } more ` +
222+ `hours to land${ fastTrackAppendix } ` ) ;
218223 return false ;
219224 }
220225
@@ -224,7 +229,8 @@ export default class PRChecker {
224229 }
225230 timeLeftMulti = timeLeftMulti < 0 || isFastTracked ? 0 : timeLeftMulti ;
226231 cli . error ( `This PR needs to wait ${ timeLeftSingle } more hours to land ` +
227- `(or ${ timeLeftMulti } hours if there is one more approval)` ) ;
232+ `(or ${ timeLeftMulti } hours if there is one more approval)` +
233+ fastTrackAppendix ) ;
228234 return false ;
229235 }
230236 }
0 commit comments