semantic-release 11.0.1 → 11.2.0

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 CHANGED
@@ -148,7 +148,9 @@ _[This is what happens under the hood.](https://github.com/semantic-release/cli#
148
148
 
149
149
  ## Options
150
150
 
151
- You can pass options either via command line (in [kebab-case](https://lodash.com/docs#kebabCase)) or in the `release` field of your `package.json` (in [camelCase](https://lodash.com/docs#camelCase)). The following two examples are the same, but CLI arguments take precedence.
151
+ You can pass options either via command line (in [kebab-case](https://lodash.com/docs#kebabCase)) or in the `release` field of your `package.json` (in [camelCase](https://lodash.com/docs#camelCase)). Alternatively the configuration can also be defined in `.releaserc.yml`, `.releaserc.js`, `.releaserc.js` or `release.config.js`.
152
+
153
+ The following two examples are the same, but CLI arguments take precedence.
152
154
 
153
155
  ##### CLI
154
156
  ```bash
@@ -169,18 +171,17 @@ These options are currently available:
169
171
  - `branch`: The branch on which releases should happen. Default: `'master'`
170
172
  - `repositoryUrl`: The git repository URL. Default: `repository` property in `package.json` or git origin url. Any valid git url format is supported (See [Git protocols](https://git-scm.com/book/en/v2/Git-on-the-Server-The-Protocols)). If the [Github plugin](https://github.com/semantic-release/github) is used the URL must be a valid Github URL that include the `owner`, the `repository` name and the `host`. The Github shorthand URL is not supported.
171
173
  - `dry-run`: Dry-run mode, skipping verifyConditions, publishing and release, printing next version and release notes
174
+ - `extends`: Array of module or files path containing a shareable configuration. Options defined via CLI or in the `release` property will take precedence over the one defined in a shareable configuration.
172
175
  - `debug`: Output debugging information
173
176
 
174
177
  _A few notes on `npm` config_:
175
178
  1. The `npm` token can only be defined in the environment as `NPM_TOKEN`, because that’s where `npm` itself is going to read it from.
176
-
177
179
  2. In order to publish to a different `npm` registry you can specify that inside the `package.json`’s [`publishConfig`](https://docs.npmjs.com/files/package.json#publishconfig) field.
178
-
179
180
  3. If you want to use another dist-tag for your publishes than `'latest'` you can specify that inside the `package.json`’s [`publishConfig`](https://docs.npmjs.com/files/package.json#publishconfig) field.
180
181
 
181
182
  ## Plugins
182
183
 
183
- There are numerous steps where you can customize `semantic-release`’s behaviour using plugins. A plugin is a regular [option](#options), but passed inside the `release` block of `package.json`:
184
+ There are numerous steps where you can customize `semantic-release`’s behavior using plugins. A plugin is a regular [option](#options), but passed inside the `release` block of `package.json`:
184
185
 
185
186
  ```json
186
187
  {
@@ -190,24 +191,27 @@ There are numerous steps where you can customize `semantic-release`’s behaviou
190
191
  "verifyConditions": {
191
192
  "path": "./path/to/a/module",
192
193
  "additional": "config"
193
- }
194
+ },
195
+ "globalPluginOptions": "globalConfig"
194
196
  }
195
197
  }
196
198
  ```
197
199
 
198
- ```
200
+ ```bash
199
201
  semantic-release --analyze-commits="npm-module-name"
200
202
  ```
201
203
 
204
+ **Note**: The plugin CLI arguments can be only used to override the plugins to use. Plugins options cannot be defined via CLI arguments and must be defined in the main configuration file or in a shareable config.
205
+
202
206
  A plugin itself is an async function that always receives three arguments.
203
207
 
204
208
  ```js
205
209
  module.exports = function (pluginConfig, config, callback) {}
206
210
  ```
207
211
 
208
- - `pluginConfig`: If the user of your plugin specifies additional plugin config in the `package.json` (see the `verifyConditions` example above) then it’s this object.
212
+ - `pluginConfig`: If the user of your plugin specifies additional plugin config in the `package.json` (see the `verifyConditions` example above) then it’s this object. Options defined directly under `release` will be passed to each plugins. Options defined within a plugin will passed only to that instance of the plugin.
209
213
  - `config`: A config object containing a lot of information to act upon.
210
- - `options`: `semantic-release` options like `debug`, or `branch`
214
+ - `options`: `semantic-release` options like `repositoryUrl`, or `branch`
211
215
  - For certain plugins the `config` object contains even more information. See below.
212
216
 
213
217
  ### `analyzeCommits`
@@ -222,9 +226,9 @@ Have a look at the [default implementation](https://github.com/semantic-release/
222
226
 
223
227
  This plugins is responsible for verifying that a release should happen in the first place.
224
228
  The default implementations are:
225
- - [travis](https://github.com/semantic-release/condition-travis/): verifies that the publish is happening on Travis, that it’s the right branch, and that all other build jobs succeeded.
226
- - [github](https://github.com/semantic-release/github/): verifies a Github authentication is set and valid.
227
- - [npm](https://github.com/semantic-release/npm/): verifies an npm authentication is set and valid.
229
+ - [travis](https://github.com/semantic-release/condition-travis/): verifies that the publish is happening on Travis, that it’s the right branch, and that all other build jobs succeeded.
230
+ - [github](https://github.com/semantic-release/github/): verifies a Github authentication is set and valid.
231
+ - [npm](https://github.com/semantic-release/npm/): verifies an npm authentication is set and valid.
228
232
 
229
233
  Passing an array of plugins will run them in series.
230
234
 
@@ -245,7 +249,7 @@ It receives a `commits` array, the `lastRelease` and `nextRelease` inside `confi
245
249
 
246
250
  ### `publish`
247
251
 
248
- This plugins is responsible for publishing the release. The default implementations publish on [npm](https://github.com/semantic-release/npm) and [github](https://github.com/semantic-release/github).
252
+ This plugins is responsible for publishing the release. The default implementations publish on [npm](https://github.com/semantic-release/npm) and [github](https://github.com/semantic-release/github).
249
253
 
250
254
  Passing an array of plugins will run them in series.
251
255
 
@@ -287,6 +291,8 @@ Being able to write code for just the most recent node versions greatly simplifi
287
291
 
288
292
  For a special purpose tool like `semantic-release`, that's only meant to be used in controlled CI environments, we think it's okay to have such a high version requirement. As `semantic-release` handles package publishing we expect almost every project to have at least one build job running node 8 already – and that's all it takes. Even if that's not that case `semantic-release` can still be executed with the help of [npx](https://www.npmjs.com/package/npx) (`npx -p node@8 npm run semantic-release`).
289
293
 
294
+ Please see our [Node Support Policy](#node-support-policy) for our long-term promise for supporting Node.
295
+
290
296
  ## Badge
291
297
 
292
298
  Use this in one of your projects? Include one of these badges in your README.md to let people know that your package is published using `semantic-release`.
@@ -309,6 +315,20 @@ Use this in one of your projects? Include one of these badges in your README.md
309
315
  [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)](https://github.com/semantic-release/semantic-release)
310
316
  ```
311
317
 
318
+ ## Node Support Policy
319
+
320
+ We only support [Long-Term Support](https://github.com/nodejs/Release) versions of Node starting with [Node 8.9.0 (LTS)](https://nodejs.org/en/blog/release/v8.9.0/).
321
+
322
+ We specifically limit our support to LTS versions of Node, not because this package won't work on other versions, but because we have a limited amount of time, and supporting LTS offers the greatest return on that investment.
323
+
324
+ It's possible this package will work correctly on newer versions of Node. It may even be possible to use this package on older versions of Node, though that's more unlikely as we'll make every effort to take advantage of features available in the oldest LTS version we support.
325
+
326
+ As each Node LTS version reaches its end-of-life we will remove that version from the node engines property of our package's package.json file. Removing a Node version is considered a breaking change and will entail the publishing of a new major version of this package. We will not accept any requests to support an end-of-life version of Node. Any merge requests or issues supporting an end-of-life version of Node will be closed.
327
+
328
+ We will accept code that allows this package to run on newer, non-LTS, versions of Node. Furthermore, we will attempt to ensure our own changes work on the latest version of Node. To help in that commitment, our continuous integration setup runs against all LTS versions of Node in addition the most recent Node release; called current.
329
+
330
+ JavaScript package managers should allow you to install this package with any version of Node, with, at most, a warning if your version of Node does not fall within the range specified by our node engines property. If you encounter issues installing this package, please report the issue to your package manager.
331
+
312
332
  ## License
313
333
 
314
334
  MIT License
package/cli.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const program = require('commander');
2
+ const {pickBy, isUndefined} = require('lodash');
2
3
  const logger = require('./lib/logger');
3
4
 
4
5
  function list(values) {
@@ -11,6 +12,7 @@ module.exports = async () => {
11
12
  .description('Run automated package publishing')
12
13
  .option('-b, --branch <branch>', 'Branch to release from')
13
14
  .option('-r, --repositoryUrl <repositoryUrl>', 'Git repository URL')
15
+ .option('-e, --extends <paths>', 'Comma separated list of shareable config paths or packages name', list)
14
16
  .option(
15
17
  '--verify-conditions <paths>',
16
18
  'Comma separated list of paths or packages name for the verifyConditions plugin(s)',
@@ -42,7 +44,8 @@ module.exports = async () => {
42
44
  program.outputHelp();
43
45
  process.exitCode = 1;
44
46
  } else {
45
- await require('.')(program.opts());
47
+ // Remove option with undefined values, as commander.js sets non defined options as `undefined`
48
+ await require('.')(pickBy(program.opts(), value => !isUndefined(value)));
46
49
  }
47
50
  } catch (err) {
48
51
  // If error is a SemanticReleaseError then it's an expected exception case (no release to be done, running on a PR etc..) and the cli will return with 0
package/index.js CHANGED
@@ -15,10 +15,6 @@ module.exports = async opts => {
15
15
  const config = await getConfig(opts, logger);
16
16
  const {plugins, options} = config;
17
17
 
18
- if (!options.repositoryUrl) {
19
- throw new SemanticReleaseError('The repositoryUrl option is required', 'ENOREPOURL');
20
- }
21
-
22
18
  logger.log('Run automated release from branch %s', options.branch);
23
19
 
24
20
  if (!options.dryRun) {
@@ -1,8 +1,8 @@
1
1
  const gitLogParser = require('git-log-parser');
2
2
  const getStream = require('get-stream');
3
3
  const debug = require('debug')('semantic-release:get-commits');
4
- const {unshallow} = require('./git');
5
- const getVersionHead = require('./get-version-head');
4
+ const SemanticReleaseError = require('@semantic-release/error');
5
+ const {unshallow, gitCommitTag, gitTagHead, isCommitInHistory} = require('./git');
6
6
 
7
7
  /**
8
8
  * Commit message.
@@ -44,22 +44,28 @@ const getVersionHead = require('./get-version-head');
44
44
  * @return {Promise<Result>} The list of commits on the branch `branch` since the last release and the updated lastRelease with the gitHead used to retrieve the commits.
45
45
  *
46
46
  * @throws {SemanticReleaseError} with code `ENOTINHISTORY` if `lastRelease.gitHead` or the commit sha derived from `config.lastRelease.version` is not in the direct history of `branch`.
47
- * @throws {SemanticReleaseError} with code `ENOGITHEAD` if `lastRelease.gitHead` is undefined and no commit sha can be found for the `config.lastRelease.version`.
48
47
  */
49
48
  module.exports = async ({version, gitHead} = {}, branch, logger) => {
50
- let gitTag;
51
- if (gitHead || version) {
52
- try {
53
- ({gitHead, gitTag} = await getVersionHead(gitHead, version, branch));
54
- } catch (err) {
55
- if (err.code === 'ENOTINHISTORY') {
56
- logger.error(notInHistoryMessage(err.gitHead, branch, version));
57
- } else {
58
- logger.error(noGitHeadMessage(branch, version));
49
+ if (gitHead) {
50
+ // If gitHead doesn't exists in release branch
51
+ if (!await isCommitInHistory(gitHead)) {
52
+ // Unshallow the repository
53
+ await unshallow();
54
+ }
55
+ // If gitHead still doesn't exists in release branch
56
+ if (!await isCommitInHistory(gitHead)) {
57
+ // Try to find the commit corresponding to the version, using got tags
58
+ const tagHead = (await gitTagHead(`v${version}`)) || (await gitTagHead(version));
59
+
60
+ // If tagHead doesn't exists in release branch
61
+ if (!tagHead || !await isCommitInHistory(tagHead)) {
62
+ // Then the commit corresponding to the version cannot be found in the bracnh hsitory
63
+ logger.error(notInHistoryMessage(gitHead, branch, version));
64
+ throw new SemanticReleaseError('Commit not in history', 'ENOTINHISTORY');
59
65
  }
60
- throw err;
66
+ gitHead = tagHead;
61
67
  }
62
- logger.log('Retrieving commits since %s, corresponding to version %s', gitHead, version);
68
+ debug('Use gitHead: %s', gitHead);
63
69
  } else {
64
70
  logger.log('No previous release found, retrieving all commits');
65
71
  // If there is no gitHead nor a version, there is no previous release. Unshallow the repo in order to retrieve all commits
@@ -76,32 +82,15 @@ module.exports = async ({version, gitHead} = {}, branch, logger) => {
76
82
  );
77
83
  logger.log('Found %s commits since last release', commits.length);
78
84
  debug('Parsed commits: %o', commits);
79
- return {commits, lastRelease: {version, gitHead, gitTag}};
85
+ return {commits, lastRelease: {version, gitHead, gitTag: await gitCommitTag(gitHead)}};
80
86
  };
81
87
 
82
- function noGitHeadMessage(branch, version) {
83
- return `The commit the last release of this package was derived from cannot be determined from the release metadata nor from the repository tags.
84
- This means semantic-release can not extract the commits between now and then.
85
- This is usually caused by releasing from outside the repository directory or with innaccessible git metadata.
86
-
87
- You can recover from this error by creating a tag for the version "${
88
- version
89
- }" on the commit corresponding to this release:
90
- $ git tag -f v${version} <commit sha1 corresponding to last release>
91
- $ git push -f --tags origin ${branch}
92
- `;
93
- }
94
-
95
88
  function notInHistoryMessage(gitHead, branch, version) {
96
- return `The commit the last release of this package was derived from is not in the direct history of the "${
97
- branch
98
- }" branch.
89
+ return `The commit the last release of this package was derived from is not in the direct history of the "${branch}" branch.
99
90
  This means semantic-release can not extract the commits between now and then.
100
91
  This is usually caused by force pushing, releasing from an unrelated branch, or using an already existing package name.
101
92
 
102
- You can recover from this error by restoring the commit "${gitHead}" or by creating a tag for the version "${
103
- version
104
- }" on the commit corresponding to this release:
93
+ You can recover from this error by restoring the commit "${gitHead}" or by creating a tag for the version "${version}" on the commit corresponding to this release:
105
94
  $ git tag -f v${version || '<version>'} <commit sha1 corresponding to last release>
106
95
  $ git push -f --tags origin ${branch}
107
96
  `;
package/lib/get-config.js CHANGED
@@ -1,14 +1,56 @@
1
1
  const readPkgUp = require('read-pkg-up');
2
- const {defaults} = require('lodash');
2
+ const {castArray, pickBy, isUndefined, isNull, isString, isPlainObject} = require('lodash');
3
3
  const cosmiconfig = require('cosmiconfig');
4
+ const resolveFrom = require('resolve-from');
5
+ const SemanticReleaseError = require('@semantic-release/error');
4
6
  const debug = require('debug')('semantic-release:config');
5
7
  const {repoUrl} = require('./git');
8
+ const PLUGINS_DEFINITION = require('./plugins/definitions');
6
9
  const plugins = require('./plugins');
7
10
 
8
11
  module.exports = async (opts, logger) => {
9
12
  const {config} = (await cosmiconfig('release', {rcExtensions: true}).load(process.cwd())) || {};
10
- const options = defaults(opts, config, {branch: 'master', repositoryUrl: (await pkgRepoUrl()) || (await repoUrl())});
13
+ // Merge config file options and CLI/API options
14
+ let options = {...config, ...opts};
15
+ const pluginsPath = {};
16
+ let extendPaths;
17
+ ({extends: extendPaths, ...options} = options);
18
+ if (extendPaths) {
19
+ // If `extends` is defined, load and merge each shareable config with `options`
20
+ options = {
21
+ ...castArray(extendPaths).reduce((result, extendPath) => {
22
+ const extendsOpts = require(resolveFrom.silent(__dirname, extendPath) ||
23
+ resolveFrom(process.cwd(), extendPath));
11
24
 
25
+ // For each plugin defined in a shareable config, save in `pluginsPath` the extendable config path,
26
+ // so those plugin will be loaded relatively to the config file
27
+ Object.keys(extendsOpts).reduce((pluginsPath, option) => {
28
+ if (PLUGINS_DEFINITION[option]) {
29
+ castArray(extendsOpts[option])
30
+ .filter(plugin => isString(plugin) || (isPlainObject(plugin) && isString(plugin.path)))
31
+ .map(plugin => (isString(plugin) ? plugin : plugin.path))
32
+ .forEach(plugin => {
33
+ pluginsPath[plugin] = extendPath;
34
+ });
35
+ }
36
+ return pluginsPath;
37
+ }, pluginsPath);
38
+
39
+ return {...result, ...extendsOpts};
40
+ }, {}),
41
+ ...options,
42
+ };
43
+ }
44
+
45
+ // Set default options values if not defined yet
46
+ options = {
47
+ branch: 'master',
48
+ repositoryUrl: (await pkgRepoUrl()) || (await repoUrl()),
49
+ // Remove `null` and `undefined` options so they can be replaced with default ones
50
+ ...pickBy(options, option => !isUndefined(option) && !isNull(option)),
51
+ };
52
+
53
+ debug('options values: %O', Object.keys(options));
12
54
  debug('name: %O', options.name);
13
55
  debug('branch: %O', options.branch);
14
56
  debug('repositoryUrl: %O', options.repositoryUrl);
@@ -18,10 +60,14 @@ module.exports = async (opts, logger) => {
18
60
  debug('verifyRelease: %O', options.verifyRelease);
19
61
  debug('publish: %O', options.publish);
20
62
 
21
- return {options, plugins: await plugins(options, logger)};
63
+ if (!options.repositoryUrl) {
64
+ throw new SemanticReleaseError('The repositoryUrl option is required', 'ENOREPOURL');
65
+ }
66
+
67
+ return {options, plugins: await plugins(options, pluginsPath, logger)};
22
68
  };
23
69
 
24
70
  async function pkgRepoUrl() {
25
71
  const {pkg} = await readPkgUp();
26
- return pkg && pkg.repository ? pkg.repository.url : null;
72
+ return pkg && pkg.repository ? pkg.repository.url : undefined;
27
73
  }
package/lib/git.js CHANGED
@@ -25,7 +25,7 @@ async function gitTagHead(tagName) {
25
25
  *
26
26
  * @param {string} gitHead The commit sha for which to retrieve the associated tag.
27
27
  *
28
- * @return {string} The tag associatedwith the sha in parameter or `null`.
28
+ * @return {string} The tag associatedwith the sha in parameter or `undefined`.
29
29
  */
30
30
  async function gitCommitTag(gitHead) {
31
31
  try {
@@ -34,7 +34,7 @@ async function gitCommitTag(gitHead) {
34
34
  return shell.stdout;
35
35
  } catch (err) {
36
36
  debug(err);
37
- return null;
37
+ return undefined;
38
38
  }
39
39
  }
40
40
 
@@ -73,10 +73,10 @@ async function gitHead() {
73
73
  }
74
74
 
75
75
  /**
76
- * @return {string|null} The value of the remote git URL.
76
+ * @return {string|undefined} The value of the remote git URL.
77
77
  */
78
78
  async function repoUrl() {
79
- return (await execa.stdout('git', ['remote', 'get-url', 'origin'], {reject: false})) || null;
79
+ return (await execa.stdout('git', ['remote', 'get-url', 'origin'], {reject: false})) || undefined;
80
80
  }
81
81
 
82
82
  /**
@@ -24,9 +24,9 @@ module.exports = {
24
24
  validator: output =>
25
25
  !output ||
26
26
  (isObject(output) && !output.version) ||
27
- (isString(output.version) && Boolean(semver.valid(semver.clean(output.version)))),
27
+ (isString(output.version) && Boolean(semver.valid(semver.clean(output.version))) && Boolean(output.gitHead)),
28
28
  message:
29
- 'The "getLastRelease" plugin output if defined, must be an object with an optionnal valid semver version in the "version" property.',
29
+ 'The "getLastRelease" plugin output if defined, must be an object with a valid semver version in the "version" property and the corresponding git reference in "gitHead" property.',
30
30
  },
31
31
  },
32
32
  analyzeCommits: {
@@ -1,11 +1,12 @@
1
- const {isArray, isObject} = require('lodash');
2
- const DEFINITIONS = require('./definitions');
1
+ const {isArray, isObject, omit} = require('lodash');
2
+ const SemanticReleaseError = require('@semantic-release/error');
3
+ const PLUGINS_DEFINITION = require('./definitions');
3
4
  const pipeline = require('./pipeline');
4
5
  const normalize = require('./normalize');
5
6
 
6
- module.exports = (options, logger) =>
7
- Object.keys(DEFINITIONS).reduce((plugins, pluginType) => {
8
- const {config, output, default: def} = DEFINITIONS[pluginType];
7
+ module.exports = (options, pluginsPath, logger) =>
8
+ Object.keys(PLUGINS_DEFINITION).reduce((plugins, pluginType) => {
9
+ const {config, output, default: def} = PLUGINS_DEFINITION[pluginType];
9
10
  let pluginConfs;
10
11
  if (options[pluginType]) {
11
12
  // If an object is passed and the path is missing, set the default one for single plugins
@@ -13,16 +14,18 @@ module.exports = (options, logger) =>
13
14
  options[pluginType].path = def;
14
15
  }
15
16
  if (config && !config.validator(options[pluginType])) {
16
- throw new Error(config.message);
17
+ throw new SemanticReleaseError(config.message, 'EPLUGINCONF');
17
18
  }
18
19
  pluginConfs = options[pluginType];
19
20
  } else {
20
21
  pluginConfs = def;
21
22
  }
22
23
 
24
+ const globalOpts = omit(options, Object.keys(PLUGINS_DEFINITION));
25
+
23
26
  plugins[pluginType] = isArray(pluginConfs)
24
- ? pipeline(pluginConfs.map(conf => normalize(pluginType, conf, logger, output)))
25
- : normalize(pluginType, pluginConfs, logger, output);
27
+ ? pipeline(pluginConfs.map(conf => normalize(pluginType, pluginsPath, globalOpts, conf, logger, output)))
28
+ : normalize(pluginType, pluginsPath, globalOpts, pluginConfs, logger, output);
26
29
 
27
30
  return plugins;
28
31
  }, {});
@@ -1,25 +1,39 @@
1
+ const {dirname} = require('path');
1
2
  const {inspect} = require('util');
3
+ const SemanticReleaseError = require('@semantic-release/error');
2
4
  const {isString, isObject, isFunction, noop, cloneDeep} = require('lodash');
3
- const importFrom = require('import-from');
5
+ const resolveFrom = require('resolve-from');
4
6
 
5
- module.exports = (pluginType, pluginConfig, logger, validator) => {
6
- if (!pluginConfig) {
7
+ module.exports = (pluginType, pluginsPath, globalOpts, pluginOpts, logger, validator) => {
8
+ if (!pluginOpts) {
7
9
  return noop;
8
10
  }
9
- const {path, ...config} = isString(pluginConfig) || isFunction(pluginConfig) ? {path: pluginConfig} : pluginConfig;
10
- if (!isFunction(pluginConfig)) {
11
- logger.log('Load plugin %s', path);
11
+
12
+ const {path, ...config} = isString(pluginOpts) || isFunction(pluginOpts) ? {path: pluginOpts} : pluginOpts;
13
+ if (!isFunction(pluginOpts)) {
14
+ if (pluginsPath[path]) {
15
+ logger.log('Load plugin %s from %s in shareable config %s', pluginType, path, pluginsPath[path]);
16
+ } else {
17
+ logger.log('Load plugin %s from %s', pluginType, path);
18
+ }
12
19
  }
13
- const plugin = isFunction(path) ? path : importFrom.silent(__dirname, path) || importFrom(process.cwd(), path);
20
+
21
+ const basePath = pluginsPath[path]
22
+ ? dirname(resolveFrom.silent(__dirname, pluginsPath[path]) || resolveFrom(process.cwd(), pluginsPath[path]))
23
+ : __dirname;
24
+ const plugin = isFunction(path)
25
+ ? path
26
+ : require(resolveFrom.silent(basePath, path) || resolveFrom(process.cwd(), path));
14
27
 
15
28
  let func;
16
29
  if (isFunction(plugin)) {
17
- func = plugin.bind(null, cloneDeep(config));
30
+ func = plugin.bind(null, cloneDeep({...globalOpts, ...config}));
18
31
  } else if (isObject(plugin) && plugin[pluginType] && isFunction(plugin[pluginType])) {
19
- func = plugin[pluginType].bind(null, cloneDeep(config));
32
+ func = plugin[pluginType].bind(null, cloneDeep({...globalOpts, ...config}));
20
33
  } else {
21
- throw new Error(
22
- `The ${pluginType} plugin must be a function, or an object with a function in the property ${pluginType}.`
34
+ throw new SemanticReleaseError(
35
+ `The ${pluginType} plugin must be a function, or an object with a function in the property ${pluginType}.`,
36
+ 'EPLUGINCONF'
23
37
  );
24
38
  }
25
39
 
package/package.json CHANGED
@@ -1 +1,134 @@
1
- {"name":"semantic-release","description":"Automated semver compliant package publishing","version":"11.0.1","author":"Stephan Bönnemann <stephan@boennemann.me> (http://boennemann.me)","bin":{"semantic-release":"bin/semantic-release.js"},"bugs":{"url":"https://github.com/semantic-release/semantic-release/issues"},"config":{"commitizen":{"path":"cz-conventional-changelog"}},"dependencies":{"@semantic-release/commit-analyzer":"^5.0.0","@semantic-release/condition-travis":"^7.0.0","@semantic-release/error":"^2.1.0","@semantic-release/github":"^2.0.0","@semantic-release/npm":"^2.0.0","@semantic-release/release-notes-generator":"^6.0.0","chalk":"^2.3.0","commander":"^2.11.0","cosmiconfig":"^3.1.0","debug":"^3.1.0","execa":"^0.8.0","get-stream":"^3.0.0","git-log-parser":"^1.2.0","import-from":"^2.1.0","lodash":"^4.0.0","marked":"^0.3.6","marked-terminal":"^2.0.0","p-reduce":"^1.0.0","read-pkg-up":"^3.0.0","semver":"^5.4.1"},"devDependencies":{"ava":"^0.24.0","codecov":"^3.0.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","dockerode":"^2.5.2","eslint-config-prettier":"^2.5.0","eslint-plugin-prettier":"^2.3.0","file-url":"^2.0.2","fs-extra":"^4.0.2","got":"^8.0.0","js-yaml":"^3.10.0","mockserver-client":"^2.0.0","nock":"^9.0.2","nyc":"^11.2.1","p-retry":"^1.0.0","prettier":"~1.8.0","proxyquire":"^1.8.0","sinon":"^4.0.0","tempy":"^0.2.1","xo":"^0.18.2"},"engines":{"node":">=4","npm":">=2"},"files":["bin","lib","index.js","cli.js"],"homepage":"https://github.com/semantic-release/semantic-release#readme","keywords":["author","automation","changelog","module","package","publish","release","semver","version"],"license":"MIT","main":"index.js","nyc":{"include":["lib/**/*.js","index.js","cli.js"],"reporter":["json","text","html"],"all":true},"prettier":{"printWidth":120,"singleQuote":true,"bracketSpacing":false,"trailingComma":"es5"},"publishConfig":{"tag":"next"},"release":{"branch":"caribou"},"repository":{"type":"git","url":"git+https://github.com/semantic-release/semantic-release.git"},"scripts":{"cm":"git-cz","codecov":"codecov -f coverage/coverage-final.json","lint":"xo","pretest":"npm run lint","semantic-release":"./bin/semantic-release.js","test":"nyc ava -v"},"xo":{"extends":["prettier"],"plugins":["prettier"],"rules":{"prettier/prettier":2}}}
1
+ {
2
+ "name": "semantic-release",
3
+ "description": "Automated semver compliant package publishing",
4
+ "version": "11.2.0",
5
+ "author": "Stephan Bönnemann <stephan@boennemann.me> (http://boennemann.me)",
6
+ "bin": {
7
+ "semantic-release": "bin/semantic-release.js"
8
+ },
9
+ "bugs": {
10
+ "url": "https://github.com/semantic-release/semantic-release/issues"
11
+ },
12
+ "config": {
13
+ "commitizen": {
14
+ "path": "cz-conventional-changelog"
15
+ }
16
+ },
17
+ "dependencies": {
18
+ "@semantic-release/commit-analyzer": "^5.0.0",
19
+ "@semantic-release/condition-travis": "^7.0.0",
20
+ "@semantic-release/error": "^2.1.0",
21
+ "@semantic-release/github": "^3.0.0",
22
+ "@semantic-release/npm": "^2.0.0",
23
+ "@semantic-release/release-notes-generator": "^6.0.0",
24
+ "chalk": "^2.3.0",
25
+ "commander": "^2.11.0",
26
+ "cosmiconfig": "^3.1.0",
27
+ "debug": "^3.1.0",
28
+ "execa": "^0.8.0",
29
+ "get-stream": "^3.0.0",
30
+ "git-log-parser": "^1.2.0",
31
+ "lodash": "^4.0.0",
32
+ "marked": "^0.3.6",
33
+ "marked-terminal": "^2.0.0",
34
+ "p-reduce": "^1.0.0",
35
+ "read-pkg-up": "^3.0.0",
36
+ "resolve-from": "^4.0.0",
37
+ "semver": "^5.4.1"
38
+ },
39
+ "devDependencies": {
40
+ "ava": "^0.24.0",
41
+ "codecov": "^3.0.0",
42
+ "commitizen": "^2.9.6",
43
+ "cz-conventional-changelog": "^2.0.0",
44
+ "delay": "^2.0.0",
45
+ "dockerode": "^2.5.2",
46
+ "eslint-config-prettier": "^2.5.0",
47
+ "eslint-plugin-prettier": "^2.3.0",
48
+ "file-url": "^2.0.2",
49
+ "fs-extra": "^5.0.0",
50
+ "got": "^8.0.0",
51
+ "js-yaml": "^3.10.0",
52
+ "mockserver-client": "^5.1.1",
53
+ "nock": "^9.0.2",
54
+ "nyc": "^11.2.1",
55
+ "p-retry": "^1.0.0",
56
+ "prettier": "~1.9.2",
57
+ "proxyquire": "^1.8.0",
58
+ "sinon": "^4.0.0",
59
+ "tempy": "^0.2.1",
60
+ "xo": "^0.18.2"
61
+ },
62
+ "engines": {
63
+ "node": ">=4",
64
+ "npm": ">=2"
65
+ },
66
+ "files": [
67
+ "bin",
68
+ "lib",
69
+ "index.js",
70
+ "cli.js"
71
+ ],
72
+ "homepage": "https://github.com/semantic-release/semantic-release#readme",
73
+ "keywords": [
74
+ "author",
75
+ "automation",
76
+ "changelog",
77
+ "module",
78
+ "package",
79
+ "publish",
80
+ "release",
81
+ "semver",
82
+ "version"
83
+ ],
84
+ "license": "MIT",
85
+ "main": "index.js",
86
+ "nyc": {
87
+ "include": [
88
+ "lib/**/*.js",
89
+ "index.js",
90
+ "cli.js"
91
+ ],
92
+ "reporter": [
93
+ "json",
94
+ "text",
95
+ "html"
96
+ ],
97
+ "all": true
98
+ },
99
+ "prettier": {
100
+ "printWidth": 120,
101
+ "singleQuote": true,
102
+ "bracketSpacing": false,
103
+ "trailingComma": "es5"
104
+ },
105
+ "publishConfig": {
106
+ "tag": "next"
107
+ },
108
+ "release": {
109
+ "branch": "caribou"
110
+ },
111
+ "repository": {
112
+ "type": "git",
113
+ "url": "git+https://github.com/semantic-release/semantic-release.git"
114
+ },
115
+ "scripts": {
116
+ "cm": "git-cz",
117
+ "codecov": "codecov -f coverage/coverage-final.json",
118
+ "lint": "xo",
119
+ "pretest": "npm run lint",
120
+ "semantic-release": "./bin/semantic-release.js",
121
+ "test": "nyc ava -v"
122
+ },
123
+ "xo": {
124
+ "extends": [
125
+ "prettier"
126
+ ],
127
+ "plugins": [
128
+ "prettier"
129
+ ],
130
+ "rules": {
131
+ "prettier/prettier": 2
132
+ }
133
+ }
134
+ }
@@ -1,52 +0,0 @@
1
- const debug = require('debug')('semantic-release:get-version-head');
2
- const SemanticReleaseError = require('@semantic-release/error');
3
- const {gitTagHead, gitCommitTag, isCommitInHistory, unshallow} = require('./git');
4
-
5
- /**
6
- * Get the commit sha for a given version, if it's contained in the given branch.
7
- *
8
- * @param {string} gitHead The commit sha to look for.
9
- * @param {string} version The version corresponding to the commit sha to look for. Used to search in git tags.
10
- *
11
- * @return {Promise<Object>} A Promise that resolves to an object with the `gitHead` and `gitTag` for the the `version`.
12
- *
13
- * @throws {SemanticReleaseError} with code `ENOTINHISTORY` if `gitHead` or the commit sha dereived from `version` is not in the direct history of `branch`.
14
- * @throws {SemanticReleaseError} with code `ENOGITHEAD` if `gitHead` is undefined and no commit sha can be found for the `version`.
15
- */
16
- module.exports = async (gitHead, version) => {
17
- // Check if gitHead is defined and exists in release branch
18
- if (gitHead && (await isCommitInHistory(gitHead))) {
19
- debug('Use gitHead: %s', gitHead);
20
- return {gitHead, gitTag: await gitCommitTag(gitHead)};
21
- }
22
-
23
- await unshallow();
24
-
25
- // Check if gitHead is defined and exists in release branch again
26
- if (gitHead && (await isCommitInHistory(gitHead))) {
27
- debug('Use gitHead: %s', gitHead);
28
- return {gitHead, gitTag: await gitCommitTag(gitHead)};
29
- }
30
-
31
- let tagHead;
32
- if (version) {
33
- // If a version is defined search a corresponding tag
34
- tagHead = (await gitTagHead(`v${version}`)) || (await gitTagHead(version));
35
-
36
- // Check if tagHead is found and exists in release branch again
37
- if (tagHead && (await isCommitInHistory(tagHead))) {
38
- debug('Use tagHead: %s', tagHead);
39
- return {gitHead: tagHead, gitTag: await gitCommitTag(tagHead)};
40
- }
41
- }
42
-
43
- // Either gitHead is defined or a tagHead has been found but none is in the branch history
44
- if (gitHead || tagHead) {
45
- const error = new SemanticReleaseError('Commit not in history', 'ENOTINHISTORY');
46
- error.gitHead = gitHead || tagHead;
47
- throw error;
48
- }
49
-
50
- // There is no gitHead in the last release and there is no tags correponsing to the last release version
51
- throw new SemanticReleaseError('There is no commit associated with last release', 'ENOGITHEAD');
52
- };