@invarn/cibuild 2.3.7 → 2.4.0

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.
Files changed (36) hide show
  1. package/dist/cli.cjs +54 -37
  2. package/dist/src/cli.js +8 -0
  3. package/dist/src/commands/fidelity-trim.d.ts +13 -0
  4. package/dist/src/commands/fidelity-trim.d.ts.map +1 -0
  5. package/dist/src/commands/fidelity-trim.js +21 -0
  6. package/dist/src/commands/fidelity-trim.test.d.ts +8 -0
  7. package/dist/src/commands/fidelity-trim.test.d.ts.map +1 -0
  8. package/dist/src/commands/fidelity-trim.test.js +79 -0
  9. package/dist/src/yaml/steps/render-post-processor.d.ts +52 -32
  10. package/dist/src/yaml/steps/render-post-processor.d.ts.map +1 -1
  11. package/dist/src/yaml/steps/render-post-processor.js +104 -205
  12. package/dist/src/yaml/steps/render-post-processor.test.d.ts +7 -10
  13. package/dist/src/yaml/steps/render-post-processor.test.d.ts.map +1 -1
  14. package/dist/src/yaml/steps/render-post-processor.test.js +80 -183
  15. package/dist/src/yaml/steps/trim-align-corpus.test.d.ts +28 -0
  16. package/dist/src/yaml/steps/trim-align-corpus.test.d.ts.map +1 -0
  17. package/dist/src/yaml/steps/trim-align-corpus.test.js +383 -0
  18. package/dist/src/yaml/steps/trim-align.d.ts +85 -0
  19. package/dist/src/yaml/steps/trim-align.d.ts.map +1 -0
  20. package/dist/src/yaml/steps/trim-align.js +348 -0
  21. package/dist/src/yaml/steps/trim-align.test.d.ts +11 -0
  22. package/dist/src/yaml/steps/trim-align.test.d.ts.map +1 -0
  23. package/dist/src/yaml/steps/trim-align.test.js +258 -0
  24. package/dist/src/yaml/steps/ui-fidelity-preview-android.d.ts +1 -1
  25. package/dist/src/yaml/steps/ui-fidelity-preview-android.d.ts.map +1 -1
  26. package/dist/src/yaml/steps/ui-fidelity-preview-android.js +9 -0
  27. package/dist/src/yaml/steps/ui-fidelity-preview-android.test.js +4 -3
  28. package/dist/src/yaml/steps/ui-fidelity-preview.d.ts.map +1 -1
  29. package/dist/src/yaml/steps/ui-fidelity-preview.js +9 -0
  30. package/dist/src/yaml/steps/ui-fidelity-preview.test.js +13 -3
  31. package/dist/src/yaml/steps/ui-fidelity-render-android.d.ts.map +1 -1
  32. package/dist/src/yaml/steps/ui-fidelity-render-android.js +7 -16
  33. package/dist/src/yaml/steps/ui-fidelity-render-android.test.js +9 -9
  34. package/dist/src/yaml/steps/ui-fidelity-render.js +1 -1
  35. package/dist/src/yaml/steps/ui-fidelity-render.test.js +25 -20
  36. package/package.json +3 -1
