2019-07-15 09:04:05 +00:00
const { logger } = require ( '../../logger' ) ;
2019-12-04 15:44:04 +00:00
const { appName } = require ( '../../config/app-strings' ) ;
2019-09-10 07:50:29 +00:00
const { platform } = require ( '../../platform' ) ;
2019-01-06 13:47:42 +00:00
2018-10-04 08:07:59 +00:00
module . exports = {
ensureMasterIssue ,
} ;
2018-11-02 05:23:45 +00:00
function getListItem ( branch , type , pr ) {
2018-10-04 08:07:59 +00:00
let item = ' - [ ] ' ;
item += ` <!-- ${ type } -branch= ${ branch . branchName } --> ` ;
2018-11-02 05:23:45 +00:00
if ( pr ) {
item += ` [ ${ branch . prTitle } ](../pull/ ${ pr . number } ) ` ;
2018-10-04 08:07:59 +00:00
} else {
item += branch . prTitle ;
}
2018-10-04 08:38:16 +00:00
const uniquePackages = [
... new Set ( branch . upgrades . map ( upgrade => '`' + upgrade . depName + '`' ) ) ,
] ;
if ( uniquePackages . length < 2 ) {
2018-10-04 08:07:59 +00:00
return item + '\n' ;
}
2018-10-04 08:38:16 +00:00
return item + ' (' + uniquePackages . join ( ', ' ) + ')\n' ;
2018-10-04 08:07:59 +00:00
}
async function ensureMasterIssue ( config , branches ) {
2019-04-28 06:23:00 +00:00
if (
2019-07-11 11:48:41 +00:00
! (
config . masterIssue ||
branches . some (
branch => branch . masterIssueApproval || branch . masterIssuePrApproval
)
)
2019-04-28 06:23:00 +00:00
) {
2018-10-04 08:07:59 +00:00
return ;
}
2018-11-02 05:52:57 +00:00
logger . info ( 'Ensuring master issue' ) ;
2018-10-04 08:07:59 +00:00
if (
! branches . length ||
branches . every ( branch => branch . res === 'automerged' )
) {
if ( config . masterIssueAutoclose ) {
2018-11-02 05:52:57 +00:00
logger . debug ( 'Closing master issue' ) ;
2019-07-04 14:00:00 +00:00
if ( config . dryRun ) {
logger . info (
'DRY-RUN: Would close Master Issue ' + config . masterIssueTitle
) ;
} else {
await platform . ensureIssueClosing ( config . masterIssueTitle ) ;
}
2018-10-04 08:07:59 +00:00
return ;
}
2019-07-04 14:00:00 +00:00
if ( config . dryRun ) {
logger . info (
'DRY-RUN: Would ensure Master Issue ' + config . masterIssueTitle
) ;
} else {
await platform . ensureIssue (
config . masterIssueTitle ,
'This repository is up-to-date and has no outstanding updates open or pending.'
) ;
}
2018-10-04 08:07:59 +00:00
return ;
}
2019-12-04 15:44:04 +00:00
let issueBody = ` This [master issue](https://renovatebot.com/blog/master-issue) contains a list of ${ appName } updates and their statuses. \n \n ` ;
2018-10-04 08:07:59 +00:00
const pendingApprovals = branches . filter (
branch => branch . res === 'needs-approval'
) ;
if ( pendingApprovals . length ) {
issueBody += '## Pending Approval\n\n' ;
2019-12-04 15:44:04 +00:00
issueBody += ` These branches will be created by ${ appName } only once you click their checkbox below. \n \n ` ;
2018-10-04 08:07:59 +00:00
for ( const branch of pendingApprovals ) {
issueBody += getListItem ( branch , 'approve' ) ;
}
issueBody += '\n' ;
}
const awaitingSchedule = branches . filter (
branch => branch . res === 'not-scheduled'
) ;
if ( awaitingSchedule . length ) {
issueBody += '## Awaiting Schedule\n\n' ;
issueBody +=
'These updates are awaiting their schedule. Click on a checkbox to ignore the schedule.\n' ;
for ( const branch of awaitingSchedule ) {
issueBody += getListItem ( branch , 'unschedule' ) ;
}
issueBody += '\n' ;
}
2018-10-08 10:53:49 +00:00
const rateLimited = branches . filter (
branch => branch . res && branch . res . endsWith ( 'pr-hourly-limit-reached' )
2018-10-04 08:07:59 +00:00
) ;
if ( rateLimited . length ) {
issueBody += '## Rate Limited\n\n' ;
issueBody +=
2019-08-26 05:57:51 +00:00
'These updates are currently rate limited. Click on a checkbox below to force their creation now.\n\n' ;
2018-10-04 08:07:59 +00:00
for ( const branch of rateLimited ) {
issueBody += getListItem ( branch , 'unlimit' ) ;
}
issueBody += '\n' ;
}
2018-10-08 10:53:49 +00:00
const errorList = branches . filter (
branch => branch . res && branch . res . endsWith ( 'error' )
) ;
2018-10-04 08:07:59 +00:00
if ( errorList . length ) {
issueBody += '## Errored\n\n' ;
issueBody +=
'These updates encountered an error and will be retried. Click a checkbox below to force a retry now.\n\n' ;
for ( const branch of errorList ) {
issueBody += getListItem ( branch , 'retry' ) ;
}
issueBody += '\n' ;
}
2019-07-11 11:48:41 +00:00
const awaitingPr = branches . filter (
branch => branch . res === 'needs-pr-approval'
) ;
if ( awaitingPr . length ) {
issueBody += '## PR Creation Approval Required\n\n' ;
issueBody +=
2019-08-26 05:57:51 +00:00
"These branches exist but PRs won't be created until you approve by ticking the checkbox.\n\n" ;
2019-07-11 11:48:41 +00:00
for ( const branch of awaitingPr ) {
issueBody += getListItem ( branch , 'approvePr' ) ;
}
issueBody += '\n' ;
}
2018-10-04 11:54:28 +00:00
const prEdited = branches . filter ( branch => branch . res === 'pr-edited' ) ;
if ( prEdited . length ) {
issueBody += '## Edited/Blocked\n\n' ;
2019-12-04 15:44:04 +00:00
issueBody += ` These updates have been manually edited so ${ appName } will no longer make changes. To discard all commits and start over, check the box below. \n \n ` ;
2018-10-04 11:54:28 +00:00
for ( const branch of prEdited ) {
2019-03-06 23:20:22 +00:00
const pr = await platform . getBranchPr ( branch . branchName ) ;
issueBody += getListItem ( branch , 'rebase' , pr ) ;
2018-10-04 11:54:28 +00:00
}
issueBody += '\n' ;
}
2019-08-26 05:58:08 +00:00
const prPending = branches . filter ( branch => branch . res === 'pending' ) ;
if ( prPending . length ) {
issueBody += '## Pending Status Checks\n\n' ;
issueBody += ` These updates await pending status checks. To force their creation now, check the box below. \n \n ` ;
for ( const branch of prPending ) {
issueBody += getListItem ( branch , 'approvePr' ) ;
}
issueBody += '\n' ;
}
2018-10-04 08:07:59 +00:00
const otherRes = [
2019-08-26 05:58:08 +00:00
'pending' ,
2018-10-04 08:07:59 +00:00
'needs-approval' ,
2019-07-11 11:48:41 +00:00
'needs-pr-approval' ,
2018-10-04 08:07:59 +00:00
'not-scheduled' ,
'pr-hourly-limit-reached' ,
'already-existed' ,
'error' ,
'automerged' ,
2018-10-04 11:54:28 +00:00
'pr-edited' ,
2018-10-04 08:07:59 +00:00
] ;
const inProgress = branches . filter ( branch => ! otherRes . includes ( branch . res ) ) ;
if ( inProgress . length ) {
issueBody += '## Open\n\n' ;
issueBody +=
'These updates have all been created already. Click a checkbox below to force a retry/rebase of any.\n\n' ;
for ( const branch of inProgress ) {
const pr = await platform . getBranchPr ( branch . branchName ) ;
2018-11-02 05:23:45 +00:00
issueBody += getListItem ( branch , 'rebase' , pr ) ;
2018-10-04 08:07:59 +00:00
}
2019-04-28 07:04:50 +00:00
if ( inProgress . length > 2 ) {
issueBody += ' - [ ] ' ;
issueBody += '<!-- rebase-all-open-prs -->' ;
issueBody +=
'**Check this option to rebase all the above open PRs at once**' ;
issueBody += '\n' ;
}
2018-10-04 08:07:59 +00:00
issueBody += '\n' ;
}
2018-10-08 10:53:49 +00:00
const alreadyExisted = branches . filter (
branch => branch . res && branch . res . endsWith ( 'already-existed' )
2018-10-04 08:07:59 +00:00
) ;
if ( alreadyExisted . length ) {
issueBody += '## Closed/Ignored\n\n' ;
issueBody +=
'These updates were closed unmerged and will not be recreated unless you click a checkbox below.\n\n' ;
for ( const branch of alreadyExisted ) {
2018-11-02 05:23:45 +00:00
const pr = await platform . findPr (
branch . branchName ,
branch . prTitle ,
'!open'
) ;
issueBody += getListItem ( branch , 'recreate' , pr ) ;
2018-10-04 08:07:59 +00:00
}
issueBody += '\n' ;
}
2019-04-28 07:04:50 +00:00
2019-08-25 08:05:30 +00:00
// istanbul ignore if
if ( global . appMode ) {
issueBody +=
'---\n<details><summary>Advanced</summary>\n\n- [ ] <!-- manual job -->Check this box to trigger a request for Renovate to run again on this repository\n\n</details>\n' ;
}
2019-07-04 14:00:00 +00:00
if ( config . dryRun ) {
logger . info (
'DRY-RUN: Would ensure Master Issue ' + config . masterIssueTitle
) ;
} else {
await platform . ensureIssue ( config . masterIssueTitle , issueBody ) ;
}
2018-10-04 08:07:59 +00:00
}