diff --git a/tools/monorepo-utils/src/code-freeze/commands/version-bump/index.ts b/tools/monorepo-utils/src/code-freeze/commands/version-bump/index.ts index 6d5365c7d20..8dc956e7073 100644 --- a/tools/monorepo-utils/src/code-freeze/commands/version-bump/index.ts +++ b/tools/monorepo-utils/src/code-freeze/commands/version-bump/index.ts @@ -16,7 +16,7 @@ import { createPullRequest } from '../../../core/github/repo'; import { getEnvVar } from '../../../core/environment'; import { getMajorMinor } from '../../../core/version'; import { bumpFiles } from './bump'; -import { validateArgs } from './lib/validate'; +import { validateArgs, getIsAccelRelease } from './lib/validate'; import { Options } from './types'; export const versionBumpCommand = new Command( 'version-bump' ) @@ -47,6 +47,16 @@ export const versionBumpCommand = new Command( 'version-bump' ) 'Commit directly to the base branch. Do not create a PR just push directly to base branch', false ) + .option( + '-f --force', + 'Force a version bump, even when the new version is less than the existing version', + false + ) + .option( + '-a --allow-accel', + 'Allow accelerated versioning. When this option is not present, versions must be semantically correct', + false + ) .action( async ( version, options: Options ) => { const { owner, name, base, dryRun, commitDirectToBase } = options; @@ -78,7 +88,10 @@ export const versionBumpCommand = new Command( 'version-bump' ) baseDir: tmpRepoPath, config: [ 'core.hooksPath=/dev/null' ], } ); - const majorMinor = getMajorMinor( version ); + + const majorMinor = getIsAccelRelease( version ) + ? version + : getMajorMinor( version ); const branch = `prep/${ base }-for-next-dev-cycle-${ majorMinor }`; try { diff --git a/tools/monorepo-utils/src/code-freeze/commands/version-bump/lib/validate.ts b/tools/monorepo-utils/src/code-freeze/commands/version-bump/lib/validate.ts index 39d8576acd2..a750b829d52 100644 --- a/tools/monorepo-utils/src/code-freeze/commands/version-bump/lib/validate.ts +++ b/tools/monorepo-utils/src/code-freeze/commands/version-bump/lib/validate.ts @@ -10,6 +10,18 @@ import { readFile } from 'fs/promises'; */ import { Logger } from '../../../../core/logger'; import { Options } from '../types'; + +/** + * Determine whether a version is an accel release. + * + * @param {string} version Version number + * @return {boolean} True if the version corresponds with an accel release, otherwise false + */ +export const getIsAccelRelease = ( version: string ): boolean => { + const isAccelRelease = version.match( /^(?:\d+\.){3}\d+?$/ ); + return isAccelRelease !== null; +}; + /** * Get a plugin's current version. * @@ -57,25 +69,39 @@ export const validateArgs = async ( version: string, options: Options ): Promise< void > => { - const { base } = options; + const { allowAccel, base, force } = options; const nextVersion = version; + const isAllowedAccelRelease = + allowAccel && getIsAccelRelease( nextVersion ); - if ( ! valid( nextVersion ) ) { - Logger.error( - 'Invalid version supplied, please pass in a semantically correct version.' - ); + if ( isAllowedAccelRelease ) { + if ( base === 'trunk' ) { + Logger.error( + `Version ${ nextVersion } is not a development version bump and cannot be applied to trunk, which only accepts development version bumps.` + ); + } + } else { + if ( ! valid( nextVersion ) ) { + Logger.error( + 'Invalid version supplied, please pass in a semantically correct version or use the correct option for accel releases.' + ); + } + + const prereleaseParameters = prerelease( nextVersion ); + const isDevVersionBump = + prereleaseParameters && prereleaseParameters[ 0 ] === 'dev'; + + if ( ! isDevVersionBump && base === 'trunk' ) { + Logger.error( + `Version ${ nextVersion } is not a development version bump and cannot be applied to trunk, which only accepts development version bumps.` + ); + } } - const prereleaseParameters = prerelease( nextVersion ); - const isDevVersionBump = - prereleaseParameters && prereleaseParameters[ 0 ] === 'dev'; - - if ( ! isDevVersionBump && base === 'trunk' ) { - Logger.error( - `Version ${ nextVersion } is not a development version bump and cannot be applied to trunk, which only accepts development version bumps.` - ); + if ( force ) { + // When the force option is set, we do not compare currentVersion. + return; } - const currentVersion = await getCurrentVersion( tmpRepoPath ); if ( ! currentVersion ) { diff --git a/tools/monorepo-utils/src/code-freeze/commands/version-bump/types.ts b/tools/monorepo-utils/src/code-freeze/commands/version-bump/types.ts index 4b8fdf15a9d..c6cc9fa413f 100644 --- a/tools/monorepo-utils/src/code-freeze/commands/version-bump/types.ts +++ b/tools/monorepo-utils/src/code-freeze/commands/version-bump/types.ts @@ -4,4 +4,6 @@ export type Options = { base?: string; dryRun?: boolean; commitDirectToBase?: boolean; + allowAccel?: boolean; + force?: boolean; };