@intentius/chant 0.124.17 → 0.124.19
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/__golden__/wave-loop/fan-out-applied.json +511 -0
- package/dist/__golden__/wave-loop/fan-out-apply-fails.json +406 -0
- package/dist/__golden__/wave-loop/fan-out-gated.json +707 -0
- package/dist/__golden__/wave-loop/fan-out-no-members.json +898 -0
- package/dist/__golden__/wave-loop/fan-out-only.json +514 -0
- package/dist/__golden__/wave-loop/fan-out-plan-fails.json +359 -0
- package/dist/__golden__/wave-loop/fan-out-same-root.json +311 -0
- package/dist/__golden__/wave-loop/op-by-apply-after-fails.json +401 -0
- package/dist/__golden__/wave-loop/op-by-apply-hold.json +756 -0
- package/dist/__golden__/wave-loop/op-by-apply-ignored.json +340 -0
- package/dist/__golden__/wave-loop/op-by-apply-pass.json +400 -0
- package/dist/__golden__/wave-loop/op-by-apply-skip.json +404 -0
- package/dist/__golden__/wave-loop/op-cost-member-clash.json +62 -0
- package/dist/__golden__/wave-loop/op-cost-member.json +191 -0
- package/dist/__golden__/wave-loop/op-denied-source.json +407 -0
- package/dist/__golden__/wave-loop/op-denied.json +399 -0
- package/dist/__golden__/wave-loop/op-discover-rest-short.json +92 -0
- package/dist/__golden__/wave-loop/op-discover-rest-stops.json +340 -0
- package/dist/__golden__/wave-loop/op-discover-rest.json +659 -0
- package/dist/__golden__/wave-loop/op-discover-wide.json +290 -0
- package/dist/__golden__/wave-loop/op-held-on-again.json +176 -0
- package/dist/__golden__/wave-loop/op-held-on-before-apply.json +689 -0
- package/dist/__golden__/wave-loop/op-held-on.json +1455 -0
- package/dist/__golden__/wave-loop/op-hooks-apply-fails.json +673 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-after-apply.json +737 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-before-apply.json +450 -0
- package/dist/__golden__/wave-loop/op-hooks-fail-before-plan.json +97 -0
- package/dist/__golden__/wave-loop/op-hooks-held.json +1059 -0
- package/dist/__golden__/wave-loop/op-hooks-hold-before-apply.json +693 -0
- package/dist/__golden__/wave-loop/op-hooks-pass.json +735 -0
- package/dist/__golden__/wave-loop/op-hooks-refused-at-base.json +148 -0
- package/dist/__golden__/wave-loop/op-hooks-share.json +1225 -0
- package/dist/__golden__/wave-loop/op-outcome-held.json +202 -0
- package/dist/__golden__/wave-loop/op-outcome-replan-approved.json +286 -0
- package/dist/__golden__/wave-loop/op-outcome-replan-forever.json +823 -0
- package/dist/__golden__/wave-loop/op-outcome-replan.json +259 -0
- package/dist/__golden__/wave-loop/op-outcome-stood-down.json +196 -0
- package/dist/__golden__/wave-loop/op-outcome-unreadable.json +193 -0
- package/dist/__golden__/wave-loop/op-overridden.json +508 -0
- package/dist/__golden__/wave-loop/op-per-run.json +518 -0
- package/dist/__golden__/wave-loop/op-point.json +495 -0
- package/dist/__golden__/wave-loop/op-pr-review.json +397 -0
- package/dist/__golden__/wave-loop/op-sealed.json +125 -0
- package/dist/__golden__/wave-loop/op-spend-change-only.json +168 -0
- package/dist/__golden__/wave-loop/op-spend.json +328 -0
- package/dist/__golden__/wave-loop/op-wave-commands.json +1808 -0
- package/dist/__golden__/wave-loop/op-wide-refused.json +291 -0
- package/dist/__golden__/wave-loop/op-wide-waiting.json +231 -0
- package/dist/__golden__/wave-loop/op-wide.json +440 -0
- package/dist/cli/commands/import.d.ts +2 -0
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/import.js +6 -2
- package/dist/cli/handlers/graph.js +24 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/misc.js +2 -1
- package/dist/cli/parse-args.d.ts.map +1 -1
- package/dist/cli/parse-args.js +4 -0
- package/dist/cli/registry.d.ts +2 -0
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/fan-out-run.d.ts +4 -3
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-run.js +138 -123
- package/dist/graph-detail.d.ts.map +1 -1
- package/dist/graph-detail.js +9 -3
- package/dist/graph-dot.d.ts.map +1 -1
- package/dist/graph-dot.js +36 -2
- package/dist/graph-ir.d.ts +98 -3
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-ir.js +71 -0
- package/dist/graph-lens.js +12 -1
- package/dist/graph-mermaid.d.ts +5 -1
- package/dist/graph-mermaid.d.ts.map +1 -1
- package/dist/graph-mermaid.js +46 -2
- package/dist/lexicon.d.ts +22 -1
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/op/op-waves-run.d.ts +7 -1
- package/dist/op/op-waves-run.d.ts.map +1 -1
- package/dist/op/op-waves-run.js +129 -72
- package/dist/wave-engine.d.ts +74 -5
- package/dist/wave-engine.d.ts.map +1 -1
- package/dist/wave-engine.js +47 -5
- package/dist/wave-runtime.mjs +215 -215
- package/package.json +1 -1
- package/src/__golden__/wave-loop/fan-out-applied.json +511 -0
- package/src/__golden__/wave-loop/fan-out-apply-fails.json +406 -0
- package/src/__golden__/wave-loop/fan-out-gated.json +707 -0
- package/src/__golden__/wave-loop/fan-out-no-members.json +898 -0
- package/src/__golden__/wave-loop/fan-out-only.json +514 -0
- package/src/__golden__/wave-loop/fan-out-plan-fails.json +359 -0
- package/src/__golden__/wave-loop/fan-out-same-root.json +311 -0
- package/src/__golden__/wave-loop/op-by-apply-after-fails.json +401 -0
- package/src/__golden__/wave-loop/op-by-apply-hold.json +756 -0
- package/src/__golden__/wave-loop/op-by-apply-ignored.json +340 -0
- package/src/__golden__/wave-loop/op-by-apply-pass.json +400 -0
- package/src/__golden__/wave-loop/op-by-apply-skip.json +404 -0
- package/src/__golden__/wave-loop/op-cost-member-clash.json +62 -0
- package/src/__golden__/wave-loop/op-cost-member.json +191 -0
- package/src/__golden__/wave-loop/op-denied-source.json +407 -0
- package/src/__golden__/wave-loop/op-denied.json +399 -0
- package/src/__golden__/wave-loop/op-discover-rest-short.json +92 -0
- package/src/__golden__/wave-loop/op-discover-rest-stops.json +340 -0
- package/src/__golden__/wave-loop/op-discover-rest.json +659 -0
- package/src/__golden__/wave-loop/op-discover-wide.json +290 -0
- package/src/__golden__/wave-loop/op-held-on-again.json +176 -0
- package/src/__golden__/wave-loop/op-held-on-before-apply.json +689 -0
- package/src/__golden__/wave-loop/op-held-on.json +1455 -0
- package/src/__golden__/wave-loop/op-hooks-apply-fails.json +673 -0
- package/src/__golden__/wave-loop/op-hooks-fail-after-apply.json +737 -0
- package/src/__golden__/wave-loop/op-hooks-fail-before-apply.json +450 -0
- package/src/__golden__/wave-loop/op-hooks-fail-before-plan.json +97 -0
- package/src/__golden__/wave-loop/op-hooks-held.json +1059 -0
- package/src/__golden__/wave-loop/op-hooks-hold-before-apply.json +693 -0
- package/src/__golden__/wave-loop/op-hooks-pass.json +735 -0
- package/src/__golden__/wave-loop/op-hooks-refused-at-base.json +148 -0
- package/src/__golden__/wave-loop/op-hooks-share.json +1225 -0
- package/src/__golden__/wave-loop/op-outcome-held.json +202 -0
- package/src/__golden__/wave-loop/op-outcome-replan-approved.json +286 -0
- package/src/__golden__/wave-loop/op-outcome-replan-forever.json +823 -0
- package/src/__golden__/wave-loop/op-outcome-replan.json +259 -0
- package/src/__golden__/wave-loop/op-outcome-stood-down.json +196 -0
- package/src/__golden__/wave-loop/op-outcome-unreadable.json +193 -0
- package/src/__golden__/wave-loop/op-overridden.json +508 -0
- package/src/__golden__/wave-loop/op-per-run.json +518 -0
- package/src/__golden__/wave-loop/op-point.json +495 -0
- package/src/__golden__/wave-loop/op-pr-review.json +397 -0
- package/src/__golden__/wave-loop/op-sealed.json +125 -0
- package/src/__golden__/wave-loop/op-spend-change-only.json +168 -0
- package/src/__golden__/wave-loop/op-spend.json +328 -0
- package/src/__golden__/wave-loop/op-wave-commands.json +1808 -0
- package/src/__golden__/wave-loop/op-wide-refused.json +291 -0
- package/src/__golden__/wave-loop/op-wide-waiting.json +231 -0
- package/src/__golden__/wave-loop/op-wide.json +440 -0
- package/src/cli/commands/import-live.test.ts +24 -0
- package/src/cli/commands/import.ts +8 -2
- package/src/cli/handlers/graph.test.ts +23 -0
- package/src/cli/handlers/graph.ts +22 -1
- package/src/cli/handlers/misc.ts +2 -1
- package/src/cli/main.test.ts +5 -0
- package/src/cli/parse-args.ts +3 -0
- package/src/cli/registry.ts +2 -0
- package/src/codegen/publish-order.test.ts +118 -4
- package/src/components/fan-out-run.ts +156 -128
- package/src/graph-ci-edges.test.ts +97 -0
- package/src/graph-detail.ts +9 -3
- package/src/graph-dot.ts +34 -2
- package/src/graph-ir.ts +156 -3
- package/src/graph-lens.ts +10 -1
- package/src/graph-mermaid.ts +44 -2
- package/src/lexicon.ts +23 -1
- package/src/meta/peer-deps.test.ts +39 -0
- package/src/op/op-waves-run.ts +184 -68
- package/src/wave-engine.test.ts +38 -1
- package/src/wave-engine.ts +101 -5
- package/src/wave-loop-golden.test.ts +627 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fan-out-run.d.ts","sourceRoot":"","sources":["../../src/components/fan-out-run.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fan-out-run.d.ts","sourceRoot":"","sources":["../../src/components/fan-out-run.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,16 +31,17 @@
|
|
|
31
31
|
* ## Or one approval per wave
|
|
32
32
|
*
|
|
33
33
|
* `waveGate` (#3049) is the other mode. Each wave is planned once the waves
|
|
34
|
-
* before it applied, and its gate binds that wave's set digest.
|
|
35
|
-
* the digest and the gate decision come from the wave engine
|
|
36
|
-
* (`../wave-engine.ts`, #3766), which `chant run wave` uses too
|
|
34
|
+
* before it applied, and its gate binds that wave's set digest. The loop,
|
|
35
|
+
* gate names, the digest and the gate decision come from the wave engine
|
|
36
|
+
* (`../wave-engine.ts`, #3766), which `chant run wave` uses too; this module
|
|
37
|
+
* hands it the steps a fan-out plans, decides and applies a wave with. See
|
|
37
38
|
* {@link runGatedWaves}.
|
|
38
39
|
*/
|
|
39
40
|
import { deployContext, runComponentDeploy, } from "./driver.js";
|
|
40
41
|
import { downstreamWithin, remainingFanOut } from "./fan-out.js";
|
|
41
42
|
import { evaluateGate, gitGateLedgerPort } from "../op/gate.js";
|
|
42
43
|
import { planWaveComponent } from "./wave-plan.js";
|
|
43
|
-
import { decideWaveGate, waveGateName, waveSetDigest } from "../wave-engine.js";
|
|
44
|
+
import { decideWaveGate, runWaveLoop, waveGateName, waveSetDigest } from "../wave-engine.js";
|
|
44
45
|
/** Thrown when `FanOutWaveGate.only` names a wave whose predecessors have not all applied. */
|
|
45
46
|
export class EarlierWaveNotAppliedError extends Error {
|
|
46
47
|
constructor(wave, earlier, components) {
|
|
@@ -230,131 +231,145 @@ async function runGatedWaves(plan, active, components, registry, options, waveGa
|
|
|
230
231
|
}
|
|
231
232
|
};
|
|
232
233
|
options.onProgress?.({ type: "run-start", waves: plan.waves });
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const gateName = waveGateName(waveGate.gate, waveNum);
|
|
246
|
-
const contexts = new Map(runnable.map((name) => [name, fanOutContext(options, name)]));
|
|
247
|
-
const planned = await Promise.all(runnable.map((name) => planComponent(byName.get(name), contexts.get(name), componentOutputs)));
|
|
248
|
-
const members = [];
|
|
249
|
-
const plansFor = new Map();
|
|
250
|
-
const waveFailures = [];
|
|
251
|
-
for (const p of planned) {
|
|
252
|
-
if ("error" in p) {
|
|
253
|
-
waveFailures.push({ component: p.component, error: p.error });
|
|
254
|
-
continue;
|
|
234
|
+
await runWaveLoop({
|
|
235
|
+
first: 1,
|
|
236
|
+
onward: (_k, outcome) => outcome === "next",
|
|
237
|
+
async plan({ k: waveNum }) {
|
|
238
|
+
const wave = plan.waves[waveNum - 1];
|
|
239
|
+
if (!wave)
|
|
240
|
+
return { end: "stop" };
|
|
241
|
+
const runnable = wave.filter((name) => left.has(name) && !blockedBy.has(name));
|
|
242
|
+
if (waveGate.only !== undefined && waveNum < waveGate.only) {
|
|
243
|
+
if (runnable.length > 0)
|
|
244
|
+
throw new EarlierWaveNotAppliedError(waveGate.only, waveNum, runnable);
|
|
245
|
+
return { end: "next" };
|
|
255
246
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
247
|
+
if (waveGate.only !== undefined && waveNum > waveGate.only)
|
|
248
|
+
return { end: "stop" };
|
|
249
|
+
if (runnable.length === 0)
|
|
250
|
+
return { end: "next" };
|
|
251
|
+
const gateName = waveGateName(waveGate.gate, waveNum);
|
|
252
|
+
const contexts = new Map(runnable.map((name) => [name, fanOutContext(options, name)]));
|
|
253
|
+
const planned = await Promise.all(runnable.map((name) => planComponent(byName.get(name), contexts.get(name), componentOutputs)));
|
|
254
|
+
const members = [];
|
|
255
|
+
const plansFor = new Map();
|
|
256
|
+
const waveFailures = [];
|
|
257
|
+
for (const p of planned) {
|
|
258
|
+
if ("error" in p) {
|
|
259
|
+
waveFailures.push({ component: p.component, error: p.error });
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
members.push(...p.members);
|
|
263
|
+
plansFor.set(p.component, p.plans);
|
|
264
|
+
}
|
|
265
|
+
return { go: { runnable, gateName, contexts, members, plansFor, waveFailures } };
|
|
266
|
+
},
|
|
267
|
+
digest(_at, { members, plansFor, waveFailures }) {
|
|
268
|
+
try {
|
|
269
|
+
// A wave where nothing planned has no set, and so no digest.
|
|
270
|
+
return members.length > 0 ? waveSetDigest(members) : "";
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
// Two components planning the same root: there is no one plan for it.
|
|
274
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
275
|
+
for (const name of plansFor.keys())
|
|
276
|
+
waveFailures.push({ component: name, error });
|
|
277
|
+
plansFor.clear();
|
|
278
|
+
return "";
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
async decide({ k: waveNum }, { runnable, gateName, members, plansFor, waveFailures }, digest) {
|
|
282
|
+
for (const f of waveFailures) {
|
|
283
|
+
failed.push(f.component);
|
|
284
|
+
results.push(planFailure(f.component, f.error ?? "plan failed"));
|
|
285
|
+
markBlocked(f.component);
|
|
286
|
+
}
|
|
287
|
+
const toRun = runnable.filter((name) => plansFor.has(name));
|
|
288
|
+
const record = {
|
|
289
|
+
wave: waveNum,
|
|
290
|
+
op: waveGate.op,
|
|
291
|
+
gate: gateName,
|
|
292
|
+
components: [...runnable].sort(),
|
|
293
|
+
digest,
|
|
294
|
+
members: [...members].sort((a, b) => a.member.localeCompare(b.member)),
|
|
295
|
+
status: "failed",
|
|
296
|
+
...(waveFailures.length > 0 ? { failed: waveFailures } : {}),
|
|
297
|
+
};
|
|
298
|
+
if (toRun.length === 0) {
|
|
299
|
+
waves.push(record);
|
|
300
|
+
options.onWaveSettled?.(record);
|
|
301
|
+
return { end: "next" };
|
|
302
|
+
}
|
|
303
|
+
const check = await decideWaveGate(gates.port, {
|
|
304
|
+
op: waveGate.op,
|
|
305
|
+
gate: gateName,
|
|
306
|
+
digest,
|
|
307
|
+
description: waveGate.description ?? `wave ${waveNum} of ${plan.waves.length}: ${toRun.join(", ")}`,
|
|
308
|
+
...(waveGate.timeout ? { timeout: waveGate.timeout } : {}),
|
|
309
|
+
...(options.now ? { now: options.now } : {}),
|
|
310
|
+
});
|
|
311
|
+
if (!check.satisfied) {
|
|
312
|
+
// Nothing in this wave ran, and no later wave is planned: its plan
|
|
313
|
+
// would read outputs this wave has not written.
|
|
314
|
+
const stopped = {
|
|
315
|
+
...record,
|
|
316
|
+
status: "gated",
|
|
317
|
+
...(check.mismatch?.approved ? { approved: check.mismatch.approved } : {}),
|
|
318
|
+
};
|
|
319
|
+
waves.push(stopped);
|
|
320
|
+
options.onWaveSettled?.(stopped);
|
|
321
|
+
gatedFact = check.pending;
|
|
322
|
+
return { end: "stop" };
|
|
323
|
+
}
|
|
324
|
+
return { go: { check, record, toRun } };
|
|
325
|
+
},
|
|
326
|
+
async apply({ k: waveNum }, { contexts, plansFor, waveFailures }, { check, record, toRun }) {
|
|
327
|
+
options.onProgress?.({ type: "wave-start", wave: waveNum, components: toRun });
|
|
328
|
+
const waveResults = await Promise.all(toRun.map(async (name) => {
|
|
329
|
+
options.onProgress?.({ type: "component-start", wave: waveNum, component: name });
|
|
330
|
+
const plans = plansFor.get(name);
|
|
331
|
+
const ctx = { ...contexts.get(name), ...(Object.keys(plans).length > 0 ? { plans } : {}) };
|
|
332
|
+
const result = await runComponentDeploy(byName.get(name), ctx, registry, componentOutputs, options.onProgress, gates);
|
|
333
|
+
options.onProgress?.({
|
|
334
|
+
type: "component-done",
|
|
335
|
+
wave: waveNum,
|
|
336
|
+
component: name,
|
|
337
|
+
status: result.status === "fail" ? "failed" : result.status,
|
|
338
|
+
});
|
|
339
|
+
options.onComponentSettled?.(result, componentOutputs[name]);
|
|
340
|
+
return result;
|
|
341
|
+
}));
|
|
342
|
+
results.push(...waveResults);
|
|
343
|
+
for (const result of waveResults) {
|
|
344
|
+
if (result.status === "ok") {
|
|
345
|
+
completed.push(result.component);
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
if (result.status === "fail") {
|
|
349
|
+
failed.push(result.component);
|
|
350
|
+
waveFailures.push({ component: result.component });
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
gatedFact ?? (gatedFact = result.gate);
|
|
354
|
+
}
|
|
355
|
+
markBlocked(result.component);
|
|
356
|
+
}
|
|
357
|
+
const settled = {
|
|
305
358
|
...record,
|
|
306
|
-
status: "
|
|
307
|
-
|
|
359
|
+
status: waveFailures.length > 0 ? "failed" : "applied",
|
|
360
|
+
approvedBy: check.resolution.resolvedBy,
|
|
361
|
+
...(waveFailures.length > 0 ? { failed: waveFailures } : {}),
|
|
308
362
|
};
|
|
309
|
-
waves.push(
|
|
310
|
-
options.onWaveSettled?.(
|
|
311
|
-
gatedFact = check.pending;
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
314
|
-
options.onProgress?.({ type: "wave-start", wave: waveNum, components: toRun });
|
|
315
|
-
const waveResults = await Promise.all(toRun.map(async (name) => {
|
|
316
|
-
options.onProgress?.({ type: "component-start", wave: waveNum, component: name });
|
|
317
|
-
const plans = plansFor.get(name);
|
|
318
|
-
const ctx = { ...contexts.get(name), ...(Object.keys(plans).length > 0 ? { plans } : {}) };
|
|
319
|
-
const result = await runComponentDeploy(byName.get(name), ctx, registry, componentOutputs, options.onProgress, gates);
|
|
363
|
+
waves.push(settled);
|
|
364
|
+
options.onWaveSettled?.(settled);
|
|
320
365
|
options.onProgress?.({
|
|
321
|
-
type: "
|
|
366
|
+
type: "wave-done",
|
|
322
367
|
wave: waveNum,
|
|
323
|
-
|
|
324
|
-
status: result.status === "fail" ? "failed" : result.status,
|
|
368
|
+
status: waveFailures.length > 0 ? "failed" : waveResults.some((r) => r.status === "gated") ? "gated" : "ok",
|
|
325
369
|
});
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
results.push(...waveResults);
|
|
330
|
-
for (const result of waveResults) {
|
|
331
|
-
if (result.status === "ok") {
|
|
332
|
-
completed.push(result.component);
|
|
333
|
-
continue;
|
|
334
|
-
}
|
|
335
|
-
if (result.status === "fail") {
|
|
336
|
-
failed.push(result.component);
|
|
337
|
-
waveFailures.push({ component: result.component });
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
gatedFact ?? (gatedFact = result.gate);
|
|
341
|
-
}
|
|
342
|
-
markBlocked(result.component);
|
|
343
|
-
}
|
|
344
|
-
const settled = {
|
|
345
|
-
...record,
|
|
346
|
-
status: waveFailures.length > 0 ? "failed" : "applied",
|
|
347
|
-
approvedBy: check.resolution.resolvedBy,
|
|
348
|
-
...(waveFailures.length > 0 ? { failed: waveFailures } : {}),
|
|
349
|
-
};
|
|
350
|
-
waves.push(settled);
|
|
351
|
-
options.onWaveSettled?.(settled);
|
|
352
|
-
options.onProgress?.({
|
|
353
|
-
type: "wave-done",
|
|
354
|
-
wave: waveNum,
|
|
355
|
-
status: waveFailures.length > 0 ? "failed" : waveResults.some((r) => r.status === "gated") ? "gated" : "ok",
|
|
356
|
-
});
|
|
357
|
-
}
|
|
370
|
+
return "next";
|
|
371
|
+
},
|
|
372
|
+
});
|
|
358
373
|
const blocked = [...blockedBy.entries()]
|
|
359
374
|
.sort(([a], [b]) => a.localeCompare(b))
|
|
360
375
|
.map(([component, by]) => ({ component, reason: "blocked", blockedBy: by }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-detail.d.ts","sourceRoot":"","sources":["../src/graph-detail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAExC,eAAO,MAAM,MAAM;aACjB,MAAM,EAAE,CAAC;aACT,UAAU,EAAE,CAAC;aACb,WAAW,EAAE,CAAC;aACd,UAAU,EAAE,CAAC;CACL,CAAC;AAEX,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAYpE;
|
|
1
|
+
{"version":3,"file":"graph-detail.d.ts","sourceRoot":"","sources":["../src/graph-detail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,YAAY,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAExC,eAAO,MAAM,MAAM;aACjB,MAAM,EAAE,CAAC;aACT,UAAU,EAAE,CAAC;aACb,WAAW,EAAE,CAAC;aACd,UAAU,EAAE,CAAC;CACL,CAAC;AAEX,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAYpE;AA4KD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAYtF"}
|
package/dist/graph-detail.js
CHANGED
|
@@ -122,10 +122,13 @@ function toComposites(ir) {
|
|
|
122
122
|
continue; // edge internal to a composite
|
|
123
123
|
// A property label only makes sense when neither endpoint was collapsed.
|
|
124
124
|
const collapsed = from !== e.from || to !== e.to;
|
|
125
|
+
// The kind survives the collapse (#3910): a job's `needs` into a
|
|
126
|
+
// collapsed composite is still a `needs`, not a typed reference.
|
|
127
|
+
const cross = e.crossPipeline ? { crossPipeline: true } : {};
|
|
125
128
|
const edge = collapsed
|
|
126
|
-
? { from, to, kind:
|
|
127
|
-
: { from, to, kind:
|
|
128
|
-
const key = `${from}\0${to}\0${edge.viaAttr ?? ""}`;
|
|
129
|
+
? { from, to, kind: e.kind, ...cross }
|
|
130
|
+
: { from, to, kind: e.kind, viaAttr: e.viaAttr, ...cross };
|
|
131
|
+
const key = `${from}\0${to}\0${edge.viaAttr ?? ""}\0${collapsed ? e.kind : ""}`;
|
|
129
132
|
if (!seen.has(key))
|
|
130
133
|
seen.set(key, edge);
|
|
131
134
|
}
|
|
@@ -136,11 +139,14 @@ function toComposites(ir) {
|
|
|
136
139
|
// not just the base + ATTRIBUTES. Filter to handles whose node survived.
|
|
137
140
|
const surviving = new Set(nodes.map((n) => n.id));
|
|
138
141
|
const imports = ir.imports?.filter((i) => surviving.has(i.node));
|
|
142
|
+
// Unresolved references (#3910) stay with whichever node now holds them.
|
|
143
|
+
const dangling = ir.dangling?.map((d) => ({ ...d, from: idMap.get(d.from) ?? d.from }));
|
|
139
144
|
return {
|
|
140
145
|
nodes,
|
|
141
146
|
edges: sortEdges([...seen.values()]),
|
|
142
147
|
groups: { byLexicon: byLexiconOf(nodes) },
|
|
143
148
|
...(imports && imports.length ? { imports } : {}),
|
|
149
|
+
...(dangling && dangling.length ? { dangling } : {}),
|
|
144
150
|
};
|
|
145
151
|
}
|
|
146
152
|
/** T3 — annotate each edge with the producer attribute it references. */
|
package/dist/graph-dot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-dot.d.ts","sourceRoot":"","sources":["../src/graph-dot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"graph-dot.d.ts","sourceRoot":"","sources":["../src/graph-dot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,YAAY,CAAC;AAG1D;;;;;;;;GAQG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CA0DzC"}
|
package/dist/graph-dot.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { edgeLabel } from "./graph-mermaid.js";
|
|
1
2
|
/**
|
|
2
3
|
* Render the graph IR as Graphviz DOT. Pure text — no `dot` needed to produce
|
|
3
4
|
* it. Two consumers: render directly with `dot -Tsvg` (mingrammer-style), or
|
|
@@ -11,18 +12,40 @@ export function toDot(ir) {
|
|
|
11
12
|
const lines = ["digraph chant {", " rankdir=TB;", ' node [shape=box];'];
|
|
12
13
|
// Cluster by wave (component graph) when present, else by lexicon (entity graph).
|
|
13
14
|
const clusters = ir.groups.byWave ?? ir.groups.byLexicon;
|
|
15
|
+
// CI pipelines (#3910) nest as clusters inside their lexicon's cluster.
|
|
16
|
+
const pipelineOf = new Map();
|
|
17
|
+
for (const [name, members] of Object.entries(ir.groups.byPipeline ?? {})) {
|
|
18
|
+
for (const id of members)
|
|
19
|
+
if (!pipelineOf.has(id))
|
|
20
|
+
pipelineOf.set(id, name);
|
|
21
|
+
}
|
|
14
22
|
const grouped = new Set();
|
|
15
23
|
if (clusters) {
|
|
16
24
|
for (const [name, members] of Object.entries(clusters)) {
|
|
17
25
|
lines.push(` subgraph ${q(`cluster_${name}`)} {`);
|
|
18
26
|
lines.push(` label=${q(name)};`);
|
|
27
|
+
const nested = new Map();
|
|
19
28
|
for (const id of members) {
|
|
20
29
|
const node = ir.nodes.find((n) => n.id === id);
|
|
21
30
|
if (!node)
|
|
22
31
|
continue;
|
|
23
32
|
grouped.add(id);
|
|
33
|
+
const pipeline = pipelineOf.get(id);
|
|
34
|
+
if (pipeline !== undefined) {
|
|
35
|
+
const arr = nested.get(pipeline) ?? [];
|
|
36
|
+
arr.push(node);
|
|
37
|
+
nested.set(pipeline, arr);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
24
40
|
lines.push(` ${nodeLine(node)}`);
|
|
25
41
|
}
|
|
42
|
+
for (const [pipeline, nodes] of [...nested].sort(([a], [b]) => a.localeCompare(b))) {
|
|
43
|
+
lines.push(` subgraph ${q(`cluster_${name}_pipeline_${pipeline}`)} {`);
|
|
44
|
+
lines.push(` label=${q(pipeline)};`);
|
|
45
|
+
for (const node of nodes)
|
|
46
|
+
lines.push(` ${nodeLine(node)}`);
|
|
47
|
+
lines.push(" }");
|
|
48
|
+
}
|
|
26
49
|
lines.push(" }");
|
|
27
50
|
}
|
|
28
51
|
}
|
|
@@ -33,6 +56,16 @@ export function toDot(ir) {
|
|
|
33
56
|
}
|
|
34
57
|
for (const e of ir.edges)
|
|
35
58
|
lines.push(` ${edgeLine(e)}`);
|
|
59
|
+
// Unresolved references (#3910): a dashed edge to a dashed stub node.
|
|
60
|
+
const stubs = new Set();
|
|
61
|
+
for (const d of ir.dangling ?? []) {
|
|
62
|
+
const stub = `dangling:${d.value}`;
|
|
63
|
+
if (!stubs.has(stub)) {
|
|
64
|
+
stubs.add(stub);
|
|
65
|
+
lines.push(` ${q(stub)} [label=${q(`${d.value}\n(not declared)`)}, shape=box, style="rounded,dashed"];`);
|
|
66
|
+
}
|
|
67
|
+
lines.push(` ${q(d.from)} -> ${q(stub)} [label=${q(d.kind)}, style=dashed];`);
|
|
68
|
+
}
|
|
36
69
|
lines.push("}");
|
|
37
70
|
return lines.join("\n") + "\n";
|
|
38
71
|
}
|
|
@@ -43,8 +76,9 @@ function nodeLine(node) {
|
|
|
43
76
|
function edgeLine(e) {
|
|
44
77
|
const from = q(e.from);
|
|
45
78
|
const to = q(e.to);
|
|
46
|
-
const label =
|
|
47
|
-
|
|
79
|
+
const label = edgeLabel(e);
|
|
80
|
+
const attrs = [label ? `label=${q(label)}` : "", e.crossPipeline ? "style=dashed" : ""].filter(Boolean);
|
|
81
|
+
return attrs.length ? `${from} -> ${to} [${attrs.join(", ")}];` : `${from} -> ${to};`;
|
|
48
82
|
}
|
|
49
83
|
/** Quote a DOT identifier/label. Graphviz accepts any string in double quotes;
|
|
50
84
|
* a real newline becomes the DOT line-break escape. */
|
package/dist/graph-ir.d.ts
CHANGED
|
@@ -68,16 +68,86 @@ export interface IRNode {
|
|
|
68
68
|
*/
|
|
69
69
|
runtimeOwner?: string;
|
|
70
70
|
}
|
|
71
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* What an edge means (#3910). `ref` is a typed cross-resource reference (an
|
|
73
|
+
* `AttrRef`, a `Ref` intrinsic, a whole node held in props, or an
|
|
74
|
+
* {@link EntityReference}). The rest are the dependency strings a CI lexicon
|
|
75
|
+
* writes, reported through a plugin's `graphEdges` hook:
|
|
76
|
+
*
|
|
77
|
+
* - `needs` — job waits for job (GitHub/GitLab `needs:`, GitLab stage order)
|
|
78
|
+
* - `calls` — job runs a reusable workflow or a local composite action (`uses:`)
|
|
79
|
+
* - `triggers` — a pipeline starts another one: GitLab `trigger:` (from starts to),
|
|
80
|
+
* GitHub `on.workflow_run` (to finishing starts from)
|
|
81
|
+
* - `includes` — a pipeline pulls in another file's config (GitLab `include:`)
|
|
82
|
+
* - `extends` — a job inherits another job's keys (GitLab `extends:`)
|
|
83
|
+
*
|
|
84
|
+
* Every edge points from the entity that holds the reference to the entity it
|
|
85
|
+
* names. The set grows additively ({@link GRAPH_IR_VERSION}): a reader ignores
|
|
86
|
+
* a kind it does not know.
|
|
87
|
+
*/
|
|
88
|
+
export type IREdgeKind = "ref" | "needs" | "calls" | "triggers" | "includes" | "extends";
|
|
89
|
+
/** A directed dependency: `from` references `to` (an attribute of it, for `ref`). */
|
|
72
90
|
export interface IREdge {
|
|
73
91
|
from: string;
|
|
74
92
|
to: string;
|
|
75
|
-
/** "ref" for an AttrRef-derived edge. */
|
|
76
|
-
kind:
|
|
93
|
+
/** "ref" for an AttrRef-derived edge; a CI kind otherwise (see {@link IREdgeKind}). */
|
|
94
|
+
kind: IREdgeKind;
|
|
77
95
|
/** The consumer-side property the reference flows through, when derivable. */
|
|
78
96
|
viaAttr?: string;
|
|
79
97
|
/** The producer-side attribute referenced (e.g. "id"). Added at detail T3. */
|
|
80
98
|
toAttr?: string;
|
|
99
|
+
/**
|
|
100
|
+
* True when the edge leaves the pipeline `from` belongs to (#3910): a
|
|
101
|
+
* reusable-workflow call, a `workflow_run` trigger, a GitLab child or
|
|
102
|
+
* multi-project trigger, an include, a cross-project `needs`. A renderer
|
|
103
|
+
* that draws each pipeline as a group ({@link IRGroups.byPipeline}) reads
|
|
104
|
+
* this to route the edge between groups. Absent on every in-pipeline edge.
|
|
105
|
+
*/
|
|
106
|
+
crossPipeline?: boolean;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* A reference whose target is not a node of this graph (#3910): a job
|
|
110
|
+
* `needs` a job no workflow declares, a `uses:` names another repository's
|
|
111
|
+
* workflow, a GitLab `include:` names a file chant did not generate. Kept on
|
|
112
|
+
* the IR rather than dropped or matched to a near name, so a reader can tell
|
|
113
|
+
* "no dependency" from "a dependency on something outside this project".
|
|
114
|
+
* Field names follow the live resolver's `DanglingRef` (./graph-refs.ts).
|
|
115
|
+
*/
|
|
116
|
+
export interface IRDanglingRef {
|
|
117
|
+
/** The node holding the reference. */
|
|
118
|
+
from: string;
|
|
119
|
+
/** The edge kind the reference would have been. */
|
|
120
|
+
kind: IREdgeKind;
|
|
121
|
+
/** Where on `from` it was written, e.g. `needs`, `uses`, `trigger.include`. */
|
|
122
|
+
path: string;
|
|
123
|
+
/** The reference exactly as written. */
|
|
124
|
+
value: string;
|
|
125
|
+
/** Same meaning as {@link IREdge.crossPipeline}. */
|
|
126
|
+
crossPipeline?: boolean;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* One reference a lexicon reports through its `graphEdges` hook (#3910),
|
|
130
|
+
* resolved by the lexicon from strings core cannot read: job names, workflow
|
|
131
|
+
* file paths, pipeline names. `from` and `to` are entity keys. A reference
|
|
132
|
+
* the lexicon could not resolve sets `dangling` and carries the string as
|
|
133
|
+
* written in `to`; core turns it into an {@link IRDanglingRef}.
|
|
134
|
+
*/
|
|
135
|
+
export interface LexiconGraphReference {
|
|
136
|
+
from: string;
|
|
137
|
+
to: string;
|
|
138
|
+
kind: IREdgeKind;
|
|
139
|
+
viaAttr?: string;
|
|
140
|
+
crossPipeline?: boolean;
|
|
141
|
+
dangling?: boolean;
|
|
142
|
+
}
|
|
143
|
+
/** What a lexicon's `graphEdges` hook returns (#3910). */
|
|
144
|
+
export interface LexiconGraphEdges {
|
|
145
|
+
references: LexiconGraphReference[];
|
|
146
|
+
/**
|
|
147
|
+
* Pipeline membership, `pipeline name -> entity keys`: a workflow and its
|
|
148
|
+
* jobs, a GitLab pipeline and its jobs. Lands on {@link IRGroups.byPipeline}.
|
|
149
|
+
*/
|
|
150
|
+
pipelines?: Record<string, string[]>;
|
|
81
151
|
}
|
|
82
152
|
/**
|
|
83
153
|
* One reference an entity declares in a vocabulary this module cannot read
|
|
@@ -179,6 +249,11 @@ export interface IRGroups {
|
|
|
179
249
|
* wave-laned renderer reads this the way `byStack` drives boundary boxes.
|
|
180
250
|
* Present only for the component-DAG projection; absent for entity IR. */
|
|
181
251
|
byWave?: Record<string, string[]>;
|
|
252
|
+
/** CI pipeline membership (#3910): a workflow or pipeline name -> the node
|
|
253
|
+
* ids it runs (the workflow node and its jobs). Reported by a CI lexicon's
|
|
254
|
+
* `graphEdges` hook; absent when no lexicon reports one. Edges marked
|
|
255
|
+
* `crossPipeline` run between these groups. */
|
|
256
|
+
byPipeline?: Record<string, string[]>;
|
|
182
257
|
}
|
|
183
258
|
/** A cross-stack export this stack publishes (a `stackOutput`/`output`): its
|
|
184
259
|
* name (the matching key another stack imports by) and the node that produces it. */
|
|
@@ -297,6 +372,11 @@ export interface GraphIR {
|
|
|
297
372
|
imports?: IRImport[];
|
|
298
373
|
/** The CI/pipeline projection alongside the component graph (#989) — see {@link IRPipeline}. */
|
|
299
374
|
pipeline?: IRPipeline;
|
|
375
|
+
/**
|
|
376
|
+
* References that name nothing in this graph (#3910) — see
|
|
377
|
+
* {@link IRDanglingRef}. Absent when there are none.
|
|
378
|
+
*/
|
|
379
|
+
dangling?: IRDanglingRef[];
|
|
300
380
|
/**
|
|
301
381
|
* Attributes chant computed rather than read back from the provider, keyed by the kind
|
|
302
382
|
* they were folded onto. An enrichment pass records what it derived here so callers can
|
|
@@ -311,6 +391,21 @@ export interface GraphIR {
|
|
|
311
391
|
* IR. `projectPath` relativizes source-file paths for portable output.
|
|
312
392
|
*/
|
|
313
393
|
export declare function buildGraphIr(entities: Map<string, Declarable>, projectPath?: string): GraphIR;
|
|
394
|
+
/**
|
|
395
|
+
* Add what the lexicons' `graphEdges` hooks reported (#3910) to a built IR.
|
|
396
|
+
*
|
|
397
|
+
* A resolved reference between two nodes becomes an edge. When it lands on
|
|
398
|
+
* the same `from`/`to`/`viaAttr` as an edge the AttrRef walk already found
|
|
399
|
+
* (a GitLab `needs:` holding the Job object itself, say), the lexicon's edge
|
|
400
|
+
* replaces it, since the lexicon knows the reference is a `needs` and the walk
|
|
401
|
+
* only knows it is a reference. A reference marked `dangling`, or whose
|
|
402
|
+
* target is not a node, goes on `ir.dangling` as written. One whose `from` is
|
|
403
|
+
* not a node is dropped: there is nothing to hang it on.
|
|
404
|
+
*
|
|
405
|
+
* Pure. Returns `ir` itself when no report added anything, so a project with
|
|
406
|
+
* no CI lexicon prints exactly what it did before.
|
|
407
|
+
*/
|
|
408
|
+
export declare function applyLexiconGraphEdges(ir: GraphIR, reports: readonly LexiconGraphEdges[]): GraphIR;
|
|
314
409
|
/** One lexicon's observed resources, keyed by logical name — the output of a
|
|
315
410
|
* plugin's `describeResources()`. The input to {@link buildLiveGraphIr}. */
|
|
316
411
|
export interface LiveObservation {
|
package/dist/graph-ir.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-ir.d.ts","sourceRoot":"","sources":["../src/graph-ir.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,cAAc,CAAC;AAI7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;;;;;GASG;AAEH,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,iCAAiC;AACjC,MAAM,WAAW,MAAM;IACrB,kEAAkE;IAClE,EAAE,EAAE,MAAM,CAAC;IACX,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,mCAAmC;IACnC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,
|
|
1
|
+
{"version":3,"file":"graph-ir.d.ts","sourceRoot":"","sources":["../src/graph-ir.ts"],"names":[],"mappings":"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"}
|