package-versioner 0.7.1 → 0.8.1
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 +110 -6
- package/dist/index.cjs +358 -134
- package/dist/index.js +358 -134
- package/docs/versioning.md +182 -16
- package/package-versioner.schema.json +10 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -138,7 +138,23 @@ function extractChangelogEntriesFromCommits(projectDir, revisionRange) {
|
|
|
138
138
|
const commits = output.split("---COMMIT_DELIMITER---").filter((commit) => commit.trim() !== "");
|
|
139
139
|
return commits.map((commit) => parseCommitMessage(commit)).filter((entry) => entry !== null);
|
|
140
140
|
} catch (error) {
|
|
141
|
-
|
|
141
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
142
|
+
if (errorMessage.includes("ambiguous argument") && errorMessage.includes("unknown revision")) {
|
|
143
|
+
const tagName = revisionRange.split("..")[0] || revisionRange;
|
|
144
|
+
if (tagName.startsWith("v") && !tagName.includes("@")) {
|
|
145
|
+
log(
|
|
146
|
+
`Error: Tag "${tagName}" not found. If you're using package-specific tags (like "package-name@v1.0.0"), you may need to configure "tagTemplate" in your version.config.json to use: \${packageName}@\${prefix}\${version}`,
|
|
147
|
+
"error"
|
|
148
|
+
);
|
|
149
|
+
} else {
|
|
150
|
+
log(
|
|
151
|
+
`Error: Tag or revision "${tagName}" not found in the repository. Please check if this tag exists or if you need to fetch it from the remote.`,
|
|
152
|
+
"error"
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
log(`Error extracting commits: ${errorMessage}`, "error");
|
|
157
|
+
}
|
|
142
158
|
return [];
|
|
143
159
|
}
|
|
144
160
|
}
|
|
@@ -783,43 +799,48 @@ async function createGitCommitAndTag(files, nextTag, commitMessage, skipHooks, d
|
|
|
783
799
|
|
|
784
800
|
// src/git/tagsAndBranches.ts
|
|
785
801
|
var import_git_semver_tags = require("git-semver-tags");
|
|
802
|
+
var import_semver = __toESM(require("semver"), 1);
|
|
786
803
|
|
|
787
804
|
// src/utils/formatting.ts
|
|
788
805
|
function escapeRegExp(string) {
|
|
789
806
|
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
790
807
|
}
|
|
791
|
-
function
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
if (
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
}
|
|
808
|
-
function formatCommitMessage(template, version, packageName, scope) {
|
|
809
|
-
return createTemplateString(template, {
|
|
810
|
-
version,
|
|
811
|
-
scope,
|
|
812
|
-
packageName: packageName || ""
|
|
813
|
-
});
|
|
808
|
+
function formatVersionPrefix(prefix) {
|
|
809
|
+
return prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
810
|
+
}
|
|
811
|
+
function formatTag(version, prefix, packageName, template, packageSpecificTags) {
|
|
812
|
+
if ((template == null ? void 0 : template.includes("${packageName}")) && !packageName) {
|
|
813
|
+
log(
|
|
814
|
+
'Warning: Your tagTemplate contains ${packageName} but no package name is available.\nThis will result in an empty package name in the tag (e.g., "@v1.0.0" instead of "my-package@v1.0.0").\n\nTo fix this:\n\u2022 If using synced mode: Set "packageSpecificTags": true in your config to enable package names in tags\n\u2022 If you want global tags: Remove ${packageName} from your tagTemplate (e.g., use "${prefix}${version}")\n\u2022 If using single/async mode: Ensure your package.json has a valid "name" field',
|
|
815
|
+
"warning"
|
|
816
|
+
);
|
|
817
|
+
}
|
|
818
|
+
if (template) {
|
|
819
|
+
return template.replace(/\$\{version\}/g, version).replace(/\$\{prefix\}/g, prefix).replace(/\$\{packageName\}/g, packageName || "");
|
|
820
|
+
}
|
|
821
|
+
if (packageSpecificTags && packageName) {
|
|
822
|
+
return `${packageName}@${prefix}${version}`;
|
|
823
|
+
}
|
|
824
|
+
return `${prefix}${version}`;
|
|
814
825
|
}
|
|
815
|
-
function
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
826
|
+
function formatCommitMessage(template, version, packageName, additionalContext) {
|
|
827
|
+
if (template.includes("${packageName}") && !packageName) {
|
|
828
|
+
log(
|
|
829
|
+
'Warning: Your commitMessage template contains ${packageName} but no package name is available.\nThis will result in an empty package name in the commit message (e.g., "Release @v1.0.0").\n\nTo fix this:\n\u2022 If using synced mode: Set "packageSpecificTags": true to enable package names in commits\n\u2022 If you want generic commit messages: Remove ${packageName} from your commitMessage template\n\u2022 If using single/async mode: Ensure your package.json has a valid "name" field',
|
|
830
|
+
"warning"
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
let result = template.replace(/\$\{version\}/g, version).replace(/\$\{packageName\}/g, packageName || "");
|
|
834
|
+
if (additionalContext) {
|
|
835
|
+
for (const [key, value] of Object.entries(additionalContext)) {
|
|
836
|
+
const placeholder = `\${${key}}`;
|
|
837
|
+
result = result.replace(
|
|
838
|
+
new RegExp(placeholder.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"),
|
|
839
|
+
value
|
|
840
|
+
);
|
|
819
841
|
}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
}, template);
|
|
842
|
+
}
|
|
843
|
+
return result;
|
|
823
844
|
}
|
|
824
845
|
|
|
825
846
|
// src/git/tagsAndBranches.ts
|
|
@@ -834,10 +855,29 @@ function getCommitsLength(pkgRoot) {
|
|
|
834
855
|
return 0;
|
|
835
856
|
}
|
|
836
857
|
}
|
|
837
|
-
async function getLatestTag() {
|
|
858
|
+
async function getLatestTag(versionPrefix) {
|
|
838
859
|
try {
|
|
839
|
-
const tags = await (0, import_git_semver_tags.getSemverTags)({
|
|
840
|
-
|
|
860
|
+
const tags = await (0, import_git_semver_tags.getSemverTags)({
|
|
861
|
+
tagPrefix: versionPrefix
|
|
862
|
+
});
|
|
863
|
+
if (tags.length === 0) {
|
|
864
|
+
return "";
|
|
865
|
+
}
|
|
866
|
+
const chronologicalLatest = tags[0];
|
|
867
|
+
const sortedTags = [...tags].sort((a, b) => {
|
|
868
|
+
const versionA = import_semver.default.clean(a) || "0.0.0";
|
|
869
|
+
const versionB = import_semver.default.clean(b) || "0.0.0";
|
|
870
|
+
return import_semver.default.rcompare(versionA, versionB);
|
|
871
|
+
});
|
|
872
|
+
const semanticLatest = sortedTags[0];
|
|
873
|
+
if (semanticLatest !== chronologicalLatest) {
|
|
874
|
+
log(
|
|
875
|
+
`Tag ordering differs: chronological latest is ${chronologicalLatest}, semantic latest is ${semanticLatest}`,
|
|
876
|
+
"debug"
|
|
877
|
+
);
|
|
878
|
+
log(`Using semantic latest (${semanticLatest}) to handle out-of-order tag creation`, "info");
|
|
879
|
+
}
|
|
880
|
+
return semanticLatest;
|
|
841
881
|
} catch (error) {
|
|
842
882
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
843
883
|
log(`Failed to get latest tag: ${errorMessage}`, "error");
|
|
@@ -862,56 +902,122 @@ async function lastMergeBranchName(branches, baseBranch) {
|
|
|
862
902
|
return null;
|
|
863
903
|
}
|
|
864
904
|
}
|
|
865
|
-
async function getLatestTagForPackage(packageName, versionPrefix) {
|
|
905
|
+
async function getLatestTagForPackage(packageName, versionPrefix, options) {
|
|
866
906
|
try {
|
|
907
|
+
const tagTemplate = (options == null ? void 0 : options.tagTemplate) || "${prefix}${version}";
|
|
908
|
+
const packageSpecificTags = (options == null ? void 0 : options.packageSpecificTags) ?? false;
|
|
867
909
|
const escapedPackageName = escapeRegExp(packageName);
|
|
910
|
+
const escapedPrefix = versionPrefix ? escapeRegExp(versionPrefix) : "";
|
|
868
911
|
log(
|
|
869
|
-
`Looking for tags for package ${packageName} with prefix ${versionPrefix || "none"}`,
|
|
912
|
+
`Looking for tags for package ${packageName} with prefix ${versionPrefix || "none"}, packageSpecificTags: ${packageSpecificTags}`,
|
|
870
913
|
"debug"
|
|
871
914
|
);
|
|
872
915
|
const allTags = await (0, import_git_semver_tags.getSemverTags)({
|
|
873
916
|
tagPrefix: versionPrefix
|
|
874
917
|
});
|
|
875
918
|
log(`Retrieved ${allTags.length} tags: ${allTags.join(", ")}`, "debug");
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
919
|
+
if (packageSpecificTags) {
|
|
920
|
+
const packageTagPattern = escapeRegExp(tagTemplate).replace(/\\\$\\\{packageName\\\}/g, `(?:${escapedPackageName})`).replace(/\\\$\\\{prefix\\\}/g, `(?:${escapedPrefix})`).replace(/\\\$\\\{version\\\}/g, "(?:[0-9]+\\.[0-9]+\\.[0-9]+(?:-[a-zA-Z0-9.-]+)?)");
|
|
921
|
+
log(`Using package tag pattern: ${packageTagPattern}`, "debug");
|
|
922
|
+
const packageTagRegex = new RegExp(`^${packageTagPattern}$`);
|
|
923
|
+
let packageTags = allTags.filter((tag) => packageTagRegex.test(tag));
|
|
880
924
|
if (packageTags.length > 0) {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
"
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
925
|
+
const chronologicalFirst = packageTags[0];
|
|
926
|
+
const sortedPackageTags2 = [...packageTags].sort((a, b) => {
|
|
927
|
+
let versionA = "";
|
|
928
|
+
let versionB = "";
|
|
929
|
+
if (a.includes("@")) {
|
|
930
|
+
const afterAt = a.split("@")[1] || "";
|
|
931
|
+
versionA = afterAt.replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
932
|
+
} else {
|
|
933
|
+
versionA = a.replace(new RegExp(`^${escapeRegExp(packageName)}`), "").replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
934
|
+
}
|
|
935
|
+
if (b.includes("@")) {
|
|
936
|
+
const afterAtB = b.split("@")[1] || "";
|
|
937
|
+
versionB = afterAtB.replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
938
|
+
} else {
|
|
939
|
+
versionB = b.replace(new RegExp(`^${escapeRegExp(packageName)}`), "").replace(new RegExp(`^${escapeRegExp(versionPrefix || "")}`), "");
|
|
940
|
+
}
|
|
941
|
+
const cleanVersionA = import_semver.default.clean(versionA) || "0.0.0";
|
|
942
|
+
const cleanVersionB = import_semver.default.clean(versionB) || "0.0.0";
|
|
943
|
+
return import_semver.default.rcompare(cleanVersionA, cleanVersionB);
|
|
944
|
+
});
|
|
945
|
+
log(`Found ${packageTags.length} package tags using configured pattern`, "debug");
|
|
946
|
+
log(`Using semantically latest tag: ${sortedPackageTags2[0]}`, "debug");
|
|
947
|
+
if (sortedPackageTags2[0] !== chronologicalFirst) {
|
|
948
|
+
log(
|
|
949
|
+
`Package tag ordering differs: chronological first is ${chronologicalFirst}, semantic latest is ${sortedPackageTags2[0]}`,
|
|
950
|
+
"debug"
|
|
951
|
+
);
|
|
952
|
+
}
|
|
953
|
+
return sortedPackageTags2[0];
|
|
954
|
+
}
|
|
955
|
+
if (versionPrefix) {
|
|
956
|
+
const pattern1 = new RegExp(`^${escapedPackageName}@${escapeRegExp(versionPrefix)}`);
|
|
957
|
+
packageTags = allTags.filter((tag) => pattern1.test(tag));
|
|
958
|
+
if (packageTags.length > 0) {
|
|
959
|
+
const sortedPackageTags2 = [...packageTags].sort((a, b) => {
|
|
960
|
+
const afterAt = a.split("@")[1] || "";
|
|
961
|
+
const versionA = afterAt.replace(
|
|
962
|
+
new RegExp(`^${escapeRegExp(versionPrefix || "")}`),
|
|
963
|
+
""
|
|
964
|
+
);
|
|
965
|
+
const afterAtB = b.split("@")[1] || "";
|
|
966
|
+
const versionB = afterAtB.replace(
|
|
967
|
+
new RegExp(`^${escapeRegExp(versionPrefix || "")}`),
|
|
968
|
+
""
|
|
969
|
+
);
|
|
970
|
+
const cleanVersionA = import_semver.default.clean(versionA) || "0.0.0";
|
|
971
|
+
const cleanVersionB = import_semver.default.clean(versionB) || "0.0.0";
|
|
972
|
+
return import_semver.default.rcompare(cleanVersionA, cleanVersionB);
|
|
973
|
+
});
|
|
974
|
+
log(
|
|
975
|
+
`Found ${packageTags.length} package tags using pattern: packageName@${versionPrefix}...`,
|
|
976
|
+
"debug"
|
|
977
|
+
);
|
|
978
|
+
log(`Using semantically latest tag: ${sortedPackageTags2[0]}`, "debug");
|
|
979
|
+
return sortedPackageTags2[0];
|
|
980
|
+
}
|
|
887
981
|
}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
982
|
+
if (versionPrefix) {
|
|
983
|
+
const pattern2 = new RegExp(`^${escapeRegExp(versionPrefix)}${escapedPackageName}@`);
|
|
984
|
+
packageTags = allTags.filter((tag) => pattern2.test(tag));
|
|
985
|
+
if (packageTags.length > 0) {
|
|
986
|
+
const sortedPackageTags2 = [...packageTags].sort((a, b) => {
|
|
987
|
+
const versionA = import_semver.default.clean(a.split("@")[1] || "") || "0.0.0";
|
|
988
|
+
const versionB = import_semver.default.clean(b.split("@")[1] || "") || "0.0.0";
|
|
989
|
+
return import_semver.default.rcompare(versionA, versionB);
|
|
990
|
+
});
|
|
991
|
+
log(
|
|
992
|
+
`Found ${packageTags.length} package tags using pattern: ${versionPrefix}packageName@...`,
|
|
993
|
+
"debug"
|
|
994
|
+
);
|
|
995
|
+
log(`Using semantically latest tag: ${sortedPackageTags2[0]}`, "debug");
|
|
996
|
+
return sortedPackageTags2[0];
|
|
997
|
+
}
|
|
899
998
|
}
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
999
|
+
const pattern3 = new RegExp(`^${escapedPackageName}@`);
|
|
1000
|
+
packageTags = allTags.filter((tag) => pattern3.test(tag));
|
|
1001
|
+
if (packageTags.length === 0) {
|
|
1002
|
+
log("No matching tags found for pattern: packageName@version", "debug");
|
|
1003
|
+
if (allTags.length > 0) {
|
|
1004
|
+
log(`Available tags: ${allTags.join(", ")}`, "debug");
|
|
1005
|
+
} else {
|
|
1006
|
+
log("No tags available in the repository", "debug");
|
|
1007
|
+
}
|
|
1008
|
+
return "";
|
|
910
1009
|
}
|
|
911
|
-
|
|
912
|
-
|
|
1010
|
+
const sortedPackageTags = [...packageTags].sort((a, b) => {
|
|
1011
|
+
const versionA = import_semver.default.clean(a.split("@")[1] || "") || "0.0.0";
|
|
1012
|
+
const versionB = import_semver.default.clean(b.split("@")[1] || "") || "0.0.0";
|
|
1013
|
+
return import_semver.default.rcompare(versionA, versionB);
|
|
1014
|
+
});
|
|
1015
|
+
log(`Found ${packageTags.length} package tags for ${packageName}`, "debug");
|
|
1016
|
+
log(`Using semantically latest tag: ${sortedPackageTags[0]}`, "debug");
|
|
1017
|
+
return sortedPackageTags[0];
|
|
913
1018
|
}
|
|
914
|
-
|
|
1019
|
+
log(`Package-specific tags disabled for ${packageName}, falling back to global tags`, "debug");
|
|
1020
|
+
return "";
|
|
915
1021
|
} catch (error) {
|
|
916
1022
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
917
1023
|
log(`Failed to get latest tag for package ${packageName}: ${errorMessage}`, "error");
|
|
@@ -1014,6 +1120,7 @@ function updatePackageVersion(packagePath, version) {
|
|
|
1014
1120
|
}
|
|
1015
1121
|
|
|
1016
1122
|
// src/package/packageProcessor.ts
|
|
1123
|
+
var import_node_child_process4 = require("child_process");
|
|
1017
1124
|
var fs8 = __toESM(require("fs"), 1);
|
|
1018
1125
|
var import_node_path6 = __toESM(require("path"), 1);
|
|
1019
1126
|
var import_node_process4 = require("process");
|
|
@@ -1346,7 +1453,7 @@ function capitalizeFirstLetter(input) {
|
|
|
1346
1453
|
// src/core/versionCalculator.ts
|
|
1347
1454
|
var import_node_process3 = require("process");
|
|
1348
1455
|
var import_conventional_recommended_bump = require("conventional-recommended-bump");
|
|
1349
|
-
var
|
|
1456
|
+
var import_semver3 = __toESM(require("semver"), 1);
|
|
1350
1457
|
|
|
1351
1458
|
// src/utils/manifestHelpers.ts
|
|
1352
1459
|
var import_node_fs5 = __toESM(require("fs"), 1);
|
|
@@ -1407,7 +1514,7 @@ function throwIfNoManifestsFound(packageDir) {
|
|
|
1407
1514
|
|
|
1408
1515
|
// src/utils/versionUtils.ts
|
|
1409
1516
|
var import_node_fs6 = __toESM(require("fs"), 1);
|
|
1410
|
-
var
|
|
1517
|
+
var import_semver2 = __toESM(require("semver"), 1);
|
|
1411
1518
|
var TOML2 = __toESM(require("smol-toml"), 1);
|
|
1412
1519
|
var STANDARD_BUMP_TYPES = ["major", "minor", "patch"];
|
|
1413
1520
|
function normalizePrereleaseIdentifier(prereleaseIdentifier, config) {
|
|
@@ -1420,58 +1527,116 @@ function normalizePrereleaseIdentifier(prereleaseIdentifier, config) {
|
|
|
1420
1527
|
return void 0;
|
|
1421
1528
|
}
|
|
1422
1529
|
function bumpVersion(currentVersion, bumpType, prereleaseIdentifier) {
|
|
1423
|
-
if (prereleaseIdentifier && STANDARD_BUMP_TYPES.includes(bumpType) && !
|
|
1530
|
+
if (prereleaseIdentifier && STANDARD_BUMP_TYPES.includes(bumpType) && !import_semver2.default.prerelease(currentVersion)) {
|
|
1424
1531
|
const preBumpType = `pre${bumpType}`;
|
|
1425
1532
|
log(
|
|
1426
1533
|
`Creating prerelease version with identifier '${prereleaseIdentifier}' using ${preBumpType}`,
|
|
1427
1534
|
"debug"
|
|
1428
1535
|
);
|
|
1429
|
-
return
|
|
1536
|
+
return import_semver2.default.inc(currentVersion, preBumpType, prereleaseIdentifier) || "";
|
|
1430
1537
|
}
|
|
1431
|
-
if (
|
|
1432
|
-
const parsed =
|
|
1538
|
+
if (import_semver2.default.prerelease(currentVersion) && STANDARD_BUMP_TYPES.includes(bumpType)) {
|
|
1539
|
+
const parsed = import_semver2.default.parse(currentVersion);
|
|
1433
1540
|
if (!parsed) {
|
|
1434
|
-
return
|
|
1541
|
+
return import_semver2.default.inc(currentVersion, bumpType) || "";
|
|
1435
1542
|
}
|
|
1436
1543
|
if (bumpType === "major" && parsed.minor === 0 && parsed.patch === 0 || bumpType === "minor" && parsed.patch === 0 || bumpType === "patch") {
|
|
1437
1544
|
log(`Cleaning prerelease identifier from ${currentVersion} for ${bumpType} bump`, "debug");
|
|
1438
1545
|
return `${parsed.major}.${parsed.minor}.${parsed.patch}`;
|
|
1439
1546
|
}
|
|
1440
1547
|
log(`Standard increment for ${currentVersion} with ${bumpType} bump`, "debug");
|
|
1441
|
-
return
|
|
1548
|
+
return import_semver2.default.inc(currentVersion, bumpType) || "";
|
|
1442
1549
|
}
|
|
1443
|
-
return
|
|
1550
|
+
return import_semver2.default.inc(currentVersion, bumpType, prereleaseIdentifier) || "";
|
|
1444
1551
|
}
|
|
1445
1552
|
|
|
1446
1553
|
// src/core/versionCalculator.ts
|
|
1447
1554
|
async function calculateVersion(config, options) {
|
|
1448
1555
|
const {
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
versionPrefix
|
|
1556
|
+
type: configType,
|
|
1557
|
+
preset = "angular",
|
|
1558
|
+
versionPrefix,
|
|
1559
|
+
prereleaseIdentifier: configPrereleaseIdentifier,
|
|
1452
1560
|
branchPattern,
|
|
1453
|
-
baseBranch
|
|
1454
|
-
|
|
1561
|
+
baseBranch
|
|
1562
|
+
} = config;
|
|
1563
|
+
const {
|
|
1564
|
+
latestTag,
|
|
1565
|
+
name,
|
|
1455
1566
|
path: pkgPath,
|
|
1456
|
-
|
|
1567
|
+
type: optionsType,
|
|
1568
|
+
prereleaseIdentifier: optionsPrereleaseIdentifier
|
|
1457
1569
|
} = options;
|
|
1458
|
-
const
|
|
1570
|
+
const type = optionsType || configType;
|
|
1571
|
+
const prereleaseIdentifier = optionsPrereleaseIdentifier || configPrereleaseIdentifier;
|
|
1459
1572
|
const initialVersion = "0.1.0";
|
|
1573
|
+
const hasNoTags = !latestTag || latestTag.trim() === "";
|
|
1460
1574
|
const normalizedPrereleaseId = normalizePrereleaseIdentifier(prereleaseIdentifier, config);
|
|
1461
1575
|
try {
|
|
1462
1576
|
let determineTagSearchPattern2 = function(packageName, prefix) {
|
|
1463
|
-
if (packageName) {
|
|
1464
|
-
|
|
1465
|
-
const escapedPrefix = escapeRegExp(prefix);
|
|
1466
|
-
return `${escapedPackageName}[@]?${escapedPrefix}`;
|
|
1577
|
+
if (!packageName) {
|
|
1578
|
+
return prefix;
|
|
1467
1579
|
}
|
|
1468
|
-
return
|
|
1580
|
+
return `${packageName}@${prefix}`;
|
|
1581
|
+
}, escapeRegExp3 = function(string) {
|
|
1582
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1469
1583
|
};
|
|
1470
|
-
var determineTagSearchPattern = determineTagSearchPattern2;
|
|
1471
|
-
const
|
|
1472
|
-
const originalPrefix = versionPrefix;
|
|
1584
|
+
var determineTagSearchPattern = determineTagSearchPattern2, escapeRegExp2 = escapeRegExp3;
|
|
1585
|
+
const originalPrefix = versionPrefix || "";
|
|
1473
1586
|
const tagSearchPattern = determineTagSearchPattern2(name, originalPrefix);
|
|
1474
|
-
const escapedTagPattern =
|
|
1587
|
+
const escapedTagPattern = escapeRegExp3(tagSearchPattern);
|
|
1588
|
+
if (!hasNoTags && pkgPath) {
|
|
1589
|
+
const packageDir = pkgPath || (0, import_node_process3.cwd)();
|
|
1590
|
+
const manifestResult = getVersionFromManifests(packageDir);
|
|
1591
|
+
if (manifestResult.manifestFound && manifestResult.version) {
|
|
1592
|
+
const cleanedTag = import_semver3.default.clean(latestTag) || latestTag;
|
|
1593
|
+
const tagVersion = import_semver3.default.clean(cleanedTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
1594
|
+
const packageVersion = manifestResult.version;
|
|
1595
|
+
if (import_semver3.default.gt(packageVersion, tagVersion)) {
|
|
1596
|
+
log(
|
|
1597
|
+
`Warning: Version mismatch detected!
|
|
1598
|
+
\u2022 ${manifestResult.manifestType} version: ${packageVersion}
|
|
1599
|
+
\u2022 Latest Git tag version: ${tagVersion} (from ${latestTag})
|
|
1600
|
+
\u2022 Package version is AHEAD of Git tags
|
|
1601
|
+
|
|
1602
|
+
This usually happens when:
|
|
1603
|
+
\u2022 A version was released but the tag wasn't pushed to the remote repository
|
|
1604
|
+
\u2022 The ${manifestResult.manifestType} was manually updated without creating a corresponding tag
|
|
1605
|
+
\u2022 You're running in CI and the latest tag isn't available yet
|
|
1606
|
+
|
|
1607
|
+
The tool will use the Git tag version (${tagVersion}) as the base for calculation.
|
|
1608
|
+
Expected next version will be based on ${tagVersion}, not ${packageVersion}.
|
|
1609
|
+
|
|
1610
|
+
To fix this mismatch:
|
|
1611
|
+
\u2022 Push missing tags: git push origin --tags
|
|
1612
|
+
\u2022 Or use package version as base by ensuring tags are up to date`,
|
|
1613
|
+
"warning"
|
|
1614
|
+
);
|
|
1615
|
+
} else if (import_semver3.default.gt(tagVersion, packageVersion)) {
|
|
1616
|
+
log(
|
|
1617
|
+
`Warning: Version mismatch detected!
|
|
1618
|
+
\u2022 ${manifestResult.manifestType} version: ${packageVersion}
|
|
1619
|
+
\u2022 Latest Git tag version: ${tagVersion} (from ${latestTag})
|
|
1620
|
+
\u2022 Git tag version is AHEAD of package version
|
|
1621
|
+
|
|
1622
|
+
This usually happens when:
|
|
1623
|
+
\u2022 A release was tagged but the ${manifestResult.manifestType} wasn't updated
|
|
1624
|
+
\u2022 You're on an older branch that hasn't been updated with the latest version
|
|
1625
|
+
\u2022 Automated release process created tags but didn't update manifest files
|
|
1626
|
+
\u2022 You pulled tags but not the corresponding commits that update the package version
|
|
1627
|
+
|
|
1628
|
+
The tool will use the Git tag version (${tagVersion}) as the base for calculation.
|
|
1629
|
+
This will likely result in a version that's already been released.
|
|
1630
|
+
|
|
1631
|
+
To fix this mismatch:
|
|
1632
|
+
\u2022 Update ${manifestResult.manifestType}: Set version to ${tagVersion} or higher
|
|
1633
|
+
\u2022 Or checkout the branch/commit that corresponds to the tag
|
|
1634
|
+
\u2022 Or ensure your branch is up to date with the latest changes`,
|
|
1635
|
+
"warning"
|
|
1636
|
+
);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1475
1640
|
const specifiedType = type;
|
|
1476
1641
|
if (specifiedType) {
|
|
1477
1642
|
if (hasNoTags) {
|
|
@@ -1483,9 +1648,9 @@ async function calculateVersion(config, options) {
|
|
|
1483
1648
|
initialVersion
|
|
1484
1649
|
);
|
|
1485
1650
|
}
|
|
1486
|
-
const cleanedTag =
|
|
1487
|
-
const currentVersion =
|
|
1488
|
-
if (STANDARD_BUMP_TYPES.includes(specifiedType) && (
|
|
1651
|
+
const cleanedTag = import_semver3.default.clean(latestTag) || latestTag;
|
|
1652
|
+
const currentVersion = import_semver3.default.clean(cleanedTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
1653
|
+
if (STANDARD_BUMP_TYPES.includes(specifiedType) && (import_semver3.default.prerelease(currentVersion) || normalizedPrereleaseId)) {
|
|
1489
1654
|
log(
|
|
1490
1655
|
normalizedPrereleaseId ? `Creating prerelease version with identifier '${normalizedPrereleaseId}' using ${specifiedType}` : `Cleaning prerelease identifier from ${currentVersion} for ${specifiedType} bump`,
|
|
1491
1656
|
"debug"
|
|
@@ -1523,8 +1688,8 @@ async function calculateVersion(config, options) {
|
|
|
1523
1688
|
initialVersion
|
|
1524
1689
|
);
|
|
1525
1690
|
}
|
|
1526
|
-
const cleanedTag =
|
|
1527
|
-
const currentVersion =
|
|
1691
|
+
const cleanedTag = import_semver3.default.clean(latestTag) || latestTag;
|
|
1692
|
+
const currentVersion = import_semver3.default.clean(cleanedTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
1528
1693
|
log(`Applying ${branchVersionType} bump based on branch pattern`, "debug");
|
|
1529
1694
|
return bumpVersion(currentVersion, branchVersionType, normalizedPrereleaseId);
|
|
1530
1695
|
}
|
|
@@ -1562,7 +1727,7 @@ async function calculateVersion(config, options) {
|
|
|
1562
1727
|
);
|
|
1563
1728
|
return "";
|
|
1564
1729
|
}
|
|
1565
|
-
const currentVersion =
|
|
1730
|
+
const currentVersion = import_semver3.default.clean(latestTag.replace(new RegExp(`^${escapedTagPattern}`), "")) || "0.0.0";
|
|
1566
1731
|
return bumpVersion(currentVersion, releaseTypeFromCommits, normalizedPrereleaseId);
|
|
1567
1732
|
} catch (error) {
|
|
1568
1733
|
log(`Failed to calculate version for ${name || "project"}`, "error");
|
|
@@ -1607,7 +1772,7 @@ function calculateNextVersion(version, manifestType, name, releaseType, prerelea
|
|
|
1607
1772
|
`No tags found for ${name || "package"}, using ${manifestType} version: ${version} as base`,
|
|
1608
1773
|
"info"
|
|
1609
1774
|
);
|
|
1610
|
-
if (STANDARD_BUMP_TYPES.includes(releaseType) && (
|
|
1775
|
+
if (STANDARD_BUMP_TYPES.includes(releaseType) && (import_semver3.default.prerelease(version) || prereleaseIdentifier)) {
|
|
1611
1776
|
log(
|
|
1612
1777
|
prereleaseIdentifier ? `Creating prerelease version with identifier '${prereleaseIdentifier}' using ${releaseType}` : `Cleaning prerelease identifier from ${version} for ${releaseType} bump`,
|
|
1613
1778
|
"debug"
|
|
@@ -1618,13 +1783,39 @@ function calculateNextVersion(version, manifestType, name, releaseType, prerelea
|
|
|
1618
1783
|
return result || initialVersion;
|
|
1619
1784
|
}
|
|
1620
1785
|
|
|
1786
|
+
// src/utils/packageMatching.ts
|
|
1787
|
+
function matchesPackageTarget(packageName, target) {
|
|
1788
|
+
if (packageName === target) {
|
|
1789
|
+
return true;
|
|
1790
|
+
}
|
|
1791
|
+
if (target.endsWith("/*")) {
|
|
1792
|
+
const scope = target.slice(0, -2);
|
|
1793
|
+
if (scope.startsWith("@")) {
|
|
1794
|
+
return packageName.startsWith(`${scope}/`);
|
|
1795
|
+
}
|
|
1796
|
+
return packageName.startsWith(`${scope}/`);
|
|
1797
|
+
}
|
|
1798
|
+
if (target === "*") {
|
|
1799
|
+
return true;
|
|
1800
|
+
}
|
|
1801
|
+
return false;
|
|
1802
|
+
}
|
|
1803
|
+
function shouldProcessPackage(packageName, targets = [], skip = []) {
|
|
1804
|
+
if (skip.includes(packageName)) {
|
|
1805
|
+
return false;
|
|
1806
|
+
}
|
|
1807
|
+
if (targets.length === 0) {
|
|
1808
|
+
return true;
|
|
1809
|
+
}
|
|
1810
|
+
return targets.some((target) => matchesPackageTarget(packageName, target));
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1621
1813
|
// src/package/packageProcessor.ts
|
|
1622
1814
|
var PackageProcessor = class {
|
|
1623
1815
|
skip;
|
|
1624
1816
|
targets;
|
|
1625
1817
|
versionPrefix;
|
|
1626
1818
|
tagTemplate;
|
|
1627
|
-
packageTagTemplate;
|
|
1628
1819
|
commitMessageTemplate;
|
|
1629
1820
|
dryRun;
|
|
1630
1821
|
skipHooks;
|
|
@@ -1637,7 +1828,6 @@ var PackageProcessor = class {
|
|
|
1637
1828
|
this.targets = options.targets || [];
|
|
1638
1829
|
this.versionPrefix = options.versionPrefix || "v";
|
|
1639
1830
|
this.tagTemplate = options.tagTemplate;
|
|
1640
|
-
this.packageTagTemplate = options.packageTagTemplate;
|
|
1641
1831
|
this.commitMessageTemplate = options.commitMessageTemplate || "";
|
|
1642
1832
|
this.dryRun = options.dryRun || false;
|
|
1643
1833
|
this.skipHooks = options.skipHooks || false;
|
|
@@ -1665,18 +1855,15 @@ var PackageProcessor = class {
|
|
|
1665
1855
|
const pkgsToConsider = packages.filter((pkg) => {
|
|
1666
1856
|
var _a2;
|
|
1667
1857
|
const pkgName = pkg.packageJson.name;
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
const isTargeted = this.targets.includes(pkgName);
|
|
1676
|
-
if (!isTargeted) {
|
|
1677
|
-
log(`Package ${pkgName} not in target list, skipping.`, "info");
|
|
1858
|
+
const shouldProcess = shouldProcessPackage(pkgName, this.targets, this.skip);
|
|
1859
|
+
if (!shouldProcess) {
|
|
1860
|
+
if ((_a2 = this.skip) == null ? void 0 : _a2.includes(pkgName)) {
|
|
1861
|
+
log(`Skipping package ${pkgName} as it's in the skip list.`, "info");
|
|
1862
|
+
} else {
|
|
1863
|
+
log(`Package ${pkgName} not in target list, skipping.`, "info");
|
|
1864
|
+
}
|
|
1678
1865
|
}
|
|
1679
|
-
return
|
|
1866
|
+
return shouldProcess;
|
|
1680
1867
|
});
|
|
1681
1868
|
log(`Found ${pkgsToConsider.length} targeted package(s) to process after filtering.`, "info");
|
|
1682
1869
|
if (pkgsToConsider.length === 0) {
|
|
@@ -1689,7 +1876,10 @@ var PackageProcessor = class {
|
|
|
1689
1876
|
const formattedPrefix = formatVersionPrefix(this.versionPrefix);
|
|
1690
1877
|
let latestTagResult = "";
|
|
1691
1878
|
try {
|
|
1692
|
-
latestTagResult = await getLatestTagForPackage(name, this.versionPrefix
|
|
1879
|
+
latestTagResult = await getLatestTagForPackage(name, this.versionPrefix, {
|
|
1880
|
+
tagTemplate: this.tagTemplate,
|
|
1881
|
+
packageSpecificTags: this.fullConfig.packageSpecificTags
|
|
1882
|
+
});
|
|
1693
1883
|
} catch (error) {
|
|
1694
1884
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1695
1885
|
log(
|
|
@@ -1743,7 +1933,24 @@ var PackageProcessor = class {
|
|
|
1743
1933
|
if (this.fullConfig.updateChangelog !== false) {
|
|
1744
1934
|
let changelogEntries = [];
|
|
1745
1935
|
try {
|
|
1746
|
-
|
|
1936
|
+
let revisionRange = latestTag;
|
|
1937
|
+
if (latestTag) {
|
|
1938
|
+
try {
|
|
1939
|
+
(0, import_node_child_process4.execSync)(`git rev-parse --verify "${latestTag}"`, {
|
|
1940
|
+
cwd: pkgPath,
|
|
1941
|
+
stdio: "ignore"
|
|
1942
|
+
});
|
|
1943
|
+
} catch {
|
|
1944
|
+
log(
|
|
1945
|
+
`Tag ${latestTag} doesn't exist, using recent commits from HEAD for changelog`,
|
|
1946
|
+
"debug"
|
|
1947
|
+
);
|
|
1948
|
+
revisionRange = "HEAD~10..HEAD";
|
|
1949
|
+
}
|
|
1950
|
+
} else {
|
|
1951
|
+
revisionRange = "HEAD~10..HEAD";
|
|
1952
|
+
}
|
|
1953
|
+
changelogEntries = extractChangelogEntriesFromCommits(pkgPath, revisionRange);
|
|
1747
1954
|
if (changelogEntries.length === 0) {
|
|
1748
1955
|
changelogEntries = [
|
|
1749
1956
|
{
|
|
@@ -1821,7 +2028,7 @@ var PackageProcessor = class {
|
|
|
1821
2028
|
this.versionPrefix,
|
|
1822
2029
|
name,
|
|
1823
2030
|
this.tagTemplate,
|
|
1824
|
-
this.
|
|
2031
|
+
this.fullConfig.packageSpecificTags
|
|
1825
2032
|
);
|
|
1826
2033
|
const tagMessage = `chore(release): ${name} ${nextVersion}`;
|
|
1827
2034
|
addTag(packageTag);
|
|
@@ -1907,16 +2114,9 @@ var PackageProcessor = class {
|
|
|
1907
2114
|
};
|
|
1908
2115
|
|
|
1909
2116
|
// src/core/versionStrategies.ts
|
|
1910
|
-
function
|
|
1911
|
-
var _a;
|
|
2117
|
+
function shouldProcessPackage2(pkg, config, targets = []) {
|
|
1912
2118
|
const pkgName = pkg.packageJson.name;
|
|
1913
|
-
|
|
1914
|
-
return false;
|
|
1915
|
-
}
|
|
1916
|
-
if (!targets || targets.length === 0) {
|
|
1917
|
-
return true;
|
|
1918
|
-
}
|
|
1919
|
-
return targets.includes(pkgName);
|
|
2119
|
+
return shouldProcessPackage(pkgName, targets, config.skip);
|
|
1920
2120
|
}
|
|
1921
2121
|
function createSyncedStrategy(config) {
|
|
1922
2122
|
return async (packages) => {
|
|
@@ -1972,6 +2172,7 @@ function createSyncedStrategy(config) {
|
|
|
1972
2172
|
}
|
|
1973
2173
|
const files = [];
|
|
1974
2174
|
const updatedPackages = [];
|
|
2175
|
+
const processedPaths = /* @__PURE__ */ new Set();
|
|
1975
2176
|
try {
|
|
1976
2177
|
if (packages.root) {
|
|
1977
2178
|
const rootPkgPath = path7.join(packages.root, "package.json");
|
|
@@ -1979,6 +2180,7 @@ function createSyncedStrategy(config) {
|
|
|
1979
2180
|
updatePackageVersion(rootPkgPath, nextVersion);
|
|
1980
2181
|
files.push(rootPkgPath);
|
|
1981
2182
|
updatedPackages.push("root");
|
|
2183
|
+
processedPaths.add(rootPkgPath);
|
|
1982
2184
|
}
|
|
1983
2185
|
} else {
|
|
1984
2186
|
log("Root package path is undefined, skipping root package.json update", "warning");
|
|
@@ -1988,13 +2190,17 @@ function createSyncedStrategy(config) {
|
|
|
1988
2190
|
log(`Failed to update root package.json: ${errMessage}`, "error");
|
|
1989
2191
|
}
|
|
1990
2192
|
for (const pkg of packages.packages) {
|
|
1991
|
-
if (!
|
|
2193
|
+
if (!shouldProcessPackage2(pkg, config)) {
|
|
1992
2194
|
continue;
|
|
1993
2195
|
}
|
|
1994
2196
|
const packageJsonPath = path7.join(pkg.dir, "package.json");
|
|
2197
|
+
if (processedPaths.has(packageJsonPath)) {
|
|
2198
|
+
continue;
|
|
2199
|
+
}
|
|
1995
2200
|
updatePackageVersion(packageJsonPath, nextVersion);
|
|
1996
2201
|
files.push(packageJsonPath);
|
|
1997
2202
|
updatedPackages.push(pkg.packageJson.name);
|
|
2203
|
+
processedPaths.add(packageJsonPath);
|
|
1998
2204
|
}
|
|
1999
2205
|
if (updatedPackages.length > 0) {
|
|
2000
2206
|
log(`Updated ${updatedPackages.length} package(s) to version ${nextVersion}`, "success");
|
|
@@ -2002,8 +2208,25 @@ function createSyncedStrategy(config) {
|
|
|
2002
2208
|
log("No packages were updated", "warning");
|
|
2003
2209
|
return;
|
|
2004
2210
|
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2211
|
+
let tagPackageName = null;
|
|
2212
|
+
let commitPackageName = void 0;
|
|
2213
|
+
if (config.packageSpecificTags && packages.packages.length === 1) {
|
|
2214
|
+
tagPackageName = packages.packages[0].packageJson.name;
|
|
2215
|
+
commitPackageName = packages.packages[0].packageJson.name;
|
|
2216
|
+
}
|
|
2217
|
+
const nextTag = formatTag(
|
|
2218
|
+
nextVersion,
|
|
2219
|
+
formattedPrefix,
|
|
2220
|
+
tagPackageName,
|
|
2221
|
+
tagTemplate,
|
|
2222
|
+
config.packageSpecificTags || false
|
|
2223
|
+
);
|
|
2224
|
+
const formattedCommitMessage = formatCommitMessage(
|
|
2225
|
+
commitMessage,
|
|
2226
|
+
nextVersion,
|
|
2227
|
+
commitPackageName,
|
|
2228
|
+
void 0
|
|
2229
|
+
);
|
|
2007
2230
|
await createGitCommitAndTag(files, nextTag, formattedCommitMessage, skipHooks, dryRun);
|
|
2008
2231
|
} catch (error) {
|
|
2009
2232
|
if (error instanceof VersionError || error instanceof GitError) {
|
|
@@ -2024,7 +2247,6 @@ function createSingleStrategy(config) {
|
|
|
2024
2247
|
mainPackage,
|
|
2025
2248
|
versionPrefix,
|
|
2026
2249
|
tagTemplate,
|
|
2027
|
-
packageTagTemplate,
|
|
2028
2250
|
commitMessage = "chore(release): ${version}",
|
|
2029
2251
|
dryRun,
|
|
2030
2252
|
skipHooks
|
|
@@ -2046,7 +2268,10 @@ function createSingleStrategy(config) {
|
|
|
2046
2268
|
}
|
|
2047
2269
|
const pkgPath = pkg.dir;
|
|
2048
2270
|
const formattedPrefix = formatVersionPrefix(versionPrefix || "v");
|
|
2049
|
-
let latestTagResult = await getLatestTagForPackage(packageName, formattedPrefix
|
|
2271
|
+
let latestTagResult = await getLatestTagForPackage(packageName, formattedPrefix, {
|
|
2272
|
+
tagTemplate,
|
|
2273
|
+
packageSpecificTags: config.packageSpecificTags
|
|
2274
|
+
});
|
|
2050
2275
|
if (!latestTagResult) {
|
|
2051
2276
|
const globalTagResult = await getLatestTag();
|
|
2052
2277
|
latestTagResult = globalTagResult || "";
|
|
@@ -2077,7 +2302,7 @@ function createSingleStrategy(config) {
|
|
|
2077
2302
|
formattedPrefix,
|
|
2078
2303
|
packageName,
|
|
2079
2304
|
tagTemplate,
|
|
2080
|
-
|
|
2305
|
+
config.packageSpecificTags
|
|
2081
2306
|
);
|
|
2082
2307
|
const formattedCommitMessage = formatCommitMessage(commitMessage, nextVersion, packageName);
|
|
2083
2308
|
await createGitCommitAndTag(
|
|
@@ -2110,7 +2335,6 @@ function createAsyncStrategy(config) {
|
|
|
2110
2335
|
targets: config.packages || [],
|
|
2111
2336
|
versionPrefix: config.versionPrefix || "v",
|
|
2112
2337
|
tagTemplate: config.tagTemplate,
|
|
2113
|
-
packageTagTemplate: config.packageTagTemplate,
|
|
2114
2338
|
commitMessageTemplate: config.commitMessage || "",
|
|
2115
2339
|
dryRun: config.dryRun || false,
|
|
2116
2340
|
skipHooks: config.skipHooks || false,
|