@invarn/cibuild 1.5.2 → 1.5.4
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/dist/cli.cjs +1 -1
- package/dist/src/commands/run.d.ts.map +1 -1
- package/dist/src/commands/run.js +5 -2
- package/dist/src/shared/prompts.d.ts +8 -0
- package/dist/src/shared/prompts.d.ts.map +1 -1
- package/dist/src/shared/prompts.js +15 -0
- package/dist/src/yaml/step-validator.d.ts.map +1 -1
- package/dist/src/yaml/step-validator.js +8 -0
- package/dist/src/yaml/steps/cache.d.ts.map +1 -1
- package/dist/src/yaml/steps/cache.js +8 -3
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/commands/run.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/src/commands/run.js
CHANGED
|
@@ -6,7 +6,7 @@ import { PipelineRunner } from "../runner.js";
|
|
|
6
6
|
import { loadConfig } from "../config.js";
|
|
7
7
|
import { loadYAMLPipeline } from "../yaml/parser.js";
|
|
8
8
|
import { convertYAMLWithSecrets } from "../yaml/pipeline-with-secrets.js";
|
|
9
|
-
import { promptForWorkflow, promptForMissingVariables, } from "../shared/prompts.js";
|
|
9
|
+
import { promptForWorkflow, promptForMissingVariables, isInteractiveTTY, } from "../shared/prompts.js";
|
|
10
10
|
/**
|
|
11
11
|
* Run a pipeline locally. Mirrors `ci run <path>`.
|
|
12
12
|
*
|
|
@@ -100,7 +100,10 @@ export async function handleRunCommand(opts = {}) {
|
|
|
100
100
|
config,
|
|
101
101
|
workflowName: selectedWorkflow,
|
|
102
102
|
yamlFilePath: pipelinePath,
|
|
103
|
-
|
|
103
|
+
// Only prompt when stdin/stdout are real TTYs. Sandboxed runs
|
|
104
|
+
// (Tart guest, CI, `tart exec`, pipes) have no terminal and
|
|
105
|
+
// MUST fail with a clear message rather than hang on a prompt.
|
|
106
|
+
interactive: isInteractiveTTY(),
|
|
104
107
|
});
|
|
105
108
|
pipeline = conversionResult.pipeline;
|
|
106
109
|
await runner.runPipeline(pipeline, conversionResult.warnings, conversionResult.skippedSteps);
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { YAMLPipeline } from "../yaml/types.js";
|
|
2
2
|
import type { CIConfig } from "../types.js";
|
|
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.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isInteractiveTTY(): boolean;
|
|
3
11
|
/**
|
|
4
12
|
* Shows an interactive workflow picker. If exactly one workflow exists,
|
|
5
13
|
* returns it without prompting. Returns `undefined` when the user cancels
|
|
@@ -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;;;;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,
|
|
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"}
|
|
@@ -2,6 +2,16 @@ import prompts from "prompts";
|
|
|
2
2
|
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
|
+
/**
|
|
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.
|
|
11
|
+
*/
|
|
12
|
+
export function isInteractiveTTY() {
|
|
13
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY);
|
|
14
|
+
}
|
|
5
15
|
/**
|
|
6
16
|
* Shows an interactive workflow picker. If exactly one workflow exists,
|
|
7
17
|
* returns it without prompting. Returns `undefined` when the user cancels
|
|
@@ -66,6 +76,11 @@ export async function promptForMissingVariables(yamlPipeline, workflowName, conf
|
|
|
66
76
|
console.log(` • ${issue.requirement.name.padEnd(30)}${stepInfo}`);
|
|
67
77
|
}
|
|
68
78
|
console.log();
|
|
79
|
+
if (!isInteractiveTTY()) {
|
|
80
|
+
console.error("\n❌ Cannot prompt for missing values: no interactive TTY available (running in a sandbox / CI).\n" +
|
|
81
|
+
" Define the required values as env vars, secrets, or app.envs before dispatch, then retry.");
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
69
84
|
const handler = new MissingEnvHandler({
|
|
70
85
|
interactive: true,
|
|
71
86
|
workflow: workflowName,
|
|
@@ -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;
|
|
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"}
|
|
@@ -167,6 +167,14 @@ export class StepValidator {
|
|
|
167
167
|
// values set by the YAML/secrets are still treated as "provided")
|
|
168
168
|
if (Object.prototype.hasOwnProperty.call(resolvedEnv, varName))
|
|
169
169
|
continue;
|
|
170
|
+
// Skip if the runner (or the surrounding shell) already exported
|
|
171
|
+
// the var into our process.env. The sandbox runner delivers
|
|
172
|
+
// dispatch-supplied `execution.env` / `execution.secrets` this
|
|
173
|
+
// way — without this fallback, bash-style `$VAR` refs in
|
|
174
|
+
// repo-hosted YAML (human CLI flow) would false-trigger the
|
|
175
|
+
// auto-discovery even though they resolve at shell runtime.
|
|
176
|
+
if (Object.prototype.hasOwnProperty.call(process.env, varName))
|
|
177
|
+
continue;
|
|
170
178
|
// Skip if provided as output by an earlier step
|
|
171
179
|
if (this.availableOutputs.has(varName))
|
|
172
180
|
continue;
|
|
@@ -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;AA8DF;;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;YAsGzF,iBAAiB;
|
|
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;AA8DF;;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;YAsGzF,iBAAiB;CA8KhC;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;CA6HhC"}
|
|
@@ -274,10 +274,13 @@ export class CachePullStepExecutor extends BaseStepExecutor {
|
|
|
274
274
|
// and creates a fresh tarball under the new key for future exact hits.
|
|
275
275
|
commands.push('else');
|
|
276
276
|
commands.push(' __ci_fb_scope="${CACHE_KEY%-*}"');
|
|
277
|
-
|
|
277
|
+
// `|| true` defuses pipefail+errexit when ls finds no matches: bare
|
|
278
|
+
// assignment would abort the whole cache-pull step silently on an empty
|
|
279
|
+
// cache dir, flipping any cold miss into a non-zero exit.
|
|
280
|
+
commands.push(' __ci_fb=$(ls -t "$CACHE_DIR"/"$__ci_fb_scope"-*.tar.zst 2>/dev/null | head -1 || true)');
|
|
278
281
|
if (peerCacheDir) {
|
|
279
282
|
commands.push(' if [ -z "$__ci_fb" ] || [ ! -f "$__ci_fb" ]; then');
|
|
280
|
-
commands.push(' __ci_fb=$(ls -t "$PEER_CACHE_DIR"/"$__ci_fb_scope"-*.tar.zst 2>/dev/null | head -1)');
|
|
283
|
+
commands.push(' __ci_fb=$(ls -t "$PEER_CACHE_DIR"/"$__ci_fb_scope"-*.tar.zst 2>/dev/null | head -1 || true)');
|
|
281
284
|
commands.push(' __ci_fb_src=peer');
|
|
282
285
|
commands.push(' else');
|
|
283
286
|
commands.push(' __ci_fb_src=local');
|
|
@@ -556,7 +559,9 @@ export class CachePushStepExecutor extends BaseStepExecutor {
|
|
|
556
559
|
// delete older ones to bound disk usage. Runs inline after every push;
|
|
557
560
|
// no cron required.
|
|
558
561
|
commands.push(' __ci_ret_scope="${CACHE_KEY%-*}"');
|
|
559
|
-
|
|
562
|
+
// `|| true` guards against pipefail when ls matches nothing (first push
|
|
563
|
+
// for a new scope) — otherwise the step would silently exit non-zero.
|
|
564
|
+
commands.push(' __ci_ret_old=$(ls -t "$CACHE_DIR"/"$__ci_ret_scope"-*.tar.zst 2>/dev/null | tail -n +6 || true)');
|
|
560
565
|
commands.push(' if [ -n "$__ci_ret_old" ]; then');
|
|
561
566
|
commands.push(' __ci_ret_count=$(printf "%s\\n" "$__ci_ret_old" | wc -l | tr -d " ")');
|
|
562
567
|
commands.push(' echo "Retention: removing $__ci_ret_count older tarball(s) from scope $__ci_ret_scope"');
|