From d7b323dd00d54687679d67506212266714114132 Mon Sep 17 00:00:00 2001 From: Pierre Vanduynslager Date: Tue, 28 Nov 2017 23:35:25 -0500 Subject: [PATCH] fix: Accept `undefined` values for the `getLastRelease` and `generateNotes` plugins Adapt tests and default value to the plugin definitions (`definitions.js`) --- lib/get-commits.js | 3 +- lib/plugins/definitions.js | 4 +-- test/index.test.js | 48 ++++++++++++++++++++++++++++++++ test/plugins/definitions.test.js | 6 ++-- 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/lib/get-commits.js b/lib/get-commits.js index 06cd4379..5f1e3425 100644 --- a/lib/get-commits.js +++ b/lib/get-commits.js @@ -18,6 +18,7 @@ const getVersionHead = require('./get-version-head'); * @typedef {Object} LastRelease * @property {string} version The version number of the last release. * @property {string} [gitHead] The commit sha used to make the last release. + * @property {string} [gitTag] The tag used to make the last release. */ /** @@ -45,7 +46,7 @@ const getVersionHead = require('./get-version-head'); * @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`. * @throws {SemanticReleaseError} with code `ENOGITHEAD` if `lastRelease.gitHead` is undefined and no commit sha can be found for the `config.lastRelease.version`. */ -module.exports = async ({version, gitHead}, branch, logger) => { +module.exports = async ({version, gitHead} = {}, branch, logger) => { let gitTag; if (gitHead || version) { try { diff --git a/lib/plugins/definitions.js b/lib/plugins/definitions.js index 60909d52..09ac7b8c 100644 --- a/lib/plugins/definitions.js +++ b/lib/plugins/definitions.js @@ -57,8 +57,8 @@ module.exports = { 'The "generateNotes" plugin, if defined, must be a single plugin definition. A plugin definition is either a string or an object with a path property.', }, output: { - validator: output => isString(output), - message: 'The "generateNotes" plugin output must be a string.', + validator: output => !output || isString(output), + message: 'The "generateNotes" plugin output, if defined, must be a string.', }, }, publish: { diff --git a/test/index.test.js b/test/index.test.js index d0ff9084..8e4c7fdc 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -193,6 +193,54 @@ test.serial('Dry-run skips verifyConditions and publish', async t => { t.true(publish.notCalled); }); +test.serial('Accept "undefined" values for the "getLastRelease" and "generateNotes" plugins', async t => { + // Create a git repository, set the current working directory at the root of the repo + await gitRepo(); + // Add commits to the master branch + await gitCommits(['First']); + // Create the tag corresponding to version 1.0.0 + await gitTagVersion('v1.0.0'); + // Add new commits to the master branch + await gitCommits(['Second']); + + const lastRelease = {gitHead: undefined, gitTag: undefined, version: undefined}; + const nextRelease = {type: 'major', version: '2.0.0', gitHead: await getGitHead(), gitTag: 'v2.0.0'}; + const verifyConditions = stub().resolves(); + const getLastRelease = stub().resolves(); + const analyzeCommits = stub().resolves(nextRelease.type); + const verifyRelease = stub().resolves(); + const generateNotes = stub().resolves(); + const publish = stub().resolves(); + + const options = { + branch: 'master', + repositoryUrl: 'git@hostname.com:owner/module.git', + verifyConditions: [verifyConditions], + getLastRelease, + analyzeCommits, + verifyRelease, + generateNotes, + publish, + }; + + await t.context.semanticRelease(options); + + t.true(getLastRelease.calledOnce); + + t.true(analyzeCommits.calledOnce); + t.deepEqual(analyzeCommits.firstCall.args[1].lastRelease, lastRelease); + + t.true(verifyRelease.calledOnce); + t.deepEqual(verifyRelease.firstCall.args[1].lastRelease, lastRelease); + + t.true(generateNotes.calledOnce); + t.deepEqual(generateNotes.firstCall.args[1].lastRelease, lastRelease); + + t.true(publish.calledOnce); + t.deepEqual(publish.firstCall.args[1].lastRelease, lastRelease); + t.falsy(publish.firstCall.args[1].nextRelease.notes); +}); + test.serial('Throw SemanticReleaseError if not running from a git repository', async t => { // Set the current working directory to a temp directory process.chdir(tempy.directory()); diff --git a/test/plugins/definitions.test.js b/test/plugins/definitions.test.js index 25820267..5c1f673d 100644 --- a/test/plugins/definitions.test.js +++ b/test/plugins/definitions.test.js @@ -89,12 +89,12 @@ test('The "analyzeCommits" plugin output must be either undefined or a valid sem t.true(definitions.analyzeCommits.output.validator('major')); }); -test('The "generateNotes" plugin output must be a string', t => { - t.false(definitions.generateNotes.output.validator()); - t.false(definitions.generateNotes.output.validator(null)); +test('The "generateNotes" plugin output, if defined, must be a string', t => { t.false(definitions.generateNotes.output.validator(1)); t.false(definitions.generateNotes.output.validator({})); + t.true(definitions.generateNotes.output.validator()); + t.true(definitions.generateNotes.output.validator(null)); t.true(definitions.generateNotes.output.validator('')); t.true(definitions.generateNotes.output.validator('string')); });