-
Notifications
You must be signed in to change notification settings - Fork 144
Expand file tree
/
Copy pathverify.js
More file actions
103 lines (92 loc) · 3.95 KB
/
verify.js
File metadata and controls
103 lines (92 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
const {isString, isPlainObject, isNil, isArray, isNumber} = require('lodash');
const urlJoin = require('url-join');
const AggregateError = require('aggregate-error');
const parseGithubUrl = require('./parse-github-url');
const resolveConfig = require('./resolve-config');
const getClient = require('./get-client');
const getError = require('./get-error');
const isNonEmptyString = (value) => isString(value) && value.trim();
const oneOf = (enumArray) => (value) => enumArray.some((element) => element === value);
const isStringOrStringArray = (value) =>
isNonEmptyString(value) || (isArray(value) && value.every((string) => isNonEmptyString(string)));
const isArrayOf = (validator) => (array) => isArray(array) && array.every((value) => validator(value));
const canBeDisabled = (validator) => (value) => value === false || validator(value);
const VALIDATORS = {
proxy: (proxy) =>
isNonEmptyString(proxy) || (isPlainObject(proxy) && isNonEmptyString(proxy.host) && isNumber(proxy.port)),
assets: isArrayOf(
(asset) => isStringOrStringArray(asset) || (isPlainObject(asset) && isStringOrStringArray(asset.path))
),
successComment: canBeDisabled(isNonEmptyString),
failTitle: canBeDisabled(isNonEmptyString),
failComment: canBeDisabled(isNonEmptyString),
labels: canBeDisabled(isArrayOf(isNonEmptyString)),
assignees: isArrayOf(isNonEmptyString),
releasedLabels: canBeDisabled(isArrayOf(isNonEmptyString)),
addReleases: canBeDisabled(oneOf(['bottom', 'top'])),
removeTitleFromReleaseNotes: canBeDisabled(oneOf([false, true])),
};
module.exports = async (pluginConfig, context) => {
const {
env,
options: {repositoryUrl},
logger,
} = context;
const {githubToken, githubUrl, githubApiPathPrefix, proxy, ...options} = resolveConfig(pluginConfig, context);
const errors = Object.entries({...options, proxy}).reduce(
(errors, [option, value]) =>
!isNil(value) && !VALIDATORS[option](value)
? [...errors, getError(`EINVALID${option.toUpperCase()}`, {[option]: value})]
: errors,
[]
);
if (githubUrl) {
logger.log('Verify GitHub authentication (%s)', urlJoin(githubUrl, githubApiPathPrefix));
} else {
logger.log('Verify GitHub authentication');
}
const {repo, owner} = parseGithubUrl(repositoryUrl);
if (!owner || !repo) {
errors.push(getError('EINVALIDGITHUBURL'));
} else if (githubToken && !errors.find(({code}) => code === 'EINVALIDPROXY')) {
const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
// https://github.com/semantic-release/github/issues/182
// Do not check for permissions in GitHub actions, as the provided token is an installation access token.
// github.repos.get({repo, owner}) does not return the "permissions" key in that case. But GitHub Actions
// have all permissions required for @semantic-release/github to work
if (env.GITHUB_ACTION) {
return;
}
try {
const {
data: {
permissions: {push},
},
} = await github.repos.get({repo, owner});
if (!push) {
// If authenticated as GitHub App installation, `push` will always be false.
// We send another request to check if current authentication is an installation.
// Note: we cannot check if the installation has all required permissions, it's
// up to the user to make sure it has
if (await github.request('HEAD /installation/repositories', {per_page: 1}).catch(() => false)) {
return;
}
errors.push(getError('EGHNOPERMISSION', {owner, repo}));
}
} catch (error) {
if (error.status === 401) {
errors.push(getError('EINVALIDGHTOKEN', {owner, repo}));
} else if (error.status === 404) {
errors.push(getError('EMISSINGREPO', {owner, repo}));
} else {
throw error;
}
}
}
if (!githubToken) {
errors.push(getError('ENOGHTOKEN', {owner, repo}));
}
if (errors.length > 0) {
throw new AggregateError(errors);
}
};