anton-bakker-deploy-engine 0.2.0 → 0.2.2
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/README.md +818 -0
- package/dist/engine.d.ts +11 -1
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +164 -41
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline.d.ts +6 -1
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +21 -1
- package/dist/pipeline.js.map +1 -0
- package/dist/types.d.ts +28 -3
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -1
- package/dist/types.js.map +1 -0
- package/dist/verify.d.ts +2 -17
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +3 -1
- package/dist/verify.js.map +1 -0
- package/package.json +6 -3
package/dist/engine.d.ts
CHANGED
|
@@ -1,23 +1,33 @@
|
|
|
1
|
-
import type { GateDefinition, PipelineReport, CheckExecutor, ExecutionContext } from './types.js';
|
|
1
|
+
import type { GateDefinition, PipelineReport, CheckExecutor, ExecutionContext, PipelineEventListener } from './types.js';
|
|
2
2
|
export declare class PipelineEngine {
|
|
3
3
|
private gates;
|
|
4
4
|
private checks;
|
|
5
5
|
private state;
|
|
6
6
|
private stateDir;
|
|
7
7
|
private ctx;
|
|
8
|
+
private listeners;
|
|
8
9
|
constructor(opts: {
|
|
9
10
|
gates: GateDefinition[];
|
|
10
11
|
checks: Map<string, CheckExecutor>;
|
|
11
12
|
ctx: ExecutionContext;
|
|
12
13
|
stateDir?: string;
|
|
13
14
|
});
|
|
15
|
+
private freshState;
|
|
16
|
+
/** Subscribe to pipeline lifecycle events */
|
|
17
|
+
on(listener: PipelineEventListener): void;
|
|
18
|
+
private emit;
|
|
14
19
|
private statePath;
|
|
15
20
|
private saveState;
|
|
16
21
|
/** Run all gates in order. Returns the pipeline report. */
|
|
17
22
|
run(): Promise<PipelineReport>;
|
|
23
|
+
private bake;
|
|
18
24
|
private executeGate;
|
|
25
|
+
private runChecksSequential;
|
|
26
|
+
private runChecksParallel;
|
|
27
|
+
private runSingleCheck;
|
|
19
28
|
private buildReport;
|
|
20
29
|
private saveReport;
|
|
21
30
|
/** Clear state for a fresh run */
|
|
22
31
|
static clearState(stateDir: string, environment: string): void;
|
|
23
32
|
}
|
|
33
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,cAAc,EAA6B,cAAc,EACzD,aAAa,EAAE,gBAAgB,EACG,qBAAqB,EACxD,MAAM,YAAY,CAAC;AAKpB,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,GAAG,CAAmB;IAC9B,OAAO,CAAC,SAAS,CAA+B;gBAEpC,IAAI,EAAE;QAChB,KAAK,EAAE,cAAc,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACnC,GAAG,EAAE,gBAAgB,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;IAyBD,OAAO,CAAC,UAAU;IAWlB,6CAA6C;IAC7C,EAAE,CAAC,QAAQ,EAAE,qBAAqB,GAAG,IAAI;IAIzC,OAAO,CAAC,IAAI;IAUZ,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,SAAS;IASjB,2DAA2D;IACrD,GAAG,IAAI,OAAO,CAAC,cAAc,CAAC;YA0FtB,IAAI;YA2BJ,WAAW;YAuBX,mBAAmB;YAQnB,iBAAiB;YAIjB,cAAc;IA2B5B,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,UAAU;IASlB,kCAAkC;IAClC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;CAS/D"}
|
package/dist/engine.js
CHANGED
|
@@ -1,34 +1,69 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/engine.ts — Pipeline gate executor with state persistence.
|
|
3
|
+
*
|
|
4
|
+
* Features: sequential/parallel checks, per-check timeout, bake time with
|
|
5
|
+
* alarm monitoring, state file integrity, structured events, resume.
|
|
3
6
|
*/
|
|
4
|
-
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
7
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, renameSync } from 'fs';
|
|
5
8
|
import { join } from 'path';
|
|
9
|
+
import { computeStateHash } from './types.js';
|
|
10
|
+
const DEFAULT_CHECK_TIMEOUT = 60_000;
|
|
6
11
|
export class PipelineEngine {
|
|
7
12
|
gates;
|
|
8
13
|
checks;
|
|
9
14
|
state;
|
|
10
15
|
stateDir;
|
|
11
16
|
ctx;
|
|
17
|
+
listeners = [];
|
|
12
18
|
constructor(opts) {
|
|
13
19
|
this.gates = opts.gates;
|
|
14
20
|
this.checks = opts.checks;
|
|
15
21
|
this.ctx = opts.ctx;
|
|
16
22
|
this.stateDir = opts.stateDir || join(opts.ctx.projectRoot, 'orchestrator');
|
|
17
|
-
// Load or create state
|
|
18
23
|
const statePath = this.statePath();
|
|
19
24
|
if (!opts.ctx.dryRun && existsSync(statePath)) {
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
const raw = readFileSync(statePath, 'utf-8');
|
|
26
|
+
const loaded = JSON.parse(raw);
|
|
27
|
+
// Integrity check
|
|
28
|
+
const { stateHash: savedHash, ...rest } = loaded;
|
|
29
|
+
const expected = computeStateHash(JSON.stringify(rest));
|
|
30
|
+
if (savedHash && savedHash !== expected) {
|
|
31
|
+
this.ctx.log(`⚠️ State file integrity check failed — starting fresh`);
|
|
32
|
+
this.state = this.freshState();
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
this.state = loaded;
|
|
36
|
+
this.ctx.log(`Resuming run ${this.state.runId} (${this.state.gates.filter(g => g.status === 'passed').length} gates already passed)`);
|
|
37
|
+
}
|
|
22
38
|
}
|
|
23
39
|
else {
|
|
24
|
-
this.state =
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
40
|
+
this.state = this.freshState();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
freshState() {
|
|
44
|
+
return {
|
|
45
|
+
runId: `deploy-${new Date().toISOString().replace(/[:.]/g, '-')}`,
|
|
46
|
+
environment: this.ctx.environment,
|
|
47
|
+
commit: this.ctx.exec('git rev-parse --short HEAD')?.trim() || 'unknown',
|
|
48
|
+
startedAt: new Date().toISOString(),
|
|
49
|
+
result: 'running',
|
|
50
|
+
gates: [],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/** Subscribe to pipeline lifecycle events */
|
|
54
|
+
on(listener) {
|
|
55
|
+
this.listeners.push(listener);
|
|
56
|
+
}
|
|
57
|
+
emit(type, gate, check, detail) {
|
|
58
|
+
const event = {
|
|
59
|
+
type, timestamp: new Date().toISOString(), runId: this.state.runId,
|
|
60
|
+
gate, check, detail,
|
|
61
|
+
};
|
|
62
|
+
for (const listener of this.listeners) {
|
|
63
|
+
try {
|
|
64
|
+
listener(event);
|
|
65
|
+
}
|
|
66
|
+
catch { /* listener errors don't break pipeline */ }
|
|
32
67
|
}
|
|
33
68
|
}
|
|
34
69
|
statePath() {
|
|
@@ -38,11 +73,31 @@ export class PipelineEngine {
|
|
|
38
73
|
if (this.ctx.dryRun)
|
|
39
74
|
return;
|
|
40
75
|
mkdirSync(this.stateDir, { recursive: true });
|
|
41
|
-
|
|
76
|
+
const forHash = { ...this.state };
|
|
77
|
+
delete forHash.stateHash;
|
|
78
|
+
this.state.stateHash = computeStateHash(JSON.stringify(forHash));
|
|
79
|
+
writeFileSync(this.statePath(), JSON.stringify(this.state, null, 2), { mode: 0o600 });
|
|
42
80
|
}
|
|
43
81
|
/** Run all gates in order. Returns the pipeline report. */
|
|
44
82
|
async run() {
|
|
45
83
|
const start = Date.now();
|
|
84
|
+
this.emit('pipeline:start', undefined, undefined, { environment: this.ctx.environment });
|
|
85
|
+
// Deployment blocker check
|
|
86
|
+
if (this.ctx.deploymentBlocker) {
|
|
87
|
+
const reason = await this.ctx.deploymentBlocker();
|
|
88
|
+
if (reason) {
|
|
89
|
+
this.ctx.log(`🚫 Deployment blocked: ${reason}`);
|
|
90
|
+
this.state.result = 'failed';
|
|
91
|
+
this.state.completedAt = new Date().toISOString();
|
|
92
|
+
this.state.gates.push({
|
|
93
|
+
id: 'blocker', name: 'Deployment Blocker', status: 'failed', onFail: 'abort',
|
|
94
|
+
checks: [{ name: 'deployment-blocker', passed: false, error: reason }],
|
|
95
|
+
startedAt: new Date().toISOString(), completedAt: new Date().toISOString(), duration: 0,
|
|
96
|
+
});
|
|
97
|
+
this.saveState();
|
|
98
|
+
return this.buildReport(Date.now() - start);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
46
101
|
for (const gate of this.gates) {
|
|
47
102
|
// Skip if condition not met
|
|
48
103
|
if (gate.condition && !gate.condition(this.ctx.envConfig)) {
|
|
@@ -51,6 +106,7 @@ export class PipelineEngine {
|
|
|
51
106
|
checks: [], startedAt: new Date().toISOString(), completedAt: new Date().toISOString(), duration: 0,
|
|
52
107
|
};
|
|
53
108
|
this.state.gates.push(skipped);
|
|
109
|
+
this.emit('gate:skip', gate.id);
|
|
54
110
|
this.ctx.log(`⏭️ Gate ${gate.name}: skipped (condition not met)`);
|
|
55
111
|
continue;
|
|
56
112
|
}
|
|
@@ -62,7 +118,6 @@ export class PipelineEngine {
|
|
|
62
118
|
}
|
|
63
119
|
// Execute gate
|
|
64
120
|
const gateResult = await this.executeGate(gate);
|
|
65
|
-
// Replace or append
|
|
66
121
|
const idx = this.state.gates.findIndex(g => g.id === gate.id);
|
|
67
122
|
if (idx >= 0)
|
|
68
123
|
this.state.gates[idx] = gateResult;
|
|
@@ -71,53 +126,121 @@ export class PipelineEngine {
|
|
|
71
126
|
this.saveState();
|
|
72
127
|
if (gateResult.status === 'failed') {
|
|
73
128
|
this.ctx.log(`❌ Gate ${gate.name} FAILED → ${gate.onFail.toUpperCase()}`);
|
|
129
|
+
this.emit('rollback:trigger', gate.id, undefined, { action: gate.onFail });
|
|
74
130
|
this.state.result = gate.onFail === 'rollback' ? 'rolled-back' : 'failed';
|
|
75
131
|
this.state.completedAt = new Date().toISOString();
|
|
76
132
|
this.saveState();
|
|
133
|
+
this.emit('pipeline:end', undefined, undefined, { result: this.state.result });
|
|
77
134
|
return this.buildReport(Date.now() - start, gate);
|
|
78
135
|
}
|
|
136
|
+
// Bake time — monitor alarms after gate passes
|
|
137
|
+
if (gate.bakeTime && gate.bakeTime > 0) {
|
|
138
|
+
const bakeOk = await this.bake(gate);
|
|
139
|
+
if (!bakeOk) {
|
|
140
|
+
// Alarm fired during bake — mark gate as failed
|
|
141
|
+
const bakeFailResult = {
|
|
142
|
+
...gateResult, status: 'failed',
|
|
143
|
+
checks: [...gateResult.checks, { name: 'bake-alarm', passed: false, error: 'Alarm fired during bake time' }],
|
|
144
|
+
completedAt: new Date().toISOString(),
|
|
145
|
+
duration: Date.now() - new Date(gateResult.startedAt).getTime(),
|
|
146
|
+
};
|
|
147
|
+
const bakeIdx = this.state.gates.findIndex(g => g.id === gate.id);
|
|
148
|
+
this.state.gates[bakeIdx] = bakeFailResult;
|
|
149
|
+
this.ctx.log(`❌ Gate ${gate.name} FAILED during bake → ${gate.onFail.toUpperCase()}`);
|
|
150
|
+
this.emit('rollback:trigger', gate.id, undefined, { action: gate.onFail, reason: 'bake-alarm' });
|
|
151
|
+
this.state.result = gate.onFail === 'rollback' ? 'rolled-back' : 'failed';
|
|
152
|
+
this.state.completedAt = new Date().toISOString();
|
|
153
|
+
this.saveState();
|
|
154
|
+
this.emit('pipeline:end', undefined, undefined, { result: this.state.result });
|
|
155
|
+
return this.buildReport(Date.now() - start, gate);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
79
158
|
}
|
|
80
159
|
this.state.result = 'passed';
|
|
81
160
|
this.state.completedAt = new Date().toISOString();
|
|
82
161
|
this.saveState();
|
|
83
162
|
this.saveReport(Date.now() - start);
|
|
163
|
+
this.emit('pipeline:end', undefined, undefined, { result: 'passed' });
|
|
84
164
|
return this.buildReport(Date.now() - start);
|
|
85
165
|
}
|
|
86
|
-
async
|
|
87
|
-
const
|
|
88
|
-
this.ctx.log(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.ctx.
|
|
95
|
-
|
|
166
|
+
async bake(gate) {
|
|
167
|
+
const bakeMs = gate.bakeTime;
|
|
168
|
+
this.ctx.log(` ⏳ Baking ${gate.name} for ${Math.round(bakeMs / 1000)}s...`);
|
|
169
|
+
this.emit('bake:start', gate.id, undefined, { bakeTime: bakeMs });
|
|
170
|
+
const interval = Math.min(bakeMs, 5_000); // poll every 5s or less
|
|
171
|
+
const end = Date.now() + bakeMs;
|
|
172
|
+
while (Date.now() < end) {
|
|
173
|
+
if (this.ctx.alarmMonitor) {
|
|
174
|
+
const alarming = await this.ctx.alarmMonitor();
|
|
175
|
+
if (alarming) {
|
|
176
|
+
this.emit('bake:alarm', gate.id);
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
96
179
|
}
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
result.duration = Date.now() - checkStart;
|
|
101
|
-
results.push(result);
|
|
102
|
-
this.ctx.log(` ${result.passed ? '✅' : '❌'} ${result.name}: ${result.actual ?? (result.passed ? 'OK' : result.error)}`);
|
|
103
|
-
}
|
|
104
|
-
catch (err) {
|
|
105
|
-
const result = {
|
|
106
|
-
name: checkName, passed: false, duration: Date.now() - checkStart,
|
|
107
|
-
error: err.message,
|
|
108
|
-
};
|
|
109
|
-
results.push(result);
|
|
110
|
-
this.ctx.log(` ❌ ${checkName}: ${result.error}`);
|
|
180
|
+
const remaining = end - Date.now();
|
|
181
|
+
if (remaining > 0) {
|
|
182
|
+
await new Promise(r => setTimeout(r, Math.min(interval, remaining)));
|
|
111
183
|
}
|
|
112
184
|
}
|
|
113
|
-
|
|
185
|
+
this.emit('bake:end', gate.id);
|
|
186
|
+
this.ctx.log(` ✅ Bake complete for ${gate.name}`);
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
async executeGate(gate) {
|
|
190
|
+
const gateStart = Date.now();
|
|
191
|
+
this.ctx.log(`\n🔒 Gate ${gate.name}`);
|
|
192
|
+
this.emit('gate:start', gate.id);
|
|
193
|
+
const timeout = gate.timeout ?? DEFAULT_CHECK_TIMEOUT;
|
|
194
|
+
const results = gate.parallel
|
|
195
|
+
? await this.runChecksParallel(gate.checks, timeout, gate.id)
|
|
196
|
+
: await this.runChecksSequential(gate.checks, timeout, gate.id);
|
|
197
|
+
const gateResult = {
|
|
114
198
|
id: gate.id, name: gate.name, onFail: gate.onFail,
|
|
115
199
|
status: results.every(r => r.passed) ? 'passed' : 'failed',
|
|
116
200
|
checks: results,
|
|
117
201
|
startedAt: new Date(gateStart).toISOString(),
|
|
118
202
|
completedAt: new Date().toISOString(),
|
|
119
203
|
duration: Date.now() - gateStart,
|
|
204
|
+
bakeTime: gate.bakeTime,
|
|
120
205
|
};
|
|
206
|
+
this.emit('gate:end', gate.id, undefined, { status: gateResult.status, duration: gateResult.duration });
|
|
207
|
+
return gateResult;
|
|
208
|
+
}
|
|
209
|
+
async runChecksSequential(checkNames, timeout, gateId) {
|
|
210
|
+
const results = [];
|
|
211
|
+
for (const checkName of checkNames) {
|
|
212
|
+
results.push(await this.runSingleCheck(checkName, timeout, gateId));
|
|
213
|
+
}
|
|
214
|
+
return results;
|
|
215
|
+
}
|
|
216
|
+
async runChecksParallel(checkNames, timeout, gateId) {
|
|
217
|
+
return Promise.all(checkNames.map(name => this.runSingleCheck(name, timeout, gateId)));
|
|
218
|
+
}
|
|
219
|
+
async runSingleCheck(checkName, timeout, gateId) {
|
|
220
|
+
const executor = this.checks.get(checkName);
|
|
221
|
+
if (!executor) {
|
|
222
|
+
this.ctx.log(` ❌ ${checkName}: no executor registered`);
|
|
223
|
+
return { name: checkName, passed: false, error: `No executor registered for '${checkName}'` };
|
|
224
|
+
}
|
|
225
|
+
this.emit('check:start', gateId, checkName);
|
|
226
|
+
const checkStart = Date.now();
|
|
227
|
+
try {
|
|
228
|
+
const result = await Promise.race([
|
|
229
|
+
executor(this.ctx),
|
|
230
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout after ${timeout}ms`)), timeout)),
|
|
231
|
+
]);
|
|
232
|
+
result.duration = Date.now() - checkStart;
|
|
233
|
+
this.ctx.log(` ${result.passed ? '✅' : '❌'} ${result.name}: ${result.actual ?? (result.passed ? 'OK' : result.error)}`);
|
|
234
|
+
this.emit('check:end', gateId, checkName, { passed: result.passed, duration: result.duration });
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
const duration = Date.now() - checkStart;
|
|
239
|
+
const result = { name: checkName, passed: false, duration, error: err.message };
|
|
240
|
+
this.ctx.log(` ❌ ${checkName}: ${result.error}`);
|
|
241
|
+
this.emit('check:end', gateId, checkName, { passed: false, duration, error: result.error });
|
|
242
|
+
return result;
|
|
243
|
+
}
|
|
121
244
|
}
|
|
122
245
|
buildReport(duration, failedGate) {
|
|
123
246
|
return {
|
|
@@ -140,7 +263,7 @@ export class PipelineEngine {
|
|
|
140
263
|
mkdirSync(reportDir, { recursive: true });
|
|
141
264
|
const ts = new Date().toISOString().replace(/[:.]/g, '-').substring(0, 16);
|
|
142
265
|
const report = this.buildReport(duration);
|
|
143
|
-
writeFileSync(join(reportDir, `${ts}-${this.ctx.envShort}.json`), JSON.stringify(report, null, 2));
|
|
266
|
+
writeFileSync(join(reportDir, `${ts}-${this.ctx.envShort}.json`), JSON.stringify(report, null, 2), { mode: 0o600 });
|
|
144
267
|
}
|
|
145
268
|
/** Clear state for a fresh run */
|
|
146
269
|
static clearState(stateDir, environment) {
|
|
@@ -149,8 +272,8 @@ export class PipelineEngine {
|
|
|
149
272
|
const archiveDir = join(stateDir, 'archive');
|
|
150
273
|
mkdirSync(archiveDir, { recursive: true });
|
|
151
274
|
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
152
|
-
const { renameSync } = require('fs');
|
|
153
275
|
renameSync(path, join(archiveDir, `state-${ts}.json`));
|
|
154
276
|
}
|
|
155
277
|
}
|
|
156
278
|
}
|
|
279
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,6 @@
|
|
|
7
7
|
export { PipelineEngine } from './engine.js';
|
|
8
8
|
export { buildGates, DEFAULT_ENVIRONMENTS } from './pipeline.js';
|
|
9
9
|
export { verifyAmplifyOutputs, verifyBuildArtifact, parseTableCount, assertTableCount, parseEcsStatus, assertCognitoGroups, assertApiHealth, deriveExpectations, summarize, } from './verify.js';
|
|
10
|
-
export
|
|
10
|
+
export { computeStateHash } from './types.js';
|
|
11
|
+
export type { CheckResult, GateDefinition, GateResult, EnvironmentConfig, PipelineState, PipelineReport, CheckExecutor, ExecutionContext, PipelineEvent, PipelineEventType, PipelineEventListener, } from './types.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAGjE,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,SAAS,GACV,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG9C,YAAY,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -10,3 +10,6 @@ export { PipelineEngine } from './engine.js';
|
|
|
10
10
|
export { buildGates, DEFAULT_ENVIRONMENTS } from './pipeline.js';
|
|
11
11
|
// Verification functions (Layer 1-3 checks)
|
|
12
12
|
export { verifyAmplifyOutputs, verifyBuildArtifact, parseTableCount, assertTableCount, parseEcsStatus, assertCognitoGroups, assertApiHealth, deriveExpectations, summarize, } from './verify.js';
|
|
13
|
+
// Utilities
|
|
14
|
+
export { computeStateHash } from './types.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc;AACd,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,mBAAmB;AACnB,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEjE,4CAA4C;AAC5C,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,SAAS,GACV,MAAM,aAAa,CAAC;AAErB,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/pipeline.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/pipeline.ts — Builds a pipeline definition from environment config.
|
|
3
|
+
*
|
|
4
|
+
* Gate sequence follows AWS Builders' Library patterns:
|
|
5
|
+
* preflight → code-quality → infra-validation → pre-deploy-safety →
|
|
6
|
+
* build → canary-deploy → deploy → inventory → configuration → functional → project
|
|
3
7
|
*/
|
|
4
8
|
import type { GateDefinition, EnvironmentConfig } from './types.js';
|
|
5
9
|
/**
|
|
@@ -7,5 +11,6 @@ import type { GateDefinition, EnvironmentConfig } from './types.js';
|
|
|
7
11
|
* No hardcoded environment checks — all driven by config.
|
|
8
12
|
*/
|
|
9
13
|
export declare function buildGates(env: EnvironmentConfig): GateDefinition[];
|
|
10
|
-
/** Default environment configs */
|
|
14
|
+
/** Default environment configs — aligned with AWS Builders' Library patterns */
|
|
11
15
|
export declare const DEFAULT_ENVIRONMENTS: Record<string, EnvironmentConfig>;
|
|
16
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpE;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,iBAAiB,GAAG,cAAc,EAAE,CAoFnE;AAED,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAuClE,CAAC"}
|
package/dist/pipeline.js
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
* No hardcoded environment checks — all driven by config.
|
|
4
4
|
*/
|
|
5
5
|
export function buildGates(env) {
|
|
6
|
+
const bake = env.defaultBakeTime ?? 0;
|
|
6
7
|
return [
|
|
7
8
|
{
|
|
8
9
|
id: 'preflight',
|
|
9
10
|
name: 'Preflight',
|
|
10
11
|
checks: ['aws-creds', 'deploy-lock'],
|
|
11
12
|
onFail: 'abort',
|
|
13
|
+
parallel: true,
|
|
12
14
|
},
|
|
13
15
|
{
|
|
14
16
|
id: 'code-quality',
|
|
@@ -38,6 +40,15 @@ export function buildGates(env) {
|
|
|
38
40
|
checks: ['docker-build', 'frontend-build', 'post-build-verify'],
|
|
39
41
|
onFail: 'abort',
|
|
40
42
|
},
|
|
43
|
+
// One-box canary: deploy to single target, bake, verify before full fleet
|
|
44
|
+
{
|
|
45
|
+
id: 'canary-deploy',
|
|
46
|
+
name: 'Canary Deploy (One-Box)',
|
|
47
|
+
checks: ['canary-deploy', 'canary-health'],
|
|
48
|
+
onFail: 'rollback',
|
|
49
|
+
bakeTime: bake > 0 ? Math.max(bake, 60_000) : undefined,
|
|
50
|
+
condition: (e) => e.rollbackOnProbeFailure, // only for envs with rollback
|
|
51
|
+
},
|
|
41
52
|
{
|
|
42
53
|
id: 'deploy',
|
|
43
54
|
name: 'Deploy',
|
|
@@ -49,18 +60,23 @@ export function buildGates(env) {
|
|
|
49
60
|
name: 'Post-Deploy Inventory',
|
|
50
61
|
checks: ['table-count', 'ecs-status', 'cognito-groups'],
|
|
51
62
|
onFail: 'rollback',
|
|
63
|
+
parallel: true,
|
|
64
|
+
bakeTime: bake,
|
|
52
65
|
},
|
|
53
66
|
{
|
|
54
67
|
id: 'configuration',
|
|
55
68
|
name: 'Post-Deploy Configuration',
|
|
56
69
|
checks: ['pitr-enabled', 'billing-mode', 'https-enforced', 's3-not-public'],
|
|
57
70
|
onFail: 'alert',
|
|
71
|
+
parallel: true,
|
|
58
72
|
},
|
|
59
73
|
{
|
|
60
74
|
id: 'functional',
|
|
61
75
|
name: 'Post-Deploy Functional',
|
|
62
76
|
checks: env.postDeployProbes,
|
|
63
77
|
onFail: env.rollbackOnProbeFailure ? 'rollback' : 'alert',
|
|
78
|
+
parallel: true,
|
|
79
|
+
bakeTime: bake,
|
|
64
80
|
},
|
|
65
81
|
{
|
|
66
82
|
id: 'project',
|
|
@@ -70,7 +86,7 @@ export function buildGates(env) {
|
|
|
70
86
|
},
|
|
71
87
|
];
|
|
72
88
|
}
|
|
73
|
-
/** Default environment configs */
|
|
89
|
+
/** Default environment configs — aligned with AWS Builders' Library patterns */
|
|
74
90
|
export const DEFAULT_ENVIRONMENTS = {
|
|
75
91
|
development: {
|
|
76
92
|
approval: 'never',
|
|
@@ -82,6 +98,7 @@ export const DEFAULT_ENVIRONMENTS = {
|
|
|
82
98
|
cdkNagLevel: 'warning',
|
|
83
99
|
postDeployProbes: ['api-health', 'table-count', 'ecs-status'],
|
|
84
100
|
rollbackOnProbeFailure: false,
|
|
101
|
+
defaultBakeTime: 0,
|
|
85
102
|
},
|
|
86
103
|
staging: {
|
|
87
104
|
approval: 'never',
|
|
@@ -94,6 +111,7 @@ export const DEFAULT_ENVIRONMENTS = {
|
|
|
94
111
|
cdkNagLevel: 'error',
|
|
95
112
|
postDeployProbes: ['api-health', 'table-count', 'ecs-status', 'cognito-groups', 'crud-probe'],
|
|
96
113
|
rollbackOnProbeFailure: true,
|
|
114
|
+
defaultBakeTime: 60_000, // 1 min bake
|
|
97
115
|
},
|
|
98
116
|
production: {
|
|
99
117
|
approval: 'broadening',
|
|
@@ -106,5 +124,7 @@ export const DEFAULT_ENVIRONMENTS = {
|
|
|
106
124
|
cdkNagLevel: 'error',
|
|
107
125
|
postDeployProbes: ['api-health', 'table-count', 'ecs-status', 'cognito-groups', 'crud-probe', 'auth-probe', 's3-probe'],
|
|
108
126
|
rollbackOnProbeFailure: true,
|
|
127
|
+
defaultBakeTime: 300_000, // 5 min bake
|
|
109
128
|
},
|
|
110
129
|
};
|
|
130
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,GAAsB;IAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,IAAI,CAAC,CAAC;IAEtC,OAAO;QACL;YACE,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,CAAC,WAAW,EAAE,aAAa,CAAC;YACpC,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,IAAI;SACf;QACD;YACE,EAAE,EAAE,cAAc;YAClB,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,GAAG,CAAC,eAAe;YAC3B,MAAM,EAAE,OAAO;SAChB;QACD;YACE,EAAE,EAAE,kBAAkB;YACtB,IAAI,EAAE,2BAA2B;YACjC,MAAM,EAAE,CAAC,WAAW,EAAE,qBAAqB,CAAC;YAC5C,MAAM,EAAE,OAAO;SAChB;QACD;YACE,EAAE,EAAE,mBAAmB;YACvB,IAAI,EAAE,mBAAmB;YACzB,MAAM,EAAE;gBACN,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9C,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aAClD;YACD,MAAM,EAAE,OAAO;YACf,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,UAAU;SACjD;QACD;YACE,EAAE,EAAE,OAAO;YACX,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,CAAC,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,CAAC;YAC/D,MAAM,EAAE,OAAO;SAChB;QACD,0EAA0E;QAC1E;YACE,EAAE,EAAE,eAAe;YACnB,IAAI,EAAE,yBAAyB;YAC/B,MAAM,EAAE,CAAC,eAAe,EAAE,eAAe,CAAC;YAC1C,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;YACvD,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB,EAAE,8BAA8B;SAC3E;QACD;YACE,EAAE,EAAE,QAAQ;YACZ,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,CAAC,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnG,MAAM,EAAE,UAAU;SACnB;QACD;YACE,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,uBAAuB;YAC7B,MAAM,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,gBAAgB,CAAC;YACvD,MAAM,EAAE,UAAU;YAClB,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;SACf;QACD;YACE,EAAE,EAAE,eAAe;YACnB,IAAI,EAAE,2BAA2B;YACjC,MAAM,EAAE,CAAC,cAAc,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,CAAC;YAC3E,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,IAAI;SACf;QACD;YACE,EAAE,EAAE,YAAY;YAChB,IAAI,EAAE,wBAAwB;YAC9B,MAAM,EAAE,GAAG,CAAC,gBAAgB;YAC5B,MAAM,EAAE,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO;YACzD,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;SACf;QACD;YACE,EAAE,EAAE,SAAS;YACb,IAAI,EAAE,oBAAoB;YAC1B,MAAM,EAAE,CAAC,qBAAqB,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACvE,MAAM,EAAE,OAAO;SAChB;KACF,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,MAAM,oBAAoB,GAAsC;IACrE,WAAW,EAAE;QACX,QAAQ,EAAE,OAAO;QACjB,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,CAAC;QACvF,UAAU,EAAE,IAAI;QAChB,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;QAC3C,QAAQ,EAAE,KAAK;QACf,YAAY,EAAE,KAAK;QACnB,WAAW,EAAE,SAAS;QACtB,gBAAgB,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,YAAY,CAAC;QAC7D,sBAAsB,EAAE,KAAK;QAC7B,eAAe,EAAE,CAAC;KACnB;IACD,OAAO,EAAE;QACP,QAAQ,EAAE,OAAO;QACjB,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,CAAC;QACpG,UAAU,EAAE,IAAI;QAChB,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE;QAC5C,QAAQ,EAAE,IAAI;QACd,YAAY,EAAE,oBAAoB;QAClC,YAAY,EAAE,IAAI;QAClB,WAAW,EAAE,OAAO;QACpB,gBAAgB,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,CAAC;QAC7F,sBAAsB,EAAE,IAAI;QAC5B,eAAe,EAAE,MAAM,EAAG,aAAa;KACxC;IACD,UAAU,EAAE;QACV,QAAQ,EAAE,YAAY;QACtB,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,wBAAwB,CAAC;QAC9H,UAAU,EAAE,IAAI;QAChB,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;QACxB,QAAQ,EAAE,IAAI;QACd,YAAY,EAAE,gBAAgB;QAC9B,YAAY,EAAE,IAAI;QAClB,WAAW,EAAE,OAAO;QACpB,gBAAgB,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,CAAC;QACvH,sBAAsB,EAAE,IAAI;QAC5B,eAAe,EAAE,OAAO,EAAE,aAAa;KACxC;CACF,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* src/types.ts — Core types for the deployment pipeline engine.
|
|
3
|
-
*/
|
|
4
1
|
export interface CheckResult {
|
|
5
2
|
name: string;
|
|
6
3
|
passed: boolean;
|
|
@@ -15,6 +12,12 @@ export interface GateDefinition {
|
|
|
15
12
|
checks: string[];
|
|
16
13
|
onFail: 'abort' | 'rollback' | 'alert';
|
|
17
14
|
condition?: (env: EnvironmentConfig) => boolean;
|
|
15
|
+
/** Run checks in parallel (default: false — sequential) */
|
|
16
|
+
parallel?: boolean;
|
|
17
|
+
/** Per-check timeout in ms (default: 60_000) */
|
|
18
|
+
timeout?: number;
|
|
19
|
+
/** Bake time in ms — monitor alarms after gate passes before proceeding */
|
|
20
|
+
bakeTime?: number;
|
|
18
21
|
}
|
|
19
22
|
export interface EnvironmentConfig {
|
|
20
23
|
approval: 'never' | 'broadening' | 'always';
|
|
@@ -30,6 +33,8 @@ export interface EnvironmentConfig {
|
|
|
30
33
|
cdkNagLevel: 'warning' | 'error';
|
|
31
34
|
postDeployProbes: string[];
|
|
32
35
|
rollbackOnProbeFailure: boolean;
|
|
36
|
+
/** Default bake time in ms for post-deploy gates (default: 0) */
|
|
37
|
+
defaultBakeTime?: number;
|
|
33
38
|
}
|
|
34
39
|
export interface GateResult {
|
|
35
40
|
id: string;
|
|
@@ -40,6 +45,7 @@ export interface GateResult {
|
|
|
40
45
|
startedAt: string;
|
|
41
46
|
completedAt: string;
|
|
42
47
|
duration: number;
|
|
48
|
+
bakeTime?: number;
|
|
43
49
|
}
|
|
44
50
|
export interface PipelineState {
|
|
45
51
|
runId: string;
|
|
@@ -49,6 +55,7 @@ export interface PipelineState {
|
|
|
49
55
|
completedAt?: string;
|
|
50
56
|
result: 'running' | 'passed' | 'failed' | 'rolled-back';
|
|
51
57
|
gates: GateResult[];
|
|
58
|
+
stateHash?: string;
|
|
52
59
|
}
|
|
53
60
|
export interface PipelineReport {
|
|
54
61
|
state: PipelineState;
|
|
@@ -64,6 +71,17 @@ export interface PipelineReport {
|
|
|
64
71
|
}
|
|
65
72
|
/** A check executor — runs a named check and returns a result */
|
|
66
73
|
export type CheckExecutor = (ctx: ExecutionContext) => Promise<CheckResult>;
|
|
74
|
+
/** Pipeline lifecycle events */
|
|
75
|
+
export type PipelineEventType = 'pipeline:start' | 'pipeline:end' | 'gate:start' | 'gate:end' | 'gate:skip' | 'check:start' | 'check:end' | 'bake:start' | 'bake:alarm' | 'bake:end' | 'rollback:trigger';
|
|
76
|
+
export interface PipelineEvent {
|
|
77
|
+
type: PipelineEventType;
|
|
78
|
+
timestamp: string;
|
|
79
|
+
runId: string;
|
|
80
|
+
gate?: string;
|
|
81
|
+
check?: string;
|
|
82
|
+
detail?: Record<string, unknown>;
|
|
83
|
+
}
|
|
84
|
+
export type PipelineEventListener = (event: PipelineEvent) => void;
|
|
67
85
|
export interface ExecutionContext {
|
|
68
86
|
environment: string;
|
|
69
87
|
envShort: string;
|
|
@@ -78,4 +96,11 @@ export interface ExecutionContext {
|
|
|
78
96
|
exec: (cmd: string) => string | null;
|
|
79
97
|
/** Log a message */
|
|
80
98
|
log: (msg: string) => void;
|
|
99
|
+
/** Optional: alarm monitor check — returns true if alarm is firing */
|
|
100
|
+
alarmMonitor?: () => Promise<boolean>;
|
|
101
|
+
/** Optional: deployment blocker — returns reason string if blocked, null if clear */
|
|
102
|
+
deploymentBlocker?: () => Promise<string | null>;
|
|
81
103
|
}
|
|
104
|
+
/** Compute SHA-256 hash of a string */
|
|
105
|
+
export declare function computeStateHash(content: string): string;
|
|
106
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/types.ts — Core types for the deployment pipeline engine.
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
import { createHash } from 'crypto';
|
|
5
|
+
/** Compute SHA-256 hash of a string */
|
|
6
|
+
export function computeStateHash(content) {
|
|
7
|
+
return createHash('sha256').update(content).digest('hex').substring(0, 16);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAsHpC,uCAAuC;AACvC,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC7E,CAAC"}
|
package/dist/verify.d.ts
CHANGED
|
@@ -6,17 +6,7 @@
|
|
|
6
6
|
* Validates amplify_outputs.json, build artifacts, DynamoDB, ECS, Cognito, and API health.
|
|
7
7
|
* Project-agnostic — works with any AWS CDK project.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
passed: boolean;
|
|
11
|
-
checks: CheckResult[];
|
|
12
|
-
}
|
|
13
|
-
export interface CheckResult {
|
|
14
|
-
name: string;
|
|
15
|
-
passed: boolean;
|
|
16
|
-
expected?: string;
|
|
17
|
-
actual?: string;
|
|
18
|
-
error?: string;
|
|
19
|
-
}
|
|
9
|
+
import type { CheckResult } from './types.js';
|
|
20
10
|
/**
|
|
21
11
|
* Verify amplify_outputs.json has all required fields.
|
|
22
12
|
*/
|
|
@@ -25,11 +15,6 @@ export declare function verifyAmplifyOutputs(outputsPath: string): CheckResult[]
|
|
|
25
15
|
* Scan built JS for environment leaks.
|
|
26
16
|
*/
|
|
27
17
|
export declare function verifyBuildArtifact(distDir: string): CheckResult[];
|
|
28
|
-
export interface PostDeployResult {
|
|
29
|
-
passed: boolean;
|
|
30
|
-
checks: CheckResult[];
|
|
31
|
-
tableCount: number;
|
|
32
|
-
}
|
|
33
18
|
/**
|
|
34
19
|
* Parse table count from AWS CLI JSON output.
|
|
35
20
|
*/
|
|
@@ -66,7 +51,6 @@ export declare function deriveExpectations(opts: {
|
|
|
66
51
|
schemaPath: string;
|
|
67
52
|
authStackPath?: string;
|
|
68
53
|
configPath: string;
|
|
69
|
-
envShort: string;
|
|
70
54
|
}): DeployExpectations;
|
|
71
55
|
/**
|
|
72
56
|
* Aggregate check results into a pass/fail summary.
|
|
@@ -77,3 +61,4 @@ export declare function summarize(checks: CheckResult[]): {
|
|
|
77
61
|
failed: number;
|
|
78
62
|
errors: string[];
|
|
79
63
|
};
|
|
64
|
+
//# sourceMappingURL=verify.d.ts.map
|