@semantic-release/github 4.2.18 → 4.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -2
- package/lib/definitions/errors.js +10 -2
- package/lib/definitions/rate-limit.js +27 -0
- package/lib/fail.js +2 -2
- package/lib/get-client.js +57 -43
- package/lib/publish.js +2 -2
- package/lib/resolve-config.js +2 -0
- package/lib/success.js +5 -4
- package/lib/verify.js +7 -5
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -50,6 +50,7 @@ Follow the [Creating a personal access token for the command line](https://help.
|
|
|
50
50
|
|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
51
51
|
| `githubUrl` | The GitHub Enterprise endpoint. | `GH_URL` or `GITHUB_URL` environment variable. |
|
|
52
52
|
| `githubApiPathPrefix` | The GitHub Enterprise API prefix. | `GH_PREFIX` or `GITHUB_PREFIX` environment variable. |
|
|
53
|
+
| `proxy` | The proxy to use to access the GitHub API. See [proxy](#proxy). | `HTTP_PROXY` environment variable. |
|
|
53
54
|
| `assets` | An array of files to upload to the release. See [assets](#assets). | - |
|
|
54
55
|
| `successComment` | The comment added to each issue and pull request resolved by the release. See [successComment](#successcomment). | `:tada: This issue has been resolved in version ${nextRelease.version} :tada:\n\nThe release is available on [GitHub release](<github_release_url>)` |
|
|
55
56
|
| `failComment` | The content of the issue created when a release fails. See [failComment](#failcomment). | Friendly message with links to **semantic-release** documentation and support, with the list of errors that caused the release to fail. |
|
|
@@ -59,10 +60,28 @@ Follow the [Creating a personal access token for the command line](https://help.
|
|
|
59
60
|
|
|
60
61
|
**Note**: If you use a [shareable configuration](https://github.com/semantic-release/semantic-release/blob/caribou/docs/usage/shareable-configurations.md#shareable-configurations) that defines one of these options you can set it to `false` in your [**semantic-release** configuration](https://github.com/semantic-release/semantic-release/blob/caribou/docs/usage/configuration.md#configuration) in order to use the default value.
|
|
61
62
|
|
|
63
|
+
#### proxy
|
|
64
|
+
|
|
65
|
+
Can be a the proxy URL or and `Object` with the following properties:
|
|
66
|
+
|
|
67
|
+
| Property | Description | Default |
|
|
68
|
+
|---------------|----------------------------------------------------------------|--------------------------------------|
|
|
69
|
+
| `host` | **Required.** Proxy host to connect to. | - |
|
|
70
|
+
| `port` | **Required.** Proxy port to connect to. | File name extracted from the `path`. |
|
|
71
|
+
| `secureProxy` | If `true`, then use TLS to connect to the proxy. | `false` |
|
|
72
|
+
| `headers` | Additional HTTP headers to be sent on the HTTP CONNECT method. | - |
|
|
73
|
+
|
|
74
|
+
See [node-https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent#new-httpsproxyagentobject-options) and [node-http-proxy-agent](https://github.com/TooTallNate/node-http-proxy-agent) for additional details.
|
|
75
|
+
|
|
76
|
+
##### proxy examples
|
|
77
|
+
|
|
78
|
+
`'http://168.63.76.32:3128'`: use the proxy running on host `168.63.76.32` and port `3128` for each GitHub API request.
|
|
79
|
+
`{host: '168.63.76.32', port: 3128, headers: {Foo: 'bar'}}`: use the proxy running on host `168.63.76.32` and port `3128` for each GitHub API request, setting the `Foo` header value to `bar`.
|
|
80
|
+
|
|
62
81
|
#### assets
|
|
63
82
|
|
|
64
83
|
Can be a [glob](https://github.com/isaacs/node-glob#glob-primer) or and `Array` of
|
|
65
|
-
[globs](https://github.com/isaacs/node-glob#glob-primer) and `Object`s with the following properties
|
|
84
|
+
[globs](https://github.com/isaacs/node-glob#glob-primer) and `Object`s with the following properties:
|
|
66
85
|
|
|
67
86
|
| Property | Description | Default |
|
|
68
87
|
| -------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------ |
|
|
@@ -76,7 +95,7 @@ can be a `String` (`"dist/**/*.js"` or `"dist/mylib.js"`) or an `Array` of `Stri
|
|
|
76
95
|
|
|
77
96
|
If a directory is configured, all the files under this directory and its children will be included.
|
|
78
97
|
|
|
79
|
-
|
|
98
|
+
**Note**: If a file has a match in `assets` it will be included even if it also has a match in `.gitignore`.
|
|
80
99
|
|
|
81
100
|
##### assets examples
|
|
82
101
|
|
|
@@ -43,7 +43,7 @@ Your configuration for the \`failComment\` option is \`${stringify(failComment)}
|
|
|
43
43
|
EINVALIDLABELS: ({labels}) => ({
|
|
44
44
|
message: 'Invalid `labels` option.',
|
|
45
45
|
details: `The [labels option](${linkify(
|
|
46
|
-
'README.md#
|
|
46
|
+
'README.md#options'
|
|
47
47
|
)}) option, if defined, must be an \`Array\` of non empty \`String\`.
|
|
48
48
|
|
|
49
49
|
Your configuration for the \`labels\` option is \`${stringify(labels)}\`.`,
|
|
@@ -51,7 +51,7 @@ Your configuration for the \`labels\` option is \`${stringify(labels)}\`.`,
|
|
|
51
51
|
EINVALIDASSIGNEES: ({assignees}) => ({
|
|
52
52
|
message: 'Invalid `assignees` option.',
|
|
53
53
|
details: `The [assignees option](${linkify(
|
|
54
|
-
'README.md#
|
|
54
|
+
'README.md#options'
|
|
55
55
|
)}) option must be an \`Array\` of non empty \`Strings\`.
|
|
56
56
|
|
|
57
57
|
Your configuration for the \`assignees\` option is \`${stringify(assignees)}\`.`,
|
|
@@ -61,6 +61,14 @@ Your configuration for the \`assignees\` option is \`${stringify(assignees)}\`.`
|
|
|
61
61
|
details: `The **semantic-release** \`repositoryUrl\` option must a valid GitHub URL with the format \`<GitHub_or_GHE_URL>/<owner>/<repo>.git\`.
|
|
62
62
|
|
|
63
63
|
By default the \`repositoryUrl\` option is retrieved from the \`repository\` property of your \`package.json\` or the [git origin url](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes) of the repository cloned by your CI environment.`,
|
|
64
|
+
}),
|
|
65
|
+
EINVALIDPROXY: ({proxy}) => ({
|
|
66
|
+
message: 'Invalid `proxy` option.',
|
|
67
|
+
details: `The [proxy option](${linkify(
|
|
68
|
+
'README.md#proxy'
|
|
69
|
+
)}) option must be a \`String\` or an \`Objects\` with a \`host\` and a \`port\` property.
|
|
70
|
+
|
|
71
|
+
Your configuration for the \`proxy\` option is \`${stringify(proxy)}\`.`,
|
|
64
72
|
}),
|
|
65
73
|
EMISSINGREPO: ({owner, repo}) => ({
|
|
66
74
|
message: `The repository ${owner}/${repo} doesn't exist.`,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default exponential backoff configuration for retries.
|
|
3
|
+
*/
|
|
4
|
+
const RETRY_CONF = {retries: 3, factor: 2, minTimeout: 1000};
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Rate limit per API endpoints.
|
|
8
|
+
*
|
|
9
|
+
* See {@link https://developer.github.com/v3/search/#rate-limit|Search API rate limit}.
|
|
10
|
+
* See {@link https://developer.github.com/v3/#rate-limiting|Rate limiting}.
|
|
11
|
+
*/
|
|
12
|
+
const RATE_LIMITS = {
|
|
13
|
+
search: ((60 * 1000) / 30) * 1.1, // 30 calls per minutes => 1 call every 2s + 10% safety margin
|
|
14
|
+
core: {
|
|
15
|
+
read: ((60 * 60 * 1000) / 5000) * 1.1, // 5000 calls per hour => 1 call per 720ms + 10% safety margin
|
|
16
|
+
write: 3000, // 1 call every 3 seconds
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Global rate limit to prevent abuse.
|
|
22
|
+
*
|
|
23
|
+
* See {@link https://developer.github.com/v3/guides/best-practices-for-integrators/#dealing-with-abuse-rate-limits|Dealing with abuse rate limits}
|
|
24
|
+
*/
|
|
25
|
+
const GLOBAL_RATE_LIMIT = 1000;
|
|
26
|
+
|
|
27
|
+
module.exports = {RETRY_CONF, RATE_LIMITS, GLOBAL_RATE_LIMIT};
|
package/lib/fail.js
CHANGED
|
@@ -8,11 +8,11 @@ const findSRIssues = require('./find-sr-issues');
|
|
|
8
8
|
const getFailComment = require('./get-fail-comment');
|
|
9
9
|
|
|
10
10
|
module.exports = async (pluginConfig, {options: {branch, repositoryUrl}, errors, logger}) => {
|
|
11
|
-
const {githubToken, githubUrl, githubApiPathPrefix, failComment, failTitle, labels, assignees} = resolveConfig(
|
|
11
|
+
const {githubToken, githubUrl, githubApiPathPrefix, proxy, failComment, failTitle, labels, assignees} = resolveConfig(
|
|
12
12
|
pluginConfig
|
|
13
13
|
);
|
|
14
14
|
const {name: repo, owner} = parseGithubUrl(repositoryUrl);
|
|
15
|
-
const github = getClient({githubToken, githubUrl, githubApiPathPrefix});
|
|
15
|
+
const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
|
|
16
16
|
const body = failComment ? template(failComment)({branch, errors}) : getFailComment(branch, errors);
|
|
17
17
|
const [srIssue] = await findSRIssues(github, failTitle, owner, repo);
|
|
18
18
|
|
package/lib/get-client.js
CHANGED
|
@@ -1,31 +1,14 @@
|
|
|
1
|
-
const
|
|
1
|
+
const url = require('url');
|
|
2
|
+
const {memoize, get} = require('lodash');
|
|
2
3
|
const Octokit = require('@octokit/rest');
|
|
3
4
|
const pRetry = require('p-retry');
|
|
4
5
|
const Bottleneck = require('bottleneck');
|
|
5
6
|
const urljoin = require('url-join');
|
|
7
|
+
const HttpProxyAgent = require('http-proxy-agent');
|
|
8
|
+
const HttpsProxyAgent = require('https-proxy-agent');
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*/
|
|
10
|
-
const DEFAULT_RETRY = {retries: 3, factor: 2, minTimeout: 1000};
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Rate limit per API endpoints.
|
|
14
|
-
*
|
|
15
|
-
* See {@link https://developer.github.com/v3/search/#rate-limit|Search API rate limit}.
|
|
16
|
-
* See {@link https://developer.github.com/v3/#rate-limiting|Rate limiting}.
|
|
17
|
-
*/
|
|
18
|
-
const RATE_LIMITS = {
|
|
19
|
-
search: (60 * 1000) / 30, // 30 calls per minutes => 1 call per 2s
|
|
20
|
-
core: (60 * 60 * 1000) / 5000, // 5000 calls per hour => 1 call per 720ms
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Global rate limit to prevent abuse.
|
|
25
|
-
*
|
|
26
|
-
* See {@link https://developer.github.com/v3/guides/best-practices-for-integrators/#dealing-with-abuse-rate-limits|Dealing with abuse rate limits}
|
|
27
|
-
*/
|
|
28
|
-
const GLOBAL_RATE_LIMIT = 1000;
|
|
10
|
+
const GH_ROUTES = require('@octokit/rest/lib/routes');
|
|
11
|
+
const {RETRY_CONF, RATE_LIMITS, GLOBAL_RATE_LIMIT} = require('./definitions/rate-limit');
|
|
29
12
|
|
|
30
13
|
/**
|
|
31
14
|
* Http error codes for which to not retry.
|
|
@@ -38,35 +21,66 @@ const SKIP_RETRY_CODES = [400, 401, 403];
|
|
|
38
21
|
* @param {Array} rate The rate limit group.
|
|
39
22
|
* @param {String} limit The rate limits per API endpoints.
|
|
40
23
|
* @param {Bottleneck} globalThrottler The global throttler.
|
|
24
|
+
*
|
|
41
25
|
* @return {Bottleneck} The throller function for the given rate limit group.
|
|
42
26
|
*/
|
|
43
|
-
const getThrottler = memoize((rate,
|
|
44
|
-
new Bottleneck({minTime:
|
|
27
|
+
const getThrottler = memoize((rate, globalThrottler) =>
|
|
28
|
+
new Bottleneck({minTime: get(RATE_LIMITS, rate)}).chain(globalThrottler)
|
|
45
29
|
);
|
|
46
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Determine if a call to a client function will trigger a read (`GET`) or a write (`POST`, `PATCH`, etc...) request.
|
|
33
|
+
*
|
|
34
|
+
* @param {String} endpoint The client API enpoint (for example the endpoint for a call to `github.repos.get` is `repos`).
|
|
35
|
+
* @param {String} command The client API command (for example the command for a call to `github.repos.get` is `get`).
|
|
36
|
+
*
|
|
37
|
+
* @return {String} `write` or `read` if there is rate limit configuration for this `endpoint` and `command`, `undefined` otherwise.
|
|
38
|
+
*/
|
|
39
|
+
const getAccess = (endpoint, command) => {
|
|
40
|
+
const method = GH_ROUTES[endpoint] && GH_ROUTES[endpoint][command] && GH_ROUTES[endpoint][command].method;
|
|
41
|
+
const access = method && method === 'GET' ? 'read' : 'write';
|
|
42
|
+
return RATE_LIMITS[endpoint][access] && access;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get the limiter identifier associated with a client API call.
|
|
47
|
+
*
|
|
48
|
+
* @param {String} endpoint The client API enpoint (for example the endpoint for a call to `github.repos.get` is `repos`).
|
|
49
|
+
* @param {String} command The client API command (for example the command for a call to `github.repos.get` is `get`).
|
|
50
|
+
*
|
|
51
|
+
* @return {String} A string identifying the limiter to use for this `endpoint` and `command` (e.g. `search` or `core.write`).
|
|
52
|
+
*/
|
|
53
|
+
const getLimitKey = (endpoint, command) => {
|
|
54
|
+
return endpoint
|
|
55
|
+
? [endpoint, RATE_LIMITS[endpoint] && getAccess(endpoint, command)].filter(Boolean).join('.')
|
|
56
|
+
: RATE_LIMITS[command]
|
|
57
|
+
? command
|
|
58
|
+
: 'core';
|
|
59
|
+
};
|
|
60
|
+
|
|
47
61
|
/**
|
|
48
62
|
* Create a`handler` for a `Proxy` wrapping an Octokit instance to:
|
|
49
63
|
* - Recursively wrap the child objects of the Octokit instance in a `Proxy`
|
|
50
64
|
* - Throttle and retry the Octokit instance functions
|
|
51
65
|
*
|
|
52
|
-
* @param {Object} retry The configuration to pass to `p-retry`.
|
|
53
|
-
* @param {Array} limit The rate limits per API endpoints.
|
|
54
66
|
* @param {Throttler} globalThrottler The throller function for the global rate limit.
|
|
55
|
-
* @param {String}
|
|
67
|
+
* @param {String} limitKey The key to find the limit rate for the API endpoint and method.
|
|
68
|
+
*
|
|
56
69
|
* @return {Function} The `handler` for a `Proxy` wrapping an Octokit instance.
|
|
57
70
|
*/
|
|
58
|
-
const handler = (
|
|
71
|
+
const handler = (globalThrottler, limitKey) => ({
|
|
59
72
|
/**
|
|
60
73
|
* If the target has the property as own, determine the rate limit based on the property name and recursively wrap the value in a `Proxy`. Otherwise returns the property value.
|
|
61
74
|
*
|
|
62
75
|
* @param {Object} target The target object.
|
|
63
76
|
* @param {String} name The name of the property to get.
|
|
64
77
|
* @param {Any} receiver The `Proxy` object.
|
|
78
|
+
*
|
|
65
79
|
* @return {Any} The property value or a `Proxy` of the property value.
|
|
66
80
|
*/
|
|
67
81
|
get: (target, name, receiver) =>
|
|
68
82
|
Reflect.apply(Object.prototype.hasOwnProperty, target, [name])
|
|
69
|
-
? new Proxy(target[name], handler(
|
|
83
|
+
? new Proxy(target[name], handler(globalThrottler, getLimitKey(limitKey, name)))
|
|
70
84
|
: Reflect.get(target, name, receiver),
|
|
71
85
|
|
|
72
86
|
/**
|
|
@@ -75,11 +89,11 @@ const handler = (retry, limit, globalThrottler, endpoint) => ({
|
|
|
75
89
|
* @param {Function} func The target function.
|
|
76
90
|
* @param {Any} that The this argument for the call.
|
|
77
91
|
* @param {Array} args The list of arguments for the call.
|
|
92
|
+
*
|
|
78
93
|
* @return {Promise<Any>} The result of the function called.
|
|
79
94
|
*/
|
|
80
95
|
apply: (func, that, args) => {
|
|
81
|
-
const throttler = getThrottler(
|
|
82
|
-
|
|
96
|
+
const throttler = getThrottler(limitKey, globalThrottler);
|
|
83
97
|
return pRetry(async () => {
|
|
84
98
|
try {
|
|
85
99
|
return await throttler.wrap(func)(...args);
|
|
@@ -89,20 +103,20 @@ const handler = (retry, limit, globalThrottler, endpoint) => ({
|
|
|
89
103
|
}
|
|
90
104
|
throw err;
|
|
91
105
|
}
|
|
92
|
-
},
|
|
106
|
+
}, RETRY_CONF);
|
|
93
107
|
},
|
|
94
108
|
});
|
|
95
109
|
|
|
96
|
-
module.exports = ({
|
|
97
|
-
githubToken,
|
|
98
|
-
githubUrl,
|
|
99
|
-
githubApiPathPrefix,
|
|
100
|
-
retry = DEFAULT_RETRY,
|
|
101
|
-
limit = RATE_LIMITS,
|
|
102
|
-
globalLimit = GLOBAL_RATE_LIMIT,
|
|
103
|
-
}) => {
|
|
110
|
+
module.exports = ({githubToken, githubUrl, githubApiPathPrefix, proxy} = {}) => {
|
|
104
111
|
const baseUrl = githubUrl && urljoin(githubUrl, githubApiPathPrefix);
|
|
105
|
-
const github = new Octokit({
|
|
112
|
+
const github = new Octokit({
|
|
113
|
+
baseUrl,
|
|
114
|
+
agent: proxy
|
|
115
|
+
? baseUrl && url.parse(baseUrl).protocol.replace(':', '') === 'http'
|
|
116
|
+
? new HttpProxyAgent(proxy)
|
|
117
|
+
: new HttpsProxyAgent(proxy)
|
|
118
|
+
: undefined,
|
|
119
|
+
});
|
|
106
120
|
github.authenticate({type: 'token', token: githubToken});
|
|
107
|
-
return new Proxy(github, handler(
|
|
121
|
+
return new Proxy(github, handler(new Bottleneck({minTime: GLOBAL_RATE_LIMIT})));
|
|
108
122
|
};
|
package/lib/publish.js
CHANGED
|
@@ -9,9 +9,9 @@ const resolveConfig = require('./resolve-config');
|
|
|
9
9
|
const getClient = require('./get-client');
|
|
10
10
|
|
|
11
11
|
module.exports = async (pluginConfig, {options: {branch, repositoryUrl}, nextRelease: {gitTag, notes}, logger}) => {
|
|
12
|
-
const {githubToken, githubUrl, githubApiPathPrefix, assets} = resolveConfig(pluginConfig);
|
|
12
|
+
const {githubToken, githubUrl, githubApiPathPrefix, proxy, assets} = resolveConfig(pluginConfig);
|
|
13
13
|
const {name: repo, owner} = parseGithubUrl(repositoryUrl);
|
|
14
|
-
const github = getClient({githubToken, githubUrl, githubApiPathPrefix});
|
|
14
|
+
const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
|
|
15
15
|
const release = {owner, repo, tag_name: gitTag, name: gitTag, target_commitish: branch, body: notes}; // eslint-disable-line camelcase
|
|
16
16
|
|
|
17
17
|
debug('release owner: %o', owner);
|
package/lib/resolve-config.js
CHANGED
|
@@ -3,6 +3,7 @@ const {isUndefined, castArray} = require('lodash');
|
|
|
3
3
|
module.exports = ({
|
|
4
4
|
githubUrl,
|
|
5
5
|
githubApiPathPrefix,
|
|
6
|
+
proxy,
|
|
6
7
|
assets,
|
|
7
8
|
successComment,
|
|
8
9
|
failTitle,
|
|
@@ -13,6 +14,7 @@ module.exports = ({
|
|
|
13
14
|
githubToken: process.env.GH_TOKEN || process.env.GITHUB_TOKEN,
|
|
14
15
|
githubUrl: githubUrl || process.env.GH_URL || process.env.GITHUB_URL,
|
|
15
16
|
githubApiPathPrefix: githubApiPathPrefix || process.env.GH_PREFIX || process.env.GITHUB_PREFIX || '',
|
|
17
|
+
proxy: proxy || process.env.HTTP_PROXY,
|
|
16
18
|
assets: assets ? castArray(assets) : assets,
|
|
17
19
|
successComment,
|
|
18
20
|
failTitle: isUndefined(failTitle) || failTitle === false ? 'The automated release is failing 🚨' : failTitle,
|
package/lib/success.js
CHANGED
|
@@ -2,7 +2,7 @@ const {isUndefined, uniqBy, template, flatten} = require('lodash');
|
|
|
2
2
|
const parseGithubUrl = require('parse-github-url');
|
|
3
3
|
const pFilter = require('p-filter');
|
|
4
4
|
const AggregateError = require('aggregate-error');
|
|
5
|
-
const issueParser = require('issue-parser')
|
|
5
|
+
const issueParser = require('issue-parser');
|
|
6
6
|
const debug = require('debug')('semantic-release:github');
|
|
7
7
|
const resolveConfig = require('./resolve-config');
|
|
8
8
|
const getClient = require('./get-client');
|
|
@@ -14,9 +14,10 @@ module.exports = async (
|
|
|
14
14
|
pluginConfig,
|
|
15
15
|
{options: {branch, repositoryUrl}, lastRelease, commits, nextRelease, releases, logger}
|
|
16
16
|
) => {
|
|
17
|
-
const {githubToken, githubUrl, githubApiPathPrefix, successComment, failTitle} = resolveConfig(pluginConfig);
|
|
17
|
+
const {githubToken, githubUrl, githubApiPathPrefix, proxy, successComment, failTitle} = resolveConfig(pluginConfig);
|
|
18
18
|
const {name: repo, owner} = parseGithubUrl(repositoryUrl);
|
|
19
|
-
const github = getClient({githubToken, githubUrl, githubApiPathPrefix});
|
|
19
|
+
const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
|
|
20
|
+
const parser = issueParser('github', githubUrl ? {hosts: [githubUrl]} : {});
|
|
20
21
|
const releaseInfos = releases.filter(release => Boolean(release.name));
|
|
21
22
|
const shas = commits.map(commit => commit.hash);
|
|
22
23
|
const treeShas = commits.map(commit => commit.tree.long);
|
|
@@ -37,7 +38,7 @@ module.exports = async (
|
|
|
37
38
|
const issues = [...prs.map(pr => pr.body), ...commits.map(commit => commit.message)].reduce((issues, message) => {
|
|
38
39
|
return message
|
|
39
40
|
? issues.concat(
|
|
40
|
-
|
|
41
|
+
parser(message)
|
|
41
42
|
.actions.filter(action => isUndefined(action.slug) || action.slug === `${owner}/${repo}`)
|
|
42
43
|
.map(action => ({number: parseInt(action.issue, 10)}))
|
|
43
44
|
)
|
package/lib/verify.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {isString, isPlainObject, isUndefined, isArray} = require('lodash');
|
|
1
|
+
const {isString, isPlainObject, isUndefined, isArray, isNumber} = require('lodash');
|
|
2
2
|
const parseGithubUrl = require('parse-github-url');
|
|
3
3
|
const urlJoin = require('url-join');
|
|
4
4
|
const AggregateError = require('aggregate-error');
|
|
@@ -11,6 +11,8 @@ const isStringOrStringArray = value => isNonEmptyString(value) || (isArray(value
|
|
|
11
11
|
const isArrayOf = validator => array => isArray(array) && array.every(value => validator(value));
|
|
12
12
|
|
|
13
13
|
const VALIDATORS = {
|
|
14
|
+
proxy: proxy =>
|
|
15
|
+
isNonEmptyString(proxy) || (isPlainObject(proxy) && isNonEmptyString(proxy.host) && isNumber(proxy.port)),
|
|
14
16
|
assets: isArrayOf(
|
|
15
17
|
asset => isStringOrStringArray(asset) || (isPlainObject(asset) && isStringOrStringArray(asset.path))
|
|
16
18
|
),
|
|
@@ -22,9 +24,9 @@ const VALIDATORS = {
|
|
|
22
24
|
};
|
|
23
25
|
|
|
24
26
|
module.exports = async (pluginConfig, {options: {repositoryUrl}, logger}) => {
|
|
25
|
-
const {githubToken, githubUrl, githubApiPathPrefix, ...options} = resolveConfig(pluginConfig);
|
|
27
|
+
const {githubToken, githubUrl, githubApiPathPrefix, proxy, ...options} = resolveConfig(pluginConfig);
|
|
26
28
|
|
|
27
|
-
const errors = Object.entries(options).reduce(
|
|
29
|
+
const errors = Object.entries({...options, proxy}).reduce(
|
|
28
30
|
(errors, [option, value]) =>
|
|
29
31
|
!isUndefined(value) && value !== false && !VALIDATORS[option](value)
|
|
30
32
|
? [...errors, getError(`EINVALID${option.toUpperCase()}`, {[option]: value})]
|
|
@@ -41,8 +43,8 @@ module.exports = async (pluginConfig, {options: {repositoryUrl}, logger}) => {
|
|
|
41
43
|
const {name: repo, owner} = parseGithubUrl(repositoryUrl);
|
|
42
44
|
if (!owner || !repo) {
|
|
43
45
|
errors.push(getError('EINVALIDGITHUBURL'));
|
|
44
|
-
} else if (githubToken) {
|
|
45
|
-
const github = getClient({githubToken, githubUrl, githubApiPathPrefix});
|
|
46
|
+
} else if (githubToken && !errors.find(({code}) => code === 'EINVALIDPROXY')) {
|
|
47
|
+
const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
|
|
46
48
|
|
|
47
49
|
try {
|
|
48
50
|
const {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semantic-release/github",
|
|
3
3
|
"description": "Set of semantic-release plugins for publishing a GitHub release",
|
|
4
|
-
"version": "4.2
|
|
4
|
+
"version": "4.4.2",
|
|
5
5
|
"author": "Pierre Vanduynslager (https://twitter.com/@pvdlg_)",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/semantic-release/github/issues"
|
|
@@ -21,9 +21,11 @@
|
|
|
21
21
|
"aggregate-error": "^1.0.0",
|
|
22
22
|
"bottleneck": "^2.0.1",
|
|
23
23
|
"debug": "^3.1.0",
|
|
24
|
-
"fs-extra": "^
|
|
24
|
+
"fs-extra": "^7.0.0",
|
|
25
25
|
"globby": "^8.0.0",
|
|
26
|
-
"
|
|
26
|
+
"http-proxy-agent": "^2.1.0",
|
|
27
|
+
"https-proxy-agent": "^2.2.1",
|
|
28
|
+
"issue-parser": "^2.2.0",
|
|
27
29
|
"lodash": "^4.17.4",
|
|
28
30
|
"mime": "^2.0.3",
|
|
29
31
|
"p-filter": "^1.0.0",
|
|
@@ -33,14 +35,16 @@
|
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
37
|
"ava": "^0.25.0",
|
|
36
|
-
"clear-module": "^
|
|
38
|
+
"clear-module": "^3.0.0",
|
|
37
39
|
"codecov": "^3.0.0",
|
|
38
40
|
"commitizen": "^2.9.6",
|
|
39
41
|
"cz-conventional-changelog": "^2.0.0",
|
|
40
42
|
"nock": "^9.1.0",
|
|
41
43
|
"nyc": "^12.0.1",
|
|
44
|
+
"proxy": "^0.2.4",
|
|
42
45
|
"proxyquire": "^2.0.0",
|
|
43
46
|
"semantic-release": "^15.0.0",
|
|
47
|
+
"server-destroy": "^1.0.1",
|
|
44
48
|
"sinon": "^6.0.0",
|
|
45
49
|
"tempy": "^0.2.1",
|
|
46
50
|
"xo": "^0.21.0"
|