From 2e10c97723a47b5efc5b18ce4933cbddca90a70f Mon Sep 17 00:00:00 2001 From: Emilien Escalle Date: Sun, 22 Jan 2023 14:27:43 +0100 Subject: [PATCH] feat: add pre-release increment behavior --- README.md | 8 + dist/index.js | 106 +++++++++-- index.js | 3 + lib/default-config.js | 3 +- lib/releases.js | 61 +++++-- lib/schema.js | 3 + lib/versions.js | 36 +++- schema.json | 14 +- .../config-with-prerelease-identifier.yml | 4 + test/index.test.js | 16 +- test/releases.test.js | 78 +++++++- test/versions.test.js | 168 ++++++++++++------ 12 files changed, 412 insertions(+), 88 deletions(-) create mode 100644 test/fixtures/config/config-with-prerelease-identifier.yml diff --git a/README.md b/README.md index 24ae540381..2dcac5cd6b 100644 --- a/README.md +++ b/README.md @@ -337,6 +337,14 @@ autolabeler: - '/JIRA-[0-9]{1,4}/' ``` +## Pre-release increment + +When creating Pre-release (`prerelease: true`), you can add a pre-release identifier to increment the pre-release version number, with the `prerelease-identifer` option. It accept any string, but it's recommended to use [Semantic Versioning](https://semver.org/) pre-release identifiers (alpha, beta, rc, etc). + +```yml +prerelease-identifer: 'alpha' # will create a pre-release with version number x.x.x-alpha.x +``` + ## Projects that don't use Semantic Versioning If your project doesn't follow [Semantic Versioning](https://semver.org) you can still use Release Drafter, but you may want to set the `version-template` option to customize how the `$NEXT_{PATCH,MINOR,MAJOR}_VERSION` environment variables are generated. diff --git a/dist/index.js b/dist/index.js index b851d5f52c..464b3d40a9 100644 --- a/dist/index.js +++ b/dist/index.js @@ -142377,11 +142377,14 @@ module.exports = (app, { getRouter }) => { config['footer'] = footer } + const findPrerelease = isPreRelease && config['prerelease-identifier'] + const { draftRelease, lastRelease } = await findReleases({ context, targetCommitish, filterByCommitish, tagPrefix, + findPrerelease, }) const { commits, pullRequests: mergedPullRequests } = @@ -142773,7 +142776,7 @@ const DEFAULT_CONFIG = Object.freeze({ 'change-template': `* $TITLE (#$NUMBER) @$AUTHOR`, 'change-title-escapes': '', 'no-changes-template': `* No changes`, - 'version-template': `$MAJOR.$MINOR.$PATCH`, + 'version-template': `$MAJOR.$MINOR.$PATCH$PRERELEASE`, 'version-resolver': { major: { labels: [] }, minor: { labels: [] }, @@ -142791,6 +142794,7 @@ const DEFAULT_CONFIG = Object.freeze({ 'sort-by': SORT_BY.mergedAt, 'sort-direction': SORT_DIRECTIONS.descending, prerelease: false, + 'prerelease-identifier': '', 'filter-by-commitish': false, commitish: '', 'category-template': `## $TITLE`, @@ -142885,6 +142889,7 @@ exports.paginate = paginate const compareVersions = __nccwpck_require__(89296) const regexEscape = __nccwpck_require__(98691) +const core = __nccwpck_require__(42186) const { getVersionInfo } = __nccwpck_require__(49914) const { template } = __nccwpck_require__(47282) @@ -142910,6 +142915,7 @@ const findReleases = async ({ targetCommitish, filterByCommitish, tagPrefix, + findPrerelease, }) => { let releaseCount = 0 let releases = await context.octokit.paginate( @@ -142941,12 +142947,14 @@ const findReleases = async ({ const filteredReleases = tagPrefix ? commitishFilteredReleases.filter((r) => r.tag_name.startsWith(tagPrefix)) : commitishFilteredReleases - const sortedPublishedReleases = sortReleases( - filteredReleases.filter((r) => !r.draft && !r.prerelease) - ) - const draftRelease = filteredReleases.find((r) => r.draft) - const lastRelease = - sortedPublishedReleases[sortedPublishedReleases.length - 1] + + const sortedReleases = sortReleases(filteredReleases) + + const draftRelease = sortedReleases.filter((r) => r.draft).at(-1) + + const lastRelease = sortedReleases + .filter((r) => !r.draft && (findPrerelease || !r.prerelease)) + .at(-1) if (draftRelease) { log({ context, message: `Draft release: ${draftRelease.tag_name}` }) @@ -142955,7 +142963,12 @@ const findReleases = async ({ } if (lastRelease) { - log({ context, message: `Last release: ${lastRelease.tag_name}` }) + log({ + context, + message: `Last release: ${lastRelease.tag_name}${ + findPrerelease ? ' (including prerelease)' : '' + }`, + }) } else { log({ context, message: `No last release found` }) } @@ -143166,12 +143179,17 @@ const generateChangeLog = (mergedPullRequests, config) => { return changeLog.join('').trim() } -const resolveVersionKeyIncrement = (mergedPullRequests, config) => { +const resolveVersionKeyIncrement = ( + mergedPullRequests, + config, + isPreRelease +) => { const priorityMap = { patch: 1, minor: 2, major: 3, } + const labelToKeyMap = Object.fromEntries( Object.keys(priorityMap) .flatMap((key) => [ @@ -143189,7 +143207,17 @@ const resolveVersionKeyIncrement = (mergedPullRequests, config) => { const versionKey = Object.keys(priorityMap).find( (key) => priorityMap[key] === priority ) - return versionKey || config['version-resolver'].default + + const versionKeyIncrement = versionKey || config['version-resolver'].default + + const shouldIncrementAsPrerelease = + isPreRelease && config['prerelease-identifier'] + + if (!shouldIncrementAsPrerelease) { + return versionKeyIncrement + } + + return `pre${versionKeyIncrement}` } const generateReleaseInfo = ({ @@ -143225,16 +143253,27 @@ const generateReleaseInfo = ({ config.replacers ) + const versionKeyIncrement = resolveVersionKeyIncrement( + mergedPullRequests, + config, + isPreRelease + ) + + core.debug('versionKeyIncrement: ' + versionKeyIncrement) + const versionInfo = getVersionInfo( lastRelease, config['version-template'], // Use the first override parameter to identify // a version, from the most accurate to the least version || tag || name, - resolveVersionKeyIncrement(mergedPullRequests, config), - config['tag-prefix'] + versionKeyIncrement, + config['tag-prefix'], + config['prerelease-identifier'] ) + core.debug('versionInfo: ' + JSON.stringify(versionInfo, null, 2)) + if (versionInfo) { body = template(body, versionInfo) } @@ -143245,6 +143284,8 @@ const generateReleaseInfo = ({ tag = template(tag, versionInfo) } + core.debug('tag: ' + tag) + if (name === undefined) { name = versionInfo ? template(config['name-template'] || '', versionInfo) @@ -143253,6 +143294,8 @@ const generateReleaseInfo = ({ name = template(name, versionInfo) } + core.debug('name: ' + name) + // Tags are not supported as `target_commitish` by Github API. // GITHUB_REF or the ref from webhook start with `refs/tags/`, so we handle // those here. If it doesn't but is still a tag - it must have been set @@ -143416,6 +143459,9 @@ const schema = (context) => { .default(DEFAULT_CONFIG['sort-direction']), prerelease: Joi.boolean().default(DEFAULT_CONFIG.prerelease), + 'prerelease-identifier': Joi.string() + .allow('') + .default(DEFAULT_CONFIG['prerelease-identifier']), 'filter-by-commitish': Joi.boolean().default( DEFAULT_CONFIG['filter-by-commitish'] @@ -143756,15 +143802,18 @@ const splitSemVersion = (input, versionKey = 'version') => { } const version = input.inc - ? semver.inc(input[versionKey], input.inc, true) + ? semver.inc(input[versionKey], input.inc, true, input.prereleaseIdentifier) : input[versionKey].version + const prereleaseVersion = semver.prerelease(version)?.join('.') || '' + return { ...input, version, $MAJOR: semver.major(version), $MINOR: semver.minor(version), $PATCH: semver.patch(version), + $PRERELEASE: prereleaseVersion ? `-${prereleaseVersion}` : '', $COMPLETE: version, } } @@ -143779,6 +143828,7 @@ const defaultVersionInfo = { $MAJOR: 1, $MINOR: 0, $PATCH: 0, + $PRERELEASE: '', }, $NEXT_MINOR_VERSION: { version: '0.1.0', @@ -143789,6 +143839,7 @@ const defaultVersionInfo = { $MAJOR: 0, $MINOR: 1, $PATCH: 0, + $PRERELEASE: '', }, $NEXT_PATCH_VERSION: { version: '0.1.0', @@ -143799,6 +143850,19 @@ const defaultVersionInfo = { $MAJOR: 0, $MINOR: 1, $PATCH: 0, + $PRERELEASE: '', + }, + $NEXT_PRERELEASE_VERSION: { + version: '0.1.0-rc.0', + template: '$MAJOR.$MINOR.$PATCH$PRERELEASE', + inputVersion: null, + versionKeyIncrement: 'prerelease', + inc: 'prerelease', + prereleaseIdentifier: 'rc', + $MAJOR: 0, + $MINOR: 1, + $PATCH: 0, + $PRERELEASE: '-rc.0', }, $INPUT_VERSION: null, $RESOLVED_VERSION: { @@ -143810,6 +143874,7 @@ const defaultVersionInfo = { $MAJOR: 0, $MINOR: 1, $PATCH: 0, + $PRERELEASE: '', }, } @@ -143863,6 +143928,11 @@ const getTemplatableVersion = (input) => { inc: 'patch', template: '$PATCH', }), + $NEXT_PRERELEASE_VERSION: splitSemVersion({ + ...input, + inc: 'prerelease', + template: '$PRERELEASE', + }), $INPUT_VERSION: splitSemVersion(input, 'inputVersion'), $RESOLVED_VERSION: splitSemVersion({ ...input, @@ -143906,12 +143976,19 @@ const getVersionInfo = ( template, inputVersion, versionKeyIncrement, - tagPrefix + tagPrefix, + prereleaseIdentifier ) => { const version = coerceVersion(release, tagPrefix) inputVersion = coerceVersion(inputVersion, tagPrefix) if (!version && !inputVersion) { + if (versionKeyIncrement && versionKeyIncrement.startsWith('pre')) { + defaultVersionInfo['$RESOLVED_VERSION'] = { + ...defaultVersionInfo['$NEXT_PRERELEASE_VERSION'], + } + } + return defaultVersionInfo } @@ -143921,6 +143998,7 @@ const getVersionInfo = ( template, inputVersion, versionKeyIncrement, + prereleaseIdentifier, }), } } diff --git a/index.js b/index.js index 52c872c16d..9d928a48c3 100644 --- a/index.js +++ b/index.js @@ -174,11 +174,14 @@ module.exports = (app, { getRouter }) => { config['footer'] = footer } + const findPrerelease = isPreRelease && config['prerelease-identifier'] + const { draftRelease, lastRelease } = await findReleases({ context, targetCommitish, filterByCommitish, tagPrefix, + findPrerelease, }) const { commits, pullRequests: mergedPullRequests } = diff --git a/lib/default-config.js b/lib/default-config.js index 5affa94652..0d9f23530f 100644 --- a/lib/default-config.js +++ b/lib/default-config.js @@ -7,7 +7,7 @@ const DEFAULT_CONFIG = Object.freeze({ 'change-template': `* $TITLE (#$NUMBER) @$AUTHOR`, 'change-title-escapes': '', 'no-changes-template': `* No changes`, - 'version-template': `$MAJOR.$MINOR.$PATCH`, + 'version-template': `$MAJOR.$MINOR.$PATCH$PRERELEASE`, 'version-resolver': { major: { labels: [] }, minor: { labels: [] }, @@ -25,6 +25,7 @@ const DEFAULT_CONFIG = Object.freeze({ 'sort-by': SORT_BY.mergedAt, 'sort-direction': SORT_DIRECTIONS.descending, prerelease: false, + 'prerelease-identifier': '', 'filter-by-commitish': false, commitish: '', 'category-template': `## $TITLE`, diff --git a/lib/releases.js b/lib/releases.js index 2d30ff1a2b..9f0a501c48 100644 --- a/lib/releases.js +++ b/lib/releases.js @@ -1,5 +1,6 @@ const compareVersions = require('compare-versions') const regexEscape = require('escape-string-regexp') +const core = require('@actions/core') const { getVersionInfo } = require('./versions') const { template } = require('./template') @@ -25,6 +26,7 @@ const findReleases = async ({ targetCommitish, filterByCommitish, tagPrefix, + findPrerelease, }) => { let releaseCount = 0 let releases = await context.octokit.paginate( @@ -56,12 +58,14 @@ const findReleases = async ({ const filteredReleases = tagPrefix ? commitishFilteredReleases.filter((r) => r.tag_name.startsWith(tagPrefix)) : commitishFilteredReleases - const sortedPublishedReleases = sortReleases( - filteredReleases.filter((r) => !r.draft && !r.prerelease) - ) - const draftRelease = filteredReleases.find((r) => r.draft) - const lastRelease = - sortedPublishedReleases[sortedPublishedReleases.length - 1] + + const sortedReleases = sortReleases(filteredReleases) + + const draftRelease = sortedReleases.filter((r) => r.draft).at(-1) + + const lastRelease = sortedReleases + .filter((r) => !r.draft && (findPrerelease || !r.prerelease)) + .at(-1) if (draftRelease) { log({ context, message: `Draft release: ${draftRelease.tag_name}` }) @@ -70,7 +74,12 @@ const findReleases = async ({ } if (lastRelease) { - log({ context, message: `Last release: ${lastRelease.tag_name}` }) + log({ + context, + message: `Last release: ${lastRelease.tag_name}${ + findPrerelease ? ' (including prerelease)' : '' + }`, + }) } else { log({ context, message: `No last release found` }) } @@ -281,12 +290,17 @@ const generateChangeLog = (mergedPullRequests, config) => { return changeLog.join('').trim() } -const resolveVersionKeyIncrement = (mergedPullRequests, config) => { +const resolveVersionKeyIncrement = ( + mergedPullRequests, + config, + isPreRelease +) => { const priorityMap = { patch: 1, minor: 2, major: 3, } + const labelToKeyMap = Object.fromEntries( Object.keys(priorityMap) .flatMap((key) => [ @@ -304,7 +318,17 @@ const resolveVersionKeyIncrement = (mergedPullRequests, config) => { const versionKey = Object.keys(priorityMap).find( (key) => priorityMap[key] === priority ) - return versionKey || config['version-resolver'].default + + const versionKeyIncrement = versionKey || config['version-resolver'].default + + const shouldIncrementAsPrerelease = + isPreRelease && config['prerelease-identifier'] + + if (!shouldIncrementAsPrerelease) { + return versionKeyIncrement + } + + return `pre${versionKeyIncrement}` } const generateReleaseInfo = ({ @@ -340,16 +364,27 @@ const generateReleaseInfo = ({ config.replacers ) + const versionKeyIncrement = resolveVersionKeyIncrement( + mergedPullRequests, + config, + isPreRelease + ) + + core.debug('versionKeyIncrement: ' + versionKeyIncrement) + const versionInfo = getVersionInfo( lastRelease, config['version-template'], // Use the first override parameter to identify // a version, from the most accurate to the least version || tag || name, - resolveVersionKeyIncrement(mergedPullRequests, config), - config['tag-prefix'] + versionKeyIncrement, + config['tag-prefix'], + config['prerelease-identifier'] ) + core.debug('versionInfo: ' + JSON.stringify(versionInfo, null, 2)) + if (versionInfo) { body = template(body, versionInfo) } @@ -360,6 +395,8 @@ const generateReleaseInfo = ({ tag = template(tag, versionInfo) } + core.debug('tag: ' + tag) + if (name === undefined) { name = versionInfo ? template(config['name-template'] || '', versionInfo) @@ -368,6 +405,8 @@ const generateReleaseInfo = ({ name = template(name, versionInfo) } + core.debug('name: ' + name) + // Tags are not supported as `target_commitish` by Github API. // GITHUB_REF or the ref from webhook start with `refs/tags/`, so we handle // those here. If it doesn't but is still a tag - it must have been set diff --git a/lib/schema.js b/lib/schema.js index 60dd8209a7..d118711bd0 100644 --- a/lib/schema.js +++ b/lib/schema.js @@ -76,6 +76,9 @@ const schema = (context) => { .default(DEFAULT_CONFIG['sort-direction']), prerelease: Joi.boolean().default(DEFAULT_CONFIG.prerelease), + 'prerelease-identifier': Joi.string() + .allow('') + .default(DEFAULT_CONFIG['prerelease-identifier']), 'filter-by-commitish': Joi.boolean().default( DEFAULT_CONFIG['filter-by-commitish'] diff --git a/lib/versions.js b/lib/versions.js index 83c8dbd5ba..69b21977ad 100644 --- a/lib/versions.js +++ b/lib/versions.js @@ -6,15 +6,18 @@ const splitSemVersion = (input, versionKey = 'version') => { } const version = input.inc - ? semver.inc(input[versionKey], input.inc, true) + ? semver.inc(input[versionKey], input.inc, true, input.prereleaseIdentifier) : input[versionKey].version + const prereleaseVersion = semver.prerelease(version)?.join('.') || '' + return { ...input, version, $MAJOR: semver.major(version), $MINOR: semver.minor(version), $PATCH: semver.patch(version), + $PRERELEASE: prereleaseVersion ? `-${prereleaseVersion}` : '', $COMPLETE: version, } } @@ -29,6 +32,7 @@ const defaultVersionInfo = { $MAJOR: 1, $MINOR: 0, $PATCH: 0, + $PRERELEASE: '', }, $NEXT_MINOR_VERSION: { version: '0.1.0', @@ -39,6 +43,7 @@ const defaultVersionInfo = { $MAJOR: 0, $MINOR: 1, $PATCH: 0, + $PRERELEASE: '', }, $NEXT_PATCH_VERSION: { version: '0.1.0', @@ -49,6 +54,19 @@ const defaultVersionInfo = { $MAJOR: 0, $MINOR: 1, $PATCH: 0, + $PRERELEASE: '', + }, + $NEXT_PRERELEASE_VERSION: { + version: '0.1.0-rc.0', + template: '$MAJOR.$MINOR.$PATCH$PRERELEASE', + inputVersion: null, + versionKeyIncrement: 'prerelease', + inc: 'prerelease', + prereleaseIdentifier: 'rc', + $MAJOR: 0, + $MINOR: 1, + $PATCH: 0, + $PRERELEASE: '-rc.0', }, $INPUT_VERSION: null, $RESOLVED_VERSION: { @@ -60,6 +78,7 @@ const defaultVersionInfo = { $MAJOR: 0, $MINOR: 1, $PATCH: 0, + $PRERELEASE: '', }, } @@ -113,6 +132,11 @@ const getTemplatableVersion = (input) => { inc: 'patch', template: '$PATCH', }), + $NEXT_PRERELEASE_VERSION: splitSemVersion({ + ...input, + inc: 'prerelease', + template: '$PRERELEASE', + }), $INPUT_VERSION: splitSemVersion(input, 'inputVersion'), $RESOLVED_VERSION: splitSemVersion({ ...input, @@ -156,12 +180,19 @@ const getVersionInfo = ( template, inputVersion, versionKeyIncrement, - tagPrefix + tagPrefix, + prereleaseIdentifier ) => { const version = coerceVersion(release, tagPrefix) inputVersion = coerceVersion(inputVersion, tagPrefix) if (!version && !inputVersion) { + if (versionKeyIncrement && versionKeyIncrement.startsWith('pre')) { + defaultVersionInfo['$RESOLVED_VERSION'] = { + ...defaultVersionInfo['$NEXT_PRERELEASE_VERSION'], + } + } + return defaultVersionInfo } @@ -171,6 +202,7 @@ const getVersionInfo = ( template, inputVersion, versionKeyIncrement, + prereleaseIdentifier, }), } } diff --git a/schema.json b/schema.json index cf5b7c8ebb..90bab01313 100644 --- a/schema.json +++ b/schema.json @@ -32,7 +32,7 @@ "type": "string" }, "version-template": { - "default": "$MAJOR.$MINOR.$PATCH", + "default": "$MAJOR.$MINOR.$PATCH$PRERELEASE", "type": "string" }, "name-template": { @@ -117,6 +117,18 @@ "default": false, "type": "boolean" }, + "prerelease-identifier": { + "anyOf": [ + { + "type": "string", + "enum": [""] + }, + { + "default": "", + "type": "string" + } + ] + }, "filter-by-commitish": { "default": false, "type": "boolean" diff --git a/test/fixtures/config/config-with-prerelease-identifier.yml b/test/fixtures/config/config-with-prerelease-identifier.yml new file mode 100644 index 0000000000..0ac5971c55 --- /dev/null +++ b/test/fixtures/config/config-with-prerelease-identifier.yml @@ -0,0 +1,4 @@ +template: This is a Pre-release with identifier. +name-template: 'v$RESOLVED_VERSION' +tag-template: 'v$RESOLVED_VERSION' +prerelease-identifier: alpha diff --git a/test/index.test.js b/test/index.test.js index 812f878560..f26784be0b 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -4,7 +4,7 @@ const { getConfigMock } = require('./helpers/config-mock') const releaseDrafter = require('../index') const mockedEnv = require('mocked-env') const pino = require('pino') -const Stream = require('stream') +const Stream = require('node:stream') const pushPayload = require('./fixtures/push.json') const pushTagPayload = require('./fixtures/push-tag.json') const releasePayload = require('./fixtures/release.json') @@ -2610,6 +2610,20 @@ describe('release-drafter', () => { } ) }) + + it('resolves tag with incremented pre-release identifier', async () => { + return overridesTest( + { + prerelease: 'true', + configName: 'config-with-prerelease-identifier.yml', + }, + { + prerelease: true, + name: 'v2.0.1-alpha.0', + tag_name: 'v2.0.1-alpha.0', + } + ) + }) }) describe('with input prerelease: false', () => { diff --git a/test/releases.test.js b/test/releases.test.js index 8dd8316fce..3049ef5fbd 100644 --- a/test/releases.test.js +++ b/test/releases.test.js @@ -1,4 +1,4 @@ -const { generateChangeLog } = require('../lib/releases') +const { generateChangeLog, findReleases } = require('../lib/releases') const { DEFAULT_CONFIG } = require('../lib/default-config') const pullRequests = [ @@ -234,4 +234,80 @@ describe('releases', () => { `) }) }) + + describe('findReleases', () => { + const paginateMock = jest.fn() + const context = { + payload: { repository: { full_name: 'test' } }, + octokit: { + paginate: paginateMock, + repos: { listReleases: { endpoint: { merge: jest.fn() } } }, + }, + repo: jest.fn(), + log: { info: jest.fn(), warn: jest.fn() }, + } + + it('should return last release without draft and prerelease', async () => { + paginateMock.mockResolvedValueOnce([ + { tag_name: 'v1.0.0', draft: true, prerelease: false }, + { tag_name: 'v1.0.1', draft: false, prerelease: false }, + { tag_name: 'v1.0.2-rc.1', draft: false, prerelease: true }, + ]) + + const { lastRelease } = await findReleases({ + context, + targetCommitish: 'refs/heads/master', + tagPrefix: '', + findPrerelease: false, + }) + + expect(lastRelease).toEqual({ + tag_name: 'v1.0.1', + draft: false, + prerelease: false, + }) + }) + + it('should return last draft release', async () => { + paginateMock.mockResolvedValueOnce([ + { tag_name: 'v1.0.0', draft: true, prerelease: false }, + { tag_name: 'v1.0.1', draft: false, prerelease: false }, + { tag_name: 'v1.0.2-rc.1', draft: false, prerelease: true }, + ]) + + const { draftRelease } = await findReleases({ + context, + targetCommitish: 'refs/heads/master', + tagPrefix: '', + findPrerelease: false, + }) + + expect(draftRelease).toEqual({ + tag_name: 'v1.0.0', + draft: true, + prerelease: false, + }) + }) + + it('should return last prerelease as last release when findPrerelease is true', async () => { + paginateMock.mockResolvedValueOnce([ + { tag_name: 'v1.0.0', draft: true, prerelease: false }, + { tag_name: 'v1.0.1', draft: false, prerelease: false }, + { tag_name: 'v1.0.2-rc.1', draft: false, prerelease: true }, + ]) + + const { lastRelease } = await findReleases({ + context, + targetCommitish: 'refs/heads/master', + tagPrefix: '', + findPrerelease: true, + }) + + expect(lastRelease).toEqual({ + tag_name: 'v1.0.2-rc.1', + draft: false, + prerelease: true, + }) + }) + }) }) diff --git a/test/versions.test.js b/test/versions.test.js index d524989ac0..d77c6e82ba 100644 --- a/test/versions.test.js +++ b/test/versions.test.js @@ -16,6 +16,7 @@ describe('versions', () => { $MAJOR: '11.0.0', $MINOR: '10.1.0', $PATCH: '10.0.4', + $PRERELEASE: '10.0.4-0', $RESOLVED: '10.0.4', }, }, @@ -33,6 +34,7 @@ describe('versions', () => { $MINOR: '10.1.0', $PATCH: '10.0.4', $RESOLVED: '10.0.4', + $PRERELEASE: '10.0.4-0', }, }, ], @@ -48,6 +50,7 @@ describe('versions', () => { $MAJOR: '11.0.0', $MINOR: '10.1.0', $PATCH: '10.0.4', + $PRERELEASE: '10.0.4-0', $RESOLVED: '10.0.4', }, }, @@ -65,72 +68,123 @@ describe('versions', () => { $MAJOR: '11.0.0', $MINOR: '10.1.0', $PATCH: '10.0.3', + $PRERELEASE: '10.0.3-alpha.0', $RESOLVED: '10.0.3-alpha', $INPUT: '10.0.3-alpha', }, }, ], - ])(`%s`, (name, { release, template, inputVersion, expected }) => { - const versionInfo = getVersionInfo(release, template, inputVersion) + [ + 'handles incremental pre-releases', + { + release: { + tag_name: 'v10.0.3', + name: 'Some release', + }, + template: '$MAJOR.$MINOR.$PATCH', + prereleaseIdentifier: 'alpha', + expected: { + $MAJOR: '11.0.0', + $MINOR: '10.1.0', + $PATCH: '10.0.4', + $PRERELEASE: '10.0.4-alpha.0', + $RESOLVED: '10.0.4', + }, + }, + ], + [ + 'handles incremental pre-releases on existing pre-releases', + { + release: { + tag_name: 'v10.0.3-alpha.2', + name: 'Some release', + }, + template: '$MAJOR.$MINOR.$PATCH', + expected: { + $MAJOR: '11.0.0', + $MINOR: '10.1.0', + $PATCH: '10.0.3', + $PRERELEASE: '10.0.3-alpha.3', + $RESOLVED: '10.0.3', + }, + }, + ], + ])( + `%s`, + ( + name, + { release, template, inputVersion, prereleaseIdentifier, expected } + ) => { + const versionInfo = getVersionInfo( + release, + template, + inputVersion, + undefined, + undefined, + prereleaseIdentifier + ) - // Next major version checks - expect(versionInfo.$NEXT_MAJOR_VERSION.version).toEqual(expected.$MAJOR) - expect(versionInfo.$NEXT_MAJOR_VERSION.template).toEqual( - '$MAJOR.$MINOR.$PATCH' - ) - expect(versionInfo.$NEXT_MAJOR_VERSION_MAJOR.version).toEqual( - expected.$MAJOR - ) - expect(versionInfo.$NEXT_MAJOR_VERSION_MAJOR.template).toEqual('$MAJOR') - expect(versionInfo.$NEXT_MAJOR_VERSION_MINOR.version).toEqual( - expected.$MAJOR - ) - expect(versionInfo.$NEXT_MAJOR_VERSION_MINOR.template).toEqual('$MINOR') - expect(versionInfo.$NEXT_MAJOR_VERSION_PATCH.version).toEqual( - expected.$MAJOR - ) - expect(versionInfo.$NEXT_MAJOR_VERSION_PATCH.template).toEqual('$PATCH') + // Next major version checks + expect(versionInfo.$NEXT_MAJOR_VERSION.version).toEqual(expected.$MAJOR) + expect(versionInfo.$NEXT_MAJOR_VERSION.template).toEqual(template) + expect(versionInfo.$NEXT_MAJOR_VERSION_MAJOR.version).toEqual( + expected.$MAJOR + ) + expect(versionInfo.$NEXT_MAJOR_VERSION_MAJOR.template).toEqual('$MAJOR') + expect(versionInfo.$NEXT_MAJOR_VERSION_MINOR.version).toEqual( + expected.$MAJOR + ) + expect(versionInfo.$NEXT_MAJOR_VERSION_MINOR.template).toEqual('$MINOR') + expect(versionInfo.$NEXT_MAJOR_VERSION_PATCH.version).toEqual( + expected.$MAJOR + ) + expect(versionInfo.$NEXT_MAJOR_VERSION_PATCH.template).toEqual('$PATCH') - // Next minor version checks - expect(versionInfo.$NEXT_MINOR_VERSION.version).toEqual(expected.$MINOR) - expect(versionInfo.$NEXT_MINOR_VERSION.template).toEqual( - '$MAJOR.$MINOR.$PATCH' - ) - expect(versionInfo.$NEXT_MINOR_VERSION_MAJOR.version).toEqual( - expected.$MINOR - ) - expect(versionInfo.$NEXT_MINOR_VERSION_MAJOR.template).toEqual('$MAJOR') - expect(versionInfo.$NEXT_MINOR_VERSION_MINOR.version).toEqual( - expected.$MINOR - ) - expect(versionInfo.$NEXT_MINOR_VERSION_MINOR.template).toEqual('$MINOR') - expect(versionInfo.$NEXT_MINOR_VERSION_PATCH.version).toEqual( - expected.$MINOR - ) - expect(versionInfo.$NEXT_MINOR_VERSION_PATCH.template).toEqual('$PATCH') + // Next minor version checks + expect(versionInfo.$NEXT_MINOR_VERSION.version).toEqual(expected.$MINOR) + expect(versionInfo.$NEXT_MINOR_VERSION.template).toEqual(template) + expect(versionInfo.$NEXT_MINOR_VERSION_MAJOR.version).toEqual( + expected.$MINOR + ) + expect(versionInfo.$NEXT_MINOR_VERSION_MAJOR.template).toEqual('$MAJOR') + expect(versionInfo.$NEXT_MINOR_VERSION_MINOR.version).toEqual( + expected.$MINOR + ) + expect(versionInfo.$NEXT_MINOR_VERSION_MINOR.template).toEqual('$MINOR') + expect(versionInfo.$NEXT_MINOR_VERSION_PATCH.version).toEqual( + expected.$MINOR + ) + expect(versionInfo.$NEXT_MINOR_VERSION_PATCH.template).toEqual('$PATCH') - // Next patch version checks - expect(versionInfo.$NEXT_PATCH_VERSION.version).toEqual(expected.$PATCH) - expect(versionInfo.$NEXT_PATCH_VERSION.template).toEqual( - '$MAJOR.$MINOR.$PATCH' - ) - expect(versionInfo.$NEXT_PATCH_VERSION_MAJOR.version).toEqual( - expected.$PATCH - ) - expect(versionInfo.$NEXT_PATCH_VERSION_MAJOR.template).toEqual('$MAJOR') - expect(versionInfo.$NEXT_PATCH_VERSION_MINOR.version).toEqual( - expected.$PATCH - ) - expect(versionInfo.$NEXT_PATCH_VERSION_MINOR.template).toEqual('$MINOR') - expect(versionInfo.$NEXT_PATCH_VERSION_PATCH.version).toEqual( - expected.$PATCH - ) - expect(versionInfo.$NEXT_PATCH_VERSION_PATCH.template).toEqual('$PATCH') + // Next patch version checks + expect(versionInfo.$NEXT_PATCH_VERSION.version).toEqual(expected.$PATCH) + expect(versionInfo.$NEXT_PATCH_VERSION.template).toEqual(template) + expect(versionInfo.$NEXT_PATCH_VERSION_MAJOR.version).toEqual( + expected.$PATCH + ) + expect(versionInfo.$NEXT_PATCH_VERSION_MAJOR.template).toEqual('$MAJOR') + expect(versionInfo.$NEXT_PATCH_VERSION_MINOR.version).toEqual( + expected.$PATCH + ) + expect(versionInfo.$NEXT_PATCH_VERSION_MINOR.template).toEqual('$MINOR') + expect(versionInfo.$NEXT_PATCH_VERSION_PATCH.version).toEqual( + expected.$PATCH + ) + expect(versionInfo.$NEXT_PATCH_VERSION_PATCH.template).toEqual('$PATCH') - expect(versionInfo.$NEXT_PATCH_VERSION.version).toEqual(expected.$PATCH) - expect(versionInfo.$INPUT_VERSION?.version).toEqual(expected.$INPUT) - expect(versionInfo.$RESOLVED_VERSION.version).toEqual(expected.$RESOLVED) - }) + // Next pre-release version checks + expect(versionInfo.$NEXT_PRERELEASE_VERSION.version).toEqual( + expected.$PRERELEASE + ) + expect(versionInfo.$NEXT_PRERELEASE_VERSION.template).toEqual( + '$PRERELEASE' + ) + + // Input & Resolved version checks + expect(versionInfo.$INPUT_VERSION?.version).toEqual(expected.$INPUT) + expect(versionInfo.$RESOLVED_VERSION.version).toEqual(expected.$RESOLVED) + } + ) it('returns default version info if no version was found in tag or name', () => { const versionInfo = getVersionInfo({})