UNPKG

2.08 kBJavaScriptView Raw
1const {escapeRegExp, template} = require('lodash');
2const semver = require('semver');
3const pLocate = require('p-locate');
4const debug = require('debug')('semantic-release:get-last-release');
5const {getTags, isRefInHistory, getTagHead} = require('./git');
6
7/**
8 * Last release.
9 *
10 * @typedef {Object} LastRelease
11 * @property {string} version The version number of the last release.
12 * @property {string} [gitHead] The Git reference used to make the last release.
13 */
14
15/**
16 * Determine the Git tag and version of the last tagged release.
17 *
18 * - Obtain all the tags referencing commits in the current branch history
19 * - Filter out the ones that are not valid semantic version or doesn't match the `tagFormat`
20 * - Sort the versions
21 * - Retrive the highest version
22 *
23 * @param {Object} context semantic-release context.
24 *
25 * @return {Promise<LastRelease>} The last tagged release or `undefined` if none is found.
26 */
27module.exports = async ({cwd, env, options: {tagFormat}, logger}) => {
28 // Generate a regex to parse tags formatted with `tagFormat`
29 // by replacing the `version` variable in the template by `(.+)`.
30 // The `tagFormat` is compiled with space as the `version` as it's an invalid tag character,
31 // so it's guaranteed to not be present in the `tagFormat`.
32 const tagRegexp = `^${escapeRegExp(template(tagFormat)({version: ' '})).replace(' ', '(.+)')}`;
33 const tags = (await getTags({cwd, env}))
34 .map(tag => ({gitTag: tag, version: (tag.match(tagRegexp) || new Array(2))[1]}))
35 .filter(
36 tag => tag.version && semver.valid(semver.clean(tag.version)) && !semver.prerelease(semver.clean(tag.version))
37 )
38 .sort((a, b) => semver.rcompare(a.version, b.version));
39
40 debug('found tags: %o', tags);
41
42 const tag = await pLocate(tags, tag => isRefInHistory(tag.gitTag, {cwd, env}), {preserveOrder: true});
43
44 if (tag) {
45 logger.log(`Found git tag ${tag.gitTag} associated with version ${tag.version}`);
46 return {gitHead: await getTagHead(tag.gitTag, {cwd, env}), ...tag};
47 }
48
49 logger.log('No git tag version found');
50 return {};
51};