1 | const {isString, isPlainObject, isNil, isArray, isNumber} = require('lodash');
|
2 | const parseGithubUrl = require('parse-github-url');
|
3 | const urlJoin = require('url-join');
|
4 | const AggregateError = require('aggregate-error');
|
5 | const resolveConfig = require('./resolve-config');
|
6 | const getClient = require('./get-client');
|
7 | const getError = require('./get-error');
|
8 |
|
9 | const isNonEmptyString = value => isString(value) && value.trim();
|
10 | const isStringOrStringArray = value => isNonEmptyString(value) || (isArray(value) && value.every(isNonEmptyString));
|
11 | const isArrayOf = validator => array => isArray(array) && array.every(value => validator(value));
|
12 | const canBeDisabled = validator => value => value === false || validator(value);
|
13 |
|
14 | const VALIDATORS = {
|
15 | proxy: proxy =>
|
16 | isNonEmptyString(proxy) || (isPlainObject(proxy) && isNonEmptyString(proxy.host) && isNumber(proxy.port)),
|
17 | assets: isArrayOf(
|
18 | asset => isStringOrStringArray(asset) || (isPlainObject(asset) && isStringOrStringArray(asset.path))
|
19 | ),
|
20 | successComment: canBeDisabled(isNonEmptyString),
|
21 | failTitle: canBeDisabled(isNonEmptyString),
|
22 | failComment: canBeDisabled(isNonEmptyString),
|
23 | labels: canBeDisabled(isArrayOf(isNonEmptyString)),
|
24 | assignees: isArrayOf(isNonEmptyString),
|
25 | releasedLabels: canBeDisabled(isArrayOf(isNonEmptyString)),
|
26 | };
|
27 |
|
28 | module.exports = async (pluginConfig, context) => {
|
29 | const {
|
30 | options: {repositoryUrl},
|
31 | logger,
|
32 | } = context;
|
33 | const {githubToken, githubUrl, githubApiPathPrefix, proxy, ...options} = resolveConfig(pluginConfig, context);
|
34 |
|
35 | const errors = Object.entries({...options, proxy}).reduce(
|
36 | (errors, [option, value]) =>
|
37 | !isNil(value) && !VALIDATORS[option](value)
|
38 | ? [...errors, getError(`EINVALID${option.toUpperCase()}`, {[option]: value})]
|
39 | : errors,
|
40 | []
|
41 | );
|
42 |
|
43 | if (githubUrl) {
|
44 | logger.log('Verify GitHub authentication (%s)', urlJoin(githubUrl, githubApiPathPrefix));
|
45 | } else {
|
46 | logger.log('Verify GitHub authentication');
|
47 | }
|
48 |
|
49 | const {name: repo, owner} = parseGithubUrl(repositoryUrl);
|
50 | if (!owner || !repo) {
|
51 | errors.push(getError('EINVALIDGITHUBURL'));
|
52 | } else if (githubToken && !errors.find(({code}) => code === 'EINVALIDPROXY')) {
|
53 | const github = getClient({githubToken, githubUrl, githubApiPathPrefix, proxy});
|
54 |
|
55 | try {
|
56 | const {
|
57 | data: {
|
58 | permissions: {push},
|
59 | },
|
60 | } = await github.repos.get({repo, owner});
|
61 | if (!push) {
|
62 | errors.push(getError('EGHNOPERMISSION', {owner, repo}));
|
63 | }
|
64 | } catch (error) {
|
65 | if (error.status === 401) {
|
66 | errors.push(getError('EINVALIDGHTOKEN', {owner, repo}));
|
67 | } else if (error.status === 404) {
|
68 | errors.push(getError('EMISSINGREPO', {owner, repo}));
|
69 | } else {
|
70 | throw error;
|
71 | }
|
72 | }
|
73 | }
|
74 |
|
75 | if (!githubToken) {
|
76 | errors.push(getError('ENOGHTOKEN', {owner, repo}));
|
77 | }
|
78 |
|
79 | if (errors.length > 0) {
|
80 | throw new AggregateError(errors);
|
81 | }
|
82 | };
|