@@ -36,10 +36,11 @@ const FAKE_GRADLEW = [
36
36
  // Fake `swift`: only the script-interpreter branch the shared trim stage uses
37
37
  // (`swift <Trim.swift> <in> <out> <aligned> <ref>`). Writes trimmed + aligned
38
38
  // PNGs and emits a fixed TRIMDIMS line.
39
- const FAKE_SWIFT = [
39
+ // Fake `ci` covering the shared trim stage's `ci fidelity-trim` invocation.
40
+ const FAKE_CI = [
40
41
  '#!/bin/bash',
41
42
  'case "$1" in',
42
- ' *.swift)',
43
+ ' fidelity-trim)',
43
44
  ' in_png="$2"; out_png="$3"; aligned_png="$4"',
44
45
  " printf '\\x89PNG\\r\\n\\x1a\\n' > \"$out_png\"",
45
46
  ' printf \'trimmed:%s\' "$(basename "$in_png")" >> "$out_png"',
@@ -56,7 +57,7 @@ function fakeToolchain() {
56
57
  const bin = tempDir('ui-fidelity-android-fakebin-');
57
58
  for (const [name, body] of [
58
59
  ['java', FAKE_JAVA],
59
- ['swift', FAKE_SWIFT],
60
+ ['ci', FAKE_CI],
60
61
  ]) {
61
62
  const p = join(bin, name);
62
63
  writeFileSync(p, body + '\n');
@@ -1 +1 @@
1
- {"version":3,"file":"ui-fidelity-preview.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/ui-fidelity-preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA4BH,+EAA+E;AAC/E,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IACnC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChD,iEAAiE;IACjE,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,4DAA4D;IAC5D,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6DAA6D;IAC7D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAC/C;;;;OAIG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,yEAAyE;IACzE,aAAa,EAAE,QAAQ,CAAC;IACxB,oEAAoE;IACpE,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrD,wDAAwD;IACxD,OAAO,EAAE,6BAA6B,EAAE,CAAC;IACzC,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,EAAE,EAAE,OAAO,CAAC;CACb;AAED,kEAAkE;AAClE,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,UAAU,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;CACjD;AAuBD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,gBAAgB,EACrB,YAAY,EAAE,MAAM,GACnB,6BAA6B,CAgB/B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,uBAAuB,CA8HzB"}
1
+ {"version":3,"file":"ui-fidelity-preview.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/ui-fidelity-preview.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA6BH,+EAA+E;AAC/E,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gEAAgE;IAChE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IACnC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,6BAA6B;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChD,iEAAiE;IACjE,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,4DAA4D;IAC5D,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,6DAA6D;IAC7D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,2BAA2B,GAAG,IAAI,CAAC;IAC/C;;;;OAIG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,yEAAyE;IACzE,aAAa,EAAE,QAAQ,CAAC;IACxB,oEAAoE;IACpE,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrD,wDAAwD;IACxD,OAAO,EAAE,6BAA6B,EAAE,CAAC;IACzC,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,EAAE,EAAE,OAAO,CAAC;CACb;AAED,kEAAkE;AAClE,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChD,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,UAAU,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;CACjD;AAuBD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,gBAAgB,EACrB,YAAY,EAAE,MAAM,GACnB,6BAA6B,CAgB/B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,uBAAuB,CAqIzB"}
@@ -21,6 +21,7 @@ import { tmpdir } from 'node:os';
21
21
  import { basename, join, resolve } from 'node:path';
22
22
  import { DEFAULT_RENDER_SIZE, DEFAULT_SCALE, generateRenderScript, parseRenderSize, parseScale, } from './ui-fidelity-render.js';
23
23
  import { evaluateAspectRatio, formatAspectRatioWarning, } from './fidelity-aspect-guard.js';
24
+ import { resolveCliJsPath } from './render-post-processor.js';
24
25
  function runTar(args, pathPrepend) {
25
26
  const env = pathPrepend
26
27
  ? { ...process.env, PATH: pathPrepend + ':' + (process.env.PATH ?? '') }
@@ -143,6 +144,14 @@ export function renderUiFidelityPreview(options) {
143
144
  if (options.toolchainPath) {
144
145
  env.PATH = options.toolchainPath + ':' + (process.env.PATH ?? '');
145
146
  }
147
+ // Hand the script this installation's CLI entrypoint so its trim stage can
148
+ // spawn `fidelity-trim` without a ci on PATH (library callers like the
149
+ // Invarn CLI). Never override an explicitly-set entrypoint.
150
+ if (!env.CIBUILD_CLI_JS) {
151
+ const cliJs = resolveCliJsPath();
152
+ if (cliJs !== null)
153
+ env.CIBUILD_CLI_JS = cliJs;
154
+ }
146
155
  const run = spawnSync('node', ['-e', script], {
147
156
  cwd: workDir,
148
157
  env,
@@ -52,8 +52,16 @@ const FAKE_SWIFT = [
52
52
  ' out="${pos[1]}"',
53
53
  " printf '\\x89PNG\\r\\n\\x1a\\n' > \"$out\"; printf 'fake-render' >> \"$out\"",
54
54
  ' exit 0 ;;',
55
- ' *.swift)',
56
- ' out_png="$2"; aligned_png="$3"',
55
+ ' *) exit 0 ;;',
56
+ 'esac',
57
+ ].join('\n');
58
+ const FAKE_XCRUN = ['#!/bin/bash', 'exit 0'].join('\n');
59
+ // Fake `ci` covering the shared trim stage's `ci fidelity-trim` invocation.
60
+ const FAKE_CI = [
61
+ '#!/bin/bash',
62
+ 'case "$1" in',
63
+ ' fidelity-trim)',
64
+ ' out_png="$3"; aligned_png="$4"',
57
65
  " printf '\\x89PNG\\r\\n\\x1a\\n' > \"$out_png\"; printf 'trimmed' >> \"$out_png\"",
58
66
  ' if [ -n "$aligned_png" ]; then printf \'\\x89PNG\\r\\n\\x1a\\n\' > "$aligned_png"; printf \'aligned\' >> "$aligned_png"; fi',
59
67
  ' echo "TRIMDIMS 320 640 160 320 400 800"',
@@ -61,7 +69,6 @@ const FAKE_SWIFT = [
61
69
  ' *) exit 0 ;;',
62
70
  'esac',
63
71
  ].join('\n');
64
- const FAKE_XCRUN = ['#!/bin/bash', 'exit 0'].join('\n');
65
72
  function fakeToolchain() {
66
73
  const bin = tempDir('ui-fidelity-fakebin-');
67
74
  const swiftPath = join(bin, 'swift');
@@ -70,6 +77,9 @@ function fakeToolchain() {
70
77
  const xcrunPath = join(bin, 'xcrun');
71
78
  writeFileSync(xcrunPath, FAKE_XCRUN + '\n');
72
79
  chmodSync(xcrunPath, 0o755);
80
+ const ciPath = join(bin, 'ci');
81
+ writeFileSync(ciPath, FAKE_CI + '\n');
82
+ chmodSync(ciPath, 0o755);
73
83
  return bin;
74
84
  }
75
85
  function writeReference() {
@@ -1 +1 @@
1
- {"version":3,"file":"ui-fidelity-render-android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/ui-fidelity-render-android.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAMpE,sDAAsD;AACtD,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,iDAAiD;AACjD,eAAO,MAAM,eAAe,6BAA8B,CAAC;AAC3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAAwB,CAAC;AAE9D,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,6BAA8B,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,eAA0B,CAAC;AAElE,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,8EAA8E;AAC9E,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAkiCD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,CAqBrF;AAED;;;GAGG;AACH,qBAAa,mCAAoC,SAAQ,gBAAgB;IACvE,yBAAyB,CACvB,OAAO,EAAE,6BAA6B,EACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,qBAAqB,EAAE;IAepB,OAAO,CACX,MAAM,EAAE,6BAA6B,EACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,OAAO,CAAC;CA0EpB"}
1
+ {"version":3,"file":"ui-fidelity-render-android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/ui-fidelity-render-android.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAMpE,sDAAsD;AACtD,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,iDAAiD;AACjD,eAAO,MAAM,eAAe,6BAA8B,CAAC;AAC3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAAwB,CAAC;AAE9D,mDAAmD;AACnD,eAAO,MAAM,iBAAiB,6BAA8B,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,eAA0B,CAAC;AAElE,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,8EAA8E;AAC9E,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAuhCD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,CAqBrF;AAED;;;GAGG;AACH,qBAAa,mCAAoC,SAAQ,gBAAgB;IACvE,yBAAyB,CACvB,OAAO,EAAE,6BAA6B,EACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,qBAAqB,EAAE;IAapB,OAAO,CACX,MAAM,EAAE,6BAA6B,EACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,OAAO,CAAC;CA0EpB"}
@@ -500,20 +500,9 @@ function cleanupShippedProject() {
500
500
 
501
501
  // ---- render stage ----
502
502
  //
503
- // runSwift drives the shared CoreGraphics trim/align helper in script-
504
- // interpreter mode (the same helper iOS uses); it is available because the
505
- // render runs on the macOS runner fleet regardless of the JVM render engine.
506
-
507
- function runSwift(args) {
508
- var result = cp.spawnSync('swift', args, { encoding: 'utf-8', maxBuffer: 16 * 1024 * 1024 });
509
- if (result.stdout) process.stdout.write(result.stdout);
510
- if (result.stderr) process.stderr.write(result.stderr);
511
- if (result.error) {
512
- result.status = result.status == null ? 127 : result.status;
513
- result.stderr = (result.stderr || '') + String(result.error.message || result.error);
514
- }
515
- return result;
516
- }
503
+ // Trim/align runs through the shared trim stage's runTrimHelper (the pure-JS
504
+ // helper inside the ci binary — the same bytes iOS uses), so this step has no
505
+ // platform-toolchain dependency and runs on macOS and Linux workers alike.
517
506
 
518
507
  // Runs the project's Roborazzi record task once, from the project root, so
519
508
  // Gradle resolves the task in whichever module declares it. Prefers the shipped
@@ -692,7 +681,7 @@ function renderScreens(renderable, projectRoot) {
692
681
  entry.source_digest = __fidSourceDigest(packageFiles, referenceBytes);
693
682
  }
694
683
  log('rendered ' + entry.screen + ' -> ' + relative);
695
- trimRenderedImage(entry, outputPath, workDir);
684
+ trimRenderedImage(entry, outputPath);
696
685
  // Signal A: the render emits a per-node layout dump into a roborazzi
697
686
  // output dir (named "<Screen>.layout.json" or "...render<Screen>.layout.json").
698
687
  // Locate it the same way as the PNG and derive structural facts; absent or
@@ -1160,8 +1149,10 @@ export function generateAndroidRenderScript(config) {
1160
1149
  */
1161
1150
  export class UiFidelityRenderAndroidStepExecutor extends BaseStepExecutor {
1162
1151
  getValidationRequirements(_inputs, _env, _config) {
1152
+ // No platform-toolchain requirement: trim/align is pure JS inside the ci
1153
+ // binary (fidelity-linux 06), so the step validates on macOS and Linux
1154
+ // runners alike.
1163
1155
  return [
1164
- this.requireCommand('swift', 'Swift toolchain used to run the CoreGraphics trim/align helper', 'Install Xcode (or the Swift toolchain) on the runner'),
1165
1156
  this.requireCommand('tar', 'Archive tool used to extract the shipped Gradle project', 'Install tar on the runner'),
1166
1157
  ];
1167
1158
  }
@@ -57,14 +57,14 @@ const FAKE_GRADLEW_LINES = [
57
57
  'done',
58
58
  'exit 0',
59
59
  ];
60
- // Fake `swift`, providing only the script-interpreter branch the shared trim
61
- // stage uses: `swift <Trim.swift> <in> <out> <aligned> <ref>`. Overwrites
62
- // <out> with a "trimmed:<in basename>" PNG, writes an "aligned:<in basename>"
63
- // PNG, and emits a fixed TRIMDIMS line. FAKE_TRIM_FAIL exercises warn-and-continue.
64
- const FAKE_SWIFT_LINES = [
60
+ // Fake `ci`, providing only the branch the shared trim stage uses:
61
+ // `ci fidelity-trim <in> <out> <aligned> <ref>`. Overwrites <out> with a
62
+ // "trimmed:<in basename>" PNG, writes an "aligned:<in basename>" PNG, and
63
+ // emits a fixed TRIMDIMS line. FAKE_TRIM_FAIL exercises warn-and-continue.
64
+ const FAKE_CI_LINES = [
65
65
  '#!/bin/bash',
66
66
  'case "$1" in',
67
- ' *.swift)',
67
+ ' fidelity-trim)',
68
68
  ' if [ -n "$FAKE_TRIM_FAIL" ]; then echo "trim: simulated failure" >&2; exit 1; fi',
69
69
  ' in_png="$2"; out_png="$3"; aligned_png="$4"',
70
70
  " printf '\\x89PNG\\r\\n\\x1a\\n' > \"$out_png\"",
@@ -84,9 +84,9 @@ function makeProject(params) {
84
84
  mkdirSync(join(dir, '.ci', 'inputs'), { recursive: true });
85
85
  const binDir = join(dir, 'bin');
86
86
  mkdirSync(binDir, { recursive: true });
87
- const swiftPath = join(binDir, 'swift');
88
- writeFileSync(swiftPath, FAKE_SWIFT_LINES.join('\n') + '\n');
89
- chmodSync(swiftPath, 0o755);
87
+ const ciPath = join(binDir, 'ci');
88
+ writeFileSync(ciPath, FAKE_CI_LINES.join('\n') + '\n');
89
+ chmodSync(ciPath, 0o755);
90
90
  if (params !== undefined) {
91
91
  writeFileSync(join(dir, '.ci', 'inputs', 'params.json'), typeof params === 'string' ? params : JSON.stringify(params));
92
92
  }
@@ -1250,7 +1250,7 @@ function buildPackageSourceMain() {
1250
1250
  // crop each rendered PNG to its content bounding box right after it renders.
1251
1251
  main = replaceOnce(main, 'function renderWithHarness(renderable, packagePath) {', RENDER_SCRIPT_TRIM_STAGE + '\nfunction renderWithHarness(renderable, packagePath) {');
1252
1252
  main = replaceOnce(main, " log('rendered ' + entry.screen + ' -> ' + relative);", " log('rendered ' + entry.screen + ' -> ' + relative);\n" +
1253
- ' trimRenderedImage(entry, outputPath, harnessDir);');
1253
+ ' trimRenderedImage(entry, outputPath);');
1254
1254
  // Per-screen result entries gain the trimmed-render fields: the aligned
1255
1255
  // (reference-sized) image and the rendered/logical/reference dimensions.
1256
1256
  // They stay null until a screen renders and is trimmed.
@@ -111,15 +111,24 @@ const FAKE_SWIFT_LINES = [
111
111
  " printf '\\x89PNG\\r\\n\\x1a\\n' > \"$out\"",
112
112
  ' printf \'fake-render:%s\' "$screen" >> "$out"',
113
113
  ' exit 0 ;;',
114
- ' *.swift)',
115
- // Script-interpreter mode (swift <Trim.swift> <in> <out> <aligned> <ref>):
116
- // stands in for the CoreGraphics trim helper. Overwrites <out> with a PNG
117
- // marked "trimmed:<in basename>" and writes an "aligned:<in basename>" PNG so
118
- // tests can prove both outputs. Emits a fixed TRIMDIMS line (rendered
119
- // 320x640, reference 160x320, source 400x800). FAKE_TRIM_FAIL exercises
120
- // warn-and-continue.
114
+ ' *)',
115
+ ' exit 0 ;;',
116
+ 'esac',
117
+ ];
118
+ /**
119
+ * PATH-shimmed fake `ci`, providing only the branch the shared trim stage
120
+ * uses: `ci fidelity-trim <in> <out> <aligned> <ref>`. Overwrites <out> with a
121
+ * PNG marked "trimmed:<in basename>" and writes an "aligned:<in basename>" PNG
122
+ * so tests can prove both outputs. Emits a fixed TRIMDIMS line (rendered
123
+ * 320x640, reference 160x320, source 400x800). FAKE_TRIM_FAIL exercises
124
+ * warn-and-continue.
125
+ */
126
+ const FAKE_CI_LINES = [
127
+ '#!/bin/bash',
128
+ 'case "$1" in',
129
+ ' fidelity-trim)',
121
130
  ' if [ -n "$FAKE_TRIM_FAIL" ]; then echo "trim: simulated failure" >&2; exit 1; fi',
122
- ' in_png="$1"; out_png="$2"; aligned_png="$3"',
131
+ ' in_png="$2"; out_png="$3"; aligned_png="$4"',
123
132
  " printf '\\x89PNG\\r\\n\\x1a\\n' > \"$out_png\"",
124
133
  ' printf \'trimmed:%s\' "$(basename "$in_png")" >> "$out_png"',
125
134
  ' if [ -n "$aligned_png" ]; then',
@@ -128,8 +137,7 @@ const FAKE_SWIFT_LINES = [
128
137
  ' fi',
129
138
  ' echo "TRIMDIMS 320 640 160 320 400 800"',
130
139
  ' exit 0 ;;',
131
- ' *)',
132
- ' exit 0 ;;',
140
+ ' *) exit 0 ;;',
133
141
  'esac',
134
142
  ];
135
143
  /**
@@ -186,6 +194,9 @@ function makeProject(params) {
186
194
  const xcrunPath = join(binDir, 'xcrun');
187
195
  writeFileSync(xcrunPath, FAKE_XCRUN_LINES.join('\n') + '\n');
188
196
  chmodSync(xcrunPath, 0o755);
197
+ const ciPath = join(binDir, 'ci');
198
+ writeFileSync(ciPath, FAKE_CI_LINES.join('\n') + '\n');
199
+ chmodSync(ciPath, 0o755);
189
200
  if (params !== undefined) {
190
201
  writeFileSync(join(dir, '.ci', 'inputs', 'params.json'), typeof params === 'string' ? params : JSON.stringify(params));
191
202
  }
@@ -1016,20 +1027,14 @@ describe('render output trimming (package_source variants)', () => {
1016
1027
  function readArtifact(project, relative) {
1017
1028
  return readFileSync(artifact(project, relative), 'utf-8');
1018
1029
  }
1019
- test('trims the rendered PNG in place via the Swift helper', async () => {
1030
+ test('trims the rendered PNG in place via the ci fidelity-trim helper', async () => {
1020
1031
  const project = makeProject({ screens: { HomeView: 'home.png' } });
1021
1032
  writeReference(project, 'home.png');
1022
1033
  const script = await buildScript(project, { package_source: 'repo' });
1023
- const logPath = join(project.dir, 'swift-invocations.log');
1024
- const run = runScript(project, script, { FAKE_SWIFT_LOG: logPath });
1034
+ const run = runScript(project, script);
1025
1035
  expect(run.status).toBe(0);
1026
- // The helper is invoked in script mode with the rendered PNG as in and out
1027
- // (in-place overwrite), after the render run.
1028
- const invocations = readFileSync(logPath, 'utf-8').trim().split('\n');
1029
- const trimCall = invocations.find((c) => c.includes('Trim.swift'));
1030
- expect(trimCall).toBeTruthy();
1031
- expect(trimCall).toContain('ui-fidelity/rendered/HomeView.png');
1032
- // The rendered file now holds the trim helper's output, not the raw render.
1036
+ // The rendered file now holds the trim helper's output, not the raw render
1037
+ // (the fake ci overwrites in place, proving the in/out in-place contract).
1033
1038
  expect(isPng(artifact(project, 'ui-fidelity/rendered/HomeView.png'))).toBe(true);
1034
1039
  expect(readArtifact(project, 'ui-fidelity/rendered/HomeView.png')).toContain('trimmed:HomeView.png');
1035
1040
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invarn/cibuild",
3
- "version": "2.3.7",
3
+ "version": "2.4.0",
4
4
  "description": "CI Build CLI — local pipeline orchestration and validation",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",
@@ -55,12 +55,14 @@
55
55
  "homepage": "https://github.com/invarnhq/cibuild",
56
56
  "dependencies": {
57
57
  "js-yaml": "^4.1.0",
58
+ "pngjs": "7.0.0",
58
59
  "prompts": "^2.4.2"
59
60
  },
60
61
  "devDependencies": {
61
62
  "@types/jest": "^29.5.14",
62
63
  "@types/js-yaml": "^4.0.9",
63
64
  "@types/node": "^22.10.1",
65
+ "@types/pngjs": "6.0.5",
64
66
  "@types/prompts": "^2.4.9",
65
67
  "@yao-pkg/pkg": "^6.14.1",
66
68
  "esbuild": "^0.27.3",