forked from semantic-release/semantic-release
-
Notifications
You must be signed in to change notification settings - Fork 0
/
get-config.js
91 lines (79 loc) · 3.29 KB
/
get-config.js
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
const {castArray, pickBy, isNil, isString, isPlainObject} = require('lodash');
const readPkgUp = require('read-pkg-up');
const {cosmiconfig} = require('cosmiconfig');
const resolveFrom = require('resolve-from');
const debug = require('debug')('semantic-release:config');
const {repoUrl} = require('./git');
const PLUGINS_DEFINITIONS = require('./definitions/plugins');
const plugins = require('./plugins');
const {validatePlugin, parseConfig} = require('./plugins/utils');
const CONFIG_NAME = 'release';
module.exports = async (context, cliOptions) => {
const {cwd, env} = context;
const {config, filepath} = (await cosmiconfig(CONFIG_NAME).search(cwd)) || {};
debug('load config from: %s', filepath);
// Merge config file options and CLI/API options
let options = {...config, ...cliOptions};
const pluginsPath = {};
let extendPaths;
({extends: extendPaths, ...options} = options);
if (extendPaths) {
// If `extends` is defined, load and merge each shareable config with `options`
options = {
...castArray(extendPaths).reduce((result, extendPath) => {
const extendsOptions = require(resolveFrom.silent(__dirname, extendPath) || resolveFrom(cwd, extendPath));
// For each plugin defined in a shareable config, save in `pluginsPath` the extendable config path,
// so those plugin will be loaded relatively to the config file
Object.entries(extendsOptions)
.filter(([, value]) => Boolean(value))
.reduce((pluginsPath, [option, value]) => {
castArray(value).forEach((plugin) => {
if (option === 'plugins' && validatePlugin(plugin)) {
pluginsPath[parseConfig(plugin)[0]] = extendPath;
} else if (
PLUGINS_DEFINITIONS[option] &&
(isString(plugin) || (isPlainObject(plugin) && isString(plugin.path)))
) {
pluginsPath[isString(plugin) ? plugin : plugin.path] = extendPath;
}
});
return pluginsPath;
}, pluginsPath);
return {...result, ...extendsOptions};
}, {}),
...options,
};
}
// Set default options values if not defined yet
options = {
branches: [
'+([0-9])?(.{+([0-9]),x}).x',
'master',
'next',
'next-major',
{name: 'beta', prerelease: true},
{name: 'alpha', prerelease: true},
],
repositoryUrl: (await pkgRepoUrl({normalize: false, cwd})) || (await repoUrl({cwd, env})),
tagFormat: `v\${version}`,
plugins: [
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
'@semantic-release/npm',
'@semantic-release/github',
],
preset: 'conventionalcommits',
// Remove `null` and `undefined` options so they can be replaced with default ones
...pickBy(options, (option) => !isNil(option)),
...(options.branches ? {branches: castArray(options.branches)} : {}),
};
if (options.ci === false) {
options.noCi = true;
}
debug('options values: %O', options);
return {options, plugins: await plugins({...context, options}, pluginsPath)};
};
async function pkgRepoUrl(options) {
const {packageJson} = (await readPkgUp(options)) || {};
return packageJson && (isPlainObject(packageJson.repository) ? packageJson.repository.url : packageJson.repository);
}