@invarn/cibuild 1.9.4 → 1.9.6

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.
@@ -23,4 +23,10 @@ export { handleBuildCommand } from "./build.js";
23
23
  export { handleResetCommand } from "./reset.js";
24
24
  export { detectMobileProjectRoot } from "../shared/detect-project.js";
25
25
  export type { MobileProjectType } from "../shared/detect-project.js";
26
+ export { scanIosProject, formatIosScanResult } from "./ios-scanner.js";
27
+ export type { IosScanResult, IosWarning, IosWarningCategory, IosWarningSeverity, } from "./ios-scanner.js";
28
+ export { scanAndroidProject, formatScanResult, detectBuildVariants, } from "./android-scanner.js";
29
+ export type { ScanResult as AndroidScanResult, BuildVariants, BuildWarning, WarningCategory, WarningSeverity, } from "./android-scanner.js";
30
+ export { collectFileSecret, findProjectFiles } from "./file-secret-collector.js";
31
+ export type { FileSecretConfig, FileSecretPaths, WorkflowGroup, } from "./file-secret-collector.js";
26
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,YAAY,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAOrE,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvE,YAAY,EACV,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,UAAU,IAAI,iBAAiB,EAC/B,aAAa,EACb,YAAY,EACZ,eAAe,EACf,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACjF,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,GACd,MAAM,4BAA4B,CAAC"}
@@ -19,4 +19,12 @@ export { handleBuildCommand } from "./build.js";
19
19
  export { handleResetCommand } from "./reset.js";
20
20
  // Helpers useful for callers that implement their own variations.
21
21
  export { detectMobileProjectRoot } from "../shared/detect-project.js";
22
+ // Project scanners — pure, toolchain-free file-content detectors. Exposed
23
+ // so external callers (the Invarn CLI) can detect build variables and
24
+ // secret-bearing files from a checkout and push them to the backend,
25
+ // rather than re-implementing the same parsing. The scanners take a
26
+ // project-root path and read file contents only — no xcodebuild/gradle.
27
+ export { scanIosProject, formatIosScanResult } from "./ios-scanner.js";
28
+ export { scanAndroidProject, formatScanResult, detectBuildVariants, } from "./android-scanner.js";
29
+ export { collectFileSecret, findProjectFiles } from "./file-secret-collector.js";
22
30
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAkBxD;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,4HAA4H;IAC5H,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sHAAsH;IACtH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAUrD,CAAC;AAmFF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,gBAAgB;IACnD,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YA0GzF,iBAAiB;CA8LhC;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,gBAAgB;IACnD,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YA4JzF,iBAAiB;CAoHhC"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAkBxD;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,4HAA4H;IAC5H,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sHAAsH;IACtH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAUrD,CAAC;AAmFF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,gBAAgB;IACnD,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YA0GzF,iBAAiB;CA8LhC;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,gBAAgB;IACnD,OAAO,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;YAgKzF,iBAAiB;CA4HhC"}
@@ -484,9 +484,13 @@ export class CachePushStepExecutor extends BaseStepExecutor {
484
484
  commands.push(' echo "Paths to cache:"');
485
485
  commands.push(' printf " %s\\n" "${PATHS_TO_CACHE[@]}"');
486
486
  }
487
- // Atomic write: .tmp + rename. No lock needed runs are serialized per runner,
488
- // and cross-writer races resolve to last-writer-wins without corruption.
489
- commands.push(' tar -cf - "${PATHS_TO_CACHE[@]}" 2>/dev/null | zstd -3 > "$CACHE_FILE.tmp" && mv "$CACHE_FILE.tmp" "$CACHE_FILE" || true');
487
+ // Atomic write into a per-process-unique temp (CBR-12). The "runs serialized
488
+ // per runner" assumption behind a fixed "$CACHE_FILE.tmp" is false with two VM
489
+ // slots and collides with the host cache daemon mutating this VirtioFS-shared
490
+ // dir; a unique name (PID + $RANDOM) removes the clash. The atomic mv is kept,
491
+ // and a failed compress/mv removes its own temp (no orphan) and stays non-fatal.
492
+ commands.push(' CACHE_TMP="$CACHE_FILE.$$.$RANDOM.tmp"');
493
+ commands.push(' tar -cf - "${PATHS_TO_CACHE[@]}" 2>/dev/null | zstd -3 > "$CACHE_TMP" && mv "$CACHE_TMP" "$CACHE_FILE" || rm -f "$CACHE_TMP"');
490
494
  commands.push(' if [ -f "$CACHE_FILE" ]; then');
491
495
  commands.push(' echo "Cache created successfully"');
