@formigio/fazemos-cli 0.10.19 → 0.10.20
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/index.js +65 -0
- package/dist/index.js.map +1 -1
- package/dist/wait-for-pipeline.d.ts +120 -0
- package/dist/wait-for-pipeline.js +337 -0
- package/dist/wait-for-pipeline.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import { printFindings, printJson } from './yaml/format.js';
|
|
|
12
12
|
import { validateManifest } from './manifest/checks.js';
|
|
13
13
|
import { findLocalRegistry, resolveRole, buildInboxFile, writeInboxFile, writeInboxFileAtPath, buildRolesSyncPayload, findUnprocessedInboxFiles, computeFileHash, gitCommitInboxFile, } from './dispatch.js';
|
|
14
14
|
import { execSync } from 'child_process';
|
|
15
|
+
import { parseExecutionsJson, resolveWaitOptions, waitForPipelines, buildAwsCommand, validateExecutionEntry, } from './wait-for-pipeline.js';
|
|
15
16
|
import { readFileSync, readdirSync, writeFileSync, mkdirSync, existsSync, statSync } from 'fs';
|
|
16
17
|
import { fileURLToPath } from 'url';
|
|
17
18
|
import { dirname, resolve, basename } from 'path';
|
|
@@ -4475,6 +4476,70 @@ pipelines
|
|
|
4475
4476
|
process.exit(1);
|
|
4476
4477
|
}
|
|
4477
4478
|
});
|
|
4479
|
+
// ── P8/I55 — deploy-completion gate ──
|
|
4480
|
+
// Poll one or more CodePipeline executions until each reaches a terminal state.
|
|
4481
|
+
// Shells out to the `aws` CLI via execSync (no @aws-sdk dependency, consistent
|
|
4482
|
+
// with the existing CLI pattern); credentials arrive via the ECS task-role
|
|
4483
|
+
// metadata service inside the agent container. Exit-code contract (spec §3.3):
|
|
4484
|
+
// 0 Succeeded (or empty map) · 2 Failed/Stopped · 3 Superseded · 4 timeout · 5 aws-call-failure.
|
|
4485
|
+
pipelines
|
|
4486
|
+
.command('wait-for-pipeline')
|
|
4487
|
+
.description('Poll CodePipeline execution(s) until terminal; exit 0 on Succeeded, non-zero with a structured diagnostic otherwise (deploy-completion gate)')
|
|
4488
|
+
.argument('[execution-id]', 'CodePipeline pipeline-execution-id (single-pair form; requires --pipeline). Omit when using --executions-json.')
|
|
4489
|
+
.option('--pipeline <name>', 'CodePipeline name (required with the single-pair form; execution-id is only unique within a pipeline)')
|
|
4490
|
+
.option('--executions-json <json>', 'Bulk form: JSON map of {pipelineName: executionId}. Empty/{} is a documented no-op (exit 0).')
|
|
4491
|
+
.option('--timeout <duration>', 'Total wall-clock budget (15m, 900s, or 900). Default 15m.')
|
|
4492
|
+
.option('--poll-interval <duration>', 'Per-poll sleep (floor 60s; values below are clamped + warned). Default 60s.')
|
|
4493
|
+
.option('--region <region>', 'AWS region (reads AWS_REGION/AWS_DEFAULT_REGION, else us-west-2). Passed explicitly to every aws call.')
|
|
4494
|
+
.action(async (executionId, opts) => {
|
|
4495
|
+
try {
|
|
4496
|
+
// Build the (pipeline, executionId) list from whichever form was used.
|
|
4497
|
+
let executions;
|
|
4498
|
+
if (opts.executionsJson !== undefined) {
|
|
4499
|
+
if (executionId || opts.pipeline) {
|
|
4500
|
+
console.error(chalk.red('wait-for-pipeline: pass EITHER --executions-json OR an execution-id + --pipeline, not both'));
|
|
4501
|
+
process.exit(1);
|
|
4502
|
+
}
|
|
4503
|
+
executions = parseExecutionsJson(opts.executionsJson);
|
|
4504
|
+
}
|
|
4505
|
+
else {
|
|
4506
|
+
if (!executionId) {
|
|
4507
|
+
console.error(chalk.red('wait-for-pipeline: an execution-id (with --pipeline) or --executions-json is required'));
|
|
4508
|
+
process.exit(1);
|
|
4509
|
+
}
|
|
4510
|
+
if (!opts.pipeline) {
|
|
4511
|
+
console.error(chalk.red('wait-for-pipeline: --pipeline <name> is required with the single-pair form (execution-id is only unique within a pipeline)'));
|
|
4512
|
+
process.exit(1);
|
|
4513
|
+
}
|
|
4514
|
+
validateExecutionEntry(opts.pipeline, executionId);
|
|
4515
|
+
executions = [{ pipeline: opts.pipeline, executionId }];
|
|
4516
|
+
}
|
|
4517
|
+
const waitOptions = resolveWaitOptions({
|
|
4518
|
+
timeout: opts.timeout,
|
|
4519
|
+
pollInterval: opts.pollInterval,
|
|
4520
|
+
region: opts.region,
|
|
4521
|
+
});
|
|
4522
|
+
// AwsRunner: shell out to the aws CLI, capturing stdout. On non-zero exit
|
|
4523
|
+
// execSync throws an Error carrying .stderr — the gate logic reads it.
|
|
4524
|
+
const aws = (args) => {
|
|
4525
|
+
const cmd = buildAwsCommand(args);
|
|
4526
|
+
return execSync(cmd, {
|
|
4527
|
+
encoding: 'utf-8',
|
|
4528
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
4529
|
+
// Default 1MB can spuriously throw on a large get-pipeline-state
|
|
4530
|
+
// response; that would map to AWS_CALL_FAILED (exit 5) incorrectly.
|
|
4531
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
4532
|
+
});
|
|
4533
|
+
};
|
|
4534
|
+
const exitCode = await waitForPipelines(executions, waitOptions, { aws });
|
|
4535
|
+
process.exit(exitCode);
|
|
4536
|
+
}
|
|
4537
|
+
catch (err) {
|
|
4538
|
+
// Configuration / parse errors (bad --executions-json, bad --timeout, etc.)
|
|
4539
|
+
console.error(chalk.red(err.message));
|
|
4540
|
+
process.exit(1);
|
|
4541
|
+
}
|
|
4542
|
+
});
|
|
4478
4543
|
const step = pipelines.command('step').description('Pipeline step commands');
|
|
4479
4544
|
step
|
|
4480
4545
|
.command('list')
|