@invarn/cibuild 2.6.2 → 2.6.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAMA,OAAO,uBAAuB,CAAC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AASA,OAAO,uBAAuB,CAAC"}
package/dist/src/cli.js CHANGED
@@ -1,6 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { resolve, extname } from "node:path";
3
3
  import { existsSync, readdirSync, readFileSync } from "node:fs";
4
+ // Static — see the note in `yaml/steps/android.ts`. `pkg` cannot evaluate a
5
+ // dynamic `import()` of a builtin.
6
+ import { createInterface } from "node:readline";
4
7
  import prompts from "prompts";
5
8
  import { SecretsManager } from "./yaml/secrets-manager.js";
6
9
  import "./yaml/steps/index.js"; // Initialize step registry
@@ -255,7 +258,6 @@ Examples:
255
258
  }
256
259
  else {
257
260
  // Collect value interactively via readline (handles multiline paste cleanly)
258
- const { createInterface } = await import('node:readline');
259
261
  console.log(`\n Enter value for ${varName}`);
260
262
  console.log(' Paste content, then type . on its own line and press Enter:\n');
261
263
  if (process.stdin.isTTY) {
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/run.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA0I3E"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/run.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAiJ3E"}
@@ -109,6 +109,13 @@ export async function handleRunCommand(opts = {}) {
109
109
  await runner.runPipeline(pipeline, conversionResult.warnings, conversionResult.skippedSteps);
110
110
  }
111
111
  else if (isJavaScriptModule) {
112
+ // The one dynamic import that has to stay dynamic: the specifier is a
113
+ // user-supplied path, so no bundler can inline it. That means this
114
+ // branch does NOT work in the `pkg`-built macOS binary — it throws
115
+ // `Invalid host defined options` before the module loads. Nothing
116
+ // reaches it today: every curated template is YAML, and the runner only
117
+ // ever executes YAML pipelines. If JS pipelines are ever exposed as a
118
+ // supported path, they need a loader that does not rely on `import()`.
112
119
  console.log(`Loading pipeline: ${pipelinePath}`);
113
120
  const pipelineUrl = pathToFileURL(pipelinePath).href;
114
121
  const pipelineModule = await import(pipelineUrl);
@@ -1 +1 @@
1
- {"version":3,"file":"interactive-prompts.d.ts","sourceRoot":"","sources":["../../../src/yaml/interactive-prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,CAAS;gBAEd,cAAc,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,MAAM;IAK7D;;;;;;OAMG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,CAAC;IA4FxB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;;;OAIG;YACW,WAAW;IAWzB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IA0BvB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAyBhB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;;OAGG;YACW,eAAe;IAuC7B;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
1
+ {"version":3,"file":"interactive-prompts.d.ts","sourceRoot":"","sources":["../../../src/yaml/interactive-prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,CAAS;gBAEd,cAAc,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,MAAM;IAK7D;;;;;;OAMG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,CAAC;IA4FxB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAe3B;;;;OAIG;YACW,WAAW;IAWzB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IA0BvB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAyBhB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAkBxB;;;OAGG;YACW,eAAe;IAqC7B;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
@@ -2,6 +2,9 @@
2
2
  * Interactive prompts for missing environment variables
3
3
  * Allows users to fill in missing values or cancel the build
4
4
  */
5
+ // Static — see the note in `steps/android.ts`. `pkg` cannot evaluate a
6
+ // dynamic `import()` of a builtin.
7
+ import { spawn } from 'node:child_process';
5
8
  import prompts from 'prompts';
6
9
  /**
7
10
  * Interactive prompt manager for collecting missing environment variables
@@ -212,7 +215,6 @@ Finish with a short "Follow-up questions" numbered list only if clarification wo
212
215
  * @param text Text to copy
213
216
  */
214
217
  async copyToClipboard(text) {
215
- const { spawn } = await import('child_process');
216
218
  return new Promise((resolve, reject) => {
217
219
  // Detect platform and use appropriate clipboard command
218
220
  const platform = process.platform;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Unit tests for what happens when a pre-execution check cannot run.
3
+ *
4
+ * A check that *ran* and found nothing, and a check that *threw* before it
5
+ * tested anything, are different events. Until 2026-09-01 they were reported
6
+ * identically: the throw was wrapped in a `Check failed:` message and carried
7
+ * the requirement's own declared severity. For the Java JDK requirement that
8
+ * severity is `info` — chosen because the check looks in several places and a
9
+ * miss is not fatal — so a check that never looked anywhere at all was
10
+ * reported as information and read as noise.
11
+ *
12
+ * It was not noise. The released macOS binary is built with `pkg`, which
13
+ * cannot evaluate a dynamic `import()` of a module it did not bundle; the JDK
14
+ * check opened with two of them and threw `Invalid host defined options` on
15
+ * every macOS build. It went unseen for as long as the fleet has existed.
16
+ *
17
+ * Two rules are pinned here:
18
+ * 1. a throw is reported at `warning`, whatever the requirement declares;
19
+ * 2. no check may reach for a Node builtin through a dynamic import, because
20
+ * nothing else in the test suite can see that failure — under plain
21
+ * `node`, and in the npm bundle, the code works.
22
+ */
23
+ export {};
24
+ //# sourceMappingURL=step-validator-check-failure.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-validator-check-failure.test.d.ts","sourceRoot":"","sources":["../../../src/yaml/step-validator-check-failure.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Unit tests for what happens when a pre-execution check cannot run.
3
+ *
4
+ * A check that *ran* and found nothing, and a check that *threw* before it
5
+ * tested anything, are different events. Until 2026-09-01 they were reported
6
+ * identically: the throw was wrapped in a `Check failed:` message and carried
7
+ * the requirement's own declared severity. For the Java JDK requirement that
8
+ * severity is `info` — chosen because the check looks in several places and a
9
+ * miss is not fatal — so a check that never looked anywhere at all was
10
+ * reported as information and read as noise.
11
+ *
12
+ * It was not noise. The released macOS binary is built with `pkg`, which
13
+ * cannot evaluate a dynamic `import()` of a module it did not bundle; the JDK
14
+ * check opened with two of them and threw `Invalid host defined options` on
15
+ * every macOS build. It went unseen for as long as the fleet has existed.
16
+ *
17
+ * Two rules are pinned here:
18
+ * 1. a throw is reported at `warning`, whatever the requirement declares;
19
+ * 2. no check may reach for a Node builtin through a dynamic import, because
20
+ * nothing else in the test suite can see that failure — under plain
21
+ * `node`, and in the npm bundle, the code works.
22
+ */
23
+ import { describe, test, expect } from '@jest/globals';
24
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
25
+ import { join } from 'node:path';
26
+ import { registerStep } from './steps/registry.js';
27
+ import { BaseStepExecutor } from './steps/base.js';
28
+ import { StepValidator } from './step-validator.js';
29
+ import { loadConfig } from '../config.js';
30
+ const config = loadConfig();
31
+ /** A step whose single requirement behaves however the test needs it to. */
32
+ function stepWhoseCheck(severity, check) {
33
+ const name = `probe-${Math.random().toString(36).slice(2)}`;
34
+ class ProbeStep extends BaseStepExecutor {
35
+ async execute() {
36
+ return this.createScriptStep('echo probe', name);
37
+ }
38
+ getValidationRequirements() {
39
+ return [
40
+ {
41
+ category: 'command',
42
+ name: 'probe-tool',
43
+ description: 'A tool the probe step needs',
44
+ timing: 'pre-execution',
45
+ severity,
46
+ check,
47
+ },
48
+ ];
49
+ }
50
+ }
51
+ registerStep(name, new ProbeStep());
52
+ return name;
53
+ }
54
+ async function validate(stepName) {
55
+ const validator = new StepValidator({
56
+ format_version: '1',
57
+ meta: { invarn: { stack: 'macos-xcode-26.4' } },
58
+ workflows: { primary: { steps: [{ [`${stepName}@1.0.0`]: { inputs: {} } }] } },
59
+ }, 'primary', config);
60
+ return validator.validateWorkflow();
61
+ }
62
+ describe('a check that could not run', () => {
63
+ test('is reported as a warning even though the requirement declares info', async () => {
64
+ const name = stepWhoseCheck('info', async () => {
65
+ throw new Error('Invalid host defined options');
66
+ });
67
+ const result = await validate(name);
68
+ expect(result.counts).toMatchObject({ errors: 0, warnings: 1, info: 0 });
69
+ expect(result.issues[0].requirement.severity).toBe('warning');
70
+ expect(result.issues[0].result.message).toBe('Check failed: Invalid host defined options');
71
+ });
72
+ test('does not turn a hard requirement into a soft one', async () => {
73
+ const name = stepWhoseCheck('error', async () => {
74
+ throw new Error('boom');
75
+ });
76
+ const result = await validate(name);
77
+ // An `error` requirement whose check throws must not be downgraded — that
78
+ // would let a pipeline proceed past a requirement nothing verified.
79
+ expect(result.counts).toMatchObject({ errors: 1, warnings: 0, info: 0 });
80
+ expect(result.valid).toBe(false);
81
+ });
82
+ test('leaves a check that ran and failed at its declared severity', async () => {
83
+ const name = stepWhoseCheck('info', async () => ({
84
+ passed: false,
85
+ message: 'Java 17 not found',
86
+ }));
87
+ const result = await validate(name);
88
+ // The whole point of the distinction: this check *worked*. `info` is the
89
+ // right severity for it and must survive.
90
+ expect(result.counts).toMatchObject({ errors: 0, warnings: 0, info: 1 });
91
+ expect(result.issues[0].result.message).toBe('Java 17 not found');
92
+ });
93
+ });
94
+ /**
95
+ * The structural half.
96
+ *
97
+ * esbuild leaves a dynamic `import()` of a Node builtin in the bundle — the
98
+ * builtins are external — and `pkg` then cannot evaluate it. Relative
99
+ * specifiers are inlined by the bundler and are unaffected, which is why
100
+ * `envman` and `fidelity-trim` work while the JDK check did not.
101
+ *
102
+ * There is no runtime test that can catch this: it reproduces only in a
103
+ * `pkg`-built binary, and `./test.sh` runs under plain `node`. So the rule is
104
+ * enforced on the source.
105
+ */
106
+ describe('no source file reaches for a Node builtin through a dynamic import', () => {
107
+ const BUILTIN = /await import\(\s*['"](?:node:)?(fs|path|os|child_process|readline|crypto|util|url|http|https|net|stream|zlib|tty|events)(?:\/[\w-]+)?['"]\s*\)/;
108
+ function sourceFiles(dir) {
109
+ return readdirSync(dir).flatMap((entry) => {
110
+ const full = join(dir, entry);
111
+ if (statSync(full).isDirectory())
112
+ return sourceFiles(full);
113
+ if (!full.endsWith('.ts') || full.endsWith('.test.ts'))
114
+ return [];
115
+ return [full];
116
+ });
117
+ }
118
+ test('src is clean', () => {
119
+ // Jest runs from the package root; `src` is the whole surface that gets
120
+ // bundled into the released binary.
121
+ const offenders = sourceFiles(join(process.cwd(), 'src'))
122
+ .flatMap((file) => readFileSync(file, 'utf8')
123
+ .split('\n')
124
+ .map((line, i) => ({ file, line: line.trim(), n: i + 1 }))
125
+ .filter(({ line }) => BUILTIN.test(line)))
126
+ .map(({ file, n, line }) => `${file.replace(/.*\/src\//, 'src/')}:${n} ${line}`);
127
+ expect(offenders).toEqual([]);
128
+ });
129
+ });
130
+ //# sourceMappingURL=step-validator-check-failure.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"step-validator.d.ts","sourceRoot":"","sources":["../../../src/yaml/step-validator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EAAE,YAAY,EAA4B,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAGV,wBAAwB,EAGzB,MAAM,uBAAuB,CAAC;AAwB/B;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,YAAY,CAAC,CAAS;IAG9B,OAAO,CAAC,gBAAgB,CAAoE;IAG5F,OAAO,CAAC,mBAAmB,CAA6B;IAKxD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;gBAGvC,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,QAAQ,EAChB,YAAY,CAAC,EAAE,MAAM;IA0BvB;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAkN3D;;OAEG;YACW,mBAAmB;IAsDjC;;;;;;;;;OASG;IACH,OAAO,CAAC,yBAAyB;IAsBjC;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,SAAS;CA8BlB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM,CA4D/E"}
1
+ {"version":3,"file":"step-validator.d.ts","sourceRoot":"","sources":["../../../src/yaml/step-validator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,KAAK,EAAE,YAAY,EAA4B,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAGV,wBAAwB,EAGzB,MAAM,uBAAuB,CAAC;AAwB/B;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,YAAY,CAAC,CAAS;IAG9B,OAAO,CAAC,gBAAgB,CAAoE;IAG5F,OAAO,CAAC,mBAAmB,CAA6B;IAKxD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;gBAGvC,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,QAAQ,EAChB,YAAY,CAAC,EAAE,MAAM;IA0BvB;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAkN3D;;OAEG;YACW,mBAAmB;IAmEjC;;;;;;;;;OASG;IACH,OAAO,CAAC,yBAAyB;IAsBjC;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;OAEG;IACH,OAAO,CAAC,SAAS;CA8BlB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM,CA4D/E"}
@@ -280,10 +280,22 @@ export class StepValidator {
280
280
  }
281
281
  }
282
282
  catch (error) {
283
+ // A check that threw did not run. That is a different event from a
284
+ // check that ran and found nothing, and it must not inherit the
285
+ // severity chosen for the latter: `info` is a reasonable verdict for
286
+ // "looked in several places, found no JDK" and a useless one for
287
+ // "never looked". Reported at `warning` so it is visible on the first
288
+ // build — a check whose own failure reads as information can stay
289
+ // broken for as long as nobody reads carefully.
290
+ //
291
+ // `error` is never downgraded. A hard requirement nothing could verify
292
+ // is not softer than one that was verified and failed.
283
293
  return {
284
294
  stepName,
285
295
  stepIndex,
286
- requirement,
296
+ requirement: requirement.severity === 'error'
297
+ ? requirement
298
+ : { ...requirement, severity: 'warning' },
287
299
  result: {
288
300
  passed: false,
289
301
  message: `Check failed: ${error instanceof Error ? error.message : String(error)}`,
@@ -1 +1 @@
1
- {"version":3,"file":"android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/android.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/android.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,13 @@
1
1
  /**
2
2
  * Android step implementations (set-java-version, gradle-build, android-lint, android-unit-test)
3
3
  */
4
+ // Static, deliberately. The released macOS binary is built with `pkg`, which
5
+ // cannot evaluate a dynamic `import()` of a builtin — esbuild leaves those
6
+ // external, so they survive into the bundle as real imports and throw
7
+ // `Invalid host defined options` at runtime. A validation check that reaches
8
+ // for one never runs on a runner.
9
+ import { existsSync, readFileSync } from 'node:fs';
10
+ import { execSync } from 'node:child_process';
4
11
  import { BaseStepExecutor } from './base.js';
5
12
  /**
6
13
  * Set Java version step executor
@@ -28,8 +35,6 @@ export class SetJavaVersionStepExecutor extends BaseStepExecutor {
28
35
  * Matches the logic in execute() method
29
36
  */
30
37
  async checkJavaVersionWithHomebrew(version) {
31
- const { existsSync } = await import('node:fs');
32
- const { execSync } = await import('node:child_process');
33
38
  // Check Homebrew paths first (same order as execute())
34
39
  const homebrewPaths = [
35
40
  `/opt/homebrew/opt/openjdk@${version}`, // Apple Silicon
@@ -48,7 +53,6 @@ export class SetJavaVersionStepExecutor extends BaseStepExecutor {
48
53
  const jbrPath = '/Applications/Android Studio.app/Contents/jbr/Contents/Home';
49
54
  if (existsSync(jbrPath)) {
50
55
  try {
51
- const { readFileSync } = await import('node:fs');
52
56
  const releaseContent = readFileSync(`${jbrPath}/release`, 'utf-8');
53
57
  const jbrVersionMatch = /JAVA_VERSION="(\d+)/.exec(releaseContent);
54
58
  if (jbrVersionMatch && jbrVersionMatch[1] === String(version)) {
@@ -1 +1 @@
1
- {"version":3,"file":"bitrise-android-tools.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/bitrise-android-tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;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,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,qBAAa,+BAAgC,SAAQ,gBAAgB;IACnE,yBAAyB,CACvB,OAAO,EAAE,yBAAyB,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,OAAO,EAAE,QAAQ,GAChB,qBAAqB,EAAE;IAiD1B,UAAU,IAAI,UAAU,EAAE;IAMpB,OAAO,CAAC,MAAM,EAAE,yBAAyB,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;CAyJlH"}
1
+ {"version":3,"file":"bitrise-android-tools.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/bitrise-android-tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,qBAAa,+BAAgC,SAAQ,gBAAgB;IACnE,yBAAyB,CACvB,OAAO,EAAE,yBAAyB,EAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,OAAO,EAAE,QAAQ,GAChB,qBAAqB,EAAE;IA+C1B,UAAU,IAAI,UAAU,EAAE;IAMpB,OAAO,CAAC,MAAM,EAAE,yBAAyB,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;CAyJlH"}
@@ -2,6 +2,10 @@
2
2
  * Bitrise install-missing-android-tools step implementation
3
3
  * Maps Bitrise install-missing-android-tools@* to CI Build Android environment setup
4
4
  */
5
+ // Static — see the note in `android.ts`. A dynamic `import()` of a builtin
6
+ // throws under the `pkg`-built binary the macOS runners use.
7
+ import { existsSync } from 'node:fs';
8
+ import { homedir } from 'node:os';
5
9
  import { BaseStepExecutor } from './base.js';
6
10
  /**
7
11
  * Bitrise install-missing-android-tools step executor (FR-3)
@@ -28,8 +32,6 @@ export class BitriseAndroidToolsStepExecutor extends BaseStepExecutor {
28
32
  };
29
33
  }
30
34
  // Check if we can auto-detect
31
- const { existsSync } = await import('node:fs');
32
- const { homedir } = await import('node:os');
33
35
  const homeDir = homedir();
34
36
  const commonPaths = [
35
37
  `${homeDir}/Library/Android/sdk`, // macOS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invarn/cibuild",
3
- "version": "2.6.2",
3
+ "version": "2.6.3",
4
4
  "description": "CI Build CLI — local pipeline orchestration and validation",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",