diff --git a/__snapshots__/cli.js b/__snapshots__/cli.js index 1a86435c9..435756ee0 100644 --- a/__snapshots__/cli.js +++ b/__snapshots__/cli.js @@ -188,6 +188,7 @@ Options: the minor for non-breaking changes prior to the first major release [boolean] [default: false] + --prerelease-type type of the prerelease, e.g., alpha [string] --extra-files extra files for the strategy to consider [string] --version-file path to version file to update, e.g., diff --git a/docs/cli.md b/docs/cli.md index cfbb5d80b..4bd7763e8 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -51,6 +51,7 @@ Extra options: | `--versioning-strategy` | [`VersioningStrategyType`](/docs/customizing.md#versioning-strategies) | Override method of determining SemVer version bumps based on commits. Defaults to `default` | | `--bump-minor-pre-major` | `boolean` | Configuration option for the versioning strategy. If set, will bump the minor version for breaking changes for versions < 1.0.0 | | `--bump-patch-for-minor-pre-major` | `boolean` | Configuration option for the versioning strategy. If set, will bump the patch version for features for versions < 1.0.0 | +| `--prerelease-type` | `string` | Configuration option for the prerelese versioning strategy. If prerelease strategy used and type set, will set the prerelese part of the version to the provided value in case prerelease part is not present. | | `--draft` | `boolean` | If set, create releases as drafts | | `--prerelease` | `boolean` | If set, create releases that are pre-major or pre-release version marked as pre-release on Github| | `--draft-pull-request` | `boolean` | If set, create pull requests as drafts | @@ -101,6 +102,7 @@ need to specify your release options: | `--versioning-strategy` | VersioningStrategy | Override method of determining SemVer version bumps based on commits. Defaults to `default` | | `--bump-minor-pre-major` | boolean | Configuration option for the versioning strategy. If set, will bump the minor version for breaking changes for versions < 1.0.0 | | `--bump-patch-for-minor-pre-major` | boolean | Configuration option for the versioning strategy. If set, will bump the patch version for features for versions < 1.0.0 | +| `--prerelease-type` | `string` | Configuration option for the prerelese versioning strategy. If prerelease strategy used and type set, will set the prerelese part of the version to the provided value in case prerelease part is not present. | | `--draft-pull-request` | boolean | If set, create pull requests as drafts | | `--label` | string | Comma-separated list of labels to apply to the release pull requests. Defaults to `autorelease: pending` |`autorelease: tagged` | | `--changelog-path` | `string` | Override the path to the managed CHANGELOG. Defaults to `CHANGELOG.md` | diff --git a/docs/customizing.md b/docs/customizing.md index 125689878..56593a3da 100644 --- a/docs/customizing.md +++ b/docs/customizing.md @@ -45,6 +45,8 @@ version given a list of parsed commits. | `always-bump-major` | Always bump major version | | `service-pack` | Designed for Java backport fixes. Uses Maven's specification for service pack versions (e.g. 1.2.3-sp.1) | +| `prerelease` | Bumping prerelease number (eg. 1.2.0-beta01 to 1.2.0-beta02) or if prerelease type is set, using that in the prerelease part (eg. 1.2.1 to 1.3.0-beta) | + ### Adding additional versioning strategy types To add a new versioning strategy, create a new class that implements the diff --git a/docs/manifest-releaser.md b/docs/manifest-releaser.md index a8bf0d075..23f6f6e1e 100644 --- a/docs/manifest-releaser.md +++ b/docs/manifest-releaser.md @@ -172,6 +172,9 @@ defaults (those are documented in comments) // absence defaults to false "bump-patch-for-minor-pre-major": true, + // setting the type of prerelease in case of prerelease strategy + "prerelease-type": "beta", + // set default conventional commit => changelog sections mapping/appearance. // absence defaults to https://git.io/JqCZL "changelog-sections": [...], diff --git a/schemas/config.json b/schemas/config.json index b92c20e34..9b8816e7c 100644 --- a/schemas/config.json +++ b/schemas/config.json @@ -20,6 +20,10 @@ "description": "Feature changes only bump semver patch if version < 1.0.0", "type": "boolean" }, + "prerelease-type": { + "description": "Configuration option for the prerelese versioning strategy. If prerelease strategy used and type set, will set the prerelese part of the version to the provided value in case prerelease part is not present.", + "type": "string" + }, "versioning": { "description": "Versioning strategy. Defaults to `default`", "type": "string" @@ -290,7 +294,11 @@ "type": { "description": "The name of the plugin.", "type": "string", - "enum": ["cargo-workspace", "maven-workspace", "node-workspace"] + "enum": [ + "cargo-workspace", + "maven-workspace", + "node-workspace" + ] }, "updateAllPackages": { "description": "Whether to force updating all packages regardless of the dependency tree. Defaults to `false`.", diff --git a/src/bin/release-please.ts b/src/bin/release-please.ts index 93563d500..ea986e65b 100644 --- a/src/bin/release-please.ts +++ b/src/bin/release-please.ts @@ -63,6 +63,7 @@ interface ManifestArgs { interface VersioningArgs { bumpMinorPreMajor?: boolean; bumpPatchForMinorPreMajor?: boolean; + prereleaseType?: string; releaseAs?: string; // only for Ruby: TODO replace with generic bootstrap option @@ -275,6 +276,10 @@ function pullRequestStrategyOptions(yargs: yargs.Argv): yargs.Argv { default: false, type: 'boolean', }) + .option('prerelease-type', { + describe: 'type of the prerelease, e.g., alpha', + type: 'string', + }) .option('extra-files', { describe: 'extra files for the strategy to consider', type: 'string', @@ -447,6 +452,7 @@ const createReleasePullRequestCommand: yargs.CommandModule< draftPullRequest: argv.draftPullRequest, bumpMinorPreMajor: argv.bumpMinorPreMajor, bumpPatchForMinorPreMajor: argv.bumpPatchForMinorPreMajor, + prereleaseType: argv.prereleaseType, changelogPath: argv.changelogPath, changelogType: argv.changelogType, changelogHost: argv.changelogHost, @@ -711,6 +717,7 @@ const bootstrapCommand: yargs.CommandModule<{}, BootstrapArgs> = { draftPullRequest: argv.draftPullRequest, bumpMinorPreMajor: argv.bumpMinorPreMajor, bumpPatchForMinorPreMajor: argv.bumpPatchForMinorPreMajor, + prereleaseType: argv.prereleaseType, changelogPath: argv.changelogPath, changelogHost: argv.changelogHost, changelogSections: argv.changelogSections, diff --git a/src/factories/versioning-strategy-factory.ts b/src/factories/versioning-strategy-factory.ts index 0c81adea7..3a009b2ba 100644 --- a/src/factories/versioning-strategy-factory.ts +++ b/src/factories/versioning-strategy-factory.ts @@ -28,6 +28,7 @@ export interface VersioningStrategyFactoryOptions { type?: VersioningStrategyType; bumpMinorPreMajor?: boolean; bumpPatchForMinorPreMajor?: boolean; + prereleaseType?: string; github: GitHub; } diff --git a/src/factory.ts b/src/factory.ts index 0be36a2f7..1f215332a 100644 --- a/src/factory.ts +++ b/src/factory.ts @@ -119,6 +119,7 @@ export async function buildStrategy( type: options.versioning, bumpMinorPreMajor: options.bumpMinorPreMajor, bumpPatchForMinorPreMajor: options.bumpPatchForMinorPreMajor, + prereleaseType: options.prereleaseType, }); const changelogNotes = buildChangelogNotes({ type: options.changelogType || 'default', diff --git a/src/manifest.ts b/src/manifest.ts index 54c539525..31a205d38 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -94,6 +94,7 @@ export interface ReleaserConfig { versioning?: VersioningStrategyType; bumpMinorPreMajor?: boolean; bumpPatchForMinorPreMajor?: boolean; + prereleaseType?: string; // Strategy options releaseAs?: string; @@ -148,6 +149,7 @@ interface ReleaserConfigJson { versioning?: VersioningStrategyType; 'bump-minor-pre-major'?: boolean; 'bump-patch-for-minor-pre-major'?: boolean; + 'prerelease-type'?: string; 'changelog-sections'?: ChangelogSection[]; 'release-as'?: string; 'skip-github-release'?: boolean; @@ -1290,6 +1292,7 @@ function extractReleaserConfig( releaseType: config['release-type'], bumpMinorPreMajor: config['bump-minor-pre-major'], bumpPatchForMinorPreMajor: config['bump-patch-for-minor-pre-major'], + prereleaseType: config['prerelease-type'], versioning: config['versioning'], changelogSections: config['changelog-sections'], changelogPath: config['changelog-path'], @@ -1635,6 +1638,7 @@ function mergeReleaserConfig( bumpPatchForMinorPreMajor: pathConfig.bumpPatchForMinorPreMajor ?? defaultConfig.bumpPatchForMinorPreMajor, + prereleaseType: pathConfig.prereleaseType ?? defaultConfig.prereleaseType, versioning: pathConfig.versioning ?? defaultConfig.versioning, changelogSections: pathConfig.changelogSections ?? defaultConfig.changelogSections, diff --git a/src/version.ts b/src/version.ts index b2c9658ae..e3bfcb145 100644 --- a/src/version.ts +++ b/src/version.ts @@ -82,6 +82,10 @@ export class Version { const buildPart = this.build ? `+${this.build}` : ''; return `${this.major}.${this.minor}.${this.patch}${preReleasePart}${buildPart}`; } + + get isPreMajor(): boolean { + return this.major < 1; + } } export type VersionsMap = Map; diff --git a/src/versioning-strategies/default.ts b/src/versioning-strategies/default.ts index 2db9c0303..6fdc0c97c 100644 --- a/src/versioning-strategies/default.ts +++ b/src/versioning-strategies/default.ts @@ -24,7 +24,7 @@ import {ConventionalCommit} from '../commit'; import {Version} from '../version'; import {logger as defaultLogger, Logger} from '../util/logger'; -interface DefaultVersioningStrategyOptions { +export interface DefaultVersioningStrategyOptions { bumpMinorPreMajor?: boolean; bumpPatchForMinorPreMajor?: boolean; logger?: Logger; @@ -89,13 +89,13 @@ export class DefaultVersioningStrategy implements VersioningStrategy { } if (breaking > 0) { - if (version.major < 1 && this.bumpMinorPreMajor) { + if (version.isPreMajor && this.bumpMinorPreMajor) { return new MinorVersionUpdate(); } else { return new MajorVersionUpdate(); } } else if (features > 0) { - if (version.major < 1 && this.bumpPatchForMinorPreMajor) { + if (version.isPreMajor && this.bumpPatchForMinorPreMajor) { return new PatchVersionUpdate(); } else { return new MinorVersionUpdate(); diff --git a/src/versioning-strategies/dependency-manifest.ts b/src/versioning-strategies/dependency-manifest.ts index 6e31b7842..fb5d606b0 100644 --- a/src/versioning-strategies/dependency-manifest.ts +++ b/src/versioning-strategies/dependency-manifest.ts @@ -57,13 +57,13 @@ export class DependencyManifest extends DefaultVersioningStrategy { let dependencyBump: VersionUpdater; if (breaking > 0) { - if (version.major < 1 && this.bumpMinorPreMajor) { + if (version.isPreMajor && this.bumpMinorPreMajor) { dependencyBump = new MinorVersionUpdate(); } else { dependencyBump = new MajorVersionUpdate(); } } else if (features > 0) { - if (version.major < 1 && this.bumpPatchForMinorPreMajor) { + if (version.isPreMajor && this.bumpPatchForMinorPreMajor) { dependencyBump = new PatchVersionUpdate(); } else { dependencyBump = new MinorVersionUpdate(); diff --git a/src/versioning-strategies/prerelease.ts b/src/versioning-strategies/prerelease.ts index 463f79dd6..1fcbadf96 100644 --- a/src/versioning-strategies/prerelease.ts +++ b/src/versioning-strategies/prerelease.ts @@ -12,14 +12,72 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {DefaultVersioningStrategy} from './default'; +import { + DefaultVersioningStrategyOptions, + DefaultVersioningStrategy, +} from './default'; import {Version} from '../version'; import {ConventionalCommit} from '..'; -import {VersionUpdater, CustomVersionUpdate} from '../versioning-strategy'; +import { + VersionUpdater, + CustomVersionUpdate, + MinorVersionUpdate, + MajorVersionUpdate, +} from '../versioning-strategy'; -const PRERELEASE_PATTERN = /^(?[a-z]+)(?\d+)$/; +interface PrereleaseVersioningStrategyOptions + extends DefaultVersioningStrategyOptions { + prereleaseType?: string; +} + +/** + * Regex to match the last set of numbers in a string + * Example: 1.2.3-beta01-01 -> 01 + */ +const PRERELEASE_NUMBER = /(?\d+)(?=\D*$)/; + +abstract class AbstractPrereleaseVersionUpdate implements VersionUpdater { + protected readonly prereleaseType?: string; + + constructor(prereleaseType?: string) { + this.prereleaseType = prereleaseType; + } + + /** + * Returns the new bumped prerelease version + * + * That is, if the current version is 1.2.3-beta01, the next prerelease version + * will be 1.2.3-beta02. If no number is found, the prerelease version will be + * 1.2.3-beta. If multiple numbers are found, the last set of numbers will be + * incremented, e.g. 1.2.3-beta01-01 -> 1.2.3-beta01-02. + * + * @param {prerelease} string The current version + * @returns {Version} The bumped version + */ + protected bumpPrerelease(prerelease: string): string { + const match = prerelease.match(PRERELEASE_NUMBER); + + let nextPrerelease = `${prerelease}.1`; + + if (match?.groups) { + const numberLength = match.groups.number.length; + const nextPrereleaseNumber = Number(match.groups.number) + 1; + const paddedNextPrereleaseNumber = `${nextPrereleaseNumber}`.padStart( + numberLength, + '0' + ); + nextPrerelease = prerelease.replace( + PRERELEASE_NUMBER, + paddedNextPrereleaseNumber + ); + } + return nextPrerelease; + } -class PrereleasePatchVersionUpdate implements VersionUpdater { + abstract bump(version: Version): Version; +} + +class PrereleasePatchVersionUpdate extends AbstractPrereleaseVersionUpdate { /** * Returns the new bumped version * @@ -28,35 +86,26 @@ class PrereleasePatchVersionUpdate implements VersionUpdater { */ bump(version: Version): Version { if (version.preRelease) { - const match = version.preRelease.match(PRERELEASE_PATTERN); - if (match?.groups) { - const numberLength = match.groups.number.length; - const nextPrereleaseNumber = Number(match.groups.number) + 1; - const paddedNextPrereleaseNumber = `${nextPrereleaseNumber}`.padStart( - numberLength, - '0' - ); - const nextPrerelease = `${match.groups.type}${paddedNextPrereleaseNumber}`; - return new Version( - version.major, - version.minor, - version.patch, - nextPrerelease, - version.build - ); - } + const nextPrerelease = this.bumpPrerelease(version.preRelease); + return new Version( + version.major, + version.minor, + version.patch, + nextPrerelease, + version.build + ); } return new Version( version.major, version.minor, version.patch + 1, - version.preRelease, + this.prereleaseType, version.build ); } } -class PrereleaseMinorVersionUpdate implements VersionUpdater { +class PrereleaseMinorVersionUpdate extends AbstractPrereleaseVersionUpdate { /** * Returns the new bumped version * @@ -65,46 +114,31 @@ class PrereleaseMinorVersionUpdate implements VersionUpdater { */ bump(version: Version): Version { if (version.preRelease) { - const match = version.preRelease.match(PRERELEASE_PATTERN); - if (match?.groups) { - const numberLength = match.groups.number.length; - const prereleaseNumber = Number(match.groups.number); - - let nextPrereleaseNumber = 1; - let nextMinorNumber = version.minor + 1; - let nextPatchNumber = 0; - if (version.patch === 0) { - // this is already the next minor candidate, then bump the pre-release number - nextPrereleaseNumber = prereleaseNumber + 1; - nextMinorNumber = version.minor; - nextPatchNumber = version.patch; - } - - const paddedNextPrereleaseNumber = `${nextPrereleaseNumber}`.padStart( - numberLength, - '0' - ); - const nextPrerelease = `${match.groups.type}${paddedNextPrereleaseNumber}`; + if (version.patch === 0) { + const nextPrerelease = this.bumpPrerelease(version.preRelease); + return new Version( version.major, - nextMinorNumber, - nextPatchNumber, + version.minor, + version.patch, nextPrerelease, version.build ); } + + return new MinorVersionUpdate().bump(version); } return new Version( version.major, version.minor + 1, 0, - version.preRelease, + this.prereleaseType, version.build ); } } -class PrereleaseMajorVersionUpdate implements VersionUpdater { +class PrereleaseMajorVersionUpdate extends AbstractPrereleaseVersionUpdate { /** * Returns the new bumped version * @@ -113,42 +147,23 @@ class PrereleaseMajorVersionUpdate implements VersionUpdater { */ bump(version: Version): Version { if (version.preRelease) { - const match = version.preRelease.match(PRERELEASE_PATTERN); - if (match?.groups) { - const numberLength = match.groups.number.length; - const prereleaseNumber = Number(match.groups.number); - - let nextPrereleaseNumber = 1; - let nextMajorNumber = version.major + 1; - let nextMinorNumber = 0; - let nextPatchNumber = 0; - if (version.patch === 0 && version.minor === 0) { - // this is already the next major candidate, then bump the pre-release number - nextPrereleaseNumber = prereleaseNumber + 1; - nextMajorNumber = version.major; - nextMinorNumber = version.minor; - nextPatchNumber = version.patch; - } - - const paddedNextPrereleaseNumber = `${nextPrereleaseNumber}`.padStart( - numberLength, - '0' - ); - const nextPrerelease = `${match.groups.type}${paddedNextPrereleaseNumber}`; + if (version.patch === 0 && version.minor === 0) { + const nextPrerelease = this.bumpPrerelease(version.preRelease); return new Version( - nextMajorNumber, - nextMinorNumber, - nextPatchNumber, + version.major, + version.minor, + version.patch, nextPrerelease, version.build ); } + return new MajorVersionUpdate().bump(version); } return new Version( version.major + 1, 0, 0, - version.preRelease, + this.prereleaseType, version.build ); } @@ -160,6 +175,13 @@ class PrereleaseMajorVersionUpdate implements VersionUpdater { * Example: 1.2.3-beta01 -> 1.2.3-beta02. */ export class PrereleaseVersioningStrategy extends DefaultVersioningStrategy { + readonly prereleaseType?: string; + + constructor(options: PrereleaseVersioningStrategyOptions = {}) { + super(options); + this.prereleaseType = options.prereleaseType; + } + determineReleaseType( version: Version, commits: ConventionalCommit[] @@ -186,18 +208,18 @@ export class PrereleaseVersioningStrategy extends DefaultVersioningStrategy { } if (breaking > 0) { - if (version.major < 1 && this.bumpMinorPreMajor) { - return new PrereleaseMinorVersionUpdate(); + if (version.isPreMajor && this.bumpMinorPreMajor) { + return new PrereleaseMinorVersionUpdate(this.prereleaseType); } else { - return new PrereleaseMajorVersionUpdate(); + return new PrereleaseMajorVersionUpdate(this.prereleaseType); } } else if (features > 0) { - if (version.major < 1 && this.bumpPatchForMinorPreMajor) { - return new PrereleasePatchVersionUpdate(); + if (version.isPreMajor && this.bumpPatchForMinorPreMajor) { + return new PrereleasePatchVersionUpdate(this.prereleaseType); } else { - return new PrereleaseMinorVersionUpdate(); + return new PrereleaseMinorVersionUpdate(this.prereleaseType); } } - return new PrereleasePatchVersionUpdate(); + return new PrereleasePatchVersionUpdate(this.prereleaseType); } } diff --git a/test/cli.ts b/test/cli.ts index 2b0635368..e1ba0cd1a 100644 --- a/test/cli.ts +++ b/test/cli.ts @@ -839,6 +839,32 @@ describe('CLI', () => { sinon.assert.calledOnce(createPullRequestsStub); }); + it('handles --prerelease-type', async () => { + await parser.parseAsync( + 'release-pr --repo-url=googleapis/release-please-cli --release-type=java-yoshi --prerelease-type=alpha' + ); + + sinon.assert.calledOnceWithExactly(gitHubCreateStub, { + owner: 'googleapis', + repo: 'release-please-cli', + token: undefined, + apiUrl: 'https://api.github.com', + graphqlUrl: 'https://api.github.com', + }); + sinon.assert.calledOnceWithExactly( + fromConfigStub, + fakeGitHub, + 'main', + sinon.match({ + releaseType: 'java-yoshi', + prereleaseType: 'alpha', + }), + sinon.match.any, + undefined + ); + sinon.assert.calledOnce(createPullRequestsStub); + }); + it('handles java --extra-files', async () => { await parser.parseAsync( 'release-pr --repo-url=googleapis/release-please-cli --release-type=java-yoshi --extra-files=foo/bar.java,asdf/qwer.java' diff --git a/test/factory.ts b/test/factory.ts index 2253518f0..1de07c1e4 100644 --- a/test/factory.ts +++ b/test/factory.ts @@ -32,6 +32,7 @@ import {DependencyManifest} from '../src/versioning-strategies/dependency-manife import {GitHubChangelogNotes} from '../src/changelog-notes/github'; import {DefaultChangelogNotes} from '../src/changelog-notes/default'; import {Java} from '../src/strategies/java'; +import {PrereleaseVersioningStrategy} from '../src/versioning-strategies/prerelease'; describe('factory', () => { let github: GitHub; @@ -74,6 +75,25 @@ describe('factory', () => { expect(versioningStrategy.bumpMinorPreMajor).to.be.true; expect(versioningStrategy.bumpPatchForMinorPreMajor).to.be.true; }); + it('should build with prerelease type', async () => { + const strategy = await buildStrategy({ + github, + releaseType: 'simple', + bumpMinorPreMajor: true, + bumpPatchForMinorPreMajor: true, + versioning: 'prerelease', + prereleaseType: 'alpha', + }); + expect(strategy).instanceof(Simple); + expect(strategy.versioningStrategy).instanceof( + PrereleaseVersioningStrategy + ); + const versioningStrategy = + strategy.versioningStrategy as PrereleaseVersioningStrategy; + expect(versioningStrategy.bumpMinorPreMajor).to.be.true; + expect(versioningStrategy.bumpPatchForMinorPreMajor).to.be.true; + expect(versioningStrategy.prereleaseType).to.eql('alpha'); + }); it('should throw for unknown type', async () => { try { await buildStrategy({ diff --git a/test/manifest.ts b/test/manifest.ts index d1ecc6ebb..cc07dedf9 100644 --- a/test/manifest.ts +++ b/test/manifest.ts @@ -5116,6 +5116,7 @@ describe('Manifest', () => { '[HOTFIX] - chore${scope}: release${component} ${version}', packageName: 'my-package-name', includeComponentInTag: false, + prerelease: undefined, }, }, { diff --git a/test/version.ts b/test/version.ts index 2daaa965c..789de116e 100644 --- a/test/version.ts +++ b/test/version.ts @@ -150,4 +150,12 @@ describe('Version', () => { ]); }); }); + describe('isPreMajor', () => { + it('should return true for versions < 1.0.0', () => { + expect(Version.parse('0.1.0').isPreMajor).to.be.true; + }); + it('should return false for versions >= 1.0.0', () => { + expect(Version.parse('1.0.0').isPreMajor).to.be.false; + }); + }); }); diff --git a/test/versioning-strategies/prerelease.ts b/test/versioning-strategies/prerelease.ts index 45b38b241..41b1a6f30 100644 --- a/test/versioning-strategies/prerelease.ts +++ b/test/versioning-strategies/prerelease.ts @@ -55,31 +55,76 @@ describe('PrereleaseVersioningStrategy', () => { breaking: false, }, ]; - const expectedBumps: Record = { - '1.2.3': '2.0.0', - '0.1.2': '1.0.0', - '1.0.0-beta01': '1.0.0-beta02', - '2.0.0-beta01': '2.0.0-beta02', - '1.0.1-beta01': '2.0.0-beta01', - '1.1.0-beta01': '2.0.0-beta01', - '1.1.1-beta01': '2.0.0-beta01', - }; - for (const old in expectedBumps) { - const expected = expectedBumps[old]; - it(`can bump ${old} to ${expected}`, async () => { - const strategy = new PrereleaseVersioningStrategy(); - const oldVersion = Version.parse(old); + describe('without prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '2.0.0', + '0.1.2': '1.0.0', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '2.0.0-beta01', + '1.1.0-beta01': '2.0.0-beta01', + '1.1.1-beta01': '2.0.0-beta01', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy(); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + it('can bump a minor pre major for breaking change', async () => { + const strategy = new PrereleaseVersioningStrategy({ + bumpMinorPreMajor: true, + }); + const oldVersion = Version.parse('0.1.2'); const newVersion = await strategy.bump(oldVersion, commits); - expect(newVersion.toString()).to.equal(expected); + expect(newVersion.toString()).to.equal('0.2.0'); }); - } - it('can bump a minor pre major for breaking change', async () => { - const strategy = new PrereleaseVersioningStrategy({ - bumpMinorPreMajor: true, + }); + + describe('with prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '2.0.0-beta', + '0.1.2': '1.0.0-beta', + '1.0.0-alpha': '1.0.0-alpha.1', + '1.0.0-beta': '1.0.0-beta.1', + '2.0.0-beta': '2.0.0-beta.1', + '1.0.1-beta': '2.0.0-beta', + '1.1.0-beta': '2.0.0-beta', + '1.1.1-beta': '2.0.0-beta', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '2.0.0-beta01', + '1.1.0-beta01': '2.0.0-beta01', + '1.1.1-beta01': '2.0.0-beta01', + '1.0.0-beta2023.1': '1.0.0-beta2023.2', + '2.0.0-beta2023.1': '2.0.0-beta2023.2', + '1.0.1-beta2023.1': '2.0.0-beta2023.1', + '1.1.0-beta2023.1': '2.0.0-beta2023.1', + '1.1.1-beta2023.1': '2.0.0-beta2023.1', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy({ + prereleaseType: 'beta', + }); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + it('can bump a minor pre major for breaking change', async () => { + const strategy = new PrereleaseVersioningStrategy({ + bumpMinorPreMajor: true, + prereleaseType: 'beta', + }); + const oldVersion = Version.parse('0.1.2'); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal('0.2.0-beta'); }); - const oldVersion = Version.parse('0.1.2'); - const newVersion = await strategy.bump(oldVersion, commits); - expect(newVersion.toString()).to.equal('0.2.0'); }); }); @@ -119,31 +164,76 @@ describe('PrereleaseVersioningStrategy', () => { breaking: false, }, ]; - const expectedBumps: Record = { - '1.2.3': '1.3.0', - '0.1.2': '0.2.0', - '1.0.0-beta01': '1.0.0-beta02', - '2.0.0-beta01': '2.0.0-beta02', - '1.0.1-beta01': '1.1.0-beta01', - '1.1.0-beta01': '1.1.0-beta02', - '1.1.1-beta01': '1.2.0-beta01', - }; - for (const old in expectedBumps) { - const expected = expectedBumps[old]; - it(`can bump ${old} to ${expected}`, async () => { - const strategy = new PrereleaseVersioningStrategy(); - const oldVersion = Version.parse(old); + describe('without prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '1.3.0', + '0.1.2': '0.2.0', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '1.1.0-beta01', + '1.1.0-beta01': '1.1.0-beta02', + '1.1.1-beta01': '1.2.0-beta01', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy(); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + it('can bump a patch pre-major', async () => { + const strategy = new PrereleaseVersioningStrategy({ + bumpPatchForMinorPreMajor: true, + }); + const oldVersion = Version.parse('0.1.2'); const newVersion = await strategy.bump(oldVersion, commits); - expect(newVersion.toString()).to.equal(expected); + expect(newVersion.toString()).to.equal('0.1.3'); }); - } - it('can bump a patch pre-major', async () => { - const strategy = new PrereleaseVersioningStrategy({ - bumpPatchForMinorPreMajor: true, + }); + describe('with prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '1.3.0-beta', + '0.1.2': '0.2.0-beta', + '1.0.0-alpha': '1.0.0-alpha.1', + '1.0.0-beta': '1.0.0-beta.1', + '2.0.0-beta': '2.0.0-beta.1', + '1.0.1-beta': '1.1.0-beta', + '1.1.0-alpha': '1.1.0-alpha.1', + '1.1.0-beta': '1.1.0-beta.1', + '1.1.1-beta': '1.2.0-beta', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '1.1.0-beta01', + '1.1.0-beta01': '1.1.0-beta02', + '1.1.1-beta01': '1.2.0-beta01', + '1.0.0-beta2023.1': '1.0.0-beta2023.2', + '2.0.0-beta2023.1': '2.0.0-beta2023.2', + '1.0.1-beta2023.1': '1.1.0-beta2023.1', + '1.1.0-beta2023.1': '1.1.0-beta2023.2', + '1.1.1-beta2023.1': '1.2.0-beta2023.1', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy({ + prereleaseType: 'beta', + }); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + it('can bump a patch pre-major', async () => { + const strategy = new PrereleaseVersioningStrategy({ + bumpPatchForMinorPreMajor: true, + prereleaseType: 'beta', + }); + const oldVersion = Version.parse('0.1.2'); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal('0.1.3-beta'); }); - const oldVersion = Version.parse('0.1.2'); - const newVersion = await strategy.bump(oldVersion, commits); - expect(newVersion.toString()).to.equal('0.1.3'); }); }); @@ -172,26 +262,59 @@ describe('PrereleaseVersioningStrategy', () => { breaking: false, }, ]; - const expectedBumps: Record = { - '1.2.3': '1.2.4', - '1.0.0-beta01': '1.0.0-beta02', - '2.0.0-beta01': '2.0.0-beta02', - '1.0.1-beta01': '1.0.1-beta02', - '1.1.0-beta01': '1.1.0-beta02', - '1.1.1-beta01': '1.1.1-beta02', - '1.0.0-beta1': '1.0.0-beta2', - '1.0.0-beta9': '1.0.0-beta10', // (although that would be unfortunate) - '1.0.0-beta09': '1.0.0-beta10', - }; - for (const old in expectedBumps) { - const expected = expectedBumps[old]; - it(`can bump ${old} to ${expected}`, async () => { - const strategy = new PrereleaseVersioningStrategy(); - const oldVersion = Version.parse(old); - const newVersion = await strategy.bump(oldVersion, commits); - expect(newVersion.toString()).to.equal(expected); - }); - } + describe('without prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '1.2.4', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '1.0.1-beta02', + '1.1.0-beta01': '1.1.0-beta02', + '1.1.1-beta01': '1.1.1-beta02', + '1.0.0-beta1': '1.0.0-beta2', + '1.0.0-beta9': '1.0.0-beta10', // (although that would be unfortunate) + '1.0.0-beta09': '1.0.0-beta10', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy(); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + }); + describe('with prerelease type', () => { + const expectedBumps: Record = { + '1.2.3': '1.2.4-beta', + '1.2.4-alpha': '1.2.4-alpha.1', + '1.2.4-beta': '1.2.4-beta.1', + '1.0.0-beta01': '1.0.0-beta02', + '2.0.0-beta01': '2.0.0-beta02', + '1.0.1-beta01': '1.0.1-beta02', + '1.1.0-beta01': '1.1.0-beta02', + '1.1.1-beta01': '1.1.1-beta02', + '1.0.0-beta1': '1.0.0-beta2', + '1.0.0-beta9': '1.0.0-beta10', // (although that would be unfortunate) + '1.0.0-beta09': '1.0.0-beta10', + '1.0.0-beta2023.1': '1.0.0-beta2023.2', + '2.0.0-beta2023.1': '2.0.0-beta2023.2', + '1.0.1-beta2023.1': '1.0.1-beta2023.2', + '1.1.0-beta2023.1': '1.1.0-beta2023.2', + '1.1.1-beta2023.1': '1.1.1-beta2023.2', + }; + for (const old in expectedBumps) { + const expected = expectedBumps[old]; + it(`can bump ${old} to ${expected}`, async () => { + const strategy = new PrereleaseVersioningStrategy({ + prereleaseType: 'beta', + }); + const oldVersion = Version.parse(old); + const newVersion = await strategy.bump(oldVersion, commits); + expect(newVersion.toString()).to.equal(expected); + }); + } + }); }); describe('with release-as', () => {