package-versioner 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/index.cjs +21 -19
- package/dist/index.js +21 -19
- package/docs/CI_CD_INTEGRATION.md +18 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ Customize behavior by creating a `version.config.json` file in your project root
|
|
|
87
87
|
"versionPrefix": "v",
|
|
88
88
|
"tagTemplate": "${prefix}${version}",
|
|
89
89
|
"packageTagTemplate": "${packageName}@${prefix}${version}",
|
|
90
|
-
"commitMessage": "chore(release): {
|
|
90
|
+
"commitMessage": "chore(release): ${version}",
|
|
91
91
|
"monorepo": {
|
|
92
92
|
"synced": true,
|
|
93
93
|
"skip": [
|
|
@@ -99,7 +99,10 @@ Customize behavior by creating a `version.config.json` file in your project root
|
|
|
99
99
|
}
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
**
|
|
102
|
+
**Notes:**
|
|
103
|
+
- Options like `synced`, `packages`, and `updateInternalDependencies` enable monorepo-specific behaviours.
|
|
104
|
+
- The `tagTemplate` and `packageTagTemplate` allow you to customize how Git tags are formatted for releases.
|
|
105
|
+
- The `commitMessage` template can include CI skip tokens like `[skip ci]` if you want to prevent CI runs after version commits (e.g., `"commitMessage": "chore(release): ${version} [skip ci]"`). See [CI/CD Integration](./docs/CI_CD_INTEGRATION.md) for more details.
|
|
103
106
|
|
|
104
107
|
## How Versioning Works
|
|
105
108
|
|
package/dist/index.cjs
CHANGED
|
@@ -334,7 +334,7 @@ function formatTag(version, versionPrefix, packageName, tagTemplate = "${prefix}
|
|
|
334
334
|
const template = packageName ? packageTagTemplate : tagTemplate;
|
|
335
335
|
return createTemplateString(template, variables);
|
|
336
336
|
}
|
|
337
|
-
function
|
|
337
|
+
function formatVersionPrefix(versionPrefix, scope) {
|
|
338
338
|
if (!versionPrefix) return "";
|
|
339
339
|
const cleanPrefix = versionPrefix.replace(/\/$/, "");
|
|
340
340
|
if (scope) {
|
|
@@ -395,12 +395,12 @@ async function lastMergeBranchName(branches, baseBranch) {
|
|
|
395
395
|
return null;
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
|
-
async function getLatestTagForPackage(packageName,
|
|
398
|
+
async function getLatestTagForPackage(packageName, versionPrefix) {
|
|
399
399
|
try {
|
|
400
400
|
const allTags = await (0, import_git_semver_tags.getSemverTags)({
|
|
401
|
-
tagPrefix
|
|
401
|
+
tagPrefix: versionPrefix
|
|
402
402
|
});
|
|
403
|
-
const packageTagPattern =
|
|
403
|
+
const packageTagPattern = versionPrefix ? new RegExp(`^${escapeRegExp(versionPrefix)}${escapeRegExp(packageName)}@`) : new RegExp(`^${escapeRegExp(packageName)}@`);
|
|
404
404
|
const packageTags = allTags.filter((tag) => packageTagPattern.test(tag));
|
|
405
405
|
return packageTags[0] || "";
|
|
406
406
|
} catch (error) {
|
|
@@ -446,11 +446,11 @@ var import_node_process3 = require("process");
|
|
|
446
446
|
var import_conventional_recommended_bump = require("conventional-recommended-bump");
|
|
447
447
|
var import_semver = __toESM(require("semver"), 1);
|
|
448
448
|
var STANDARD_BUMP_TYPES = ["major", "minor", "patch"];
|
|
449
|
-
async function calculateVersion(config, options
|
|
449
|
+
async function calculateVersion(config, options) {
|
|
450
450
|
const { latestTag, type, path: pkgPath, name, branchPattern } = options;
|
|
451
451
|
const { preset } = config;
|
|
452
|
-
const
|
|
453
|
-
const prereleaseIdentifier = options.prereleaseIdentifier ||
|
|
452
|
+
const originalPrefix = options.versionPrefix || "";
|
|
453
|
+
const prereleaseIdentifier = options.prereleaseIdentifier || config.prereleaseIdentifier;
|
|
454
454
|
const initialVersion = prereleaseIdentifier ? `0.0.1-${prereleaseIdentifier}` : "0.0.1";
|
|
455
455
|
const hasNoTags = !latestTag || latestTag === "";
|
|
456
456
|
function determineTagSearchPattern(packageName, prefix) {
|
|
@@ -459,9 +459,9 @@ async function calculateVersion(config, options, forcedType, configPrereleaseIde
|
|
|
459
459
|
}
|
|
460
460
|
return prefix;
|
|
461
461
|
}
|
|
462
|
-
const tagSearchPattern = determineTagSearchPattern(name,
|
|
462
|
+
const tagSearchPattern = determineTagSearchPattern(name, originalPrefix);
|
|
463
463
|
const escapedTagPattern = escapeRegExp(tagSearchPattern);
|
|
464
|
-
const specifiedType =
|
|
464
|
+
const specifiedType = type;
|
|
465
465
|
if (specifiedType) {
|
|
466
466
|
if (hasNoTags) {
|
|
467
467
|
return getPackageVersionFallback(
|
|
@@ -681,7 +681,7 @@ var PackageProcessor = class {
|
|
|
681
681
|
for (const pkg of pkgsToConsider) {
|
|
682
682
|
const name = pkg.packageJson.name;
|
|
683
683
|
const pkgPath = pkg.dir;
|
|
684
|
-
const formattedPrefix =
|
|
684
|
+
const formattedPrefix = formatVersionPrefix(this.versionPrefix);
|
|
685
685
|
let latestTagResult = "";
|
|
686
686
|
try {
|
|
687
687
|
latestTagResult = await getLatestTagForPackage(name, this.versionPrefix);
|
|
@@ -713,7 +713,7 @@ var PackageProcessor = class {
|
|
|
713
713
|
branchPattern: this.config.branchPattern,
|
|
714
714
|
baseBranch: this.config.baseBranch,
|
|
715
715
|
prereleaseIdentifier: this.config.prereleaseIdentifier,
|
|
716
|
-
type: this.config.
|
|
716
|
+
type: this.config.type
|
|
717
717
|
});
|
|
718
718
|
if (!nextVersion) {
|
|
719
719
|
continue;
|
|
@@ -758,7 +758,6 @@ var PackageProcessor = class {
|
|
|
758
758
|
} else {
|
|
759
759
|
commitMessage = `chore(release): ${packageNames} ${representativeVersion}`;
|
|
760
760
|
}
|
|
761
|
-
commitMessage += " [skip-ci]";
|
|
762
761
|
setCommitMessage(commitMessage);
|
|
763
762
|
if (!this.dryRun) {
|
|
764
763
|
try {
|
|
@@ -810,14 +809,15 @@ function createSyncedStrategy(config) {
|
|
|
810
809
|
dryRun,
|
|
811
810
|
skipHooks
|
|
812
811
|
} = config;
|
|
813
|
-
const formattedPrefix =
|
|
812
|
+
const formattedPrefix = formatVersionPrefix(versionPrefix || "v");
|
|
814
813
|
const latestTag = await getLatestTag();
|
|
815
814
|
const nextVersion = await calculateVersion(config, {
|
|
816
815
|
latestTag,
|
|
817
816
|
versionPrefix: formattedPrefix,
|
|
818
817
|
branchPattern,
|
|
819
818
|
baseBranch,
|
|
820
|
-
prereleaseIdentifier
|
|
819
|
+
prereleaseIdentifier,
|
|
820
|
+
type: config.type
|
|
821
821
|
});
|
|
822
822
|
if (!nextVersion) {
|
|
823
823
|
log("No version change needed", "info");
|
|
@@ -888,7 +888,7 @@ function createSingleStrategy(config) {
|
|
|
888
888
|
throw createVersionError("PACKAGE_NOT_FOUND" /* PACKAGE_NOT_FOUND */, packageName);
|
|
889
889
|
}
|
|
890
890
|
const pkgPath = pkg.dir;
|
|
891
|
-
const formattedPrefix =
|
|
891
|
+
const formattedPrefix = formatVersionPrefix(versionPrefix || "v");
|
|
892
892
|
let latestTagResult = await getLatestTagForPackage(packageName, formattedPrefix);
|
|
893
893
|
if (!latestTagResult) {
|
|
894
894
|
const globalTagResult = await getLatestTag();
|
|
@@ -901,7 +901,8 @@ function createSingleStrategy(config) {
|
|
|
901
901
|
latestTag,
|
|
902
902
|
versionPrefix: formattedPrefix,
|
|
903
903
|
path: pkgPath,
|
|
904
|
-
name: packageName
|
|
904
|
+
name: packageName,
|
|
905
|
+
type: config.type
|
|
905
906
|
});
|
|
906
907
|
} catch (error) {
|
|
907
908
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -958,11 +959,12 @@ function createAsyncStrategy(config) {
|
|
|
958
959
|
skipHooks: config.skipHooks || false,
|
|
959
960
|
getLatestTag: dependencies.getLatestTag,
|
|
960
961
|
fullConfig: config,
|
|
962
|
+
// Extract common version configuration properties
|
|
961
963
|
config: {
|
|
962
964
|
branchPattern: config.branchPattern || [],
|
|
963
965
|
baseBranch: config.baseBranch || "main",
|
|
964
966
|
prereleaseIdentifier: config.prereleaseIdentifier,
|
|
965
|
-
|
|
967
|
+
type: config.type
|
|
966
968
|
}
|
|
967
969
|
};
|
|
968
970
|
const packageProcessor = new PackageProcessor(processorOptions);
|
|
@@ -1093,7 +1095,7 @@ async function run() {
|
|
|
1093
1095
|
).version(process.env.npm_package_version || "0.0.0").option(
|
|
1094
1096
|
"-c, --config <path>",
|
|
1095
1097
|
"Path to config file (defaults to version.config.json in current directory)"
|
|
1096
|
-
).option("-d, --dry-run", "Dry run (no changes made)", false).option("-b, --bump <type>", "
|
|
1098
|
+
).option("-d, --dry-run", "Dry run (no changes made)", false).option("-b, --bump <type>", "Specify bump type (patch|minor|major)").option("-p, --prerelease [identifier]", "Create prerelease version").option("-s, --synced", "Use synchronized versioning across all packages").option("-j, --json", "Output results as JSON", false).option("-t, --target <packages>", "Comma-delimited list of package names to target").parse(process.argv);
|
|
1097
1099
|
const options = program.opts();
|
|
1098
1100
|
if (options.json) {
|
|
1099
1101
|
enableJsonOutput(options.dryRun);
|
|
@@ -1103,7 +1105,7 @@ async function run() {
|
|
|
1103
1105
|
log(`Loaded configuration from ${options.config || "version.config.json"}`, "info");
|
|
1104
1106
|
if (options.dryRun) config.dryRun = true;
|
|
1105
1107
|
if (options.synced) config.synced = true;
|
|
1106
|
-
if (options.bump) config.
|
|
1108
|
+
if (options.bump) config.type = options.bump;
|
|
1107
1109
|
if (options.prerelease)
|
|
1108
1110
|
config.prereleaseIdentifier = options.prerelease === true ? "rc" : options.prerelease;
|
|
1109
1111
|
const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
|
package/dist/index.js
CHANGED
|
@@ -311,7 +311,7 @@ function formatTag(version, versionPrefix, packageName, tagTemplate = "${prefix}
|
|
|
311
311
|
const template = packageName ? packageTagTemplate : tagTemplate;
|
|
312
312
|
return createTemplateString(template, variables);
|
|
313
313
|
}
|
|
314
|
-
function
|
|
314
|
+
function formatVersionPrefix(versionPrefix, scope) {
|
|
315
315
|
if (!versionPrefix) return "";
|
|
316
316
|
const cleanPrefix = versionPrefix.replace(/\/$/, "");
|
|
317
317
|
if (scope) {
|
|
@@ -372,12 +372,12 @@ async function lastMergeBranchName(branches, baseBranch) {
|
|
|
372
372
|
return null;
|
|
373
373
|
}
|
|
374
374
|
}
|
|
375
|
-
async function getLatestTagForPackage(packageName,
|
|
375
|
+
async function getLatestTagForPackage(packageName, versionPrefix) {
|
|
376
376
|
try {
|
|
377
377
|
const allTags = await getSemverTags({
|
|
378
|
-
tagPrefix
|
|
378
|
+
tagPrefix: versionPrefix
|
|
379
379
|
});
|
|
380
|
-
const packageTagPattern =
|
|
380
|
+
const packageTagPattern = versionPrefix ? new RegExp(`^${escapeRegExp(versionPrefix)}${escapeRegExp(packageName)}@`) : new RegExp(`^${escapeRegExp(packageName)}@`);
|
|
381
381
|
const packageTags = allTags.filter((tag) => packageTagPattern.test(tag));
|
|
382
382
|
return packageTags[0] || "";
|
|
383
383
|
} catch (error) {
|
|
@@ -422,11 +422,11 @@ import { cwd as cwd3 } from "node:process";
|
|
|
422
422
|
import { Bumper } from "conventional-recommended-bump";
|
|
423
423
|
import semver from "semver";
|
|
424
424
|
var STANDARD_BUMP_TYPES = ["major", "minor", "patch"];
|
|
425
|
-
async function calculateVersion(config, options
|
|
425
|
+
async function calculateVersion(config, options) {
|
|
426
426
|
const { latestTag, type, path: pkgPath, name, branchPattern } = options;
|
|
427
427
|
const { preset } = config;
|
|
428
|
-
const
|
|
429
|
-
const prereleaseIdentifier = options.prereleaseIdentifier ||
|
|
428
|
+
const originalPrefix = options.versionPrefix || "";
|
|
429
|
+
const prereleaseIdentifier = options.prereleaseIdentifier || config.prereleaseIdentifier;
|
|
430
430
|
const initialVersion = prereleaseIdentifier ? `0.0.1-${prereleaseIdentifier}` : "0.0.1";
|
|
431
431
|
const hasNoTags = !latestTag || latestTag === "";
|
|
432
432
|
function determineTagSearchPattern(packageName, prefix) {
|
|
@@ -435,9 +435,9 @@ async function calculateVersion(config, options, forcedType, configPrereleaseIde
|
|
|
435
435
|
}
|
|
436
436
|
return prefix;
|
|
437
437
|
}
|
|
438
|
-
const tagSearchPattern = determineTagSearchPattern(name,
|
|
438
|
+
const tagSearchPattern = determineTagSearchPattern(name, originalPrefix);
|
|
439
439
|
const escapedTagPattern = escapeRegExp(tagSearchPattern);
|
|
440
|
-
const specifiedType =
|
|
440
|
+
const specifiedType = type;
|
|
441
441
|
if (specifiedType) {
|
|
442
442
|
if (hasNoTags) {
|
|
443
443
|
return getPackageVersionFallback(
|
|
@@ -657,7 +657,7 @@ var PackageProcessor = class {
|
|
|
657
657
|
for (const pkg of pkgsToConsider) {
|
|
658
658
|
const name = pkg.packageJson.name;
|
|
659
659
|
const pkgPath = pkg.dir;
|
|
660
|
-
const formattedPrefix =
|
|
660
|
+
const formattedPrefix = formatVersionPrefix(this.versionPrefix);
|
|
661
661
|
let latestTagResult = "";
|
|
662
662
|
try {
|
|
663
663
|
latestTagResult = await getLatestTagForPackage(name, this.versionPrefix);
|
|
@@ -689,7 +689,7 @@ var PackageProcessor = class {
|
|
|
689
689
|
branchPattern: this.config.branchPattern,
|
|
690
690
|
baseBranch: this.config.baseBranch,
|
|
691
691
|
prereleaseIdentifier: this.config.prereleaseIdentifier,
|
|
692
|
-
type: this.config.
|
|
692
|
+
type: this.config.type
|
|
693
693
|
});
|
|
694
694
|
if (!nextVersion) {
|
|
695
695
|
continue;
|
|
@@ -734,7 +734,6 @@ var PackageProcessor = class {
|
|
|
734
734
|
} else {
|
|
735
735
|
commitMessage = `chore(release): ${packageNames} ${representativeVersion}`;
|
|
736
736
|
}
|
|
737
|
-
commitMessage += " [skip-ci]";
|
|
738
737
|
setCommitMessage(commitMessage);
|
|
739
738
|
if (!this.dryRun) {
|
|
740
739
|
try {
|
|
@@ -786,14 +785,15 @@ function createSyncedStrategy(config) {
|
|
|
786
785
|
dryRun,
|
|
787
786
|
skipHooks
|
|
788
787
|
} = config;
|
|
789
|
-
const formattedPrefix =
|
|
788
|
+
const formattedPrefix = formatVersionPrefix(versionPrefix || "v");
|
|
790
789
|
const latestTag = await getLatestTag();
|
|
791
790
|
const nextVersion = await calculateVersion(config, {
|
|
792
791
|
latestTag,
|
|
793
792
|
versionPrefix: formattedPrefix,
|
|
794
793
|
branchPattern,
|
|
795
794
|
baseBranch,
|
|
796
|
-
prereleaseIdentifier
|
|
795
|
+
prereleaseIdentifier,
|
|
796
|
+
type: config.type
|
|
797
797
|
});
|
|
798
798
|
if (!nextVersion) {
|
|
799
799
|
log("No version change needed", "info");
|
|
@@ -864,7 +864,7 @@ function createSingleStrategy(config) {
|
|
|
864
864
|
throw createVersionError("PACKAGE_NOT_FOUND" /* PACKAGE_NOT_FOUND */, packageName);
|
|
865
865
|
}
|
|
866
866
|
const pkgPath = pkg.dir;
|
|
867
|
-
const formattedPrefix =
|
|
867
|
+
const formattedPrefix = formatVersionPrefix(versionPrefix || "v");
|
|
868
868
|
let latestTagResult = await getLatestTagForPackage(packageName, formattedPrefix);
|
|
869
869
|
if (!latestTagResult) {
|
|
870
870
|
const globalTagResult = await getLatestTag();
|
|
@@ -877,7 +877,8 @@ function createSingleStrategy(config) {
|
|
|
877
877
|
latestTag,
|
|
878
878
|
versionPrefix: formattedPrefix,
|
|
879
879
|
path: pkgPath,
|
|
880
|
-
name: packageName
|
|
880
|
+
name: packageName,
|
|
881
|
+
type: config.type
|
|
881
882
|
});
|
|
882
883
|
} catch (error) {
|
|
883
884
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -934,11 +935,12 @@ function createAsyncStrategy(config) {
|
|
|
934
935
|
skipHooks: config.skipHooks || false,
|
|
935
936
|
getLatestTag: dependencies.getLatestTag,
|
|
936
937
|
fullConfig: config,
|
|
938
|
+
// Extract common version configuration properties
|
|
937
939
|
config: {
|
|
938
940
|
branchPattern: config.branchPattern || [],
|
|
939
941
|
baseBranch: config.baseBranch || "main",
|
|
940
942
|
prereleaseIdentifier: config.prereleaseIdentifier,
|
|
941
|
-
|
|
943
|
+
type: config.type
|
|
942
944
|
}
|
|
943
945
|
};
|
|
944
946
|
const packageProcessor = new PackageProcessor(processorOptions);
|
|
@@ -1069,7 +1071,7 @@ async function run() {
|
|
|
1069
1071
|
).version(process.env.npm_package_version || "0.0.0").option(
|
|
1070
1072
|
"-c, --config <path>",
|
|
1071
1073
|
"Path to config file (defaults to version.config.json in current directory)"
|
|
1072
|
-
).option("-d, --dry-run", "Dry run (no changes made)", false).option("-b, --bump <type>", "
|
|
1074
|
+
).option("-d, --dry-run", "Dry run (no changes made)", false).option("-b, --bump <type>", "Specify bump type (patch|minor|major)").option("-p, --prerelease [identifier]", "Create prerelease version").option("-s, --synced", "Use synchronized versioning across all packages").option("-j, --json", "Output results as JSON", false).option("-t, --target <packages>", "Comma-delimited list of package names to target").parse(process.argv);
|
|
1073
1075
|
const options = program.opts();
|
|
1074
1076
|
if (options.json) {
|
|
1075
1077
|
enableJsonOutput(options.dryRun);
|
|
@@ -1079,7 +1081,7 @@ async function run() {
|
|
|
1079
1081
|
log(`Loaded configuration from ${options.config || "version.config.json"}`, "info");
|
|
1080
1082
|
if (options.dryRun) config.dryRun = true;
|
|
1081
1083
|
if (options.synced) config.synced = true;
|
|
1082
|
-
if (options.bump) config.
|
|
1084
|
+
if (options.bump) config.type = options.bump;
|
|
1083
1085
|
if (options.prerelease)
|
|
1084
1086
|
config.prereleaseIdentifier = options.prerelease === true ? "rc" : options.prerelease;
|
|
1085
1087
|
const cliTargets = options.target ? options.target.split(",").map((t) => t.trim()) : [];
|
|
@@ -156,6 +156,24 @@ git push origin "v$NEW_VERSION"
|
|
|
156
156
|
- `NO_COLOR=1`: Disables colored output in logs (automatically detected in CI environments)
|
|
157
157
|
- `CI=true`: Most CI environments set this automatically, which helps the tool adjust its output behavior
|
|
158
158
|
|
|
159
|
+
## Skipping CI for Version Commits
|
|
160
|
+
|
|
161
|
+
If you want to prevent additional CI runs when version commits are made, you can include CI skip flags in your commit message template in `version.config.json`:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"commitMessage": "chore(release): ${version} [skip ci]",
|
|
166
|
+
// other configuration options...
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Common CI skip patterns include:
|
|
171
|
+
- `[skip ci]` or `[ci skip]` - Works in GitHub Actions, GitLab CI, CircleCI
|
|
172
|
+
- `[skip-ci]` - Alternative format supported by some CI systems
|
|
173
|
+
- `[no ci]` - Another variant
|
|
174
|
+
|
|
175
|
+
Each CI system might have slightly different syntax, so check your CI provider's documentation for the exact skip token to use.
|
|
176
|
+
|
|
159
177
|
## Tips for Reliable CI/CD Integration
|
|
160
178
|
|
|
161
179
|
1. **Always use `--json`** in CI/CD pipelines for consistent output parsing
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "package-versioner",
|
|
3
3
|
"description": "A lightweight yet powerful CLI tool for automated semantic versioning based on Git history and conventional commits.",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.mjs",
|