@invarn/cibuild 1.5.4 → 1.5.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.
@@ -1,11 +1,15 @@
1
1
  import type { YAMLPipeline } from "../yaml/types.js";
2
2
  import type { CIConfig } from "../types.js";
3
3
  /**
4
- * True only when stdin AND stdout are real TTYs. Sandboxed runs
5
- * (Tart guest via `tart exec`, CI pipelines, redirected shells) all
6
- * fail this check and therefore must never reach an interactive
7
- * prompt hanging on an unanswerable question turns a clear error
8
- * into a silent timeout.
4
+ * True only when stdin AND stdout are real TTYs AND the caller has not
5
+ * explicitly opted out of interactivity.
6
+ *
7
+ * `process.stdin.isTTY` is unreliable as a sole signal: Tart guest
8
+ * sessions opened via `tart exec` attach a pseudo-TTY, so the check
9
+ * passes and the prompt runs — only for nobody to ever answer it. The
10
+ * runner sets `CIBUILD_NON_INTERACTIVE=1` (and the generic `CI=1` env
11
+ * is also honored) to make the override unambiguous regardless of
12
+ * whether the shell looks interactive.
9
13
  */
10
14
  export declare function isInteractiveTTY(): boolean;
11
15
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/shared/prompts.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA0BxF;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,QAAQ,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CAwFlB"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/shared/prompts.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAU1C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA0BxF;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,QAAQ,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CAwFlB"}
@@ -3,13 +3,23 @@ import { StepValidator, formatValidationResult } from "../yaml/step-validator.js
3
3
  import { MissingEnvHandler } from "../yaml/missing-env-handler.js";
4
4
  import { MissingEnvironmentVariableError } from "../yaml/env-resolver.js";
5
5
  /**
6
- * True only when stdin AND stdout are real TTYs. Sandboxed runs
7
- * (Tart guest via `tart exec`, CI pipelines, redirected shells) all
8
- * fail this check and therefore must never reach an interactive
9
- * prompt hanging on an unanswerable question turns a clear error
10
- * into a silent timeout.
6
+ * True only when stdin AND stdout are real TTYs AND the caller has not
7
+ * explicitly opted out of interactivity.
8
+ *
9
+ * `process.stdin.isTTY` is unreliable as a sole signal: Tart guest
10
+ * sessions opened via `tart exec` attach a pseudo-TTY, so the check
11
+ * passes and the prompt runs — only for nobody to ever answer it. The
12
+ * runner sets `CIBUILD_NON_INTERACTIVE=1` (and the generic `CI=1` env
13
+ * is also honored) to make the override unambiguous regardless of
14
+ * whether the shell looks interactive.
11
15
  */
12
16
  export function isInteractiveTTY() {
17
+ if (process.env.CIBUILD_NON_INTERACTIVE === '1' ||
18
+ process.env.CIBUILD_NON_INTERACTIVE === 'true' ||
19
+ process.env.CI === '1' ||
20
+ process.env.CI === 'true') {
21
+ return false;
22
+ }
13
23
  return Boolean(process.stdin.isTTY && process.stdout.isTTY);
14
24
  }
15
25
  /**
@@ -34,12 +34,24 @@ export declare class StepValidator {
34
34
  private validateRequirement;
35
35
  /**
36
36
  * Extracts all $VAR and ${VAR} variable names referenced in an object recursively.
37
+ *
38
+ * `${{ secrets.X }}` / `${{ vars.X }}` references are deliberately ignored:
39
+ * those are resolved by the runner-side interpolator before cibuild sees
40
+ * the YAML (or by the dashboard's secrets-resolver on dispatch). Without
41
+ * this filter the inner regex would capture `{ secrets.X ` as if it were
42
+ * a `${VAR}` reference, producing garbled variable names in the
43
+ * missing-env error output.
37
44
  */
38
45
  private extractVariableReferences;
