fix: prune modified branches if no PR (#7467)

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
This commit is contained in:
Rhys Arkins 2020-10-14 16:29:45 +02:00 committed by GitHub
parent 1409aa1f7e
commit 5a7fb4b993
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 38 deletions

View file

@ -50,6 +50,19 @@ describe('workers/repository/finalise/prune', () => {
expect(git.deleteBranch).toHaveBeenCalledTimes(1); expect(git.deleteBranch).toHaveBeenCalledTimes(1);
expect(platform.updatePr).toHaveBeenCalledTimes(1); expect(platform.updatePr).toHaveBeenCalledTimes(1);
}); });
it('skips rename but still deletes branch', async () => {
config.branchList = ['renovate/a', 'renovate/b'];
git.getBranchList.mockReturnValueOnce(
config.branchList.concat(['renovate/c'])
);
platform.findPr.mockResolvedValueOnce({
title: 'foo - autoclosed',
} as never);
await cleanup.pruneStaleBranches(config, config.branchList);
expect(git.getBranchList).toHaveBeenCalledTimes(1);
expect(git.deleteBranch).toHaveBeenCalledTimes(1);
expect(platform.updatePr).toHaveBeenCalledTimes(1);
});
it('does nothing on dryRun', async () => { it('does nothing on dryRun', async () => {
config.branchList = ['renovate/a', 'renovate/b']; config.branchList = ['renovate/a', 'renovate/b'];
config.dryRun = true; config.dryRun = true;
@ -105,5 +118,29 @@ describe('workers/repository/finalise/prune', () => {
expect(platform.updatePr).toHaveBeenCalledTimes(0); expect(platform.updatePr).toHaveBeenCalledTimes(0);
expect(platform.ensureComment).toHaveBeenCalledTimes(0); expect(platform.ensureComment).toHaveBeenCalledTimes(0);
}); });
it('dry run delete branch no PR', async () => {
config.branchList = ['renovate/a', 'renovate/b'];
config.dryRun = true;
git.getBranchList.mockReturnValueOnce(
config.branchList.concat(['renovate/c'])
);
platform.findPr.mockResolvedValueOnce(null as never);
await cleanup.pruneStaleBranches(config, config.branchList);
expect(git.getBranchList).toHaveBeenCalledTimes(1);
expect(git.deleteBranch).toHaveBeenCalledTimes(0);
expect(platform.updatePr).toHaveBeenCalledTimes(0);
});
it('delete branch no PR', async () => {
config.branchList = ['renovate/a', 'renovate/b'];
config.dryRun = false;
git.getBranchList.mockReturnValueOnce(
config.branchList.concat(['renovate/c'])
);
platform.findPr.mockResolvedValueOnce(null as never);
await cleanup.pruneStaleBranches(config, config.branchList);
expect(git.getBranchList).toHaveBeenCalledTimes(1);
expect(git.deleteBranch).toHaveBeenCalledTimes(1);
expect(platform.updatePr).toHaveBeenCalledTimes(0);
});
}); });
}); });

View file

@ -13,6 +13,10 @@ async function cleanUpBranches(
{ dryRun, pruneStaleBranches: enabled }: RenovateConfig, { dryRun, pruneStaleBranches: enabled }: RenovateConfig,
remainingBranches: string[] remainingBranches: string[]
): Promise<void> { ): Promise<void> {
if (enabled === false) {
logger.debug('Branch/PR pruning is disabled - skipping');
return;
}
for (const branchName of remainingBranches) { for (const branchName of remainingBranches) {
try { try {
const pr = await platform.findPr({ const pr = await platform.findPr({
@ -20,39 +24,11 @@ async function cleanUpBranches(
state: PrState.Open, state: PrState.Open,
}); });
const branchIsModified = await isBranchModified(branchName); const branchIsModified = await isBranchModified(branchName);
if (pr && !branchIsModified) { if (pr) {
if (!pr.title.endsWith('- autoclosed')) { if (branchIsModified) {
if (dryRun) {
logger.info(
`DRY-RUN: Would update pr ${pr.number} to ${pr.title} - autoclosed`
);
} else if (enabled === false) {
logger.info(
`PRUNING-DISABLED: Would update pr ${pr.number} to ${pr.title} - autoclosed`
);
} else {
logger.info(
{ branchName, prNo: pr.number, prTitle: pr.title },
'Autoclosing PR'
);
await platform.updatePr({
number: pr.number,
prTitle: `${pr.title} - autoclosed`,
state: PrState.Closed,
});
}
}
}
if (branchIsModified) {
logger.debug(
{ branch: branchName },
`Skipping orphan branch deletion as branch has been modified`
);
if (pr) {
logger.debug( logger.debug(
{ prNo: pr?.number, prTitle: pr?.title }, { prNo: pr.number, prTitle: pr.title },
'Skip PR autoclosing' 'Branch is modified - skipping PR autoclosing'
); );
if (dryRun) { if (dryRun) {
logger.info(`DRY-RUN: Would add Autoclosing Skipped comment to PR`); logger.info(`DRY-RUN: Would add Autoclosing Skipped comment to PR`);
@ -64,15 +40,31 @@ async function cleanUpBranches(
'This PR has been flagged for autoclosing, however it is being skipped due to the branch being already modified. Please close/delete it manually or report a bug if you think this is in error.', 'This PR has been flagged for autoclosing, however it is being skipped due to the branch being already modified. Please close/delete it manually or report a bug if you think this is in error.',
}); });
} }
} else if (dryRun) {
logger.info(
{ prNo: pr.number, prTitle: pr.title },
`DRY-RUN: Would autoclose PR`
);
} else {
logger.info(
{ branchName, prNo: pr.number, prTitle: pr.title },
'Autoclosing PR'
);
let newPrTitle = pr.title;
if (!pr.title.endsWith('- autoclosed')) {
newPrTitle += '- autoclosed';
}
await platform.updatePr({
number: pr.number,
prTitle: newPrTitle,
state: PrState.Closed,
});
await deleteBranch(branchName);
} }
} else if (dryRun) { } else if (dryRun) {
logger.info(`DRY-RUN: Would deleting orphan branch ${branchName}`); logger.info(`DRY-RUN: Would delete orphan branch ${branchName}`);
} else if (enabled === false) {
logger.info(
`PRUNING-DISABLED: Would deleting orphan branch ${branchName}`
);
} else { } else {
logger.debug({ branch: branchName }, `Deleting orphan branch`); logger.info({ branch: branchName }, `Deleting orphan branch`);
await deleteBranch(branchName); await deleteBranch(branchName);
} }
} catch (err) /* istanbul ignore next */ { } catch (err) /* istanbul ignore next */ {