From 39c99e5de070ea5f06bb8357418f831867aec5a6 Mon Sep 17 00:00:00 2001 From: babblebey Date: Mon, 28 Apr 2025 19:00:04 +0100 Subject: [PATCH 1/4] refactor: remove unused title parameter and deprecated fallback for issue retrieval --- lib/find-sr-issues.js | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/lib/find-sr-issues.js b/lib/find-sr-issues.js index 47af4104..c4c76655 100644 --- a/lib/find-sr-issues.js +++ b/lib/find-sr-issues.js @@ -1,7 +1,7 @@ import { uniqBy } from "lodash-es"; import { ISSUE_ID, RELEASE_FAIL_LABEL } from "./definitions/constants.js"; -export default async (octokit, logger, title, labels, owner, repo) => { +export default async (octokit, logger, labels, owner, repo) => { let issues = []; const { @@ -18,25 +18,6 @@ export default async (octokit, logger, title, labels, owner, repo) => { issues.push(...issueNodes); - /** - * BACKWARD COMPATIBILITY: Fallback to the search API if the issue was not found in the GraphQL response. - * This fallback will be removed in a future release - */ - if (issueNodes.length === 0) { - try { - const { - data: { items: backwardIssues }, - } = await octokit.request("GET /search/issues", { - q: `in:title+repo:${owner}/${repo}+type:issue+state:open+${title}`, - }); - issues.push(...backwardIssues); - } catch (error) { - logger.log( - "An error occured fetching issue via fallback (with GH SearchAPI)", - ); - } - } - const uniqueSRIssues = uniqBy( issues.filter((issue) => issue.body && issue.body.includes(ISSUE_ID)), "number", From e778ca38e983bba1f7008392fd3ed219632524f6 Mon Sep 17 00:00:00 2001 From: babblebey Date: Mon, 28 Apr 2025 19:00:28 +0100 Subject: [PATCH 2/4] fix: correct typo in GraphQL query documentation --- lib/find-sr-issues.js | 2 +- lib/success.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/find-sr-issues.js b/lib/find-sr-issues.js index c4c76655..10a52716 100644 --- a/lib/find-sr-issues.js +++ b/lib/find-sr-issues.js @@ -27,7 +27,7 @@ export default async (octokit, logger, labels, owner, repo) => { }; /** - * GraphQL Query to et the semantic-release issues for a repository. + * GraphQL Query to get the semantic-release issues for a repository. */ const loadGetSRIssuesQuery = `#graphql query getSRIssues($owner: String!, $repo: String!, $filter: IssueFilters) { diff --git a/lib/success.js b/lib/success.js index 5363863c..77b66f22 100644 --- a/lib/success.js +++ b/lib/success.js @@ -269,7 +269,6 @@ export default async function success(pluginConfig, context, { Octokit }) { const srIssues = await findSRIssues( octokit, logger, - failTitle, labels, owner, repo, From 648bb78ff8a76179151ab2a291a5339f6b353d63 Mon Sep 17 00:00:00 2001 From: babblebey Date: Mon, 28 Apr 2025 19:44:54 +0100 Subject: [PATCH 3/4] refactor: simplify findSRIssues call by removing unnecessary line breaks --- lib/success.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/success.js b/lib/success.js index 77b66f22..997368cf 100644 --- a/lib/success.js +++ b/lib/success.js @@ -266,13 +266,7 @@ export default async function success(pluginConfig, context, { Octokit }) { if (failComment === false || failTitle === false) { logger.log("Skip closing issue."); } else { - const srIssues = await findSRIssues( - octokit, - logger, - labels, - owner, - repo, - ); + const srIssues = await findSRIssues(octokit, logger, labels, owner, repo); debug("found semantic-release issues: %O", srIssues); From 4c97e1ad513954f79e889dcc40372d4e6c8559a7 Mon Sep 17 00:00:00 2001 From: babblebey Date: Mon, 28 Apr 2025 20:09:18 +0100 Subject: [PATCH 4/4] refactor: remove redundant GitHub issue search calls from tests --- test/fail.test.js | 42 ---------- test/find-sr-issue.test.js | 92 +-------------------- test/integration.test.js | 40 ---------- test/success.test.js | 160 +------------------------------------ 4 files changed, 3 insertions(+), 331 deletions(-) diff --git a/test/fail.test.js b/test/fail.test.js index 6daa543d..6d1f9d91 100644 --- a/test/fail.test.js +++ b/test/fail.test.js @@ -48,16 +48,6 @@ test("Open a new issue with the list of errors", async (t) => { }, }, }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent( - `repo:${redirectedOwner}/${redirectedRepo}`, - )}+${encodeURIComponent("type:issue")}+${encodeURIComponent( - "state:open", - )}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .postOnce( (url, { body }) => { t.is( @@ -136,14 +126,6 @@ test("Open a new issue with the list of errors and custom title and comment", as }, }, }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .postOnce( `https://api.github.local/repos/${owner}/${repo}/issues`, { html_url: "https://github.com/issues/1", number: 1 }, @@ -211,14 +193,6 @@ test("Open a new issue with assignees and the list of errors", async (t) => { }, }, }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .postOnce( (url, { body }) => { t.is(url, `https://api.github.local/repos/${owner}/${repo}/issues`); @@ -291,14 +265,6 @@ test("Open a new issue without labels and the list of errors", async (t) => { }, }, }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .postOnce( (url, { body }) => { t.is(url, `https://api.github.local/repos/${owner}/${repo}/issues`); @@ -599,14 +565,6 @@ test(`Post new issue if none exists yet, but don't comment on existing issues wh }, }, ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .postOnce( (url, { body }) => { t.is(url, `https://api.github.local/repos/${owner}/${repo}/issues`); diff --git a/test/find-sr-issue.test.js b/test/find-sr-issue.test.js index 3916e859..5009372d 100644 --- a/test/find-sr-issue.test.js +++ b/test/find-sr-issue.test.js @@ -69,7 +69,6 @@ test("Return empty array if not issues found", async (t) => { const repo = "test_repo"; const title = "The automated release is failing 🚨"; const labels = []; - const issues = []; const fetch = fetchMock .sandbox() .postOnce("https://api.github.local/graphql", { @@ -78,15 +77,7 @@ test("Return empty array if not issues found", async (t) => { issues: { nodes: [] }, }, }, - }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(title)}`, - { items: issues }, - ); + }); const srIssues = await findSRIssues( new TestOctokit({ request: { fetch } }), @@ -133,84 +124,3 @@ test("Return empty array if not issues has matching ID", async (t) => { t.deepEqual(srIssues, []); t.true(fetch.done()); }); - -test("Handle error in searchAPI fallback", async (t) => { - const owner = "test_user"; - const repo = "test_repo"; - const title = "The automated release is failing 🚨"; - const labels = []; - const issues = []; - - const response = new Response("Not Found", { - url: "https://api.github.com/search/issues?q=in%3Atitle+repo%3Aourorg%2Frepo+type%3Aissue+state%3Aopen+The%20automated%20release%20is%20failing%20%F0%9F%9A%A8", - status: 403, - headers: { - "access-control-allow-origin": "*", - "access-control-expose-headers": - "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset", - "content-encoding": "gzip", - "content-security-policy": "default-repo 'none'", - "content-type": "application/json; charset=utf-8", - date: "Tue, 28 May 2024 19:49:00 GMT", - "referrer-policy": - "origin-when-cross-origin, strict-origin-when-cross-origin", - server: "GitHub.com", - "strict-transport-security": - "max-age=31536000; includeSubdomains; preload", - "transfer-encoding": "chunked", - vary: "Accept-Encoding, Accept, X-Requested-With", - "x-content-type-options": "nosniff", - "x-frame-options": "deny", - "x-github-api-version-selected": "2022-11-28", - "x-github-media-type": "github.v3; format=json", - "x-github-request-id": "2**0:29*****4:3868737:6*****3:6****52C", - "x-ratelimit-limit": "30", - "x-ratelimit-remaining": "30", - "x-ratelimit-reset": "1716925800", - "x-ratelimit-resource": "search", - "x-ratelimit-used": "1", - "x-xss-protection": "0", - }, - data: { - documentation_url: - "https://docs.github.com/free-pro-team@latest/rest/overview/rate-limits-for-the-rest-api#about-secondary-rate-limits", - message: - "You have exceeded a secondary rate limit. Please wait a few minutes before you try again. If you reach out to GitHub Support for help, please include the request ID 2840:295B44:3868737:64A2183:6232352C.", - }, - }); - - const fetch = fetchMock - .sandbox() - .postOnce("https://api.github.local/graphql", { - data: { - repository: { - issues: { nodes: issues }, - }, - }, - }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(title)}`, - response, - ); - - const srIssues = await findSRIssues( - new TestOctokit({ request: { fetch } }), - t.context.logger, - title, - labels, - owner, - repo, - ); - - t.true( - t.context.log.calledWith( - "An error occured fetching issue via fallback (with GH SearchAPI)", - ), - ); - t.log(t.context.log); - t.true(fetch.done()); -}); diff --git a/test/integration.test.js b/test/integration.test.js index ffcae3ed..b4b83f55 100644 --- a/test/integration.test.js +++ b/test/integration.test.js @@ -517,14 +517,6 @@ test("Comment and add labels on PR included in the releases", async (t) => { }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await t.context.m.success( @@ -590,14 +582,6 @@ test("Open a new issue with the list of errors", async (t) => { }, }, }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .postOnce( (url, { body }) => { t.is(url, `https://api.github.local/repos/${owner}/${repo}/issues`); @@ -751,14 +735,6 @@ test("Verify, release and notify success", async (t) => { {}, { body: ["released"] }, ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .postOnce( `${uploadOrigin}${uploadUri}?name=${encodeURIComponent("upload.txt")}&`, { browser_download_url: assetUrl }, @@ -938,14 +914,6 @@ test("Verify, update release and notify success", async (t) => { }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await t.notThrowsAsync( @@ -1036,14 +1004,6 @@ test("Verify and notify failure", async (t) => { }, }, }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .postOnce(`https://api.github.local/repos/${owner}/${repo}/issues`, { html_url: "https://github.com/issues/1", number: 1, diff --git a/test/success.test.js b/test/success.test.js index 6f8a4ed5..f7eecd90 100644 --- a/test/success.test.js +++ b/test/success.test.js @@ -239,16 +239,6 @@ test("Add comment and labels to PRs associated with release commits and issues s }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent( - `repo:${redirectedOwner}/${redirectedRepo}`, - )}+${encodeURIComponent("type:issue")}+${encodeURIComponent( - "state:open", - )}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -537,16 +527,6 @@ test("Add comment and labels to PRs associated with release commits and issues ( }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent( - `repo:${owner}/${repo}`, - )}+${encodeURIComponent("type:issue")}+${encodeURIComponent( - "state:open", - )}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -1118,14 +1098,6 @@ test("Make multiple search queries if necessary", async (t) => { }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -1309,14 +1281,6 @@ test("Do not add comment and labels for unrelated PR returned by search (compare }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -1408,14 +1372,6 @@ test("Do not add comment and labels if no PR is associated with release commits" }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -1467,15 +1423,7 @@ test("Do not add comment and labels if no commits is found for release", async ( issues: { nodes: [] }, }, }, - }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ); + }); await success( pluginConfig, @@ -1635,14 +1583,6 @@ test("Do not add comment and labels to PR/issues from other repo", async (t) => }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -1930,14 +1870,6 @@ test("Ignore missing and forbidden issues/PRs", async (t) => { }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -2085,14 +2017,6 @@ test("Add custom comment and labels", async (t) => { }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -2202,14 +2126,6 @@ test("Add custom label", async (t) => { }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -2310,14 +2226,6 @@ test("Comment on issue/PR without ading a label", async (t) => { }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -2431,14 +2339,6 @@ test("Editing the release to include all release links at the bottom", async (t) }, }, ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .patchOnce( `https://api.github.local/repos/${owner}/${repo}/releases/${releaseId}`, { @@ -2562,14 +2462,6 @@ test("Editing the release to include all release links at the top", async (t) => }, }, ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ) .patchOnce( `https://api.github.local/repos/${owner}/${repo}/releases/${releaseId}`, { @@ -2689,14 +2581,6 @@ test("Editing the release to include all release links with no additional releas }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -2806,14 +2690,6 @@ test("Editing the release to include all release links with no additional releas }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -2916,14 +2792,6 @@ test("Editing the release to include all release links with no releases", async }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -3028,14 +2896,6 @@ test("Editing the release with no ID in the release", async (t) => { }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -3401,14 +3261,6 @@ test('Skip comment on on issues/PR if "successComment" is "false"', async (t) => }, }, }, - ) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, ); await success( @@ -3468,15 +3320,7 @@ test('Does not comment/label on issues/PR if "successCommentCondition" is "false issues: { nodes: [] }, }, }, - }) - .getOnce( - `https://api.github.local/search/issues?q=${encodeURIComponent( - "in:title", - )}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent( - "type:issue", - )}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`, - { items: [] }, - ); + }); await success( pluginConfig,