39
46
  /**
40
47
  * Replaces all unresolved $VAR and ${VAR} references with empty string.
41
48
  * Used as a lenient fallback when full interpolation fails, so that
42
49
  * getValidationRequirements can detect truly-missing variables correctly.
50
+ *
51
+ * `${{ ... }}` refs are left intact — they belong to the runner-side
52
+ * interpolator / dashboard secrets-resolver layer, not to shell-level
53
+ * variable substitution. Stripping them here would destroy the YAML for
54
+ * any downstream consumer that still expects to see them.
43
55
  */
44
56
  private stripUnresolvedVars;
45
57
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"step-validator.d.ts","sourceRoot":"","sources":["../../../src/yaml/step-validator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,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;gBAGtD,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,QAAQ,EAChB,YAAY,CAAC,EAAE,MAAM;IAwBvB;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,wBAAwB,CAAC;IA8M3D;;OAEG;YACW,mBAAmB;IAsDjC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAoBjC;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;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;AAMH,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;gBAGtD,QAAQ,EAAE,YAAY,EACtB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,QAAQ,EAChB,YAAY,CAAC,EAAE,MAAM;IAwBvB;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,wBAAwB,CAAC;IA8M3D;;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"}
@@ -285,13 +285,22 @@ export class StepValidator {
285
285
  }
286
286
  /**
287
287
  * Extracts all $VAR and ${VAR} variable names referenced in an object recursively.
288
+ *
289
+ * `${{ secrets.X }}` / `${{ vars.X }}` references are deliberately ignored:
290
+ * those are resolved by the runner-side interpolator before cibuild sees
291
+ * the YAML (or by the dashboard's secrets-resolver on dispatch). Without
292
+ * this filter the inner regex would capture `{ secrets.X ` as if it were
293
+ * a `${VAR}` reference, producing garbled variable names in the
294
+ * missing-env error output.
288
295
  */
289
296
  extractVariableReferences(obj) {
290
297
  const vars = new Set();
291
298
  if (typeof obj === 'string') {
299
+ // Strip `${{ ... }}` refs first so they can't be mis-matched as `${VAR}`.
300
+ const sanitized = obj.replace(/\$\{\{[^}]*\}\}/g, '');
292
301
  const pattern = /\$\{([^}]+)\}|\$([A-Z_][A-Z_0-9]*)/g;
293
302
  let match;
294
- while ((match = pattern.exec(obj)) !== null) {
303
+ while ((match = pattern.exec(sanitized)) !== null) {
295
304
  vars.add(match[1] || match[2]);
296
305
  }
297
306
  }
@@ -313,10 +322,18 @@ export class StepValidator {
313
322
  * Replaces all unresolved $VAR and ${VAR} references with empty string.
314
323
  * Used as a lenient fallback when full interpolation fails, so that
315
324
  * getValidationRequirements can detect truly-missing variables correctly.
325
+ *
326
+ * `${{ ... }}` refs are left intact — they belong to the runner-side
327
+ * interpolator / dashboard secrets-resolver layer, not to shell-level
328
+ * variable substitution. Stripping them here would destroy the YAML for
329
+ * any downstream consumer that still expects to see them.
316
330
  */
317
331
  stripUnresolvedVars(obj) {
318
332
  if (typeof obj === 'string') {
319
- return obj.replace(/\$\{[^}]+\}|\$[A-Z_][A-Z_0-9]*/g, '');
333
+ // `(?!\{)` prevents `\$\{[^}]+\}` from matching a leading `${` of
334
+ // `${{ ... }}` and stripping the inner content. Plain `$VAR` and
335
+ // `${VAR}` are still stripped as before.
336
+ return obj.replace(/\$\{(?!\{)[^}]+\}|\$[A-Z_][A-Z_0-9]*/g, '');
320
337
  }
321
338
  if (Array.isArray(obj)) {
322
339
  return obj.map((item) => this.stripUnresolvedVars(item));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invarn/cibuild",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "description": "CI Build CLI — local pipeline orchestration and validation",
5
5
  "type": "module",
6
6
  "main": "dist/cli.cjs",