diff --git a/lib/api/github.js b/lib/api/github.js index cc0ab896a972a18bc6e63b2b03a4847ef91fefbd..8615d258bfc7adc3b6a9e18e5100fab18c3a7a52 100644 --- a/lib/api/github.js +++ b/lib/api/github.js @@ -621,8 +621,13 @@ async function getPr(prNo) { } async function updatePr(prNo, title, body) { + logger.debug(`updatePr(${prNo}, ${title}, body)`); + const patchBody = { title }; + if (body) { + patchBody.body = body; + } await get.patch(`repos/${config.repoName}/pulls/${prNo}`, { - body: { title, body }, + body: patchBody, }); } diff --git a/lib/workers/repository/cleanup.js b/lib/workers/repository/cleanup.js index 559aadb7ada0c9cba99a021fcb312e7f929140f6..b58232b1af9f87f9fe515f4d75c80c078c2ad5df 100644 --- a/lib/workers/repository/cleanup.js +++ b/lib/workers/repository/cleanup.js @@ -56,6 +56,11 @@ async function pruneStaleBranches(config, branchList) { } for (const branchName of remainingBranches) { logger.debug({ branch: branchName }, `Deleting orphan branch`); + const pr = await config.api.findPr(branchName, null, 'open'); + if (pr) { + logger.info({ prNo: pr.number, prTitle: pr.title }, 'Autoclosing PR'); + await config.api.updatePr(pr.number, `${pr.title} - autoclosed`); + } await config.api.deleteBranch(branchName); } } diff --git a/test/workers/repository/cleanup.spec.js b/test/workers/repository/cleanup.spec.js index 756404eb8ffc006a281ed41c392156983acec01f..5164214118c649f332fa0ef18f9a0cbdff8ab65c 100644 --- a/test/workers/repository/cleanup.spec.js +++ b/test/workers/repository/cleanup.spec.js @@ -13,6 +13,8 @@ describe('workers/repository/cleanup', () => { getAllRenovateBranches: jest.fn(), getPr: jest.fn(), deleteBranch: jest.fn(), + findPr: jest.fn(), + updatePr: jest.fn(), }; config.logger = logger; }); @@ -27,14 +29,16 @@ describe('workers/repository/cleanup', () => { await cleanup.pruneStaleBranches(config, branchNames); expect(config.api.getAllRenovateBranches.mock.calls).toHaveLength(1); }); - it('deletes remaining branch', async () => { + it('renames deletes remaining branch', async () => { branchNames = ['renovate/a', 'renovate/b']; config.api.getAllRenovateBranches.mockReturnValueOnce( branchNames.concat(['renovate/c']) ); + config.api.findPr.mockReturnValueOnce({}); await cleanup.pruneStaleBranches(config, branchNames); expect(config.api.getAllRenovateBranches.mock.calls).toHaveLength(1); expect(config.api.deleteBranch.mock.calls).toHaveLength(1); + expect(config.api.updatePr.mock.calls).toHaveLength(1); }); it('deletes lock file maintenance if pr is closed', async () => { branchNames = ['renovate/lock-file-maintenance'];