enablement-build-monorepo-version 2.0.7 → 2.0.9

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/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "enablement-build-monorepo-version",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
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": [
@@ -18,10 +23,5 @@
18
23
  },
19
24
  "devDependencies": {
20
25
  "jest": "^30.4.2"
21
- },
22
- "scripts": {
23
- "start": "node src/index.mjs",
24
- "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
25
- "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch"
26
26
  }
27
27
  }
package/src/index.mjs CHANGED
@@ -35,7 +35,7 @@ function buildHashesForCicd(current) {
35
35
  hashData[entry.fullName] = {
36
36
  hash: entry.hash,
37
37
  version: entry.version,
38
- folderName: shortName,
38
+ name: entry.fullName,
39
39
  packageFolder: entry.packageFolder
40
40
  };
41
41
  versions[entry.fullName] = entry.version;
@@ -155,16 +155,25 @@ async function main(options) {
155
155
  }
156
156
  }
157
157
 
158
- // Load manifest for later use (will extract hashes after building current)
158
+ // Load previous hashes.
159
+ // - hash.json mode: compare directly by short package folder name.
160
+ // - manifest.json mode: defer to full-name mapping after building current.
159
161
  let manifestData = {};
160
162
  if (usesManifestHashFile) {
161
163
  const data = existsSync(changeConfig) ? readFileSync(changeConfig, "utf8") : "{}";
162
164
  manifestData = JSON.parse(data || "{}");
163
- }
164
165
 
165
- // For now, set previous to empty - will populate after building current
166
- // (because we need the fullName mapping from current)
167
- previous = {};
166
+ // Backward compatibility: some manifests may still store hashes in the old
167
+ // flat format. Keep these as a fallback in case cicd is not present.
168
+ if (!manifestData.cicd) {
169
+ previous = convertOldHashFormat(manifestData);
170
+ } else {
171
+ previous = {};
172
+ }
173
+ } else {
174
+ const data = existsSync(changeConfig) ? readFileSync(changeConfig, "utf8") : "{}";
175
+ previous = JSON.parse(data || "{}");
176
+ }
168
177
  if (options.debug) console.log("PREVIOUS", JSON.stringify(previous));
169
178
 
