feat: Expect plugins to return Promises
BREAKING CHANGE: Each plugin is expected to return an async function or a Promise returning function. The callback parameter is not passed to plugins anymore.
This commit is contained in:
parent
d4c7605f68
commit
5bec59b26b
@ -210,8 +210,6 @@ module.exports = function (pluginConfig, config, callback) {}
|
|||||||
- `options`: `semantic-release` options like `debug`, or `branch`
|
- `options`: `semantic-release` options like `debug`, or `branch`
|
||||||
- `pkg`: Parsed `package.json`
|
- `pkg`: Parsed `package.json`
|
||||||
- For certain plugins the `config` object contains even more information. See below.
|
- For certain plugins the `config` object contains even more information. See below.
|
||||||
- `callback`: If an error occurs pass it as first argument. Otherwise pass your result as second argument.
|
|
||||||
|
|
||||||
|
|
||||||
### `analyzeCommits`
|
### `analyzeCommits`
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const {promisify, inspect} = require('util');
|
const {inspect} = require('util');
|
||||||
const {isString, isObject, isFunction, noop, cloneDeep} = require('lodash');
|
const {isString, isObject, isFunction, noop, cloneDeep} = require('lodash');
|
||||||
const importFrom = require('import-from');
|
const importFrom = require('import-from');
|
||||||
|
|
||||||
@ -14,9 +14,9 @@ module.exports = (pluginType, pluginConfig, logger, validator) => {
|
|||||||
|
|
||||||
let func;
|
let func;
|
||||||
if (isFunction(plugin)) {
|
if (isFunction(plugin)) {
|
||||||
func = promisify(plugin.bind(null, cloneDeep(config)));
|
func = plugin.bind(null, cloneDeep(config));
|
||||||
} else if (isObject(plugin) && plugin[pluginType] && isFunction(plugin[pluginType])) {
|
} else if (isObject(plugin) && plugin[pluginType] && isFunction(plugin[pluginType])) {
|
||||||
func = promisify(plugin[pluginType].bind(null, cloneDeep(config)));
|
func = plugin[pluginType].bind(null, cloneDeep(config));
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`The ${pluginType} plugin must be a function, or an object with a function in the property ${pluginType}.`
|
`The ${pluginType} plugin must be a function, or an object with a function in the property ${pluginType}.`
|
||||||
|
25
test/fixtures/multi-plugin.js
vendored
25
test/fixtures/multi-plugin.js
vendored
@ -1,21 +1,8 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
verifyConditions(config, options, cb) {
|
verifyConditions: () => {},
|
||||||
cb();
|
getLastRelease: () => {},
|
||||||
},
|
analyzeCommits: () => {},
|
||||||
|
verifyRelease: () => {},
|
||||||
getLastRelease(config, options, cb) {
|
generateNotes: () => {},
|
||||||
cb();
|
publish: () => {},
|
||||||
},
|
|
||||||
analyzeCommits(config, options, cb) {
|
|
||||||
cb();
|
|
||||||
},
|
|
||||||
verifyRelease(config, options, cb) {
|
|
||||||
cb();
|
|
||||||
},
|
|
||||||
generateNotes(config, options, cb) {
|
|
||||||
cb();
|
|
||||||
},
|
|
||||||
publish(config, options, cb) {
|
|
||||||
cb();
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
4
test/fixtures/plugin-error-inherited.js
vendored
4
test/fixtures/plugin-error-inherited.js
vendored
@ -9,6 +9,6 @@ class InheritedError extends SemanticReleaseError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function(config, options, cb) {
|
module.exports = () => {
|
||||||
cb(new InheritedError('Inherited error', 'EINHERITED'));
|
throw new InheritedError('Inherited error', 'EINHERITED');
|
||||||
};
|
};
|
||||||
|
4
test/fixtures/plugin-error.js
vendored
4
test/fixtures/plugin-error.js
vendored
@ -1,5 +1,5 @@
|
|||||||
module.exports = function(config, options, cb) {
|
module.exports = () => {
|
||||||
const error = new Error('a');
|
const error = new Error('a');
|
||||||
error.errorProperty = 'errorProperty';
|
error.errorProperty = 'errorProperty';
|
||||||
cb(error);
|
throw error;
|
||||||
};
|
};
|
||||||
|
4
test/fixtures/plugin-noop.js
vendored
4
test/fixtures/plugin-noop.js
vendored
@ -1,3 +1 @@
|
|||||||
module.exports = (config, options, cb) => {
|
module.exports = () => {};
|
||||||
cb(null);
|
|
||||||
};
|
|
||||||
|
4
test/fixtures/plugin-result-config.js
vendored
4
test/fixtures/plugin-result-config.js
vendored
@ -1,3 +1 @@
|
|||||||
module.exports = function(pluginConfig, options, cb) {
|
module.exports = (pluginConfig, options) => ({pluginConfig, options});
|
||||||
cb(null, {pluginConfig, options});
|
|
||||||
};
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {callbackify} from 'util';
|
|
||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
import {writeJson} from 'fs-extra';
|
import {writeJson} from 'fs-extra';
|
||||||
import proxyquire from 'proxyquire';
|
import proxyquire from 'proxyquire';
|
||||||
@ -57,12 +56,12 @@ test.serial('Plugins are called with expected values', async t => {
|
|||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
branch: 'master',
|
branch: 'master',
|
||||||
verifyConditions: [callbackify(verifyConditions1), callbackify(verifyConditions2)],
|
verifyConditions: [verifyConditions1, verifyConditions2],
|
||||||
getLastRelease: callbackify(getLastRelease),
|
getLastRelease,
|
||||||
analyzeCommits: callbackify(analyzeCommits),
|
analyzeCommits,
|
||||||
verifyRelease: callbackify(verifyRelease),
|
verifyRelease,
|
||||||
generateNotes: callbackify(generateNotes),
|
generateNotes,
|
||||||
publish: callbackify(publish),
|
publish,
|
||||||
};
|
};
|
||||||
const pkg = {name, version: '0.0.0-dev'};
|
const pkg = {name, version: '0.0.0-dev'};
|
||||||
normalizeData(pkg);
|
normalizeData(pkg);
|
||||||
@ -140,12 +139,12 @@ test.serial('Use new gitHead, and recreate release notes if a publish plugin cre
|
|||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
branch: 'master',
|
branch: 'master',
|
||||||
verifyConditions: callbackify(stub().resolves()),
|
verifyConditions: stub().resolves(),
|
||||||
getLastRelease: callbackify(stub().resolves(lastRelease)),
|
getLastRelease: stub().resolves(lastRelease),
|
||||||
analyzeCommits: callbackify(stub().resolves(nextRelease.type)),
|
analyzeCommits: stub().resolves(nextRelease.type),
|
||||||
verifyRelease: callbackify(stub().resolves()),
|
verifyRelease: stub().resolves(),
|
||||||
generateNotes: callbackify(generateNotes),
|
generateNotes,
|
||||||
publish: [callbackify(publish1), callbackify(publish2)],
|
publish: [publish1, publish2],
|
||||||
};
|
};
|
||||||
|
|
||||||
await writeJson('./package.json', {});
|
await writeJson('./package.json', {});
|
||||||
@ -188,12 +187,12 @@ test.serial('Dry-run skips verifyConditions and publish', async t => {
|
|||||||
const options = {
|
const options = {
|
||||||
dryRun: true,
|
dryRun: true,
|
||||||
branch: 'master',
|
branch: 'master',
|
||||||
verifyConditions: callbackify(verifyConditions),
|
verifyConditions,
|
||||||
getLastRelease: callbackify(getLastRelease),
|
getLastRelease,
|
||||||
analyzeCommits: callbackify(analyzeCommits),
|
analyzeCommits,
|
||||||
verifyRelease: callbackify(verifyRelease),
|
verifyRelease,
|
||||||
generateNotes: callbackify(generateNotes),
|
generateNotes,
|
||||||
publish: callbackify(publish),
|
publish,
|
||||||
};
|
};
|
||||||
const pkg = {name, version: '0.0.0-dev'};
|
const pkg = {name, version: '0.0.0-dev'};
|
||||||
normalizeData(pkg);
|
normalizeData(pkg);
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {callbackify} from 'util';
|
|
||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
import {noop} from 'lodash';
|
import {noop} from 'lodash';
|
||||||
import {stub, match} from 'sinon';
|
import {stub, match} from 'sinon';
|
||||||
@ -39,7 +38,7 @@ test('Normalize and load plugin that retuns multiple functions', t => {
|
|||||||
|
|
||||||
test('Wrap plugin in a function that validate the output of the plugin', async t => {
|
test('Wrap plugin in a function that validate the output of the plugin', async t => {
|
||||||
const pluginFunction = stub().resolves(1);
|
const pluginFunction = stub().resolves(1);
|
||||||
const plugin = normalize('', callbackify(pluginFunction), t.context.logger, {
|
const plugin = normalize('', pluginFunction, t.context.logger, {
|
||||||
validator: output => output === 1,
|
validator: output => output === 1,
|
||||||
message: 'The output must be 1',
|
message: 'The output must be 1',
|
||||||
});
|
});
|
||||||
@ -53,7 +52,7 @@ test('Wrap plugin in a function that validate the output of the plugin', async t
|
|||||||
|
|
||||||
test('Plugin is called with "pluginConfig" (omitting "path") and input', async t => {
|
test('Plugin is called with "pluginConfig" (omitting "path") and input', async t => {
|
||||||
const pluginFunction = stub().resolves();
|
const pluginFunction = stub().resolves();
|
||||||
const conf = {path: callbackify(pluginFunction), conf: 'confValue'};
|
const conf = {path: pluginFunction, conf: 'confValue'};
|
||||||
const plugin = normalize('', conf, t.context.logger);
|
const plugin = normalize('', conf, t.context.logger);
|
||||||
await plugin('param');
|
await plugin('param');
|
||||||
|
|
||||||
@ -61,9 +60,8 @@ test('Plugin is called with "pluginConfig" (omitting "path") and input', async t
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Prevent plugins to modify "pluginConfig"', async t => {
|
test('Prevent plugins to modify "pluginConfig"', async t => {
|
||||||
const pluginFunction = stub().callsFake((pluginConfig, options, cb) => {
|
const pluginFunction = stub().callsFake(pluginConfig => {
|
||||||
pluginConfig.conf.subConf = 'otherConf';
|
pluginConfig.conf.subConf = 'otherConf';
|
||||||
cb();
|
|
||||||
});
|
});
|
||||||
const conf = {path: pluginFunction, conf: {subConf: 'originalConf'}};
|
const conf = {path: pluginFunction, conf: {subConf: 'originalConf'}};
|
||||||
const plugin = normalize('', conf, t.context.logger);
|
const plugin = normalize('', conf, t.context.logger);
|
||||||
@ -73,9 +71,8 @@ test('Prevent plugins to modify "pluginConfig"', async t => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Prevent plugins to modify its input', async t => {
|
test('Prevent plugins to modify its input', async t => {
|
||||||
const pluginFunction = stub().callsFake((pluginConfig, options, cb) => {
|
const pluginFunction = stub().callsFake((pluginConfig, options) => {
|
||||||
options.param.subParam = 'otherParam';
|
options.param.subParam = 'otherParam';
|
||||||
cb();
|
|
||||||
});
|
});
|
||||||
const input = {param: {subParam: 'originalSubParam'}};
|
const input = {param: {subParam: 'originalSubParam'}};
|
||||||
const plugin = normalize('', pluginFunction, t.context.logger);
|
const plugin = normalize('', pluginFunction, t.context.logger);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user