diff --git a/dist/index.js b/dist/index.js index 3e93901..03b3b5b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -619,7 +619,7 @@ function setOutput(versionResult) { const { major, minor, patch, increment, versionType, formattedVersion, versionTag, changed, isTagged, authors, currentCommit, previousCommit, previousVersion, debugOutput } = versionResult; const repository = process.env.GITHUB_REPOSITORY; if (!changed) { - core.info("VAGOOO") + core.info("VAGOOO2") core.info('No changes detected for this commit'); } core.info(`Version is ${formattedVersion}`); diff --git a/lib/action.js b/lib/action.js index d027db6..c6221f8 100644 --- a/lib/action.js +++ b/lib/action.js @@ -1,4 +1,27 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -15,8 +38,10 @@ const VersionType_1 = require("./providers/VersionType"); const UserInfo_1 = require("./providers/UserInfo"); const VersionInformation_1 = require("./providers/VersionInformation"); const DebugManager_1 = require("./DebugManager"); +const core = __importStar(require("@actions/core")); function runAction(configurationProvider) { return __awaiter(this, void 0, void 0, function* () { + core.info("VAGO STARTING runAction"); const currentCommitResolver = configurationProvider.GetCurrentCommitResolver(); const lastReleaseResolver = configurationProvider.GetLastReleaseResolver(); const commitsProvider = configurationProvider.GetCommitsProvider(); @@ -26,13 +51,20 @@ function runAction(configurationProvider) { const userFormatter = configurationProvider.GetUserFormatter(); const debugManager = DebugManager_1.DebugManager.getInstance(); if (yield currentCommitResolver.IsEmptyRepoAsync()) { + core.info("VAGO REPO WAS EMPTY, returning default version information"); const versionInfo = new VersionInformation_1.VersionInformation(0, 0, 0, 0, VersionType_1.VersionType.None, [], false, false); return new VersionResult_1.VersionResult(versionInfo.major, versionInfo.minor, versionInfo.patch, versionInfo.increment, versionInfo.type, versionFormatter.Format(versionInfo), tagFormatter.Format(versionInfo), versionInfo.changed, versionInfo.isTagged, userFormatter.Format('author', []), '', '', tagFormatter.Parse(tagFormatter.Format(versionInfo)).join('.'), debugManager.getDebugOutput(true)); } + core.info("VAGO REPO IS NOT EMPTY, continuing with versioning"); const currentCommit = yield currentCommitResolver.ResolveAsync(); + core.info("VAGO CURRENT COMMIT: " + currentCommit); const lastRelease = yield lastReleaseResolver.ResolveAsync(currentCommit, tagFormatter); + core.info("VAGO LAST RELEASE: " + lastRelease.hash + " " + lastRelease.major + "." + lastRelease.minor + "." + lastRelease.patch); const commitSet = yield commitsProvider.GetCommitsAsync(lastRelease.hash, currentCommit); + core.info("VAGO commit set le:" + commitSet.commits.length); + core.info("VAGO commit set changed: " + commitSet.changed.toString()); const classification = yield versionClassifier.ClassifyAsync(lastRelease, commitSet); + core.info("VAGO classification: " + JSON.stringify(classification)); const { isTagged } = lastRelease; const { major, minor, patch, increment, type, changed } = classification; // At this point all necessary data has been pulled from the database, create diff --git a/lib/main.js b/lib/main.js index ecb4d1c..036a1ab 100644 --- a/lib/main.js +++ b/lib/main.js @@ -41,6 +41,7 @@ function setOutput(versionResult) { const { major, minor, patch, increment, versionType, formattedVersion, versionTag, changed, isTagged, authors, currentCommit, previousCommit, previousVersion, debugOutput } = versionResult; const repository = process.env.GITHUB_REPOSITORY; if (!changed) { + core.info("VAGOOO1"); core.info('No changes detected for this commit'); } core.info(`Version is ${formattedVersion}`); @@ -64,6 +65,7 @@ function setOutput(versionResult) { } function run() { return __awaiter(this, void 0, void 0, function* () { + core.info("VAGO Starting run action..."); function toBool(value) { if (!value || value.toLowerCase() === 'false') { return false; @@ -113,7 +115,9 @@ function run() { core.warning(`The 'short_tags' input option is no longer supported`); } const configurationProvider = new ConfigurationProvider_1.ConfigurationProvider(config); + core.info("VAGO start await runAction(configurationProvider)"); const result = yield (0, action_1.runAction)(configurationProvider); + core.info("VAGO before setOutput(result)"); setOutput(result); }); } diff --git a/lib/providers/DefaultVersionClassifier.js b/lib/providers/DefaultVersionClassifier.js index c0fad58..e94d8ae 100644 --- a/lib/providers/DefaultVersionClassifier.js +++ b/lib/providers/DefaultVersionClassifier.js @@ -1,4 +1,27 @@ "use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { @@ -12,6 +35,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.DefaultVersionClassifier = void 0; const VersionClassification_1 = require("./VersionClassification"); const VersionType_1 = require("./VersionType"); +const core = __importStar(require("@actions/core")); class DefaultVersionClassifier { constructor(config) { const searchBody = config.searchCommitBody; @@ -85,9 +109,13 @@ class DefaultVersionClassifier { } ClassifyAsync(lastRelease, commitSet) { return __awaiter(this, void 0, void 0, function* () { + core.info("VAGO DefaultVersionClassifier.ClassifyAsync called"); const { type, increment, changed } = this.resolveCommitType(commitSet); + core.info("VAGO DefaultVersionClassifier.ClassifyAsync: type: " + VersionType_1.VersionType[type] + ", increment: " + increment + ", changed: " + changed); const { major, minor, patch } = this.getNextVersion(lastRelease, type); + core.info("VAGOO DefaultVersionClassifier.ClassifyAsync: major: " + major + ", minor: " + minor + ", patch: " + patch); if (lastRelease.currentPatch !== null) { + core.info("VAGO DefaultVersionClassifier.ClassifyAsync: lastRelease.currentPatch is not null, using it to determine version classification"); // If the current commit is tagged, we must use that version. Here we check if the version we have resolved from the // previous commits is the same as the current version. If it is, we will use the increment value, otherwise we reset // to zero. For example: @@ -97,6 +125,10 @@ class DefaultVersionClassifier { // - commit 4 - v2.0.1+0 const versionsMatch = lastRelease.currentMajor === major && lastRelease.currentMinor === minor && lastRelease.currentPatch === patch; const currentIncrement = versionsMatch ? increment : 0; + core.info("VAGO DefaultVersionClassifier.ClassifyAsync: versionsMatch: " + versionsMatch + ", currentIncrement: " + currentIncrement); + core.info("VAGO DefaultVersionClassifier.ClassifyAsync: lastRelease.currentMajor: " + lastRelease.currentMajor); + core.info("VAGO DefaultVersionClassifier.ClassifyAsync: lastRelease.currentMinor: " + lastRelease.currentMinor); + core.info("VAGO DefaultVersionClassifier.ClassifyAsync: lastRelease.currentPatch: " + lastRelease.currentPatch); return new VersionClassification_1.VersionClassification(VersionType_1.VersionType.None, currentIncrement, false, lastRelease.currentMajor, lastRelease.currentMinor, lastRelease.currentPatch); } return new VersionClassification_1.VersionClassification(type, increment, changed, major, minor, patch); diff --git a/src/ActionConfig.ts b/src/ActionConfig.ts index aee4e8d..ad27f90 100644 --- a/src/ActionConfig.ts +++ b/src/ActionConfig.ts @@ -1,39 +1,39 @@ /** Represents the input configuration for the semantic-version action */ export class ActionConfig { - /** Set to specify a specific branch, default is the current HEAD */ - public branch: string = "HEAD"; - /** The prefix to use to identify tags */ - public tagPrefix: string = "v"; - /** (Deprecated) Use branches instead of tags */ - public useBranches: boolean = false; - /** If true, the branch will be used to select the maximum version. */ - public versionFromBranch: string | boolean = false; - /** A string which, if present in a git commit, indicates that a change represents a major (breaking) change. Wrap with '/' to match using a regular expression. */ - public majorPattern: string = "(MAJOR)"; - /** A string which indicates the flags used by the `majorPattern` regular expression. */ - public majorFlags: string = ""; - /** A string which, if present in a git commit, indicates that a change represents a minor (feature) change. Wrap with '/' to match using a regular expression. */ - public minorPattern: string = "(MINOR)"; - /** A string which indicates the flags used by the `minorPattern` regular expression. */ - public minorFlags: string = ""; - /** Pattern to use when formatting output version */ - public versionFormat: string = '${major}.${minor}.${patch}'; - /** Path to check for changes. If any changes are detected in the path the 'changed' output will true. Enter multiple paths separated by spaces. */ - public changePath: string = ''; - /** Use to create a named sub-version. This value will be appended to tags created for this version. */ - public namespace: string = ""; - /** If true, every commit will be treated as a bump to the version. */ - public bumpEachCommit: boolean = false; - /** If true, the body of commits will also be searched for major/minor patterns to determine the version type */ - public searchCommitBody: boolean = false; - /** The output method used to generate list of users, 'csv' or 'json'. Default is 'csv'. */ - public userFormatType: string = "csv"; - /** Prevents pre-v1.0.0 version from automatically incrementing the major version. If enabled, when the major version is 0, major releases will be treated as minor and minor as patch. Note that the versionType output is unchanged. */ - public enablePrereleaseMode: boolean = false; - /** If bump_each_commit is also set to true, setting this value will cause the version to increment only if the pattern specified is matched. */ - public bumpEachCommitPatchPattern: string = ""; - /** If enabled, diagnostic information will be added to the action output. */ - public debug: boolean = false; - /** Diagnostics to replay */ - public replay: string = ''; -} \ No newline at end of file + /** Set to specify a specific branch, default is the current HEAD */ + public branch: string = "HEAD"; + /** The prefix to use to identify tags */ + public tagPrefix: string = "v"; + /** (Deprecated) Use branches instead of tags */ + public useBranches: boolean = false; + /** If true, the branch will be used to select the maximum version. */ + public versionFromBranch: string | boolean = false; + /** A string which, if present in a git commit, indicates that a change represents a major (breaking) change. Wrap with '/' to match using a regular expression. */ + public majorPattern: string = "(MAJOR)"; + /** A string which indicates the flags used by the `majorPattern` regular expression. */ + public majorFlags: string = ""; + /** A string which, if present in a git commit, indicates that a change represents a minor (feature) change. Wrap with '/' to match using a regular expression. */ + public minorPattern: string = "(MINOR)"; + /** A string which indicates the flags used by the `minorPattern` regular expression. */ + public minorFlags: string = ""; + /** Pattern to use when formatting output version */ + public versionFormat: string = "${major}.${minor}.${patch}"; + /** Path to check for changes. If any changes are detected in the path the 'changed' output will true. Enter multiple paths separated by spaces. */ + public changePath: string = ""; + /** Use to create a named sub-version. This value will be appended to tags created for this version. */ + public namespace: string = ""; + /** If true, every commit will be treated as a bump to the version. */ + public bumpEachCommit: boolean = false; + /** If true, the body of commits will also be searched for major/minor patterns to determine the version type */ + public searchCommitBody: boolean = false; + /** The output method used to generate list of users, 'csv' or 'json'. Default is 'csv'. */ + public userFormatType: string = "csv"; + /** Prevents pre-v1.0.0 version from automatically incrementing the major version. If enabled, when the major version is 0, major releases will be treated as minor and minor as patch. Note that the versionType output is unchanged. */ + public enablePrereleaseMode: boolean = false; + /** If bump_each_commit is also set to true, setting this value will cause the version to increment only if the pattern specified is matched. */ + public bumpEachCommitPatchPattern: string = ""; + /** If enabled, diagnostic information will be added to the action output. */ + public debug: boolean = false; + /** Diagnostics to replay */ + public replay: string = ""; +} diff --git a/src/CommandRunner.ts b/src/CommandRunner.ts index 192396b..804cdec 100644 --- a/src/CommandRunner.ts +++ b/src/CommandRunner.ts @@ -1,34 +1,38 @@ // Using require instead of import to support integration testing -import * as exec from '@actions/exec'; -import { DebugManager } from './DebugManager'; +import * as exec from "@actions/exec"; +import { DebugManager } from "./DebugManager"; export const cmd = async (command: string, ...args: any): Promise => { + const debugManager = DebugManager.getInstance(); - const debugManager = DebugManager.getInstance(); + if (debugManager.isReplayMode()) { + return debugManager.replayCommand(command, args); + } - if (debugManager.isReplayMode()) { - return debugManager.replayCommand(command, args); - } + let output = "", + errors = ""; + const options = { + silent: true, + listeners: { + stdout: (data: any) => { + output += data.toString(); + }, + stderr: (data: any) => { + errors += data.toString(); + }, + ignoreReturnCode: true, + silent: true, + }, + }; - let output = '', errors = ''; - const options = { - silent: true, - listeners: { - stdout: (data: any) => { output += data.toString(); }, - stderr: (data: any) => { errors += data.toString(); }, - ignoreReturnCode: true, - silent: true - } - }; + let caughtError: any = null; + try { + await exec.exec(command, args, options); + } catch (err) { + caughtError = err; + } - let caughtError: any = null; - try { - await exec.exec(command, args, options); - } catch (err) { - caughtError = err; - } + debugManager.recordCommand(command, args, output, errors, caughtError); - debugManager.recordCommand(command, args, output, errors, caughtError); - - return output; -}; \ No newline at end of file + return output; +}; diff --git a/src/ConfigurationProvider.ts b/src/ConfigurationProvider.ts index e5912ec..53ba5bd 100644 --- a/src/ConfigurationProvider.ts +++ b/src/ConfigurationProvider.ts @@ -1,25 +1,24 @@ -import { CsvUserFormatter } from './formatting/CsvUserFormatter' -import { BranchVersioningTagFormatter } from './formatting/BranchVersioningTagFormatter' -import { DefaultTagFormatter } from './formatting/DefaultTagFormatter' -import { DefaultVersionFormatter } from './formatting/DefaultVersionFormatter' -import { JsonUserFormatter } from './formatting/JsonUserFormatter' -import { TagFormatter } from './formatting/TagFormatter' -import { UserFormatter } from './formatting/UserFormatter' -import { VersionFormatter } from './formatting/VersionFormatter' -import { CommitsProvider } from './providers/CommitsProvider' -import { CurrentCommitResolver } from './providers/CurrentCommitResolver' -import { DefaultCommitsProvider } from './providers/DefaultCommitsProvider' -import { DefaultCurrentCommitResolver } from './providers/DefaultCurrentCommitResolver' -import { DefaultVersionClassifier } from './providers/DefaultVersionClassifier' -import { LastReleaseResolver } from './providers/LastReleaseResolver' -import { DefaultLastReleaseResolver } from './providers/DefaultLastReleaseResolver' -import { VersionClassifier } from './providers/VersionClassifier' -import { BumpAlwaysVersionClassifier } from './providers/BumpAlwaysVersionClassifier' -import { ActionConfig } from './ActionConfig'; -import { DebugManager } from './DebugManager'; +import { CsvUserFormatter } from "./formatting/CsvUserFormatter"; +import { BranchVersioningTagFormatter } from "./formatting/BranchVersioningTagFormatter"; +import { DefaultTagFormatter } from "./formatting/DefaultTagFormatter"; +import { DefaultVersionFormatter } from "./formatting/DefaultVersionFormatter"; +import { JsonUserFormatter } from "./formatting/JsonUserFormatter"; +import { TagFormatter } from "./formatting/TagFormatter"; +import { UserFormatter } from "./formatting/UserFormatter"; +import { VersionFormatter } from "./formatting/VersionFormatter"; +import { CommitsProvider } from "./providers/CommitsProvider"; +import { CurrentCommitResolver } from "./providers/CurrentCommitResolver"; +import { DefaultCommitsProvider } from "./providers/DefaultCommitsProvider"; +import { DefaultCurrentCommitResolver } from "./providers/DefaultCurrentCommitResolver"; +import { DefaultVersionClassifier } from "./providers/DefaultVersionClassifier"; +import { LastReleaseResolver } from "./providers/LastReleaseResolver"; +import { DefaultLastReleaseResolver } from "./providers/DefaultLastReleaseResolver"; +import { VersionClassifier } from "./providers/VersionClassifier"; +import { BumpAlwaysVersionClassifier } from "./providers/BumpAlwaysVersionClassifier"; +import { ActionConfig } from "./ActionConfig"; +import { DebugManager } from "./DebugManager"; export class ConfigurationProvider { - constructor(config: ActionConfig) { this.config = config; DebugManager.getInstance().initializeConfig(config); @@ -27,11 +26,17 @@ export class ConfigurationProvider { private config: ActionConfig; - public GetCurrentCommitResolver(): CurrentCommitResolver { return new DefaultCurrentCommitResolver(this.config); } + public GetCurrentCommitResolver(): CurrentCommitResolver { + return new DefaultCurrentCommitResolver(this.config); + } - public GetLastReleaseResolver(): LastReleaseResolver { return new DefaultLastReleaseResolver(this.config); } + public GetLastReleaseResolver(): LastReleaseResolver { + return new DefaultLastReleaseResolver(this.config); + } - public GetCommitsProvider(): CommitsProvider { return new DefaultCommitsProvider(this.config); } + public GetCommitsProvider(): CommitsProvider { + return new DefaultCommitsProvider(this.config); + } public GetVersionClassifier(): VersionClassifier { if (this.config.bumpEachCommit) { @@ -40,7 +45,9 @@ export class ConfigurationProvider { return new DefaultVersionClassifier(this.config); } - public GetVersionFormatter(): VersionFormatter { return new DefaultVersionFormatter(this.config); } + public GetVersionFormatter(): VersionFormatter { + return new DefaultVersionFormatter(this.config); + } public GetTagFormatter(branchName: string): TagFormatter { if (this.config.versionFromBranch) { @@ -51,10 +58,14 @@ export class ConfigurationProvider { public GetUserFormatter(): UserFormatter { switch (this.config.userFormatType) { - case 'json': return new JsonUserFormatter(this.config); - case 'csv': return new CsvUserFormatter(this.config); + case "json": + return new JsonUserFormatter(this.config); + case "csv": + return new CsvUserFormatter(this.config); default: - throw new Error(`Unknown user format type: ${this.config.userFormatType}, supported types: json, csv`); + throw new Error( + `Unknown user format type: ${this.config.userFormatType}, supported types: json, csv`, + ); } } } diff --git a/src/DebugManager.ts b/src/DebugManager.ts index 0317498..3a689c9 100644 --- a/src/DebugManager.ts +++ b/src/DebugManager.ts @@ -1,115 +1,134 @@ import { ActionConfig } from "./ActionConfig"; - /** Utility class for managing debug mode and diagnostic information */ export class DebugManager { - private constructor() { } + private constructor() {} - private static instance: DebugManager; - /** Returns the singleton instance of the DebugManager */ - public static getInstance(): DebugManager { - if (!DebugManager.instance) { - DebugManager.instance = new DebugManager(); - } - return DebugManager.instance; + private static instance: DebugManager; + /** Returns the singleton instance of the DebugManager */ + public static getInstance(): DebugManager { + if (!DebugManager.instance) { + DebugManager.instance = new DebugManager(); + } + return DebugManager.instance; + } + + /** Clears the singleton instance of the DebugManager (used for testing) */ + public static clearState() { + DebugManager.instance = new DebugManager(); + } + + private debugEnabled: boolean = false; + private replayMode: boolean = false; + private diagnosticInfo: DiagnosticInfo | null = null; + + /** Returns true if debug mode is enabled */ + public isDebugEnabled(): boolean { + return this.debugEnabled; + } + + /** Returns true if replay mode is enabled */ + public isReplayMode(): boolean { + return this.replayMode; + } + + initializeConfig(config: ActionConfig) { + if (config.debug) { + this.setDebugEnabled(true); + } else if (config.replay.length > 0) { + this.replayFromDiagnostics(config.replay); + } + } + + /** Enables or disables debug mode, also clears any existing diagnostics info */ + public setDebugEnabled(enableDebug: boolean = true): void { + this.debugEnabled = enableDebug; + this.replayMode = false; + this.diagnosticInfo = new DiagnosticInfo(); + } + + /** Enables replay mode and loads the diagnostic information from the specified string */ + public replayFromDiagnostics(diagnostics: string): void { + this.debugEnabled = false; + this.replayMode = true; + this.diagnosticInfo = JSON.parse(diagnostics); + } + + /** Returns a JSON string containing the diagnostic information for this run */ + public getDebugOutput(emptyRepo: boolean = false): string { + return this.isDebugEnabled() ? JSON.stringify(this.diagnosticInfo) : ""; + } + + /** Records a command and its output for diagnostic purposes */ + public recordCommand( + command: string, + args: any[], + output: string, + stderr: string, + error: any, + ): void { + if (this.isDebugEnabled()) { + this.diagnosticInfo?.recordCommand(command, args, output, stderr, error); + } + } + + /** Replays the specified command and returns the output */ + public replayCommand(command: string, args: any[]): string { + if (this.diagnosticInfo === null) { + throw new Error("No diagnostic information available for replay"); } - /** Clears the singleton instance of the DebugManager (used for testing) */ - public static clearState() { - DebugManager.instance = new DebugManager(); + const commandResult = this.diagnosticInfo.commands.find( + (c) => + c.command === command && + JSON.stringify(c.args) === JSON.stringify(args), + ); + if (!commandResult) { + throw new Error(`No result found in diagnostic for command "${command}"`); } - - - private debugEnabled: boolean = false; - private replayMode: boolean = false; - private diagnosticInfo: DiagnosticInfo | null = null; - - /** Returns true if debug mode is enabled */ - public isDebugEnabled(): boolean { - return this.debugEnabled; + if (commandResult.error) { + throw commandResult.error; } - - /** Returns true if replay mode is enabled */ - public isReplayMode(): boolean { - return this.replayMode; - } - - initializeConfig(config: ActionConfig) { - if (config.debug) { - this.setDebugEnabled(true); - } else if (config.replay.length > 0) { - this.replayFromDiagnostics(config.replay); - } - } - - - /** Enables or disables debug mode, also clears any existing diagnostics info */ - public setDebugEnabled(enableDebug: boolean = true): void { - this.debugEnabled = enableDebug; - this.replayMode = false; - this.diagnosticInfo = new DiagnosticInfo(); - }; - - /** Enables replay mode and loads the diagnostic information from the specified string */ - public replayFromDiagnostics(diagnostics: string): void { - this.debugEnabled = false - this.replayMode = true; - this.diagnosticInfo = JSON.parse(diagnostics); - } - - /** Returns a JSON string containing the diagnostic information for this run */ - public getDebugOutput(emptyRepo: boolean = false): string { - return this.isDebugEnabled() ? JSON.stringify(this.diagnosticInfo) : ''; - } - - /** Records a command and its output for diagnostic purposes */ - public recordCommand(command: string, args: any[], output: string, stderr: string, error: any): void { - if (this.isDebugEnabled()) { - this.diagnosticInfo?.recordCommand(command, args, output, stderr, error); - } - } - - /** Replays the specified command and returns the output */ - public replayCommand(command: string, args: any[]): string { - if (this.diagnosticInfo === null) { - throw new Error('No diagnostic information available for replay'); - } - - const commandResult = this.diagnosticInfo.commands.find(c => c.command === command && JSON.stringify(c.args) === JSON.stringify(args)); - if (!commandResult) { - throw new Error(`No result found in diagnostic for command "${command}"`); - } - if (commandResult.error) { - throw commandResult.error; - } - if (commandResult.stderr) { - console.error(commandResult.stderr); - } - return commandResult.output; + if (commandResult.stderr) { + console.error(commandResult.stderr); } + return commandResult.output; + } } /** Represents a CLI command result */ class CommandResult { - public command: string; - public args: any[]; - public output: string; - public stderr: string; - public error: any; - public constructor(command: string, args: any[], output: string, stderr: string, error: any) { - this.command = command; - this.args = args; - this.output = output; - this.stderr = stderr; - this.error = error; - } + public command: string; + public args: any[]; + public output: string; + public stderr: string; + public error: any; + public constructor( + command: string, + args: any[], + output: string, + stderr: string, + error: any, + ) { + this.command = command; + this.args = args; + this.output = output; + this.stderr = stderr; + this.error = error; + } } /** Represents the result of the commands executed for a run */ class DiagnosticInfo { - public commands: CommandResult[] = []; - public empty: boolean = false; - public recordCommand(command: string, args: any[], output: string, stderr: string, error: any): void { - this.commands.push(new CommandResult(command, args, output, stderr, error)); - } -} \ No newline at end of file + public commands: CommandResult[] = []; + public empty: boolean = false; + public recordCommand( + command: string, + args: any[], + output: string, + stderr: string, + error: any, + ): void { + this.commands.push(new CommandResult(command, args, output, stderr, error)); + } +} diff --git a/src/VersionResult.ts b/src/VersionResult.ts index e3c942d..d8d6739 100644 --- a/src/VersionResult.ts +++ b/src/VersionResult.ts @@ -15,7 +15,7 @@ export class VersionResult { * @param changed - True if the version was changed, otherwise false * @param isTagged - True if the commit had a tag that matched the `versionTag` format * @param authors - Authors formatted according to the format mode (e.g. JSON, CSV, YAML, etc.) - * @param currentCommit - The current commit hash + * @param currentCommit - The current commit hash * @param previousCommit - The previous commit hash * @param previousVersion - The previous version * @param debugOutput - Diagnostic information, if debug is enabled @@ -34,5 +34,6 @@ export class VersionResult { public currentCommit: string, public previousCommit: string, public previousVersion: string, - public debugOutput: string) { } + public debugOutput: string, + ) {} } diff --git a/src/action.ts b/src/action.ts index 73d8562..10062b7 100644 --- a/src/action.ts +++ b/src/action.ts @@ -1,27 +1,39 @@ -import { ConfigurationProvider } from './ConfigurationProvider'; -import { VersionResult } from './VersionResult'; -import { VersionType } from './providers/VersionType'; -import { UserInfo } from './providers/UserInfo'; -import { VersionInformation } from './providers/VersionInformation'; -import { DebugManager } from './DebugManager'; -import * as core from '@actions/core'; -export async function runAction(configurationProvider: ConfigurationProvider): Promise { - +import { ConfigurationProvider } from "./ConfigurationProvider"; +import { VersionResult } from "./VersionResult"; +import { VersionType } from "./providers/VersionType"; +import { UserInfo } from "./providers/UserInfo"; +import { VersionInformation } from "./providers/VersionInformation"; +import { DebugManager } from "./DebugManager"; +import * as core from "@actions/core"; +export async function runAction( + configurationProvider: ConfigurationProvider, +): Promise { core.info("VAGO STARTING runAction"); - const currentCommitResolver = configurationProvider.GetCurrentCommitResolver(); + const currentCommitResolver = + configurationProvider.GetCurrentCommitResolver(); const lastReleaseResolver = configurationProvider.GetLastReleaseResolver(); const commitsProvider = configurationProvider.GetCommitsProvider(); const versionClassifier = configurationProvider.GetVersionClassifier(); const versionFormatter = configurationProvider.GetVersionFormatter(); - const tagFormatter = configurationProvider.GetTagFormatter(await currentCommitResolver.ResolveBranchNameAsync()); + const tagFormatter = configurationProvider.GetTagFormatter( + await currentCommitResolver.ResolveBranchNameAsync(), + ); const userFormatter = configurationProvider.GetUserFormatter(); const debugManager = DebugManager.getInstance(); if (await currentCommitResolver.IsEmptyRepoAsync()) { - core.info("VAGO REPO WAS EMPTY, returning default version information"); - const versionInfo = new VersionInformation(0, 0, 0, 0, VersionType.None, [], false, false); + const versionInfo = new VersionInformation( + 0, + 0, + 0, + 0, + VersionType.None, + [], + false, + false, + ); return new VersionResult( versionInfo.major, versionInfo.minor, @@ -32,23 +44,41 @@ export async function runAction(configurationProvider: ConfigurationProvider): P tagFormatter.Format(versionInfo), versionInfo.changed, versionInfo.isTagged, - userFormatter.Format('author', []), - '', - '', - tagFormatter.Parse(tagFormatter.Format(versionInfo)).join('.'), - debugManager.getDebugOutput(true) + userFormatter.Format("author", []), + "", + "", + tagFormatter.Parse(tagFormatter.Format(versionInfo)).join("."), + debugManager.getDebugOutput(true), ); } core.info("VAGO REPO IS NOT EMPTY, continuing with versioning"); const currentCommit = await currentCommitResolver.ResolveAsync(); core.info("VAGO CURRENT COMMIT: " + currentCommit); - const lastRelease = await lastReleaseResolver.ResolveAsync(currentCommit, tagFormatter); - core.info("VAGO LAST RELEASE: " + lastRelease.hash + " " + lastRelease.major + "." + lastRelease.minor + "." + lastRelease.patch); - const commitSet = await commitsProvider.GetCommitsAsync(lastRelease.hash, currentCommit); - core.info("VAGO commit set le:" + commitSet.commits.length) + const lastRelease = await lastReleaseResolver.ResolveAsync( + currentCommit, + tagFormatter, + ); + core.info( + "VAGO LAST RELEASE: " + + lastRelease.hash + + " " + + lastRelease.major + + "." + + lastRelease.minor + + "." + + lastRelease.patch, + ); + const commitSet = await commitsProvider.GetCommitsAsync( + lastRelease.hash, + currentCommit, + ); + core.info("VAGO commit set le:" + commitSet.commits.length); core.info("VAGO commit set changed: " + commitSet.changed.toString()); - const classification = await versionClassifier.ClassifyAsync(lastRelease, commitSet); + const classification = await versionClassifier.ClassifyAsync( + lastRelease, + commitSet, + ); core.info("VAGO classification: " + JSON.stringify(classification)); const { isTagged } = lastRelease; @@ -56,16 +86,24 @@ export async function runAction(configurationProvider: ConfigurationProvider): P // At this point all necessary data has been pulled from the database, create // version information to be used by the formatters - let versionInfo = new VersionInformation(major, minor, patch, increment, type, commitSet.commits, changed, isTagged); + let versionInfo = new VersionInformation( + major, + minor, + patch, + increment, + type, + commitSet.commits, + changed, + isTagged, + ); // Group all the authors together, count the number of commits per author - const allAuthors = versionInfo.commits - .reduce((acc: any, commit) => { - const key = `${commit.author} <${commit.authorEmail}>`; - acc[key] = acc[key] || { n: commit.author, e: commit.authorEmail, c: 0 }; - acc[key].c++; - return acc; - }, {}); + const allAuthors = versionInfo.commits.reduce((acc: any, commit) => { + const key = `${commit.author} <${commit.authorEmail}>`; + acc[key] = acc[key] || { n: commit.author, e: commit.authorEmail, c: 0 }; + acc[key].c++; + return acc; + }, {}); const authors = Object.values(allAuthors) .map((u: any) => new UserInfo(u.n, u.e, u.c)) @@ -81,10 +119,10 @@ export async function runAction(configurationProvider: ConfigurationProvider): P tagFormatter.Format(versionInfo), versionInfo.changed, versionInfo.isTagged, - userFormatter.Format('author', authors), + userFormatter.Format("author", authors), currentCommit, lastRelease.hash, `${lastRelease.major}.${lastRelease.minor}.${lastRelease.patch}`, - debugManager.getDebugOutput() + debugManager.getDebugOutput(), ); } diff --git a/src/main.test.ts b/src/main.test.ts index b6f8950..b08ed6e 100644 --- a/src/main.test.ts +++ b/src/main.test.ts @@ -1,195 +1,249 @@ -import * as process from 'process' -import * as cp from 'child_process' -import * as path from 'path' -import * as os from 'os'; -import { expect, test } from '@jest/globals' -import { runAction } from '../src/action'; -import { ConfigurationProvider } from './ConfigurationProvider'; -import { ActionConfig } from './ActionConfig'; -import { DebugManager } from './DebugManager'; +import * as process from "process"; +import * as cp from "child_process"; +import * as path from "path"; +import * as os from "os"; +import { expect, test } from "@jest/globals"; +import { runAction } from "../src/action"; +import { ConfigurationProvider } from "./ConfigurationProvider"; +import { ActionConfig } from "./ActionConfig"; +import { DebugManager } from "./DebugManager"; const windows = process.platform === "win32"; const timeout = 30000; // Creates a randomly named git repository and returns a function to execute commands in it const createTestRepo = (repoDefaultConfig?: Partial) => { - const repoDirectory = path.join(os.tmpdir(), `test${Math.random().toString(36).substring(2, 15)}`); - cp.execSync(`mkdir ${repoDirectory}`); - cp.execSync(`git init --initial-branch=master ${repoDirectory}`); + const repoDirectory = path.join( + os.tmpdir(), + `test${Math.random().toString(36).substring(2, 15)}`, + ); + cp.execSync(`mkdir ${repoDirectory}`); + cp.execSync(`git init --initial-branch=master ${repoDirectory}`); - const run = (command: string) => { - return execute(repoDirectory, command); - } + const run = (command: string) => { + return execute(repoDirectory, command); + }; - // Configure up git user - run(`git config user.name "Test User"`); - run(`git config user.email "test@example.com"`); - run(`git config commit.gpgsign false`); + // Configure up git user + run(`git config user.name "Test User"`); + run(`git config user.email "test@example.com"`); + run(`git config commit.gpgsign false`); - let i = 1; + let i = 1; - return { - makeCommit: (msg: string, path: string = '') => { - if (windows) { - run(`fsutil file createnew ${path !== '' ? path.trim() + '/' : ''}test${i++} 0`); - } else { - run(`touch ${path !== '' ? path.trim() + '/' : ''}test${i++}`); - } - run(`git add --all`); - run(`git commit -m "${msg}"`); - }, - merge: (branch: string) => { - run(`git merge ${branch}`); - }, - runAction: async (inputs?: Partial) => { - DebugManager.clearState(); - let config = new ActionConfig(); - config = { ...config, ...{ versionFormat: "${major}.${minor}.${patch}+${increment}" }, ...repoDefaultConfig, ...inputs }; - process.chdir(repoDirectory); - return await runAction(new ConfigurationProvider(config)); - }, - exec: run - }; + return { + makeCommit: (msg: string, path: string = "") => { + if (windows) { + run( + `fsutil file createnew ${path !== "" ? path.trim() + "/" : ""}test${i++} 0`, + ); + } else { + run(`touch ${path !== "" ? path.trim() + "/" : ""}test${i++}`); + } + run(`git add --all`); + run(`git commit -m "${msg}"`); + }, + merge: (branch: string) => { + run(`git merge ${branch}`); + }, + runAction: async (inputs?: Partial) => { + DebugManager.clearState(); + let config = new ActionConfig(); + config = { + ...config, + ...{ versionFormat: "${major}.${minor}.${patch}+${increment}" }, + ...repoDefaultConfig, + ...inputs, + }; + process.chdir(repoDirectory); + return await runAction(new ConfigurationProvider(config)); + }, + exec: run, + }; }; // Executes a set of commands in the specified directory const execute = (workingDirectory: string, command: string, env?: any) => { - try { - return String(cp.execSync(command, { env: { ...process.env, ...env }, cwd: workingDirectory })); - } - catch (e: any) { - throw e; - } + try { + return String( + cp.execSync(command, { + env: { ...process.env, ...env }, + cwd: workingDirectory, + }), + ); + } catch (e: any) { + throw e; + } }; -test('Empty repository version is correct', async () => { +test( + "Empty repository version is correct", + async () => { const repo = createTestRepo(); // 0.0.0+0 var result = await repo.runAction(); - expect(result.formattedVersion).toBe('0.0.0+0'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.0+0"); + }, + timeout, +); -test('Repository with commits shows increment', async () => { +test( + "Repository with commits shows increment", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 + repo.makeCommit("Initial Commit"); // 0.0.1+0 repo.makeCommit(`Second Commit`); // 0.0.1+1 const result = await repo.runAction(); - expect(result.formattedVersion).toBe('0.0.1+1'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.1+1"); + }, + timeout, +); -test('Repository show commit for checked out commit', async () => { +test( + "Repository show commit for checked out commit", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 + repo.makeCommit("Initial Commit"); // 0.0.1+0 repo.makeCommit(`Second Commit`); // 0.0.1+1 let result = await repo.runAction(); - expect(result.formattedVersion).toBe('0.0.1+1'); + expect(result.formattedVersion).toBe("0.0.1+1"); repo.exec(`git checkout HEAD~1`); // 0.0.1+1 result = await repo.runAction(); - expect(result.formattedVersion).toBe('0.0.1+0'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.1+0"); + }, + timeout, +); -test('Tagging does not break version', async () => { +test( + "Tagging does not break version", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 + repo.makeCommit("Initial Commit"); // 0.0.1+0 repo.makeCommit(`Second Commit`); // 0.0.1+1 repo.makeCommit(`Third Commit`); // 0.0.1+2 - repo.exec('git tag v0.0.1') + repo.exec("git tag v0.0.1"); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('0.0.1+2'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.1+2"); + }, + timeout, +); - -test('Tagging does not break version from previous tag', async () => { +test( + "Tagging does not break version from previous tag", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.exec('git tag v0.0.1') + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.exec("git tag v0.0.1"); repo.makeCommit(`Second Commit`); // 0.0.2+0 repo.makeCommit(`Third Commit`); // 0.0.2+1 - repo.exec('git tag v0.0.2') + repo.exec("git tag v0.0.2"); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('0.0.2+1'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.2+1"); + }, + timeout, +); -test('Minor update bumps minor version and resets increment', async () => { +test( + "Minor update bumps minor version and resets increment", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit (MINOR)'); // 0.1.0+0 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit (MINOR)"); // 0.1.0+0 const result = await repo.runAction(); - expect(result.formattedVersion).toBe('0.1.0+0'); -}, timeout); + expect(result.formattedVersion).toBe("0.1.0+0"); + }, + timeout, +); -test('Major update bumps major version and resets increment', async () => { +test( + "Major update bumps major version and resets increment", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit (MAJOR)'); // 1.0.0+0 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit (MAJOR)"); // 1.0.0+0 const result = await repo.runAction(); + expect(result.formattedVersion).toBe("1.0.0+0"); + }, + timeout, +); - expect(result.formattedVersion).toBe('1.0.0+0'); -}, timeout); - -test('Multiple major commits are idempotent', async () => { +test( + "Multiple major commits are idempotent", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit (MAJOR)'); // 1.0.0+0 - repo.makeCommit('Third Commit (MAJOR)'); // 1.0.0+1 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit (MAJOR)"); // 1.0.0+0 + repo.makeCommit("Third Commit (MAJOR)"); // 1.0.0+1 const result = await repo.runAction(); + expect(result.formattedVersion).toBe("1.0.0+1"); + }, + timeout, +); - expect(result.formattedVersion).toBe('1.0.0+1'); -}, timeout); - -test('Minor commits after a major commit are ignored', async () => { +test( + "Minor commits after a major commit are ignored", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit (MAJOR)'); // 1.0.0+0 - repo.makeCommit('Third Commit (MINOR)'); // 1.0.0+1 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit (MAJOR)"); // 1.0.0+0 + repo.makeCommit("Third Commit (MINOR)"); // 1.0.0+1 const result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.0.0+1'); -}, timeout); + expect(result.formattedVersion).toBe("1.0.0+1"); + }, + timeout, +); -test('Tags start new version', async () => { +test( + "Tags start new version", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit'); // 0.0.1+1 - repo.exec('git tag v0.0.1'); - repo.makeCommit('Third Commit'); // 0.0.2+0 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit"); // 0.0.1+1 + repo.exec("git tag v0.0.1"); + repo.makeCommit("Third Commit"); // 0.0.2+0 const result = await repo.runAction(); + expect(result.formattedVersion).toBe("0.0.2+0"); + }, + timeout, +); - expect(result.formattedVersion).toBe('0.0.2+0'); -}, timeout); - -test('Version pulled from last release branch', async () => { +test( + "Version pulled from last release branch", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.exec('git tag v0.0.1'); - repo.makeCommit('Second Commit'); // 0.0.2+0 - repo.exec('git tag v5.6.7'); - repo.makeCommit('Third Commit'); // 5.6.7+0 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.exec("git tag v0.0.1"); + repo.makeCommit("Second Commit"); // 0.0.2+0 + repo.exec("git tag v5.6.7"); + repo.makeCommit("Third Commit"); // 5.6.7+0 const result = await repo.runAction(); + expect(result.formattedVersion).toBe("5.6.8+0"); + }, + timeout, +); - expect(result.formattedVersion).toBe('5.6.8+0'); -}, timeout); - -test('Merged tags do not affect version', async () => { - +test( + "Merged tags do not affect version", + async () => { // This test checks that merges don't override tags // Tagged v0.0.2 @@ -198,882 +252,1133 @@ test('Merged tags do not affect version', async () => { // \ / // release o---o <- taged v0.0.1 - const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit'); // 0.0.1+1 - repo.makeCommit('Third Commit'); // 0.1.1+2 - repo.exec('git checkout -b release/0.0.1') - repo.makeCommit('Fourth Commit'); // 0.1.1+3 - repo.exec('git tag v0.0.1'); - repo.exec('git checkout master'); - repo.makeCommit('Fifth Commit'); // 0.0.2.0 - repo.exec('git tag v0.0.2'); - repo.merge('release/0.0.1'); + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit"); // 0.0.1+1 + repo.makeCommit("Third Commit"); // 0.1.1+2 + repo.exec("git checkout -b release/0.0.1"); + repo.makeCommit("Fourth Commit"); // 0.1.1+3 + repo.exec("git tag v0.0.1"); + repo.exec("git checkout master"); + repo.makeCommit("Fifth Commit"); // 0.0.2.0 + repo.exec("git tag v0.0.2"); + repo.merge("release/0.0.1"); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('0.0.3+1'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.3+1"); + }, + timeout, +); -test('Format input is respected', async () => { - const repo = createTestRepo({ versionFormat: 'M${major}m${minor}p${patch}i${increment}' }); // M0m0p0i0 +test( + "Format input is respected", + async () => { + const repo = createTestRepo({ + versionFormat: "M${major}m${minor}p${patch}i${increment}", + }); // M0m0p0i0 - repo.makeCommit('Initial Commit'); // M1m2p3i0 - repo.exec('git tag v1.2.3'); + repo.makeCommit("Initial Commit"); // M1m2p3i0 + repo.exec("git tag v1.2.3"); repo.makeCommit(`Second Commit`); // M1m2p4i0 const result = await repo.runAction(); - expect(result.formattedVersion).toBe('M1m2p4i0'); -}, timeout); + expect(result.formattedVersion).toBe("M1m2p4i0"); + }, + timeout, +); -test('Version prefixes are not required/can be empty', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Version prefixes are not required/can be empty", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); repo.makeCommit(`Second Commit`); // 0.0.2 const result = await repo.runAction(); - expect(result.formattedVersion).toBe('0.0.2+0'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.2+0"); + }, + timeout, +); -test('Tag order comes from commit order, not tag create order', async () => { +test( + "Tag order comes from commit order, not tag create order", + async () => { const repo = createTestRepo(); // 0.0.0+0 - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit'); // 0.0.1+1 - repo.makeCommit('Third Commit'); // 0.0.1+2 - repo.exec('git tag v2.0.0'); + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit"); // 0.0.1+1 + repo.makeCommit("Third Commit"); // 0.0.1+2 + repo.exec("git tag v2.0.0"); // Can't timeout in this context on Windows, ping localhost to delay - repo.exec(windows ? 'ping 127.0.0.1 -n 2' : 'sleep 2'); - repo.exec('git tag v1.0.0 HEAD~1'); - repo.makeCommit('Fourth Commit'); // 0.0.1+2 + repo.exec(windows ? "ping 127.0.0.1 -n 2" : "sleep 2"); + repo.exec("git tag v1.0.0 HEAD~1"); + repo.makeCommit("Fourth Commit"); // 0.0.1+2 const result = await repo.runAction(); + expect(result.formattedVersion).toBe("2.0.1+0"); + }, + timeout, +); - expect(result.formattedVersion).toBe('2.0.1+0'); -}, timeout); +test( + "Change detection is true by default", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - -test('Change detection is true by default', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 - - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); repo.makeCommit(`Second Commit`); // 0.0.2 const result = await repo.runAction(); expect(result.changed).toBe(true); -}, timeout); + }, + timeout, +); -test('Changes to monitored path is true when change is in path', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Changes to monitored path is true when change is in path", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); - repo.exec('mkdir project1'); - repo.makeCommit(`Second Commit`, 'project1'); // 0.0.2 + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); + repo.exec("mkdir project1"); + repo.makeCommit(`Second Commit`, "project1"); // 0.0.2 const result = await repo.runAction({ changePath: "project1" }); expect(result.changed).toBe(true); -}, timeout); + }, + timeout, +); -test('Changes to monitored path is false when changes are not in path', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Changes to monitored path is false when changes are not in path", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); - repo.exec('mkdir project1'); - repo.exec('mkdir project2'); - repo.makeCommit(`Second Commit`, 'project2'); // 0.0.2 + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); + repo.exec("mkdir project1"); + repo.exec("mkdir project2"); + repo.makeCommit(`Second Commit`, "project2"); // 0.0.2 const result = await repo.runAction({ changePath: "project1" }); expect(result.changed).toBe(false); -}, timeout); + }, + timeout, +); -test('Changes can be detected without tags', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Changes can be detected without tags", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('mkdir project1'); - repo.makeCommit(`Second Commit`, 'project1'); // 0.0.2 + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("mkdir project1"); + repo.makeCommit(`Second Commit`, "project1"); // 0.0.2 const result = await repo.runAction({ changePath: "project1" }); expect(result.changed).toBe(true); -}, timeout); + }, + timeout, +); -test('Changes to multiple monitored path is true when change is in path', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Changes to multiple monitored path is true when change is in path", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); - repo.exec('mkdir project1'); - repo.exec('mkdir project2'); - repo.makeCommit(`Second Commit`, 'project2'); // 0.0.2 + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); + repo.exec("mkdir project1"); + repo.exec("mkdir project2"); + repo.makeCommit(`Second Commit`, "project2"); // 0.0.2 const result = await repo.runAction({ changePath: "project1 project2" }); expect(result.changed).toBe(true); -}, timeout); + }, + timeout, +); -test('Changes to multiple monitored path is false when change is not in path', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Changes to multiple monitored path is false when change is not in path", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); - repo.exec('mkdir project1'); - repo.exec('mkdir project2'); - repo.exec('mkdir project3'); - repo.makeCommit(`Second Commit`, 'project3'); // 0.0.2 + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); + repo.exec("mkdir project1"); + repo.exec("mkdir project2"); + repo.exec("mkdir project3"); + repo.makeCommit(`Second Commit`, "project3"); // 0.0.2 const result = await repo.runAction({ changePath: "project1 project2" }); expect(result.changed).toBe(false); -}, timeout); + }, + timeout, +); +test( + "Namespace is tracked separately", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 -test('Namespace is tracked separately', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 - - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); - repo.makeCommit('Second Commit'); // 0.0.2 - repo.exec('git tag 0.1.0-subproject'); - repo.makeCommit('Third Commit'); // 0.0.2 / 0.1.1 + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); + repo.makeCommit("Second Commit"); // 0.0.2 + repo.exec("git tag 0.1.0-subproject"); + repo.makeCommit("Third Commit"); // 0.0.2 / 0.1.1 const result = await repo.runAction(); const subprojectResult = await repo.runAction({ namespace: "subproject" }); - expect(result.formattedVersion).toBe('0.0.2+1'); - expect(subprojectResult.formattedVersion).toBe('0.1.1+0'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.2+1"); + expect(subprojectResult.formattedVersion).toBe("0.1.1+0"); + }, + timeout, +); +test( + "Version Namespace is tracked separately", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 -test('Version Namespace is tracked separately', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 - - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); - repo.makeCommit('Second Commit'); // 0.0.2 - repo.exec('git tag subproject0.1.0'); - repo.makeCommit('Third Commit'); // 0.0.2 / 0.1.1 + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); + repo.makeCommit("Second Commit"); // 0.0.2 + repo.exec("git tag subproject0.1.0"); + repo.makeCommit("Third Commit"); // 0.0.2 / 0.1.1 const result = await repo.runAction(); const subprojectResult = await repo.runAction({ tagPrefix: "subproject" }); - expect(result.formattedVersion).toBe('0.0.2+1'); - expect(subprojectResult.formattedVersion).toBe('0.1.1+0'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.2+1"); + expect(subprojectResult.formattedVersion).toBe("0.1.1+0"); + }, + timeout, +); -test('Namespace allows dashes', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Namespace allows dashes", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); - repo.makeCommit('Second Commit'); // 0.0.2 + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); + repo.makeCommit("Second Commit"); // 0.0.2 repo.exec('git tag "0.1.0-sub/project"'); - repo.makeCommit('Third Commit'); // 0.0.2 / 0.1.1 + repo.makeCommit("Third Commit"); // 0.0.2 / 0.1.1 const result = await repo.runAction(); const subprojectResult = await repo.runAction({ namespace: "sub/project" }); - expect(result.formattedVersion).toBe('0.0.2+1'); - expect(subprojectResult.formattedVersion).toBe('0.1.1+0'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.2+1"); + expect(subprojectResult.formattedVersion).toBe("0.1.1+0"); + }, + timeout, +); -test('Commits outside of path are not counted', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Commits outside of path are not counted", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); - repo.makeCommit('Second Commit'); - repo.makeCommit('Third Commit'); + repo.makeCommit("Initial Commit"); + repo.makeCommit("Second Commit"); + repo.makeCommit("Third Commit"); const result = await repo.runAction({ changePath: "project1" }); - expect(result.formattedVersion).toBe('0.0.0+0'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.0+0"); + }, + timeout, +); -test('Commits inside path are counted', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Commits inside path are counted", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); - repo.makeCommit('Second Commit'); - repo.makeCommit('Third Commit'); - repo.exec('mkdir project1'); - repo.makeCommit('Fourth Commit', 'project1'); // 0.0.1+0 - repo.makeCommit('Fifth Commit', 'project1'); // 0.0.1+1 - repo.makeCommit('Sixth Commit', 'project1'); // 0.0.1+2 + repo.makeCommit("Initial Commit"); + repo.makeCommit("Second Commit"); + repo.makeCommit("Third Commit"); + repo.exec("mkdir project1"); + repo.makeCommit("Fourth Commit", "project1"); // 0.0.1+0 + repo.makeCommit("Fifth Commit", "project1"); // 0.0.1+1 + repo.makeCommit("Sixth Commit", "project1"); // 0.0.1+2 const result = await repo.runAction({ changePath: "project1" }); - expect(result.formattedVersion).toBe('0.0.1+2'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.1+2"); + }, + timeout, +); -test('Current tag is used', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Current tag is used", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); - repo.makeCommit('Second Commit'); - repo.makeCommit('Third Commit'); - repo.exec('git tag 7.6.5'); + repo.makeCommit("Initial Commit"); + repo.makeCommit("Second Commit"); + repo.makeCommit("Third Commit"); + repo.exec("git tag 7.6.5"); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('7.6.5+0'); -}, timeout); + expect(result.formattedVersion).toBe("7.6.5+0"); + }, + timeout, +); -test('Bump each commit works', async () => { +test( + "Bump each commit works", + async () => { + const repo = createTestRepo({ tagPrefix: "", bumpEachCommit: true }); // 0.0.0 - const repo = createTestRepo({ tagPrefix: '', bumpEachCommit: true }); // 0.0.0 + expect((await repo.runAction()).formattedVersion).toBe("0.0.0+0"); + repo.makeCommit("Initial Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.1+0"); + repo.makeCommit("Second Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.2+0"); + repo.makeCommit("Third Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.3+0"); + repo.makeCommit("Fourth Commit (MINOR)"); + expect((await repo.runAction()).formattedVersion).toBe("0.1.0+0"); + repo.makeCommit("Fifth Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.1.1+0"); + repo.makeCommit("Sixth Commit (MAJOR)"); + expect((await repo.runAction()).formattedVersion).toBe("1.0.0+0"); + repo.makeCommit("Seventh Commit"); + expect((await repo.runAction()).formattedVersion).toBe("1.0.1+0"); + }, + timeout, +); - expect((await repo.runAction()).formattedVersion).toBe('0.0.0+0'); - repo.makeCommit('Initial Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.1+0'); - repo.makeCommit('Second Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.2+0'); - repo.makeCommit('Third Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.3+0'); - repo.makeCommit('Fourth Commit (MINOR)'); - expect((await repo.runAction()).formattedVersion).toBe('0.1.0+0'); - repo.makeCommit('Fifth Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.1.1+0'); - repo.makeCommit('Sixth Commit (MAJOR)'); - expect((await repo.runAction()).formattedVersion).toBe('1.0.0+0'); - repo.makeCommit('Seventh Commit'); - expect((await repo.runAction()).formattedVersion).toBe('1.0.1+0'); -}, timeout); +test( + "Bump each commit picks up tags", + async () => { + const repo = createTestRepo({ tagPrefix: "", bumpEachCommit: true }); // 0.0.0 -test('Bump each commit picks up tags', async () => { - const repo = createTestRepo({ tagPrefix: '', bumpEachCommit: true }); // 0.0.0 + expect((await repo.runAction()).formattedVersion).toBe("0.0.0+0"); + repo.makeCommit("Initial Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.1+0"); + repo.makeCommit("Second Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.2+0"); + repo.makeCommit("Third Commit"); + repo.exec("git tag 3.0.0"); + expect((await repo.runAction()).formattedVersion).toBe("3.0.0+0"); + repo.makeCommit("Fourth Commit"); + expect((await repo.runAction()).formattedVersion).toBe("3.0.1+0"); + }, + timeout, +); - expect((await repo.runAction()).formattedVersion).toBe('0.0.0+0'); - repo.makeCommit('Initial Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.1+0'); - repo.makeCommit('Second Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.2+0'); - repo.makeCommit('Third Commit'); - repo.exec('git tag 3.0.0'); - expect((await repo.runAction()).formattedVersion).toBe('3.0.0+0'); - repo.makeCommit('Fourth Commit'); - expect((await repo.runAction()).formattedVersion).toBe('3.0.1+0'); -}, timeout); +test( + "Increment not affected by matching tag", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.1 -test('Increment not affected by matching tag', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.1 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit"); // 0.0.1+1 + repo.exec("git tag 0.0.1"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.1+1"); + }, + timeout, +); - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit'); // 0.0.1+1 - repo.exec('git tag 0.0.1'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.1+1'); -}, timeout); +test( + "Regular expressions can be used as major tag", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + majorPattern: "/S[a-z]+Value/", + }); // 0.0.1 -test('Regular expressions can be used as major tag', async () => { - const repo = createTestRepo({ tagPrefix: '', majorPattern: '/S[a-z]+Value/' }); // 0.0.1 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit SomeValue"); // 1.0.0+0 + expect((await repo.runAction()).formattedVersion).toBe("1.0.0+0"); + }, + timeout, +); - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit SomeValue'); // 1.0.0+0 - expect((await repo.runAction()).formattedVersion).toBe('1.0.0+0'); -}, timeout); +test( + "Regular expressions can be used as minor tag", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + minorPattern: "/S[a-z]+Value/", + }); // 0.0.1 -test('Regular expressions can be used as minor tag', async () => { - const repo = createTestRepo({ tagPrefix: '', minorPattern: '/S[a-z]+Value/' }); // 0.0.1 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit SomeValue"); // 0.0.1+1 + expect((await repo.runAction()).formattedVersion).toBe("0.1.0+0"); + }, + timeout, +); - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit SomeValue'); // 0.0.1+1 - expect((await repo.runAction()).formattedVersion).toBe('0.1.0+0'); -}, timeout); +test( + "Regular expressions and flags can be used as major tag", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + majorPattern: "/s[a-z]+value/", + majorFlags: "i", + }); // 0.0.1 -test('Regular expressions and flags can be used as major tag', async () => { - const repo = createTestRepo({ tagPrefix: '', majorPattern: '/s[a-z]+value/', majorFlags: 'i' }); // 0.0.1 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit SomeValue"); // 1.0.0+0 + expect((await repo.runAction()).formattedVersion).toBe("1.0.0+0"); + }, + timeout, +); - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit SomeValue'); // 1.0.0+0 - expect((await repo.runAction()).formattedVersion).toBe('1.0.0+0'); -}, timeout); +test( + "Regular expressions and flags can be used as minor tag", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + minorPattern: "/s[a-z]+value/", + minorFlags: "i", + }); // 0.0.1 -test('Regular expressions and flags can be used as minor tag', async () => { - const repo = createTestRepo({ tagPrefix: '', minorPattern: '/s[a-z]+value/', minorFlags: 'i' }); // 0.0.1 + repo.makeCommit("Initial Commit"); // 0.0.1+0 + repo.makeCommit("Second Commit SomeValue"); // 0.0.1+1 + expect((await repo.runAction()).formattedVersion).toBe("0.1.0+0"); + }, + timeout, +); - repo.makeCommit('Initial Commit'); // 0.0.1+0 - repo.makeCommit('Second Commit SomeValue'); // 0.0.1+1 - expect((await repo.runAction()).formattedVersion).toBe('0.1.0+0'); -}, timeout); +test( + "Tag prefix can include forward slash", + async () => { + const repo = createTestRepo({ tagPrefix: "version/" }); // 0.0.0 -test('Tag prefix can include forward slash', async () => { - const repo = createTestRepo({ tagPrefix: 'version/' }); // 0.0.0 - - repo.makeCommit('Initial Commit'); - repo.exec('git tag version/1.2.3'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag version/1.2.3"); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.2.3+0'); -}, timeout); + expect(result.formattedVersion).toBe("1.2.3+0"); + }, + timeout, +); -test('Tags immediately before merge are detected', async () => { - const repo = createTestRepo({ tagPrefix: 'v' }); // 0.0.0 +test( + "Tags immediately before merge are detected", + async () => { + const repo = createTestRepo({ tagPrefix: "v" }); // 0.0.0 - repo.makeCommit('Initial Commit'); - repo.makeCommit('Commit 1'); - repo.exec('git tag v1.0.0'); - repo.makeCommit('Commit 2'); - repo.exec('git checkout -b feature/branch'); - repo.makeCommit('Commit 3'); - repo.makeCommit('Commit 4'); - repo.exec('git tag v2.0.0'); - repo.exec('git checkout master'); - repo.makeCommit('Commit 5'); - repo.merge('feature/branch'); + repo.makeCommit("Initial Commit"); + repo.makeCommit("Commit 1"); + repo.exec("git tag v1.0.0"); + repo.makeCommit("Commit 2"); + repo.exec("git checkout -b feature/branch"); + repo.makeCommit("Commit 3"); + repo.makeCommit("Commit 4"); + repo.exec("git tag v2.0.0"); + repo.exec("git checkout master"); + repo.makeCommit("Commit 5"); + repo.merge("feature/branch"); const result = await repo.runAction(); - expect(result.versionTag).toBe('v2.0.1'); -}, timeout); + expect(result.versionTag).toBe("v2.0.1"); + }, + timeout, +); -test('Correct tag is detected on merged branches', async () => { - const repo = createTestRepo({ tagPrefix: 'v' }); // 0.0.0 +test( + "Correct tag is detected on merged branches", + async () => { + const repo = createTestRepo({ tagPrefix: "v" }); // 0.0.0 - repo.makeCommit('Initial Commit'); - repo.makeCommit('Commit 1'); - repo.exec('git tag v1.0.0'); - repo.makeCommit('Commit 2'); - repo.exec('git checkout -b feature/branch'); - repo.makeCommit('Commit 3'); - repo.exec('git tag v2.0.0'); - repo.makeCommit('Commit 4'); - repo.exec('git checkout master'); - repo.makeCommit('Commit 5'); - repo.merge('feature/branch'); + repo.makeCommit("Initial Commit"); + repo.makeCommit("Commit 1"); + repo.exec("git tag v1.0.0"); + repo.makeCommit("Commit 2"); + repo.exec("git checkout -b feature/branch"); + repo.makeCommit("Commit 3"); + repo.exec("git tag v2.0.0"); + repo.makeCommit("Commit 4"); + repo.exec("git checkout master"); + repo.makeCommit("Commit 5"); + repo.merge("feature/branch"); const result = await repo.runAction(); - expect(result.versionTag).toBe('v2.0.1'); -}, timeout); + expect(result.versionTag).toBe("v2.0.1"); + }, + timeout, +); -test('Correct tag is detected on multiple branches', async () => { - const repo = createTestRepo({ tagPrefix: 'v' }); // 0.0.0 +test( + "Correct tag is detected on multiple branches", + async () => { + const repo = createTestRepo({ tagPrefix: "v" }); // 0.0.0 - repo.makeCommit('Initial Commit'); - repo.makeCommit('Commit 1'); - repo.exec('git checkout -b feature/branch1'); - repo.exec('git tag v1.0.0'); - repo.makeCommit('Commit 2'); - repo.exec('git checkout master'); - repo.merge('feature/branch1'); - repo.exec('git checkout -b feature/branch2'); - repo.makeCommit('Commit 3'); - repo.exec('git tag v2.0.0'); - repo.makeCommit('Commit 4'); - repo.exec('git checkout master'); - repo.makeCommit('Commit 5'); - repo.merge('feature/branch2'); + repo.makeCommit("Initial Commit"); + repo.makeCommit("Commit 1"); + repo.exec("git checkout -b feature/branch1"); + repo.exec("git tag v1.0.0"); + repo.makeCommit("Commit 2"); + repo.exec("git checkout master"); + repo.merge("feature/branch1"); + repo.exec("git checkout -b feature/branch2"); + repo.makeCommit("Commit 3"); + repo.exec("git tag v2.0.0"); + repo.makeCommit("Commit 4"); + repo.exec("git checkout master"); + repo.makeCommit("Commit 5"); + repo.merge("feature/branch2"); const result = await repo.runAction(); - expect(result.versionTag).toBe('v2.0.1'); -}, timeout); + expect(result.versionTag).toBe("v2.0.1"); + }, + timeout, +); -test('Correct tag is detected when versions pass 10s place', async () => { - const repo = createTestRepo({ tagPrefix: 'v' }); // 0.0.0 +test( + "Correct tag is detected when versions pass 10s place", + async () => { + const repo = createTestRepo({ tagPrefix: "v" }); // 0.0.0 - repo.makeCommit('Initial Commit'); - repo.makeCommit('Commit 1'); - repo.exec('git checkout -b feature/branch1'); - repo.exec('git tag v10.15.0'); - repo.makeCommit('Commit 2'); - repo.exec('git checkout master'); - repo.merge('feature/branch1'); - repo.exec('git checkout -b feature/branch2'); - repo.makeCommit('Commit 3'); - repo.exec('git tag v10.7.0'); - repo.makeCommit('Commit 4'); - repo.exec('git checkout master'); - repo.makeCommit('Commit 5'); - repo.merge('feature/branch2'); + repo.makeCommit("Initial Commit"); + repo.makeCommit("Commit 1"); + repo.exec("git checkout -b feature/branch1"); + repo.exec("git tag v10.15.0"); + repo.makeCommit("Commit 2"); + repo.exec("git checkout master"); + repo.merge("feature/branch1"); + repo.exec("git checkout -b feature/branch2"); + repo.makeCommit("Commit 3"); + repo.exec("git tag v10.7.0"); + repo.makeCommit("Commit 4"); + repo.exec("git checkout master"); + repo.makeCommit("Commit 5"); + repo.merge("feature/branch2"); const result = await repo.runAction(); - expect(result.versionTag).toBe('v10.15.1'); -}, timeout); + expect(result.versionTag).toBe("v10.15.1"); + }, + timeout, +); -test('Tags on unmerged branches are not considered', async () => { - const repo = createTestRepo({ tagPrefix: 'v' }); // 0.0.0 +test( + "Tags on unmerged branches are not considered", + async () => { + const repo = createTestRepo({ tagPrefix: "v" }); // 0.0.0 - repo.makeCommit('Initial Commit'); - repo.makeCommit('Commit 1'); - repo.exec('git checkout -b feature/branch1'); - repo.makeCommit('Commit 2'); - repo.exec('git tag v2.0.0'); - repo.makeCommit('Commit 3'); - repo.exec('git checkout master'); - repo.makeCommit('Commit 4'); - repo.exec('git tag v1.0.0'); - repo.makeCommit('Commit 5'); + repo.makeCommit("Initial Commit"); + repo.makeCommit("Commit 1"); + repo.exec("git checkout -b feature/branch1"); + repo.makeCommit("Commit 2"); + repo.exec("git tag v2.0.0"); + repo.makeCommit("Commit 3"); + repo.exec("git checkout master"); + repo.makeCommit("Commit 4"); + repo.exec("git tag v1.0.0"); + repo.makeCommit("Commit 5"); const result = await repo.runAction(); - expect(result.versionTag).toBe('v1.0.1'); -}, timeout); + expect(result.versionTag).toBe("v1.0.1"); + }, + timeout, +); -test('Can use branches instead of tags', async () => { - const repo = createTestRepo({ tagPrefix: 'release/', useBranches: true }); // 0.0.0 +test( + "Can use branches instead of tags", + async () => { + const repo = createTestRepo({ tagPrefix: "release/", useBranches: true }); // 0.0.0 - repo.makeCommit('Initial Commit'); - repo.makeCommit('Commit 1'); - repo.exec('git checkout -b release/1.0.0'); - repo.makeCommit('Commit 2'); - repo.exec('git checkout master'); - repo.merge('release/1.0.0'); - repo.makeCommit('Commit 3'); + repo.makeCommit("Initial Commit"); + repo.makeCommit("Commit 1"); + repo.exec("git checkout -b release/1.0.0"); + repo.makeCommit("Commit 2"); + repo.exec("git checkout master"); + repo.merge("release/1.0.0"); + repo.makeCommit("Commit 3"); const result = await repo.runAction(); - expect(result.versionTag).toBe('release/1.0.1'); -}, timeout); + expect(result.versionTag).toBe("release/1.0.1"); + }, + timeout, +); -test('Correct previous version is returned', async () => { +test( + "Correct previous version is returned", + async () => { const repo = createTestRepo(); - repo.makeCommit('Initial Commit'); - repo.exec('git tag v2.0.1'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag v2.0.1"); repo.makeCommit(`Second Commit`); repo.makeCommit(`Third Commit`); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('2.0.2+1'); - expect(result.previousVersion).toBe('2.0.1'); -}, timeout); + expect(result.formattedVersion).toBe("2.0.2+1"); + expect(result.previousVersion).toBe("2.0.1"); + }, + timeout, +); -test('Correct previous version is returned when multiple tags are present', async () => { +test( + "Correct previous version is returned when multiple tags are present", + async () => { const repo = createTestRepo(); - repo.makeCommit('Initial Commit'); - repo.exec('git tag v1.0.1'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag v1.0.1"); repo.makeCommit(`Second Commit`); - repo.exec('git tag v2.0.1'); + repo.exec("git tag v2.0.1"); repo.makeCommit(`Third Commit`); - repo.exec('git tag v3.0.1'); + repo.exec("git tag v3.0.1"); repo.makeCommit(`Fourth Commit`); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('3.0.2+0'); - expect(result.previousVersion).toBe('3.0.1'); -}, timeout); + expect(result.formattedVersion).toBe("3.0.2+0"); + expect(result.previousVersion).toBe("3.0.1"); + }, + timeout, +); -test('Correct previous version is returned when using branches', async () => { - const repo = createTestRepo({ tagPrefix: 'release/', useBranches: true }); +test( + "Correct previous version is returned when using branches", + async () => { + const repo = createTestRepo({ tagPrefix: "release/", useBranches: true }); - repo.makeCommit('Initial Commit'); - repo.exec('git checkout -b release/2.0.1'); + repo.makeCommit("Initial Commit"); + repo.exec("git checkout -b release/2.0.1"); repo.makeCommit(`Second Commit`); - repo.exec('git checkout master'); - repo.merge('release/2.0.1'); + repo.exec("git checkout master"); + repo.merge("release/2.0.1"); repo.makeCommit(`Third Commit`); const result = await repo.runAction(); - expect(result.previousVersion).toBe('2.0.1'); - expect(result.formattedVersion).toBe('2.0.2+0'); -}, timeout); + expect(result.previousVersion).toBe("2.0.1"); + expect(result.formattedVersion).toBe("2.0.2+0"); + }, + timeout, +); -test('Correct previous version is returned when directly tagged', async () => { +test( + "Correct previous version is returned when directly tagged", + async () => { const repo = createTestRepo(); - repo.makeCommit('Initial Commit'); - repo.exec('git tag v2.0.1') + repo.makeCommit("Initial Commit"); + repo.exec("git tag v2.0.1"); repo.makeCommit(`Second Commit`); repo.makeCommit(`Third Commit`); - repo.exec('git tag v2.0.2') + repo.exec("git tag v2.0.2"); const result = await repo.runAction(); - expect(result.previousVersion).toBe('2.0.1'); - expect(result.formattedVersion).toBe('2.0.2+1'); -}, timeout); + expect(result.previousVersion).toBe("2.0.1"); + expect(result.formattedVersion).toBe("2.0.2+1"); + }, + timeout, +); -test('Correct previous version is returned when directly tagged with multiple previous tags', async () => { +test( + "Correct previous version is returned when directly tagged with multiple previous tags", + async () => { const repo = createTestRepo(); - repo.makeCommit('Initial Commit'); - repo.exec('git tag v2.0.1') + repo.makeCommit("Initial Commit"); + repo.exec("git tag v2.0.1"); repo.makeCommit(`Second Commit`); - repo.exec('git tag v2.0.2') + repo.exec("git tag v2.0.2"); repo.makeCommit(`Third Commit`); - repo.exec('git tag v2.0.3') + repo.exec("git tag v2.0.3"); const result = await repo.runAction(); - expect(result.previousVersion).toBe('2.0.2'); - expect(result.formattedVersion).toBe('2.0.3+0'); -}, timeout); + expect(result.previousVersion).toBe("2.0.2"); + expect(result.formattedVersion).toBe("2.0.3+0"); + }, + timeout, +); -test('Prerelease suffixes are ignored', async () => { +test( + "Prerelease suffixes are ignored", + async () => { const repo = createTestRepo(); - repo.makeCommit('Initial Commit (MAJOR)'); + repo.makeCommit("Initial Commit (MAJOR)"); repo.makeCommit(`Second Commit`); - repo.exec('git tag v1.0.0-alpha.1') + repo.exec("git tag v1.0.0-alpha.1"); repo.makeCommit(`Third Commit`); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.0.0+2'); -}, timeout); + expect(result.formattedVersion).toBe("1.0.0+2"); + }, + timeout, +); -test('Prerelease suffixes are ignored when namespaces are set', async () => { - const repo = createTestRepo({ namespace: 'test' }); +test( + "Prerelease suffixes are ignored when namespaces are set", + async () => { + const repo = createTestRepo({ namespace: "test" }); - repo.makeCommit('Initial Commit (MAJOR)'); - repo.exec('git tag v1.0.0-test') + repo.makeCommit("Initial Commit (MAJOR)"); + repo.exec("git tag v1.0.0-test"); repo.makeCommit(`Second Commit`); - repo.exec('git tag v1.0.1-test-alpha.1') + repo.exec("git tag v1.0.1-test-alpha.1"); repo.makeCommit(`Third Commit`); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.0.1+1'); -}, timeout); + expect(result.formattedVersion).toBe("1.0.1+1"); + }, + timeout, +); -test('Namespace can contains a slash', async () => { - const repo = createTestRepo({ tagPrefix: '' }); // 0.0.0 +test( + "Namespace can contains a slash", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); // 0.0.0 - repo.makeCommit('Initial Commit'); // 0.0.1 - repo.exec('git tag 0.0.1'); - repo.makeCommit('Second Commit'); // 0.0.2 - repo.exec('git tag 0.1.0-sub/project'); - repo.makeCommit('Third Commit'); // 0.0.2 / 0.1.1 + repo.makeCommit("Initial Commit"); // 0.0.1 + repo.exec("git tag 0.0.1"); + repo.makeCommit("Second Commit"); // 0.0.2 + repo.exec("git tag 0.1.0-sub/project"); + repo.makeCommit("Third Commit"); // 0.0.2 / 0.1.1 const result = await repo.runAction(); const subprojectResult = await repo.runAction({ namespace: "sub/project" }); - expect(result.formattedVersion).toBe('0.0.2+1'); - expect(subprojectResult.formattedVersion).toBe('0.1.1+0'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.2+1"); + expect(subprojectResult.formattedVersion).toBe("0.1.1+0"); + }, + timeout, +); -test('Namespace can contains a dot', async () => { - const repo = createTestRepo({ tagPrefix: '' }); +test( + "Namespace can contains a dot", + async () => { + const repo = createTestRepo({ tagPrefix: "" }); - repo.makeCommit('Initial Commit'); - repo.exec('git tag 0.0.1'); - repo.makeCommit('Second Commit'); - repo.exec('git tag 0.1.0-sub.project'); - repo.makeCommit('Third Commit'); - repo.exec('git tag 0.2.0-sub/project'); - repo.makeCommit('fourth Commit'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag 0.0.1"); + repo.makeCommit("Second Commit"); + repo.exec("git tag 0.1.0-sub.project"); + repo.makeCommit("Third Commit"); + repo.exec("git tag 0.2.0-sub/project"); + repo.makeCommit("fourth Commit"); const result = await repo.runAction(); const subprojectResult = await repo.runAction({ namespace: "sub.project" }); - expect(result.formattedVersion).toBe('0.0.2+2'); - expect(subprojectResult.formattedVersion).toBe('0.1.1+1'); -}, timeout); + expect(result.formattedVersion).toBe("0.0.2+2"); + expect(subprojectResult.formattedVersion).toBe("0.1.1+1"); + }, + timeout, +); -test('Patch increments only once', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}" }); +test( + "Patch increments only once", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}", + }); - repo.makeCommit('Initial Commit'); - repo.exec('git tag 0.0.1'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag 0.0.1"); const firstResult = await repo.runAction(); - repo.makeCommit('Second Commit'); + repo.makeCommit("Second Commit"); const secondResult = await repo.runAction(); - repo.makeCommit('Third Commit'); + repo.makeCommit("Third Commit"); const thirdResult = await repo.runAction(); - repo.makeCommit('fourth Commit'); + repo.makeCommit("fourth Commit"); const fourthResult = await repo.runAction(); + expect(firstResult.formattedVersion).toBe("0.0.1"); + expect(secondResult.formattedVersion).toBe("0.0.2"); + expect(thirdResult.formattedVersion).toBe("0.0.2"); + expect(fourthResult.formattedVersion).toBe("0.0.2"); + }, + timeout, +); - expect(firstResult.formattedVersion).toBe('0.0.1'); - expect(secondResult.formattedVersion).toBe('0.0.2'); - expect(thirdResult.formattedVersion).toBe('0.0.2'); - expect(fourthResult.formattedVersion).toBe('0.0.2'); +test( + "Patch increments each time when bump each commit is set", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}", + bumpEachCommit: true, + }); -}, timeout); - -test('Patch increments each time when bump each commit is set', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}", bumpEachCommit: true }); - - repo.makeCommit('Initial Commit'); - repo.exec('git tag 0.0.1'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag 0.0.1"); const firstResult = await repo.runAction(); - repo.makeCommit('Second Commit'); + repo.makeCommit("Second Commit"); const secondResult = await repo.runAction(); - repo.makeCommit('Third Commit'); + repo.makeCommit("Third Commit"); const thirdResult = await repo.runAction(); - repo.makeCommit('fourth Commit'); + repo.makeCommit("fourth Commit"); const fourthResult = await repo.runAction(); + expect(firstResult.formattedVersion).toBe("0.0.1"); + expect(secondResult.formattedVersion).toBe("0.0.2"); + expect(thirdResult.formattedVersion).toBe("0.0.3"); + expect(fourthResult.formattedVersion).toBe("0.0.4"); + }, + timeout, +); - expect(firstResult.formattedVersion).toBe('0.0.1'); - expect(secondResult.formattedVersion).toBe('0.0.2'); - expect(thirdResult.formattedVersion).toBe('0.0.3'); - expect(fourthResult.formattedVersion).toBe('0.0.4'); +test( + "Patch does not increment on bump each commit if a patch pattern is set", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}+${increment}", + bumpEachCommit: true, + bumpEachCommitPatchPattern: "(PATCH)", + }); -}, timeout); - -test('Patch does not increment on bump each commit if a patch pattern is set', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}+${increment}", bumpEachCommit: true, bumpEachCommitPatchPattern: '(PATCH)' }); - - repo.makeCommit('Initial Commit'); - repo.exec('git tag 0.0.1'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag 0.0.1"); const firstResult = await repo.runAction(); - repo.makeCommit('Second Commit'); + repo.makeCommit("Second Commit"); const secondResult = await repo.runAction(); - repo.makeCommit('Third Commit'); + repo.makeCommit("Third Commit"); const thirdResult = await repo.runAction(); - repo.makeCommit('fourth Commit'); + repo.makeCommit("fourth Commit"); const fourthResult = await repo.runAction(); + expect(firstResult.formattedVersion).toBe("0.0.1+0"); + expect(secondResult.formattedVersion).toBe("0.0.1+1"); + expect(thirdResult.formattedVersion).toBe("0.0.1+2"); + expect(fourthResult.formattedVersion).toBe("0.0.1+3"); + }, + timeout, +); - expect(firstResult.formattedVersion).toBe('0.0.1+0'); - expect(secondResult.formattedVersion).toBe('0.0.1+1'); - expect(thirdResult.formattedVersion).toBe('0.0.1+2'); - expect(fourthResult.formattedVersion).toBe('0.0.1+3'); - -}, timeout); - -test('Patch pattern increment is correct on empty repo', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}+${increment}", bumpEachCommit: true, bumpEachCommitPatchPattern: '(PATCH)' }); - +test( + "Patch pattern increment is correct on empty repo", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}+${increment}", + bumpEachCommit: true, + bumpEachCommitPatchPattern: "(PATCH)", + }); const initialResult = await repo.runAction(); - repo.makeCommit('Initial Commit'); + repo.makeCommit("Initial Commit"); const firstResult = await repo.runAction(); - repo.makeCommit('Second Commit'); + repo.makeCommit("Second Commit"); const secondResult = await repo.runAction(); - repo.makeCommit('Third Commit'); + repo.makeCommit("Third Commit"); const thirdResult = await repo.runAction(); - repo.makeCommit('fourth Commit'); + repo.makeCommit("fourth Commit"); const fourthResult = await repo.runAction(); - expect(initialResult.formattedVersion).toBe('0.0.0+0'); - expect(firstResult.formattedVersion).toBe('0.0.1+0'); - expect(secondResult.formattedVersion).toBe('0.0.1+1'); - expect(thirdResult.formattedVersion).toBe('0.0.1+2'); - expect(fourthResult.formattedVersion).toBe('0.0.1+3'); + expect(initialResult.formattedVersion).toBe("0.0.0+0"); + expect(firstResult.formattedVersion).toBe("0.0.1+0"); + expect(secondResult.formattedVersion).toBe("0.0.1+1"); + expect(thirdResult.formattedVersion).toBe("0.0.1+2"); + expect(fourthResult.formattedVersion).toBe("0.0.1+3"); + }, + timeout, +); -}, timeout); +test( + "Patch pattern increment is correct/matches non-bumped on empty repo", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}+${increment}", + bumpEachCommit: true, + bumpEachCommitPatchPattern: "(PATCH)", + }); -test('Patch pattern increment is correct/matches non-bumped on empty repo', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}+${increment}", bumpEachCommit: true, bumpEachCommitPatchPattern: '(PATCH)' }); - - - repo.makeCommit('Initial Commit'); + repo.makeCommit("Initial Commit"); const firstResult = await repo.runAction(); - repo.makeCommit('Second Commit'); + repo.makeCommit("Second Commit"); const secondResult = await repo.runAction(); - repo.makeCommit('Third Commit'); + repo.makeCommit("Third Commit"); const thirdResult = await repo.runAction(); - repo.makeCommit('fourth Commit'); + repo.makeCommit("fourth Commit"); const fourthResult = await repo.runAction(); - expect(firstResult.formattedVersion).toBe('0.0.1+0'); - expect(secondResult.formattedVersion).toBe('0.0.1+1'); - expect(thirdResult.formattedVersion).toBe('0.0.1+2'); - expect(fourthResult.formattedVersion).toBe('0.0.1+3'); + expect(firstResult.formattedVersion).toBe("0.0.1+0"); + expect(secondResult.formattedVersion).toBe("0.0.1+1"); + expect(thirdResult.formattedVersion).toBe("0.0.1+2"); + expect(fourthResult.formattedVersion).toBe("0.0.1+3"); + }, + timeout, +); -}, timeout); +test( + "Patch pattern applied when present using tag as initial version", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}+${increment}", + bumpEachCommit: true, + bumpEachCommitPatchPattern: "(PATCH)", + }); -test('Patch pattern applied when present using tag as initial version', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}+${increment}", bumpEachCommit: true, bumpEachCommitPatchPattern: '(PATCH)' }); - - - repo.makeCommit('Initial Commit'); - repo.exec('git tag 1.0.1'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag 1.0.1"); const firstResult = await repo.runAction(); // 1.0.1+0 - repo.makeCommit('Second Commit'); + repo.makeCommit("Second Commit"); const secondResult = await repo.runAction(); // 1.0.1+1 - repo.makeCommit('Third Commit (PATCH)'); + repo.makeCommit("Third Commit (PATCH)"); const thirdResult = await repo.runAction(); // 1.0.2+0 - repo.makeCommit('fourth Commit'); + repo.makeCommit("fourth Commit"); const fourthResult = await repo.runAction(); // 1.0.2+1 - expect(firstResult.formattedVersion).toBe('1.0.1+0'); - expect(secondResult.formattedVersion).toBe('1.0.1+1'); - expect(thirdResult.formattedVersion).toBe('1.0.2+0'); - expect(fourthResult.formattedVersion).toBe('1.0.2+1'); + expect(firstResult.formattedVersion).toBe("1.0.1+0"); + expect(secondResult.formattedVersion).toBe("1.0.1+1"); + expect(thirdResult.formattedVersion).toBe("1.0.2+0"); + expect(fourthResult.formattedVersion).toBe("1.0.2+1"); + }, + timeout, +); -}, timeout); +test( + "Current commit is provided", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}", + }); -test('Current commit is provided', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}" }); - - repo.makeCommit('Initial Commit'); - repo.makeCommit('Second Commit'); - repo.makeCommit('Third Commit'); - repo.makeCommit('fourth Commit'); - repo.exec('git tag 0.0.1'); + repo.makeCommit("Initial Commit"); + repo.makeCommit("Second Commit"); + repo.makeCommit("Third Commit"); + repo.makeCommit("fourth Commit"); + repo.exec("git tag 0.0.1"); const result = await repo.runAction(); - expect(result.currentCommit).toBeTruthy(); + }, + timeout, +); -}, timeout); - -test('Prerelease tags are ignored on current commit', async () => { +test( + "Prerelease tags are ignored on current commit", + async () => { const repo = createTestRepo({ - minorPattern: '/.*/' + minorPattern: "/.*/", }); let i = 0; const validate = async (version: string, changed: boolean = true) => { - const result = await repo.runAction(); - expect(result.formattedVersion).toBe(version); - expect(result.changed).toBe(changed); - } + const result = await repo.runAction(); + expect(result.formattedVersion).toBe(version); + expect(result.changed).toBe(changed); + }; - await validate('0.0.0+0', false); + await validate("0.0.0+0", false); repo.makeCommit(`Commit ${i++}`); - await validate('0.1.0+0'); - repo.exec('git tag v0.0.0'); - await validate('0.0.0+0', false); + await validate("0.1.0+0"); + repo.exec("git tag v0.0.0"); + await validate("0.0.0+0", false); repo.makeCommit(`Commit ${i++}`); - await validate('0.1.0+0'); - repo.exec('git tag v1.0.0-rc1'); - await validate('0.1.0+0'); + await validate("0.1.0+0"); + repo.exec("git tag v1.0.0-rc1"); + await validate("0.1.0+0"); repo.makeCommit(`Commit ${i++}`); - await validate('0.1.0+1'); - repo.exec('git tag v1.0.0-rc2'); - await validate('0.1.0+1'); + await validate("0.1.0+1"); + repo.exec("git tag v1.0.0-rc2"); + await validate("0.1.0+1"); repo.makeCommit(`Commit ${i++}`); - await validate('0.1.0+2'); - repo.exec('git tag v1.0.0-rc3'); - await validate('0.1.0+2'); + await validate("0.1.0+2"); + repo.exec("git tag v1.0.0-rc3"); + await validate("0.1.0+2"); repo.makeCommit(`Commit ${i++}`); - await validate('0.1.0+3'); - repo.exec('git tag v1.0.0'); - await validate('1.0.0+0', false); + await validate("0.1.0+3"); + repo.exec("git tag v1.0.0"); + await validate("1.0.0+0", false); repo.makeCommit(`Commit ${i++}`); - await validate('1.1.0+0'); - repo.exec('git tag v1.1.0-rc2'); - await validate('1.1.0+0'); + await validate("1.1.0+0"); + repo.exec("git tag v1.1.0-rc2"); + await validate("1.1.0+0"); repo.makeCommit(`Commit ${i++}`); - await validate('1.1.0+1'); - repo.exec('git tag v1.1.0-rc4'); - await validate('1.1.0+1'); + await validate("1.1.0+1"); + repo.exec("git tag v1.1.0-rc4"); + await validate("1.1.0+1"); repo.makeCommit(`Commit ${i++}`); - await validate('1.1.0+2'); - repo.exec('git tag v1.1.0-rc8'); - await validate('1.1.0+2'); + await validate("1.1.0+2"); + repo.exec("git tag v1.1.0-rc8"); + await validate("1.1.0+2"); repo.makeCommit(`Commit ${i++}`); - await validate('1.1.0+3'); - repo.exec('git tag v1.1.0-rc9'); - await validate('1.1.0+3'); + await validate("1.1.0+3"); + repo.exec("git tag v1.1.0-rc9"); + await validate("1.1.0+3"); repo.makeCommit(`Commit ${i++}`); - await validate('1.1.0+4'); -}, timeout); + await validate("1.1.0+4"); + }, + timeout, +); -test('Pre-release mode does not update major version if major version is 0', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}", enablePrereleaseMode: true }); - - repo.makeCommit('Initial Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.1'); - repo.makeCommit('Second Commit (MINOR)'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.1'); - repo.makeCommit('Third Commit (MAJOR)'); - expect((await repo.runAction()).formattedVersion).toBe('0.1.0'); - repo.exec('git tag 0.1.0'); - repo.makeCommit('Fourth Commit (MAJOR)'); - expect((await repo.runAction()).formattedVersion).toBe('0.2.0'); -}, timeout); - -test('Pre-release mode updates major version if major version is not 0', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}", enablePrereleaseMode: true }); - - repo.makeCommit('Initial Commit'); - repo.exec('git tag 1.0.0'); - repo.makeCommit('Second Commit'); - expect((await repo.runAction()).formattedVersion).toBe('1.0.1'); - repo.makeCommit('Third Commit (MINOR)'); - expect((await repo.runAction()).formattedVersion).toBe('1.1.0'); - repo.makeCommit('Fourth Commit (MAJOR)'); - expect((await repo.runAction()).formattedVersion).toBe('2.0.0'); - repo.exec('git tag 2.0.0'); - repo.makeCommit('Fifth Commit (MAJOR)'); - expect((await repo.runAction()).formattedVersion).toBe('3.0.0'); -}, timeout); - -test('Tagged commit is flagged as release', async () => { - const repo = createTestRepo({ tagPrefix: 'v', versionFormat: "${major}.${minor}.${patch}-prerelease.${increment}", enablePrereleaseMode: true }); - - repo.makeCommit('Initial Commit'); - repo.exec('git tag v1.0.0'); - var result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.0.0-prerelease.0'); - expect(result.isTagged).toBe(true); - - repo.makeCommit('Second Commit'); - result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.0.1-prerelease.0') - expect(result.isTagged).toBe(false); - - repo.makeCommit('Third Commit (MINOR)'); - result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.1.0-prerelease.0'); - expect(result.isTagged).toBe(false); - - repo.makeCommit('Fourth Commit (MINOR)'); - repo.exec('git tag v1.1.0') - result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.1.0-prerelease.1'); - expect(result.isTagged).toBe(true); -}, timeout); - - -test('Pre-release mode with bump each commit does not update major version if major version is 0', async () => { - const repo = createTestRepo({ tagPrefix: '', versionFormat: "${major}.${minor}.${patch}", enablePrereleaseMode: true, bumpEachCommit: true }); - - repo.makeCommit('Initial Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.1'); - repo.makeCommit('Second Commit (MINOR)'); - expect((await repo.runAction()).formattedVersion).toBe('0.1.0'); - repo.makeCommit('Third Commit (MAJOR)'); - expect((await repo.runAction()).formattedVersion).toBe('0.2.0'); - repo.exec('git tag 0.1.0'); - repo.makeCommit('Fourth Commit (MAJOR)'); - expect((await repo.runAction()).formattedVersion).toBe('0.2.0'); -}, timeout); - -test('Pre-release mode with bump each commit does not update major version if major version is 0, respecting patch pattern', async () => { +test( + "Pre-release mode does not update major version if major version is 0", + async () => { const repo = createTestRepo({ - tagPrefix: '', - versionFormat: "${major}.${minor}.${patch}.${increment}", - enablePrereleaseMode: true, - bumpEachCommit: true, - bumpEachCommitPatchPattern: '(PATCH)', + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}", + enablePrereleaseMode: true, }); - repo.makeCommit('Initial Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.1.0'); - repo.makeCommit('Second Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.1.1'); - repo.makeCommit('Third Commit'); - expect((await repo.runAction()).formattedVersion).toBe('0.0.1.2'); - repo.makeCommit('Fourth Commit (MAJOR)'); - expect((await repo.runAction()).formattedVersion).toBe('0.1.0.0'); -}, timeout); + repo.makeCommit("Initial Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.1"); + repo.makeCommit("Second Commit (MINOR)"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.1"); + repo.makeCommit("Third Commit (MAJOR)"); + expect((await repo.runAction()).formattedVersion).toBe("0.1.0"); + repo.exec("git tag 0.1.0"); + repo.makeCommit("Fourth Commit (MAJOR)"); + expect((await repo.runAction()).formattedVersion).toBe("0.2.0"); + }, + timeout, +); +test( + "Pre-release mode updates major version if major version is not 0", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}", + enablePrereleaseMode: true, + }); -test('Highest tag is chosen when multiple tags are present', async () => { - const repo = createTestRepo(); + repo.makeCommit("Initial Commit"); + repo.exec("git tag 1.0.0"); + repo.makeCommit("Second Commit"); + expect((await repo.runAction()).formattedVersion).toBe("1.0.1"); + repo.makeCommit("Third Commit (MINOR)"); + expect((await repo.runAction()).formattedVersion).toBe("1.1.0"); + repo.makeCommit("Fourth Commit (MAJOR)"); + expect((await repo.runAction()).formattedVersion).toBe("2.0.0"); + repo.exec("git tag 2.0.0"); + repo.makeCommit("Fifth Commit (MAJOR)"); + expect((await repo.runAction()).formattedVersion).toBe("3.0.0"); + }, + timeout, +); - repo.makeCommit('Initial Commit'); - repo.exec('git tag v2.0.0'); - repo.exec('git tag v1.0.0'); - repo.exec('git tag v1.5.0'); +test( + "Tagged commit is flagged as release", + async () => { + const repo = createTestRepo({ + tagPrefix: "v", + versionFormat: "${major}.${minor}.${patch}-prerelease.${increment}", + enablePrereleaseMode: true, + }); + + repo.makeCommit("Initial Commit"); + repo.exec("git tag v1.0.0"); var result = await repo.runAction(); - expect(result.formattedVersion).toBe('2.0.0+0'); + expect(result.formattedVersion).toBe("1.0.0-prerelease.0"); + expect(result.isTagged).toBe(true); - repo.exec('git tag v3.0.0'); - repo.exec('git tag v2.1.0'); + repo.makeCommit("Second Commit"); result = await repo.runAction(); - expect(result.formattedVersion).toBe('3.0.0+0'); + expect(result.formattedVersion).toBe("1.0.1-prerelease.0"); + expect(result.isTagged).toBe(false); - repo.makeCommit('Additional Commit'); + repo.makeCommit("Third Commit (MINOR)"); result = await repo.runAction(); - expect(result.formattedVersion).toBe('3.0.1+0'); + expect(result.formattedVersion).toBe("1.1.0-prerelease.0"); + expect(result.isTagged).toBe(false); -}, timeout); + repo.makeCommit("Fourth Commit (MINOR)"); + repo.exec("git tag v1.1.0"); + result = await repo.runAction(); + expect(result.formattedVersion).toBe("1.1.0-prerelease.1"); + expect(result.isTagged).toBe(true); + }, + timeout, +); +test( + "Pre-release mode with bump each commit does not update major version if major version is 0", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}", + enablePrereleaseMode: true, + bumpEachCommit: true, + }); -test('Debug records and replays expected data', async () => { + repo.makeCommit("Initial Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.1"); + repo.makeCommit("Second Commit (MINOR)"); + expect((await repo.runAction()).formattedVersion).toBe("0.1.0"); + repo.makeCommit("Third Commit (MAJOR)"); + expect((await repo.runAction()).formattedVersion).toBe("0.2.0"); + repo.exec("git tag 0.1.0"); + repo.makeCommit("Fourth Commit (MAJOR)"); + expect((await repo.runAction()).formattedVersion).toBe("0.2.0"); + }, + timeout, +); + +test( + "Pre-release mode with bump each commit does not update major version if major version is 0, respecting patch pattern", + async () => { + const repo = createTestRepo({ + tagPrefix: "", + versionFormat: "${major}.${minor}.${patch}.${increment}", + enablePrereleaseMode: true, + bumpEachCommit: true, + bumpEachCommitPatchPattern: "(PATCH)", + }); + + repo.makeCommit("Initial Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.1.0"); + repo.makeCommit("Second Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.1.1"); + repo.makeCommit("Third Commit"); + expect((await repo.runAction()).formattedVersion).toBe("0.0.1.2"); + repo.makeCommit("Fourth Commit (MAJOR)"); + expect((await repo.runAction()).formattedVersion).toBe("0.1.0.0"); + }, + timeout, +); + +test( + "Highest tag is chosen when multiple tags are present", + async () => { const repo = createTestRepo(); - repo.makeCommit('Initial Commit'); - repo.exec('git tag v3.0.0'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag v2.0.0"); + repo.exec("git tag v1.0.0"); + repo.exec("git tag v1.5.0"); + var result = await repo.runAction(); + expect(result.formattedVersion).toBe("2.0.0+0"); + + repo.exec("git tag v3.0.0"); + repo.exec("git tag v2.1.0"); + result = await repo.runAction(); + expect(result.formattedVersion).toBe("3.0.0+0"); + + repo.makeCommit("Additional Commit"); + result = await repo.runAction(); + expect(result.formattedVersion).toBe("3.0.1+0"); + }, + timeout, +); + +test( + "Debug records and replays expected data", + async () => { + const repo = createTestRepo(); + + repo.makeCommit("Initial Commit"); + repo.exec("git tag v3.0.0"); repo.makeCommit(`Second Commit`); const result = await repo.runAction({ debug: true }); repo.makeCommit(`Breaking Commit`); - repo.exec('git tag v9.9.9'); + repo.exec("git tag v9.9.9"); var replayResult = await repo.runAction({ replay: result.debugOutput }); @@ -1081,31 +1386,37 @@ test('Debug records and replays expected data', async () => { expect(replayResult.minor).toBe(result.minor); expect(replayResult.patch).toBe(result.patch); expect(replayResult.increment).toBe(result.increment); + }, + timeout, +); -}, timeout); - -test('Version branch using major version ignores other tags', async () => { +test( + "Version branch using major version ignores other tags", + async () => { const repo = createTestRepo({ versionFromBranch: true }); - repo.makeCommit('Initial Commit'); + repo.makeCommit("Initial Commit"); repo.makeCommit(`Second Commit`); repo.exec("git checkout -b release/v3"); - repo.exec('git tag v3.0.0'); + repo.exec("git tag v3.0.0"); repo.makeCommit(`Third Commit`); - repo.exec('git tag v4.0.0'); + repo.exec("git tag v4.0.0"); repo.makeCommit(`Fourth Commit`); repo.makeCommit(`Fifth Commit`); const result = await repo.runAction(); - expect(result.formattedVersion).toBe('3.0.1+2'); + expect(result.formattedVersion).toBe("3.0.1+2"); + }, + timeout, +); -}, timeout); - -test('Versioning from branch always takes version from branch name even without tags', async () => { +test( + "Versioning from branch always takes version from branch name even without tags", + async () => { const repo = createTestRepo({ versionFromBranch: true }); - repo.makeCommit('Initial Commit'); + repo.makeCommit("Initial Commit"); repo.makeCommit(`Second Commit`); repo.exec("git checkout -b release/v3.2"); repo.makeCommit(`Third Commit`); @@ -1114,33 +1425,41 @@ test('Versioning from branch always takes version from branch name even without const result = await repo.runAction(); - expect(result.formattedVersion).toBe('3.2.1+4'); + expect(result.formattedVersion).toBe("3.2.1+4"); + }, + timeout, +); -}, timeout); +test( + "Prerelease mode does not increment to 1.x.x", + async () => { + const repo = createTestRepo({ + tagPrefix: "v", + versionFormat: "${major}.${minor}.${patch}-prerelease.${increment}", + enablePrereleaseMode: true, + }); - -test('Prerelease mode does not increment to 1.x.x', async () => { - const repo = createTestRepo({ tagPrefix: 'v', versionFormat: "${major}.${minor}.${patch}-prerelease.${increment}", enablePrereleaseMode: true }); - - repo.makeCommit('Initial Commit'); - repo.exec('git tag v1.0.0'); + repo.makeCommit("Initial Commit"); + repo.exec("git tag v1.0.0"); var result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.0.0-prerelease.0'); + expect(result.formattedVersion).toBe("1.0.0-prerelease.0"); expect(result.isTagged).toBe(true); - repo.makeCommit('Second Commit'); + repo.makeCommit("Second Commit"); result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.0.1-prerelease.0') + expect(result.formattedVersion).toBe("1.0.1-prerelease.0"); expect(result.isTagged).toBe(false); - repo.makeCommit('Third Commit (MINOR)'); + repo.makeCommit("Third Commit (MINOR)"); result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.1.0-prerelease.0'); + expect(result.formattedVersion).toBe("1.1.0-prerelease.0"); expect(result.isTagged).toBe(false); - repo.makeCommit('Fourth Commit (MINOR)'); - repo.exec('git tag v1.1.0') + repo.makeCommit("Fourth Commit (MINOR)"); + repo.exec("git tag v1.1.0"); result = await repo.runAction(); - expect(result.formattedVersion).toBe('1.1.0-prerelease.1'); + expect(result.formattedVersion).toBe("1.1.0-prerelease.1"); expect(result.isTagged).toBe(true); -}, timeout); \ No newline at end of file + }, + timeout, +); diff --git a/src/main.ts b/src/main.ts index b35d605..d8d5e6f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,23 +1,40 @@ -import { runAction } from './action'; -import { ActionConfig } from './ActionConfig'; -import { ConfigurationProvider } from './ConfigurationProvider'; -import { VersionResult } from './VersionResult'; -import * as core from '@actions/core'; -import { VersionType } from './providers/VersionType'; +import { runAction } from "./action"; +import { ActionConfig } from "./ActionConfig"; +import { ConfigurationProvider } from "./ConfigurationProvider"; +import { VersionResult } from "./VersionResult"; +import * as core from "@actions/core"; +import { VersionType } from "./providers/VersionType"; function setOutput(versionResult: VersionResult) { - const { major, minor, patch, increment, versionType, formattedVersion, versionTag, changed, isTagged, authors, currentCommit, previousCommit, previousVersion, debugOutput } = versionResult; + const { + major, + minor, + patch, + increment, + versionType, + formattedVersion, + versionTag, + changed, + isTagged, + authors, + currentCommit, + previousCommit, + previousVersion, + debugOutput, + } = versionResult; const repository = process.env.GITHUB_REPOSITORY; if (!changed) { - core.info("VAGOOO1") - core.info('No changes detected for this commit'); + core.info("VAGOOO1"); + core.info("No changes detected for this commit"); } core.info(`Version is ${formattedVersion}`); if (repository !== undefined) { - core.info(`To create a release for this version, go to https://github.com/${repository}/releases/new?tag=${versionTag}&target=${currentCommit.split('/').slice(-1)[0]}`); + core.info( + `To create a release for this version, go to https://github.com/${repository}/releases/new?tag=${versionTag}&target=${currentCommit.split("/").slice(-1)[0]}`, + ); } core.setOutput("version", formattedVersion); @@ -37,57 +54,60 @@ function setOutput(versionResult: VersionResult) { } export async function run() { - core.info("VAGO Starting run action..."); function toBool(value: string): boolean { - if (!value || value.toLowerCase() === 'false') { + if (!value || value.toLowerCase() === "false") { return false; - } else if (value.toLowerCase() === 'true') { + } else if (value.toLowerCase() === "true") { return true; } return false; } - + function toStringOrBool(value: string): string | boolean { - if (!value || value === 'false') { + if (!value || value === "false") { return false; } - if (value === 'true') { + if (value === "true") { return true; } return value; - } + } const config: ActionConfig = { - branch: core.getInput('branch'), - tagPrefix: core.getInput('tag_prefix'), - useBranches: toBool(core.getInput('use_branches')), - versionFromBranch: toStringOrBool(core.getInput('version_from_branch')), - majorPattern: core.getInput('major_pattern'), - minorPattern: core.getInput('minor_pattern'), - majorFlags: core.getInput('major_regexp_flags'), - minorFlags: core.getInput('minor_regexp_flags'), - versionFormat: core.getInput('version_format'), - changePath: core.getInput('change_path'), - namespace: core.getInput('namespace'), - bumpEachCommit: toBool(core.getInput('bump_each_commit')), - searchCommitBody: toBool(core.getInput('search_commit_body')), - userFormatType: core.getInput('user_format_type'), - enablePrereleaseMode: toBool(core.getInput('enable_prerelease_mode')), - bumpEachCommitPatchPattern: core.getInput('bump_each_commit_patch_pattern'), - debug: toBool(core.getInput('debug')), - replay: '' + branch: core.getInput("branch"), + tagPrefix: core.getInput("tag_prefix"), + useBranches: toBool(core.getInput("use_branches")), + versionFromBranch: toStringOrBool(core.getInput("version_from_branch")), + majorPattern: core.getInput("major_pattern"), + minorPattern: core.getInput("minor_pattern"), + majorFlags: core.getInput("major_regexp_flags"), + minorFlags: core.getInput("minor_regexp_flags"), + versionFormat: core.getInput("version_format"), + changePath: core.getInput("change_path"), + namespace: core.getInput("namespace"), + bumpEachCommit: toBool(core.getInput("bump_each_commit")), + searchCommitBody: toBool(core.getInput("search_commit_body")), + userFormatType: core.getInput("user_format_type"), + enablePrereleaseMode: toBool(core.getInput("enable_prerelease_mode")), + bumpEachCommitPatchPattern: core.getInput("bump_each_commit_patch_pattern"), + debug: toBool(core.getInput("debug")), + replay: "", }; if (config.useBranches) { - core.warning(`The 'use_branches' input option is deprecated, please see the documentation for more information on how to use branches`); + core.warning( + `The 'use_branches' input option is deprecated, please see the documentation for more information on how to use branches`, + ); } - if (config.versionFormat === '' && core.getInput('format') !== '') { - core.warning(`The 'format' input is deprecated, use 'versionFormat' instead`); - config.versionFormat = core.getInput('format'); + if (config.versionFormat === "" && core.getInput("format") !== "") { + core.warning( + `The 'format' input is deprecated, use 'versionFormat' instead`, + ); + config.versionFormat = core.getInput("format"); } - if (core.getInput('short_tags') !== '') { + if (core.getInput("short_tags") !== "") { core.warning(`The 'short_tags' input option is no longer supported`); } @@ -98,4 +118,4 @@ export async function run() { setOutput(result); } -run(); \ No newline at end of file +run();