diff --git a/lib/platform/github/index.js b/lib/platform/github/index.js index 04dd8c66006454f584ffd2a2680cca6f4f39f1e2..f4992d40302e026cde375f343fdbec6f08e25971 100644 --- a/lib/platform/github/index.js +++ b/lib/platform/github/index.js @@ -602,8 +602,8 @@ async function getIssueList() { logger.debug('Retrieving issueList'); const res = await get( `repos/${config.parentRepo || - config.repository}/issues?filter=created&state=open&per_page=100&sort=updated`, - { useCache: false } + config.repository}/issues?filter=created&state=all&per_page=100&sort=updated`, + { paginate: true, useCache: false } ); // istanbul ignore if if (!is.array(res.body)) { @@ -612,6 +612,7 @@ async function getIssueList() { } config.issueList = res.body.map(i => ({ number: i.number, + state: i.state, title: i.title, })); logger.debug('Retrieved ' + config.issueList.length + ' issues'); @@ -622,7 +623,9 @@ async function getIssueList() { async function findIssue(title) { logger.debug(`findIssue(${title})`); try { - const [issue] = (await getIssueList()).filter(i => i.title === title); + const [issue] = (await getIssueList()).filter( + i => i.state === 'open' && i.title === title + ); if (!issue) { return null; } @@ -640,20 +643,25 @@ async function findIssue(title) { } } -async function ensureIssue(title, body) { +async function ensureIssue(title, body, once = false) { logger.debug(`ensureIssue()`); try { const issueList = await getIssueList(); const issues = issueList.filter(i => i.title === title).reverse(); if (issues.length) { if (issues.length > 1) { - logger.warn('Found duplicate issues'); for (const issue of issues.slice(1)) { - logger.debug('Closing duplicate issue ' + issue.number); - await closeIssue(issue.number); + if (issue.state === 'open') { + logger.warn('Closing duplicate issue ' + issue.number); + await closeIssue(issue.number); + } } } const [issue] = issues; + if (once && issue.state === 'closed') { + logger.debug('Issue is closed - skipping'); + return null; + } const issueBody = (await get( `repos/${config.parentRepo || config.repository}/issues/${issue.number}` )).body.body; @@ -670,13 +678,13 @@ async function ensureIssue(title, body) { return 'updated'; } } else { - logger.info('Issue created'); await get.post(`repos/${config.parentRepo || config.repository}/issues`, { body: { title, body, }, }); + logger.info('Issue created'); // reset issueList so that it will be fetched again as-needed delete config.issueList; return 'created'; @@ -707,7 +715,7 @@ async function ensureIssueClosing(title) { logger.debug(`ensureIssueClosing()`); const issueList = await getIssueList(); for (const issue of issueList) { - if (issue.title === title) { + if (issue.state === 'open' && issue.title === title) { await closeIssue(issue.number); logger.info({ number: issue.number }, 'Issue closed'); } diff --git a/lib/workers/repository/process/deprecated.js b/lib/workers/repository/process/deprecated.js index a836ca8d015ce2685722944c8c8bc44291f27196..1a687c432e575f3b02be8697a82fd74d8faa677a 100644 --- a/lib/workers/repository/process/deprecated.js +++ b/lib/workers/repository/process/deprecated.js @@ -51,7 +51,8 @@ async function raiseDeprecationWarnings(config, packageFiles) { if (config.dryRun) { logger.info('DRY-RUN: Ensure deprecation warning issue for ' + depName); } else { - await platform.ensureIssue(issueTitle, issueBody); + const ensureOnce = true; + await platform.ensureIssue(issueTitle, issueBody, ensureOnce); } } } diff --git a/test/platform/github/index.spec.js b/test/platform/github/index.spec.js index 94495a99a7c9e81e8e899b0af06999b3a8e23cd6..9545da9b62210a8a466c23d0fa85aa2ccc382ee2 100644 --- a/test/platform/github/index.spec.js +++ b/test/platform/github/index.spec.js @@ -1007,10 +1007,12 @@ describe('platform/github', () => { { number: 1, title: 'title-1', + state: 'open', }, { number: 2, title: 'title-2', + state: 'open', }, ], }); @@ -1026,26 +1028,67 @@ describe('platform/github', () => { { number: 1, title: 'title-1', + state: 'open', }, { number: 2, title: 'title-2', + state: 'open', }, ], })); const res = await github.ensureIssue('new-title', 'new-content'); expect(res).toEqual('created'); }); + it('creates issue if not ensuring only once', async () => { + get.mockImplementationOnce(() => ({ + body: [ + { + number: 1, + title: 'title-1', + state: 'closed', + }, + { + number: 2, + title: 'title-2', + state: 'open', + }, + ], + })); + const res = await github.ensureIssue('title-1', 'new-content'); + expect(res).toEqual(null); + }); + it('does not create issue if ensuring only once', async () => { + get.mockImplementationOnce(() => ({ + body: [ + { + number: 1, + title: 'title-1', + state: 'closed', + }, + { + number: 2, + title: 'title-2', + state: 'open', + }, + ], + })); + const once = true; + const res = await github.ensureIssue('title-1', 'new-content', once); + expect(res).toEqual(null); + }); it('updates issue', async () => { get.mockReturnValueOnce({ body: [ { number: 1, title: 'title-1', + state: 'open', }, { number: 2, title: 'title-2', + state: 'open', }, ], }); @@ -1059,10 +1102,12 @@ describe('platform/github', () => { { number: 1, title: 'title-1', + state: 'open', }, { number: 2, title: 'title-2', + state: 'open', }, ], }); @@ -1076,10 +1121,12 @@ describe('platform/github', () => { { number: 1, title: 'title-1', + state: 'open', }, { number: 2, title: 'title-1', + state: 'open', }, ], }); @@ -1095,10 +1142,12 @@ describe('platform/github', () => { { number: 1, title: 'title-1', + state: 'open', }, { number: 2, title: 'title-2', + state: 'open', }, ], })); diff --git a/test/workers/repository/process/__snapshots__/deprecated.spec.js.snap b/test/workers/repository/process/__snapshots__/deprecated.spec.js.snap index 2a743008502fe5495f8aa7a5f62960616a89be1f..6351b4b8cac88794f62f5bbfa57c4bff1cb76000 100644 --- a/test/workers/repository/process/__snapshots__/deprecated.spec.js.snap +++ b/test/workers/repository/process/__snapshots__/deprecated.spec.js.snap @@ -17,6 +17,7 @@ Affected package file(s): \`package.json\`, \`frontend/package.json\` \`\`\` ", + true, ], ] `;