492
496
  if (isDebugMode) {
@@ -587,7 +591,15 @@ export class CachePushStepExecutor extends BaseStepExecutor {
587
591
  // build. Atomic .tmp + mv overwrites any prior tarball under this key.
588
592
  commands.push('if [ ${#PATHS_TO_CACHE[@]} -gt 0 ]; then');
589
593
  commands.push(' echo "Caching ${#PATHS_TO_CACHE[@]} path(s)..."');
590
- commands.push(' tar -cf - "${PATHS_TO_CACHE[@]}" 2>/dev/null | zstd -3 > "$CACHE_FILE.tmp" && mv "$CACHE_FILE.tmp" "$CACHE_FILE" || true');
594
+ // Per-process-unique temp (CBR-12). The old fixed "$CACHE_FILE.tmp" assumed
595
+ // a single serialized writer — false with two VM slots, and it collides with
596
+ // the host cache daemon mutating this VirtioFS-shared dir, which (a) made the
597
+ // guest's own .tmp transiently vanish at `mv` (silent clobber, masked by
598
+ // `|| true`) and (b) dropped VirtioFS off its async fast path. A unique name
599
+ // removes the collision; the atomic mv into place is preserved, and a failed
600
+ // compress/mv removes its own temp (no orphan) while staying non-fatal.
601
+ commands.push(' CACHE_TMP="$CACHE_FILE.$$.$RANDOM.tmp"');
602
+ commands.push(' tar -cf - "${PATHS_TO_CACHE[@]}" 2>/dev/null | zstd -3 > "$CACHE_TMP" && mv "$CACHE_TMP" "$CACHE_FILE" || rm -f "$CACHE_TMP"');
591
603
  commands.push(' if [ -f "$CACHE_FILE" ]; then');
592
604
  commands.push(' echo "Cache created successfully"');
593
605
  if (isDebugMode) {
@@ -336,6 +336,20 @@ describe('Step Implementations', () => {
336
336
  const result = await executor.execute(inputs, {}, testConfig);
337
337
  expect(result.script).toContain('skipped');
338
338
  });
339
+ test('uses a per-process-unique temp for the atomic write (CBR-12)', async () => {
340
+ const executor = new CachePushStepExecutor();
341
+ const result = await executor.execute({ technology: 'kmm' }, {}, testConfig);
342
+ // The old fixed "$CACHE_FILE.tmp" assumed a single writer ("runs
343
+ // serialized per runner") — false with two VM slots, and it collides with
344
+ // the host cache daemon mutating the same VirtioFS-shared dir. A unique
345
+ // temp (PID + $RANDOM) removes the collision; the atomic mv is preserved.
346
+ expect(result.script).not.toContain('> "$CACHE_FILE.tmp"');
347
+ expect(result.script).toContain('CACHE_TMP="$CACHE_FILE.$$.$RANDOM.tmp"');
348
+ expect(result.script).toContain('mv "$CACHE_TMP" "$CACHE_FILE"');
349
+ // A failed compress/mv cleans its own temp instead of leaking orphans,
350
+ // and stays non-fatal (never fails the build).
351
+ expect(result.script).toContain('rm -f "$CACHE_TMP"');
352
+ });
339
353
  test('should require cache_paths', async () => {
340
354
  const executor = new CachePushStepExecutor();
341
355
  const inputs = {
@@ -421,8 +435,8 @@ describe('Step Implementations', () => {
421
435
  test('should use atomic write (tmp + mv) for preset push', async () => {
422
436
  const executor = new CachePushStepExecutor();
423
437
  const result = await executor.execute({ technology: 'gradle' }, {}, testConfig);
424
- expect(result.script).toContain('> "$CACHE_FILE.tmp"');
425
- expect(result.script).toContain('mv "$CACHE_FILE.tmp" "$CACHE_FILE"');
438
+ expect(result.script).toContain('> "$CACHE_TMP"');
439
+ expect(result.script).toContain('mv "$CACHE_TMP" "$CACHE_FILE"');
426
440
  });
427
441
  test('should NOT emit guest-side retention (the peer cache daemon owns it, CBR-6)', async () => {
428
442
  // ADR 0002 / CBR-6: retention moved into the long-lived peer cache daemon,
@@ -447,8 +461,8 @@ describe('Step Implementations', () => {
447
461
  test('should use atomic write (tmp + mv) for manual cache_key push', async () => {
448
462
  const executor = new CachePushStepExecutor();
449
463
  const result = await executor.execute({ cache_key: 'my-key', cache_paths: ['build'] }, {}, testConfig);
450
- expect(result.script).toContain('> "$CACHE_FILE.tmp"');
451
- expect(result.script).toContain('mv "$CACHE_FILE.tmp" "$CACHE_FILE"');
464
+ expect(result.script).toContain('> "$CACHE_TMP"');
465
+ expect(result.script).toContain('mv "$CACHE_TMP" "$CACHE_FILE"');
452
466
  });
453
467
  });
454
468
  describe('XcodeBuildStepExecutor', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invarn/cibuild",
3
- "version": "1.9.4",
3
+ "version": "1.9.6",
4
4
  "description": "CI Build CLI — local pipeline orchestration and validation",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",