Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 311eecf

Browse filesBrowse files
authored
Merge branch 'master' into add/warn
2 parents 775480e + 7fb46a3 commit 311eecf
Copy full SHA for 311eecf

File tree

8 files changed

+998
-303
lines changed
Filter options

8 files changed

+998
-303
lines changed

‎lib/definitions/constants.js

Copy file name to clipboard
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
export const ISSUE_ID = "<!-- semantic-release:github -->";
22

33
export const RELEASE_NAME = "GitHub release";
4+
5+
export const RELEASE_FAIL_LABEL = "semantic-release";

‎lib/fail.js

Copy file name to clipboardExpand all lines: lib/fail.js
+10-3Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { template } from "lodash-es";
22
import debugFactory from "debug";
33

44
import parseGithubUrl from "./parse-github-url.js";
5-
import { ISSUE_ID } from "./definitions/constants.js";
5+
import { ISSUE_ID, RELEASE_FAIL_LABEL } from "./definitions/constants.js";
66
import resolveConfig from "./resolve-config.js";
77
import { toOctokitOptions } from "./octokit.js";
88
import findSRIssues from "./find-sr-issues.js";
@@ -56,7 +56,14 @@ export default async function fail(pluginConfig, context, { Octokit }) {
5656
const body = failComment
5757
? template(failComment)({ branch, errors })
5858
: getFailComment(branch, errors);
59-
const [srIssue] = await findSRIssues(octokit, failTitle, owner, repo);
59+
const [srIssue] = await findSRIssues(
60+
octokit,
61+
logger,
62+
failTitle,
63+
labels,
64+
owner,
65+
repo,
66+
);
6067

6168
const canCommentOnOrCreateIssue = failCommentCondition
6269
? template(failCommentCondition)({ ...context, issue: srIssue })
@@ -84,7 +91,7 @@ export default async function fail(pluginConfig, context, { Octokit }) {
8491
repo,
8592
title: failTitle,
8693
body: `${body}\n\n${ISSUE_ID}`,
87-
labels: labels || [],
94+
labels: (labels || []).concat([RELEASE_FAIL_LABEL]),
8895
assignees,
8996
};
9097
debug("create issue: %O", newIssue);

‎lib/find-sr-issues.js

Copy file name to clipboard
+58-6Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,63 @@
1-
import { ISSUE_ID } from "./definitions/constants.js";
1+
import { uniqBy } from "lodash-es";
2+
import { ISSUE_ID, RELEASE_FAIL_LABEL } from "./definitions/constants.js";
3+
4+
export default async (octokit, logger, title, labels, owner, repo) => {
5+
let issues = [];
26

3-
export default async (octokit, title, owner, repo) => {
47
const {
5-
data: { items: issues },
6-
} = await octokit.request("GET /search/issues", {
7-
q: `in:title+repo:${owner}/${repo}+type:issue+state:open+${title}`,
8+
repository: {
9+
issues: { nodes: issueNodes },
10+
},
11+
} = await octokit.graphql(loadGetSRIssuesQuery, {
12+
owner,
13+
repo,
14+
filter: {
15+
labels: (labels || []).concat([RELEASE_FAIL_LABEL]),
16+
},
817
});
918

10-
return issues.filter((issue) => issue.body && issue.body.includes(ISSUE_ID));
19+
issues.push(...issueNodes);
20+
21+
/**
22+
* BACKWARD COMPATIBILITY: Fallback to the search API if the issue was not found in the GraphQL response.
23+
* This fallback will be removed in a future release
24+
*/
25+
if (issueNodes.length === 0) {
26+
try {
27+
const {
28+
data: { items: backwardIssues },
29+
} = await octokit.request("GET /search/issues", {
30+
q: `in:title+repo:${owner}/${repo}+type:issue+state:open+${title}`,
31+
});
32+
issues.push(...backwardIssues);
33+
} catch (error) {
34+
logger.log(
35+
"An error occured fetching issue via fallback (with GH SearchAPI)",
36+
);
37+
}
38+
}
39+
40+
const uniqueSRIssues = uniqBy(
41+
issues.filter((issue) => issue.body && issue.body.includes(ISSUE_ID)),
42+
"number",
43+
);
44+
45+
return uniqueSRIssues;
1146
};
47+
48+
/**
49+
* GraphQL Query to et the semantic-release issues for a repository.
50+
*/
51+
const loadGetSRIssuesQuery = `#graphql
52+
query getSRIssues($owner: String!, $repo: String!, $filter: IssueFilters) {
53+
repository(owner: $owner, name: $repo) {
54+
issues(first: 100, states: OPEN, filterBy: $filter) {
55+
nodes {
56+
number
57+
title
58+
body
59+
}
60+
}
61+
}
62+
}
63+
`;

‎lib/success.js

Copy file name to clipboardExpand all lines: lib/success.js
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export default async function success(pluginConfig, context, { Octokit }) {
2828
githubApiPathPrefix,
2929
githubApiUrl,
3030
proxy,
31+
labels,
3132
successComment,
3233
successCommentCondition,
3334
failTitle,
@@ -265,7 +266,14 @@ export default async function success(pluginConfig, context, { Octokit }) {
265266
if (failComment === false || failTitle === false) {
266267
logger.log("Skip closing issue.");
267268
} else {
268-
const srIssues = await findSRIssues(octokit, failTitle, owner, repo);
269+
const srIssues = await findSRIssues(
270+
octokit,
271+
logger,
272+
failTitle,
273+
labels,
274+
owner,
275+
repo,
276+
);
269277

270278
debug("found semantic-release issues: %O", srIssues);
271279

‎test/fail.test.js

Copy file name to clipboardExpand all lines: test/fail.test.js
+63-20Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import sinon from "sinon";
33
import test from "ava";
44
import fetchMock from "fetch-mock";
55

6-
import { ISSUE_ID } from "../lib/definitions/constants.js";
6+
import { ISSUE_ID, RELEASE_FAIL_LABEL } from "../lib/definitions/constants.js";
77
import { TestOctokit } from "./helpers/test-octokit.js";
88

99
/* eslint camelcase: ["error", {properties: "never"}] */
@@ -41,6 +41,13 @@ test("Open a new issue with the list of errors", async (t) => {
4141
.getOnce("https://api.github.local/repos/test_user/test_repo", {
4242
full_name: `${redirectedOwner}/${redirectedRepo}`,
4343
})
44+
.postOnce("https://api.github.local/graphql", {
45+
data: {
46+
repository: {
47+
issues: { nodes: [] },
48+
},
49+
},
50+
})
4451
.getOnce(
4552
`https://api.github.local/search/issues?q=${encodeURIComponent(
4653
"in:title",
@@ -64,7 +71,7 @@ test("Open a new issue with the list of errors", async (t) => {
6471
data.body,
6572
/---\n\n### Error message 1\n\nError 1 details\n\n---\n\n### Error message 2\n\nError 2 details\n\n---\n\n### Error message 3\n\nError 3 details\n\n---/,
6673
);
67-
t.deepEqual(data.labels, ["semantic-release"]);
74+
t.deepEqual(data.labels, ["semantic-release", RELEASE_FAIL_LABEL]);
6875
return true;
6976
},
7077
{
@@ -122,6 +129,13 @@ test("Open a new issue with the list of errors and custom title and comment", as
122129
full_name: `${owner}/${repo}`,
123130
clone_url: `https://api.github.local/${owner}/${repo}.git`,
124131
})
132+
.postOnce("https://api.github.local/graphql", {
133+
data: {
134+
repository: {
135+
issues: { nodes: [] },
136+
},
137+
},
138+
})
125139
.getOnce(
126140
`https://api.github.local/search/issues?q=${encodeURIComponent(
127141
"in:title",
@@ -137,7 +151,7 @@ test("Open a new issue with the list of errors and custom title and comment", as
137151
body: {
138152
title: failTitle,
139153
body: `branch master Error message 1 Error message 2 Error message 3\n\n${ISSUE_ID}`,
140-
labels: ["semantic-release"],
154+
labels: ["semantic-release", RELEASE_FAIL_LABEL],
141155
},
142156
},
143157
);
@@ -190,6 +204,13 @@ test("Open a new issue with assignees and the list of errors", async (t) => {
190204
full_name: `${owner}/${repo}`,
191205
clone_url: `https://api.github.local/${owner}/${repo}.git`,
192206
})
207+
.postOnce("https://api.github.local/graphql", {
208+
data: {
209+
repository: {
210+
issues: { nodes: [] },
211+
},
212+
},
213+
})
193214
.getOnce(
194215
`https://api.github.local/search/issues?q=${encodeURIComponent(
195216
"in:title",
@@ -208,7 +229,7 @@ test("Open a new issue with assignees and the list of errors", async (t) => {
208229
data.body,
209230
/---\n\n### Error message 1\n\nError 1 details\n\n---\n\n### Error message 2\n\nError 2 details\n\n---/,
210231
);
211-
t.deepEqual(data.labels, ["semantic-release"]);
232+
t.deepEqual(data.labels, ["semantic-release", RELEASE_FAIL_LABEL]);
212233
t.deepEqual(data.assignees, ["user1", "user2"]);
213234
return true;
214235
},
@@ -263,6 +284,13 @@ test("Open a new issue without labels and the list of errors", async (t) => {
263284
full_name: `${owner}/${repo}`,
264285
clone_url: `https://api.github.local/${owner}/${repo}.git`,
265286
})
287+
.postOnce("https://api.github.local/graphql", {
288+
data: {
289+
repository: {
290+
issues: { nodes: [] },
291+
},
292+
},
293+
})
266294
.getOnce(
267295
`https://api.github.local/search/issues?q=${encodeURIComponent(
268296
"in:title",
@@ -281,7 +309,7 @@ test("Open a new issue without labels and the list of errors", async (t) => {
281309
data.body,
282310
/---\n\n### Error message 1\n\nError 1 details\n\n---\n\n### Error message 2\n\nError 2 details\n\n---/,
283311
);
284-
t.deepEqual(data.labels, []);
312+
t.deepEqual(data.labels, [RELEASE_FAIL_LABEL]);
285313
return true;
286314
},
287315
{ html_url: "https://github.com/issues/1", number: 1 },
@@ -340,14 +368,13 @@ test("Update the first existing issue with the list of errors", async (t) => {
340368
full_name: `${owner}/${repo}`,
341369
clone_url: `https://api.github.local/${owner}/${repo}.git`,
342370
})
343-
.getOnce(
344-
`https://api.github.local/search/issues?q=${encodeURIComponent(
345-
"in:title",
346-
)}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent(
347-
"type:issue",
348-
)}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`,
349-
{ items: issues },
350-
)
371+
.postOnce("https://api.github.local/graphql", {
372+
data: {
373+
repository: {
374+
issues: { nodes: issues },
375+
},
376+
},
377+
})
351378
.postOnce(
352379
(url, { body }) => {
353380
t.is(
@@ -506,13 +533,17 @@ test('Does not post comments on existing issues when "failCommentCondition" is "
506533
.getOnce(`https://api.github.local/repos/${owner}/${repo}`, {
507534
full_name: `${owner}/${repo}`,
508535
})
509-
.getOnce(
510-
`https://api.github.local/search/issues?q=${encodeURIComponent(
511-
"in:title",
512-
)}+${encodeURIComponent(`repo:${owner}/${repo}`)}+${encodeURIComponent(
513-
"type:issue",
514-
)}+${encodeURIComponent("state:open")}+${encodeURIComponent(failTitle)}`,
515-
{ items: issues },
536+
.postOnce(
537+
(url, { body }) =>
538+
url === "https://api.github.local/graphql" &&
539+
JSON.parse(body).query.includes("query getSRIssues("),
540+
{
541+
data: {
542+
repository: {
543+
issues: { nodes: issues },
544+
},
545+
},
546+
},
516547
);
517548

518549
await fail(
@@ -556,6 +587,18 @@ test(`Post new issue if none exists yet, but don't comment on existing issues wh
556587
.getOnce(`https://api.github.local/repos/${owner}/${repo}`, {
557588
full_name: `${owner}/${repo}`,
558589
})
590+
.postOnce(
591+
(url, { body }) =>
592+
url === "https://api.github.local/graphql" &&
593+
JSON.parse(body).query.includes("query getSRIssues("),
594+
{
595+
data: {
596+
repository: {
597+
issues: { nodes: [] },
598+
},
599+
},
600+
},
601+
)
559602
.getOnce(
560603
`https://api.github.local/search/issues?q=${encodeURIComponent(
561604
"in:title",

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.