enablement-build-monorepo-version 8.4.1 → 8.4.5
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 +4 -0
- package/package.json +8 -8
- package/src/index.mjs +26 -5
- package/src/version.mjs +4 -1
- package/tests/version.test.mjs +30 -0
package/README.md
CHANGED
|
@@ -27,6 +27,8 @@ npx enablement-build-monorepo-version@latest [flags]
|
|
|
27
27
|
| `--hash` | off | Compute and **save** current hashes to the hash state file. Must be run before `--changed` / `--version` to establish a baseline. |
|
|
28
28
|
| `--changed` | off | Print the list of changed packages and emit a `changed` pipeline variable. |
|
|
29
29
|
| `--version` | off | Emit a pipeline variable per changed package containing its next version. |
|
|
30
|
+
| `--patchonly` | off | Restrict package version bumps to the patch number, even for commits normally classified as minor or major. |
|
|
31
|
+
| `--suffix <value>` | — | Force this prerelease suffix on every bumped version, replacing any existing suffix. A leading `-` is optional. |
|
|
30
32
|
| `--save` | off | Write the bumped version back into each changed package's version manifests (`package.json`, `version.json`, and/or `pyproject.toml`). Requires `--version`. |
|
|
31
33
|
| `--tag` | off | Create a git tag (`<short-name>/<version>`) for each changed package, where `short-name` is the npm package name with its scope prefix removed (e.g. `@scope/lib-foo` → `lib-foo/1.2.3`). |
|
|
32
34
|
| `--retag` | off | Convert existing tags that use the old folder-name format to the new short-package-name format. Non-destructive: old tags are left in place. |
|
|
@@ -43,6 +45,8 @@ npx enablement-build-monorepo-version@latest [flags]
|
|
|
43
45
|
| `--hashExcludeFiles <list>` | see below | Comma-separated file names to skip when hashing. |
|
|
44
46
|
| `--hashFiles <list>` | — | Comma-separated individual file paths to include in the hash state (outside of `children` folders). |
|
|
45
47
|
|
|
48
|
+
Existing prerelease suffixes (for example, `-devA`) are retained when bumping versions unless `--suffix` is provided.
|
|
49
|
+
|
|
46
50
|
**Default excluded folders:** `node_modules`, `coverage`, `dist`, `bin`, `obj`, `__pycache__`, `.vs`, `.nx`, `.vscode`, `.idea`, `.git`, `.github`, `.azuredevops`, `.release`
|
|
47
51
|
|
|
48
52
|
**Default excluded files:** `.npmrc`, `CHANGELOG.md`, `README.md`
|
package/package.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "enablement-build-monorepo-version",
|
|
3
|
-
"version": "8.4.
|
|
3
|
+
"version": "8.4.5",
|
|
4
4
|
"description": "This detects changes in the children packages of a monorepo.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./src/index.mjs",
|
|
7
7
|
"bin": "./src/index.mjs",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"author": "Contributors",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node src/index.mjs",
|
|
12
|
+
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
13
|
+
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch"
|
|
14
|
+
},
|
|
10
15
|
"jest": {
|
|
11
16
|
"testEnvironment": "node",
|
|
12
17
|
"testMatch": [
|
|
@@ -14,15 +19,10 @@
|
|
|
14
19
|
]
|
|
15
20
|
},
|
|
16
21
|
"dependencies": {
|
|
17
|
-
"
|
|
18
|
-
"
|
|
22
|
+
"enablement-build-manifest": "workspace:*",
|
|
23
|
+
"minimatch": "~10.1.1"
|
|
19
24
|
},
|
|
20
25
|
"devDependencies": {
|
|
21
26
|
"jest": "^30.4.2"
|
|
22
|
-
},
|
|
23
|
-
"scripts": {
|
|
24
|
-
"start": "node src/index.mjs",
|
|
25
|
-
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
26
|
-
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch"
|
|
27
27
|
}
|
|
28
28
|
}
|
package/src/index.mjs
CHANGED
|
@@ -12,11 +12,14 @@ const packageVersion = packageMetadata.version;
|
|
|
12
12
|
import { dependencyMap, compare, getCurrentVersion, updateVersion, retagToPackageNames, detectOldFormatTags, resolveWorkspaceChildren, excludeChildren, applyInitScripts, RELEASE_SCRIPTS, emitVariable, hashElement, resolveHashFilePath, ensureHashFileExists, loadHashFile, writeHashFile } from "./lib.mjs";
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
function bumpPatchVersion(version) {
|
|
15
|
+
function bumpPatchVersion(version, forcedSuffix) {
|
|
16
16
|
const value = (version || '0.0.0').trim();
|
|
17
17
|
const parts = value.split('-');
|
|
18
18
|
const base = parts[0] || '0.0.0';
|
|
19
|
-
|
|
19
|
+
let suffix = parts.length > 1 ? parts.slice(1).join('-') : '';
|
|
20
|
+
if (forcedSuffix !== null && forcedSuffix !== undefined) {
|
|
21
|
+
suffix = String(forcedSuffix).replace(/^-+/, '');
|
|
22
|
+
}
|
|
20
23
|
|
|
21
24
|
const nums = base.split('.');
|
|
22
25
|
const major = Number.parseInt(nums[0] || '0', 10) || 0;
|
|
@@ -35,7 +38,7 @@ async function updateRootVersionIfNeeded(options, changeList) {
|
|
|
35
38
|
|
|
36
39
|
const pkg = JSON.parse(readFileSync(rootPackageFile, 'utf8'));
|
|
37
40
|
const previous = pkg.version || '0.0.0';
|
|
38
|
-
const next = bumpPatchVersion(previous);
|
|
41
|
+
const next = bumpPatchVersion(previous, options.suffix);
|
|
39
42
|
|
|
40
43
|
if (options.try) {
|
|
41
44
|
console.log('\x1b[36m%s\x1b[0m', `[try] Would update ${rootPackageFile} version ${previous} -> ${next}`);
|
|
@@ -196,7 +199,13 @@ async function main(options) {
|
|
|
196
199
|
let children = options.children.replace(/\s/g, ",");
|
|
197
200
|
children.split(',').forEach((packageFolder) => {
|
|
198
201
|
scanlist.push(new Promise((resolve, reject) => {
|
|
199
|
-
|
|
202
|
+
const folderPath = path.join(options.prefixPath, packageFolder);
|
|
203
|
+
if (!existsSync(folderPath)) {
|
|
204
|
+
console.log('\x1b[33m%s\x1b[0m', `Warning: workspace folder "${packageFolder}" does not exist, skipping`);
|
|
205
|
+
resolve("OK");
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
hashElement(folderPath, hashOptions).then(async hash => {
|
|
200
209
|
const children = hash.children;
|
|
201
210
|
if (options.debug) console.log("HASH", JSON.stringify(children));
|
|
202
211
|
|
|
@@ -257,7 +266,8 @@ async function main(options) {
|
|
|
257
266
|
resolve("OK");
|
|
258
267
|
})
|
|
259
268
|
.catch(error => {
|
|
260
|
-
|
|
269
|
+
console.error('hashing failed:', error);
|
|
270
|
+
resolve("OK");
|
|
261
271
|
});
|
|
262
272
|
}));
|
|
263
273
|
});
|
|
@@ -336,6 +346,8 @@ async function main(options) {
|
|
|
336
346
|
let options = {
|
|
337
347
|
saveVersion: false,
|
|
338
348
|
changed: false,
|
|
349
|
+
patchonly: false,
|
|
350
|
+
suffix: null,
|
|
339
351
|
version: false,
|
|
340
352
|
hash: false,
|
|
341
353
|
tag: false,
|
|
@@ -365,6 +377,15 @@ if (process.argv.length === 2) {
|
|
|
365
377
|
if (argv[i] === "--save") options.saveVersion = true;
|
|
366
378
|
else if (argv[i] === "--debug") options.debug = true;
|
|
367
379
|
else if (argv[i] === "--changed") options.changed = true;
|
|
380
|
+
else if (argv[i] === "--patchonly") options.patchonly = true;
|
|
381
|
+
else if (argv[i] === "--suffix") {
|
|
382
|
+
if (!argv[i + 1] || argv[i + 1].startsWith("--")) {
|
|
383
|
+
console.error("Expected a value for --suffix");
|
|
384
|
+
process.exit(1);
|
|
385
|
+
}
|
|
386
|
+
options.suffix = argv[i + 1];
|
|
387
|
+
i++;
|
|
388
|
+
}
|
|
368
389
|
else if (argv[i] === "--version") options.version = true;
|
|
369
390
|
else if (argv[i] === "--hash") options.hash = true;
|
|
370
391
|
else if (argv[i] === "--tag") options.tag = true;
|
package/src/version.mjs
CHANGED
|
@@ -51,7 +51,10 @@ function processMessage(message, tag, imageName, options, args) {
|
|
|
51
51
|
let minor = Number.parseInt(parts[1] || '0', 10) || 0;
|
|
52
52
|
let patch = Number.parseInt(parts[2] || '0', 10) || 0;
|
|
53
53
|
|
|
54
|
-
const bump = getBumpType(message);
|
|
54
|
+
const bump = options.patchonly ? "patch" : getBumpType(message);
|
|
55
|
+
if (options.suffix !== null && options.suffix !== undefined) {
|
|
56
|
+
suffix = String(options.suffix).replace(/^-+/, "");
|
|
57
|
+
}
|
|
55
58
|
let build = false;
|
|
56
59
|
|
|
57
60
|
if (bump === "major") {
|
package/tests/version.test.mjs
CHANGED
|
@@ -25,6 +25,36 @@ describe('version bump parsing', () => {
|
|
|
25
25
|
expect(result.version).toBe('2.0.0');
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
+
it('preserves a suffix during a normal bump without patchonly', () => {
|
|
29
|
+
const result = processMessage('feat: add endpoint', '1.2.3-devA', 'pkg', options, {});
|
|
30
|
+
expect(result.version).toBe('1.3.0-devA');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('limits breaking changes to a patch bump when patchonly is enabled', () => {
|
|
34
|
+
const result = processMessage('feat!: remove old API', '1.2.3', 'pkg', { ...options, patchonly: true }, {});
|
|
35
|
+
expect(result.version).toBe('1.2.4');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('limits minor changes to a patch bump when patchonly is enabled', () => {
|
|
39
|
+
const result = processMessage('feat: add endpoint', '1.2.3', 'pkg', { ...options, patchonly: true }, {});
|
|
40
|
+
expect(result.version).toBe('1.2.4');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('preserves a suffix when patchonly is enabled', () => {
|
|
44
|
+
const result = processMessage('feat!: remove old API', '1.2.3-devA', 'pkg', { ...options, patchonly: true }, {});
|
|
45
|
+
expect(result.version).toBe('1.2.4-devA');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('adds a forced suffix when the version has none', () => {
|
|
49
|
+
const result = processMessage('fix: adjust typo', '1.2.3', 'pkg', { ...options, suffix: 'devA' }, {});
|
|
50
|
+
expect(result.version).toBe('1.2.4-devA');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('replaces an existing suffix with the forced suffix', () => {
|
|
54
|
+
const result = processMessage('feat: add endpoint', '1.2.3-old', 'pkg', { ...options, suffix: '-devA' }, {});
|
|
55
|
+
expect(result.version).toBe('1.3.0-devA');
|
|
56
|
+
});
|
|
57
|
+
|
|
28
58
|
it('classifies bump types directly', () => {
|
|
29
59
|
expect(getBumpType('feat(parser): support x')).toBe('minor');
|
|
30
60
|
expect(getBumpType('refactor(core): split module')).toBe('minor');
|