Skip to content

Commit 467dfa0

Browse files
committed
remove quibble / need for mocking imports
1 parent e6aa1c4 commit 467dfa0

21 files changed

+1024
-810
lines changed

index.js

Lines changed: 61 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,101 @@
11
/* eslint require-atomic-updates: off */
22

3-
import {defaultTo, castArray} from 'lodash-es';
3+
import { defaultTo, castArray } from "lodash-es";
44

5-
import verifyGitHub from './lib/verify.js';
6-
import addChannelGitHub from './lib/add-channel.js';
7-
import publishGitHub from './lib/publish.js';
8-
import successGitHub from './lib/success.js';
9-
import failGitHub from './lib/fail.js';
5+
import verifyGitHub from "./lib/verify.js";
6+
import addChannelGitHub from "./lib/add-channel.js";
7+
import publishGitHub from "./lib/publish.js";
8+
import successGitHub from "./lib/success.js";
9+
import failGitHub from "./lib/fail.js";
10+
import { SemanticReleaseOctokit } from "./lib/octokit.js";
1011

1112
let verified;
1213

13-
export async function verifyConditions(pluginConfig, context) {
14-
const {options} = context;
14+
export async function verifyConditions(
15+
pluginConfig,
16+
context,
17+
{ Octokit = SemanticReleaseOctokit } = {}
18+
) {
19+
const { options } = context;
1520
// If the GitHub publish plugin is used and has `assets`, `successComment`, `failComment`, `failTitle`, `labels` or `assignees` configured, validate it now in order to prevent any release if the configuration is wrong
1621
if (options.publish) {
1722
const publishPlugin =
18-
castArray(options.publish).find((config) => config.path && config.path === '@semantic-release/github') || {};
23+
castArray(options.publish).find(
24+
(config) => config.path && config.path === "@semantic-release/github"
25+
) || {};
1926

2027
pluginConfig.assets = defaultTo(pluginConfig.assets, publishPlugin.assets);
21-
pluginConfig.successComment = defaultTo(pluginConfig.successComment, publishPlugin.successComment);
22-
pluginConfig.failComment = defaultTo(pluginConfig.failComment, publishPlugin.failComment);
23-
pluginConfig.failTitle = defaultTo(pluginConfig.failTitle, publishPlugin.failTitle);
28+
pluginConfig.successComment = defaultTo(
29+
pluginConfig.successComment,
30+
publishPlugin.successComment
31+
);
32+
pluginConfig.failComment = defaultTo(
33+
pluginConfig.failComment,
34+
publishPlugin.failComment
35+
);
36+
pluginConfig.failTitle = defaultTo(
37+
pluginConfig.failTitle,
38+
publishPlugin.failTitle
39+
);
2440
pluginConfig.labels = defaultTo(pluginConfig.labels, publishPlugin.labels);
25-
pluginConfig.assignees = defaultTo(pluginConfig.assignees, publishPlugin.assignees);
41+
pluginConfig.assignees = defaultTo(
42+
pluginConfig.assignees,
43+
publishPlugin.assignees
44+
);
2645
}
2746

28-
await verifyGitHub(pluginConfig, context);
47+
await verifyGitHub(pluginConfig, context, { Octokit });
2948
verified = true;
3049
}
3150

32-
export async function publish(pluginConfig, context) {
51+
export async function publish(
52+
pluginConfig,
53+
context,
54+
{ Octokit = SemanticReleaseOctokit } = {}
55+
) {
3356
if (!verified) {
34-
await verifyGitHub(pluginConfig, context);
57+
await verifyGitHub(pluginConfig, context, { Octokit });
3558
verified = true;
3659
}
3760

38-
return publishGitHub(pluginConfig, context);
61+
return publishGitHub(pluginConfig, context, { Octokit });
3962
}
4063

41-
export async function addChannel(pluginConfig, context) {
64+
export async function addChannel(
65+
pluginConfig,
66+
context,
67+
{ Octokit = SemanticReleaseOctokit } = {}
68+
) {
4269
if (!verified) {
43-
await verifyGitHub(pluginConfig, context);
70+
await verifyGitHub(pluginConfig, context, { Octokit });
4471
verified = true;
4572
}
4673

47-
return addChannelGitHub(pluginConfig, context);
74+
return addChannelGitHub(pluginConfig, context, { Octokit });
4875
}
4976

50-
export async function success(pluginConfig, context) {
77+
export async function success(
78+
pluginConfig,
79+
context,
80+
{ Octokit = SemanticReleaseOctokit } = {}
81+
) {
5182
if (!verified) {
52-
await verifyGitHub(pluginConfig, context);
83+
await verifyGitHub(pluginConfig, context, { Octokit });
5384
verified = true;
5485
}
5586

56-
await successGitHub(pluginConfig, context);
87+
await successGitHub(pluginConfig, context, { Octokit });
5788
}
5889

59-
export async function fail(pluginConfig, context) {
90+
export async function fail(
91+
pluginConfig,
92+
context,
93+
{ Octokit = SemanticReleaseOctokit } = {}
94+
) {
6095
if (!verified) {
61-
await verifyGitHub(pluginConfig, context);
96+
await verifyGitHub(pluginConfig, context, { Octokit });
6297
verified = true;
6398
}
6499

65-
await failGitHub(pluginConfig, context);
100+
await failGitHub(pluginConfig, context, { Octokit });
66101
}

lib/add-channel.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ import debugFactory from "debug";
33
import { RELEASE_NAME } from "./definitions/constants.js";
44
import parseGithubUrl from "./parse-github-url.js";
55
import resolveConfig from "./resolve-config.js";
6-
import getClient from "./get-client.js";
76
import isPrerelease from "./is-prerelease.js";
7+
import { toOctokitOptions, SemanticReleaseOctokit } from "./octokit.js";
88

99
const debug = debugFactory("semantic-release:github");
1010

11-
export default async function addChannel(pluginConfig, context) {
11+
export default async function addChannel(
12+
pluginConfig,
13+
context,
14+
{ Octokit = SemanticReleaseOctokit } = {}
15+
) {
1216
const {
1317
options: { repositoryUrl },
1418
branch,
@@ -20,12 +24,14 @@ export default async function addChannel(pluginConfig, context) {
2024
context
2125
);
2226
const { owner, repo } = parseGithubUrl(repositoryUrl);
23-
const octokit = getClient({
24-
githubToken,
25-
githubUrl,
26-
githubApiPathPrefix,
27-
proxy,
28-
});
27+
const octokit = new Octokit(
28+
toOctokitOptions({
29+
githubToken,
30+
githubUrl,
31+
githubApiPathPrefix,
32+
proxy,
33+
})
34+
);
2935
let releaseId;
3036

3137
const release = {

lib/fail.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ import debugFactory from "debug";
44
import parseGithubUrl from "./parse-github-url.js";
55
import { ISSUE_ID } from "./definitions/constants.js";
66
import resolveConfig from "./resolve-config.js";
7-
import getClient from "./get-client.js";
7+
import { toOctokitOptions, SemanticReleaseOctokit } from "./octokit.js";
88
import findSRIssues from "./find-sr-issues.js";
99
import getFailComment from "./get-fail-comment.js";
1010

1111
const debug = debugFactory("semantic-release:github");
1212

13-
export default async function fail(pluginConfig, context) {
13+
export default async function fail(
14+
pluginConfig,
15+
context,
16+
{ Octokit = SemanticReleaseOctokit } = {}
17+
) {
1418
const {
1519
options: { repositoryUrl },
1620
branch,
@@ -31,12 +35,9 @@ export default async function fail(pluginConfig, context) {
3135
if (failComment === false || failTitle === false) {
3236
logger.log("Skip issue creation.");
3337
} else {
34-
const octokit = getClient({
35-
githubToken,
36-
githubUrl,
37-
githubApiPathPrefix,
38-
proxy,
39-
});
38+
const octokit = new Octokit(
39+
toOctokitOptions({ githubToken, githubUrl, githubApiPathPrefix, proxy })
40+
);
4041
// In case the repo changed name, get the new `repo`/`owner` as the search API will not follow redirects
4142
const { data: repoData } = await octokit.request(
4243
"GET /repos/{owner}/{repo}",

lib/get-client.js

Lines changed: 0 additions & 34 deletions
This file was deleted.

lib/octokit.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* c8 ignore start */
2+
// @ts-check
3+
4+
// If maintaining @octokit/core and the separate plugins gets to cumbersome
5+
// then the `octokit` package can be used which has all these plugins included.
6+
// However the `octokit` package has a lot of other things we don't care about.
7+
// We use only the bits we need to minimize the size of the package.
8+
import { Octokit } from "@octokit/core";
9+
import { paginateRest } from "@octokit/plugin-paginate-rest";
10+
import { retry } from "@octokit/plugin-retry";
11+
import { throttling } from "@octokit/plugin-throttling";
12+
import urljoin from "url-join";
13+
import { HttpProxyAgent } from "http-proxy-agent";
14+
import { HttpsProxyAgent } from "https-proxy-agent";
15+
import nodeFetch from "node-fetch";
16+
17+
import { RETRY_CONF } from "./definitions/retry.js";
18+
import { THROTTLE_CONF } from "./definitions/throttle.js";
19+
20+
const onRetry = (retryAfter, options, octokit, retryCount) => {
21+
octokit.log.warn(
22+
`Request quota exhausted for request ${options.method} ${options.url}`
23+
);
24+
25+
if (retryCount <= RETRY_CONF.retries) {
26+
octokit.log.debug(`Will retry after ${retryAfter}.`);
27+
return true;
28+
}
29+
};
30+
31+
export const SemanticReleaseOctokit = Octokit.plugin(
32+
paginateRest,
33+
retry,
34+
throttling
35+
).defaults({
36+
userAgent: `@semantic-release/github`,
37+
retry: RETRY_CONF,
38+
throttle: {
39+
...THROTTLE_CONF,
40+
onRateLimit: onRetry,
41+
onSecondaryRateLimit: onRetry,
42+
},
43+
});
44+
/* c8 ignore stop */
45+
46+
/**
47+
* @param {{githubToken: string, proxy: any} | {githubUrl: string, githubApiPathPrefix: string, githubToken: string, proxy: any}} options
48+
* @returns {{ auth: string, baseUrl: undefined | string, request: { agent?: any, fetch: nodeFetch } }}
49+
*/
50+
export function toOctokitOptions(options) {
51+
const baseUrl =
52+
"githubUrl" in options && options.githubUrl
53+
? urljoin(options.githubUrl, options.githubApiPathPrefix)
54+
: undefined;
55+
56+
const agent = options.proxy
57+
? baseUrl && new URL(baseUrl).protocol.replace(":", "") === "http"
58+
? // Some `proxy.headers` need to be passed as second arguments since version 6 or 7
59+
// For simplicity, we just pass the same proxy object twice. It works 🤷🏻
60+
new HttpProxyAgent(options.proxy, options.proxy)
61+
: new HttpsProxyAgent(options.proxy, options.proxy)
62+
: undefined;
63+
64+
return {
65+
baseUrl,
66+
auth: options.githubToken,
67+
request: {
68+
// TODO: we temporary use use `node-fetch` because `nock` does not support
69+
// mocking Node's native fetch yet. The plan is to replace nock with `fetch-mock`
70+
// before merging this PR.
71+
fetch: nodeFetch,
72+
73+
agent,
74+
},
75+
};
76+
}

0 commit comments

Comments
 (0)