170
179
  options.hashFiles.forEach(file => {
@@ -319,7 +328,8 @@ async function main(options) {
319
328
  if (!manifest.cicd) manifest.cicd = {};
320
329
  if (!manifest.cicd[fullname]) manifest.cicd[fullname] = {};
321
330
  manifest.cicd[fullname].hash = hashData[fullname].hash;
322
- manifest.cicd[fullname].folderName = hashData[fullname].folderName;
331
+ manifest.cicd[fullname].name = hashData[fullname].name;
332
+ delete manifest.cicd[fullname].folderName;
323
333
  manifest.cicd[fullname].packageFolder = hashData[fullname].packageFolder;
324
334
  });
325
335
 
@@ -0,0 +1,120 @@
1
+ import { describe, it, expect } from "@jest/globals";
2
+ import { execFileSync } from "child_process";
3
+ import os from "os";
4
+ import path from "path";
5
+ import { fileURLToPath } from "url";
6
+ import {
7
+ mkdtempSync,
8
+ mkdirSync,
9
+ readFileSync,
10
+ rmSync,
11
+ writeFileSync,
12
+ } from "fs";
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+ const repoRoot = path.resolve(__dirname, "..", "..");
17
+ const cliPath = path.resolve(repoRoot, "monorepo-version", "src", "index.mjs");
18
+
19
+ function setupWorkspace() {
20
+ const root = mkdtempSync(path.join(os.tmpdir(), "monorepo-version-"));
21
+
22
+ mkdirSync(path.join(root, "packages", "example"), { recursive: true });
23
+ mkdirSync(path.join(root, ".cicd"), { recursive: true });
24
+
25
+ writeFileSync(
26
+ path.join(root, "package.json"),
27
+ JSON.stringify(
28
+ {
29
+ name: "tmp-monorepo",
30
+ private: true,
31
+ workspaces: ["packages/*"],
32
+ },
33
+ null,
34
+ 2,
35
+ ) + "\n",
36
+ "utf8",
37
+ );
38
+
39
+ writeFileSync(
40
+ path.join(root, "packages", "example", "package.json"),
41
+ JSON.stringify(
42
+ {
43
+ name: "@scope/example",
44
+ version: "1.0.0",
45
+ },
46
+ null,
47
+ 2,
48
+ ) + "\n",
49
+ "utf8",
50
+ );
51
+
52
+ writeFileSync(path.join(root, "packages", "example", "index.js"), "export default 1;\n", "utf8");
53
+
54
+ return root;
55
+ }
56
+
57
+ function runRelease(root, hashFile) {
58
+ const stdout = execFileSync(
59
+ "node",
60
+ [
61
+ cliPath,
62
+ "--hash",
63
+ "--changed",
64
+ "--children",
65
+ "packages",
66
+ "--prefixPath",
67
+ root,
68
+ "--hashFile",
69
+ hashFile,
70
+ ],
71
+ {
72
+ cwd: repoRoot,
73
+ encoding: "utf8",
74
+ },
75
+ );
76
+
77
+ const changedMatch = stdout.match(/CHANGED - (\[[^\n]*\])/);
78
+ if (!changedMatch) {
79
+ throw new Error(`Could not find changed list in output:\n${stdout}`);
80
+ }
81
+
82
+ return JSON.parse(changedMatch[1]);
83
+ }
84
+
85
+ describe("index CLI hash loading", () => {
86
+ it("supports non-manifest hash mode across repeated runs", () => {
87
+ const root = setupWorkspace();
88
+ try {
89
+ const first = runRelease(root, ".cicd/hash.json");
90
+ const second = runRelease(root, ".cicd/hash.json");
91
+
92
+ expect(first).toContain("example");
93
+ expect(second).toEqual([]);
94
+
95
+ const hashJson = JSON.parse(readFileSync(path.join(root, ".cicd", "hash.json"), "utf8"));
96
+ expect(hashJson.example).toBeDefined();
97
+ expect(hashJson.example.hash).toBeTruthy();
98
+ } finally {
99
+ rmSync(root, { recursive: true, force: true });
100
+ }
101
+ });
102
+
103
+ it("supports manifest hash mode across repeated runs", () => {
104
+ const root = setupWorkspace();
105
+ try {
106
+ const first = runRelease(root, ".cicd/manifest.json");
107
+ const second = runRelease(root, ".cicd/manifest.json");
108
+
109
+ expect(first).toContain("example");
110
+ expect(second).toEqual([]);
111
+
112
+ const manifest = JSON.parse(readFileSync(path.join(root, ".cicd", "manifest.json"), "utf8"));
113
+ expect(manifest.cicd["@scope/example"]).toBeDefined();
114
+ expect(manifest.cicd["@scope/example"].hash).toBeTruthy();
115
+ expect(manifest.versions["@scope/example"]).toBe("1.0.0");
116
+ } finally {
117
+ rmSync(root, { recursive: true, force: true });
118
+ }
119
+ });
120
+ });
@@ -343,6 +343,65 @@ describe("version manifest precedence and updates", () => {
343
343
  rmSync(root, { recursive: true, force: true });
344
344
  });
345
345
 
346
+ it("reads current version and name from version.json when package.json is absent", () => {
347
+ const root = mkdtempSync(path.join(os.tmpdir(), "monorepo-version-"));
348
+ const pkgDir = path.join(root, "packages", "gamma");
349
+ mkdirSync(pkgDir, { recursive: true });
350
+
351
+ writeFileSync(
352
+ path.join(pkgDir, "version.json"),
353
+ JSON.stringify({ name: "@s/gamma-version", version: "2.1.0" }, null, 2),
354
+ "utf8",
355
+ );
356
+ writeFileSync(
357
+ path.join(pkgDir, "pyproject.toml"),
358
+ '[project]\nname = "gamma-toml"\nversion = "3.0.0"\n',
359
+ "utf8",
360
+ );
361
+
362
+ const current = getCurrentVersion(root, "packages", "gamma");
363
+ expect(current.version).toBe("2.1.0");
364
+ expect(current.fullName).toBe("@s/gamma-version");
365
+
366
+ rmSync(root, { recursive: true, force: true });
367
+ });
368
+
369
+ it("reads current version and name from pyproject.toml only when package.json and version.json are absent", () => {
370
+ const root = mkdtempSync(path.join(os.tmpdir(), "monorepo-version-"));
371
+ const pkgDir = path.join(root, "packages", "delta");
372
+ mkdirSync(pkgDir, { recursive: true });
373
+
374
+ writeFileSync(
375
+ path.join(pkgDir, "pyproject.toml"),
376
+ '[project]\nname = "delta-toml"\nversion = "3.2.0"\n',
377
+ "utf8",
378
+ );
379
+
380
+ const current = getCurrentVersion(root, "packages", "delta");
381
+ expect(current.version).toBe("3.2.0");
382
+ expect(current.fullName).toBe("delta-toml");
383
+
384
+ rmSync(root, { recursive: true, force: true });
385
+ });
386
+
387
+ it("does not fall back to folder name when no manifest name exists", () => {
388
+ const root = mkdtempSync(path.join(os.tmpdir(), "monorepo-version-"));
389
+ const pkgDir = path.join(root, "packages", "epsilon");
390
+ mkdirSync(pkgDir, { recursive: true });
391
+
392
+ writeFileSync(
393
+ path.join(pkgDir, "package.json"),
394
+ JSON.stringify({ version: "1.0.0" }, null, 2),
395
+ "utf8",
396
+ );
397
+
398
+ const current = getCurrentVersion(root, "packages", "epsilon");
399
+ expect(current.version).toBe("1.0.0");
400
+ expect(current.fullName).toBeUndefined();
401
+
402
+ rmSync(root, { recursive: true, force: true });
403
+ });
404
+
346
405
  it("updates all version manifests when package.json, version.json, and pyproject.toml exist", async () => {
347
406
  const root = mkdtempSync(path.join(os.tmpdir(), "monorepo-version-"));
348
407
  const pkgDir = path.join(root, "packages", "beta");