@intentius/chant 0.59.0 → 0.60.0
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/build-params.d.ts +2 -2
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/handlers/lint.d.ts.map +1 -1
- package/dist/components/pilots/alb-ecs.pilot.d.ts +2 -2
- package/dist/config.d.ts +4 -4
- package/dist/lexicon.d.ts +48 -5
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/observe.d.ts +4 -4
- package/dist/op/activities/index.d.ts +1 -1
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/reconcile.d.ts +79 -7
- package/dist/op/activities/reconcile.d.ts.map +1 -1
- package/dist/op/gate-summary.d.ts +16 -4
- package/dist/op/gate-summary.d.ts.map +1 -1
- package/dist/params.d.ts +1 -1
- package/dist/project-root.d.ts +2 -2
- package/package.json +1 -1
- package/src/build-params.ts +2 -2
- package/src/cli/commands/build.ts +8 -8
- package/src/cli/commands/lint.test.ts +151 -0
- package/src/cli/commands/lint.ts +37 -4
- package/src/cli/handlers/graph.test.ts +4 -4
- package/src/cli/handlers/graph.ts +11 -11
- package/src/cli/handlers/lint.test.ts +107 -0
- package/src/cli/handlers/lint.ts +30 -0
- package/src/components/SPRAWL-VALIDATION.md +5 -5
- package/src/components/pilots/README.md +1 -1
- package/src/components/pilots/alb-ecs.pilot.ts +2 -2
- package/src/config.ts +4 -4
- package/src/discovery/fold-import.test.ts +1 -1
- package/src/discovery/fold-import.ts +3 -3
- package/src/lexicon.ts +49 -5
- package/src/lifecycle/observe.test.ts +2 -2
- package/src/lifecycle/observe.ts +8 -8
- package/src/lifecycle/release-ledger.test.ts +2 -2
- package/src/op/activities/index.ts +8 -1
- package/src/op/activities/reconcile.test.ts +238 -0
- package/src/op/activities/reconcile.ts +267 -13
- package/src/op/gate-summary.test.ts +62 -0
- package/src/op/gate-summary.ts +17 -5
- package/src/params.ts +1 -1
- package/src/project-root.ts +2 -2
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pending-gate block a CI run leaves where people actually look (#2243),
|
|
3
|
+
* and the second surface GitLab needs for it (#2256).
|
|
4
|
+
*
|
|
5
|
+
* GitHub Actions, Forgejo Actions and Gitea all hand a step a markdown
|
|
6
|
+
* scratchpad through `GITHUB_STEP_SUMMARY`. GitLab CI has no equivalent at
|
|
7
|
+
* all — a job's surfaces are its log and its artifacts — so `CHANT_GATE_SUMMARY`
|
|
8
|
+
* names a path the generated GitLab job also declares under `artifacts:`. One
|
|
9
|
+
* more environment variable, the same block, still no API call and no token.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { mkdtempSync, readFileSync, existsSync } from "node:fs";
|
|
13
|
+
import { tmpdir } from "node:os";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
import { describe, test, expect } from "vitest";
|
|
16
|
+
import { gatedRunSummaryMarkdown, writeGatedRunSummary } from "./gate-summary";
|
|
17
|
+
|
|
18
|
+
const summary = { op: "app-apply", gate: "approve-app-apply", expiresAt: "2026-09-08T00:00:00Z" };
|
|
19
|
+
|
|
20
|
+
function tempPath(name: string): string {
|
|
21
|
+
return join(mkdtempSync(join(tmpdir(), "chant-gate-")), name);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe("gatedRunSummaryMarkdown (#2243)", () => {
|
|
25
|
+
test("names the gate, the exact approve command and the ledger path", () => {
|
|
26
|
+
const md = gatedRunSummaryMarkdown(summary);
|
|
27
|
+
expect(md).toContain("Waiting on gate `approve-app-apply`");
|
|
28
|
+
expect(md).toContain("chant approve app-apply approve-app-apply --approver <you>");
|
|
29
|
+
expect(md).toContain("_gates/app-apply.jsonl");
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
describe("writeGatedRunSummary surfaces (#2243, #2256)", () => {
|
|
34
|
+
test("writes to GITHUB_STEP_SUMMARY where the forge sets one", () => {
|
|
35
|
+
const path = tempPath("step-summary.md");
|
|
36
|
+
expect(writeGatedRunSummary(summary, { GITHUB_STEP_SUMMARY: path })).toBe(path);
|
|
37
|
+
expect(readFileSync(path, "utf8")).toContain("approve-app-apply");
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("writes to CHANT_GATE_SUMMARY where the forge sets none — GitLab's artifact path", () => {
|
|
41
|
+
const path = tempPath("chant-gate-app-apply.md");
|
|
42
|
+
expect(writeGatedRunSummary(summary, { CHANT_GATE_SUMMARY: path })).toBe(path);
|
|
43
|
+
expect(readFileSync(path, "utf8")).toContain("chant approve app-apply approve-app-apply");
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("the forge's own variable wins when both are set", () => {
|
|
47
|
+
const forge = tempPath("step-summary.md");
|
|
48
|
+
const artifact = tempPath("chant-gate-app-apply.md");
|
|
49
|
+
expect(
|
|
50
|
+
writeGatedRunSummary(summary, { GITHUB_STEP_SUMMARY: forge, CHANT_GATE_SUMMARY: artifact }),
|
|
51
|
+
).toBe(forge);
|
|
52
|
+
expect(existsSync(artifact)).toBe(false);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("a run with neither variable writes nothing and reports nothing", () => {
|
|
56
|
+
expect(writeGatedRunSummary(summary, {})).toBeUndefined();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("an unwritable path is swallowed: a decided run does not change outcome over a scratchpad", () => {
|
|
60
|
+
expect(writeGatedRunSummary(summary, { CHANT_GATE_SUMMARY: "/no/such/dir/gate.md" })).toBeUndefined();
|
|
61
|
+
});
|
|
62
|
+
});
|
package/src/op/gate-summary.ts
CHANGED
|
@@ -8,9 +8,14 @@
|
|
|
8
8
|
* markdown scratchpad through `GITHUB_STEP_SUMMARY`, rendered at the top of
|
|
9
9
|
* the run page; anything else that sets the variable gets the same block.
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
11
|
+
* GitLab CI sets no such variable and has no step summary at all: a job's
|
|
12
|
+
* surfaces are its log and its artifacts (#2256). So `CHANT_GATE_SUMMARY`
|
|
13
|
+
* names a second path, which the generated GitLab job sets to a file it also
|
|
14
|
+
* declares under `artifacts:`. Same block, same rule, one more variable.
|
|
15
|
+
*
|
|
16
|
+
* That is the whole forge coupling: two environment variables, appended to
|
|
17
|
+
* whichever is set, and nothing at all when neither is. No API call, no
|
|
18
|
+
* token, no flag to turn it on.
|
|
14
19
|
*/
|
|
15
20
|
|
|
16
21
|
import { appendFileSync } from "node:fs";
|
|
@@ -63,7 +68,14 @@ export function gatedRunSummaryMarkdown(summary: GatedRunSummary): string {
|
|
|
63
68
|
|
|
64
69
|
/**
|
|
65
70
|
* Append {@link gatedRunSummaryMarkdown} to the file `GITHUB_STEP_SUMMARY`
|
|
66
|
-
* names,
|
|
71
|
+
* names, or, where the forge sets no such variable, the one
|
|
72
|
+
* `CHANT_GATE_SUMMARY` names (#2256) — when it is set and the file can be
|
|
73
|
+
* written.
|
|
74
|
+
*
|
|
75
|
+
* The forge's own variable wins where both are set: a step summary is
|
|
76
|
+
* rendered on the run page, an artifact has to be downloaded, and writing
|
|
77
|
+
* both would put the same block in two places on a forge that already shows
|
|
78
|
+
* one of them.
|
|
67
79
|
*
|
|
68
80
|
* Returns the path written, or `undefined` when there was nothing to write to.
|
|
69
81
|
* A write that fails is swallowed: a run that already decided its outcome must
|
|
@@ -73,7 +85,7 @@ export function writeGatedRunSummary(
|
|
|
73
85
|
summary: GatedRunSummary,
|
|
74
86
|
env: NodeJS.ProcessEnv = process.env,
|
|
75
87
|
): string | undefined {
|
|
76
|
-
const path = env.GITHUB_STEP_SUMMARY;
|
|
88
|
+
const path = env.GITHUB_STEP_SUMMARY || env.CHANT_GATE_SUMMARY;
|
|
77
89
|
if (!path) return undefined;
|
|
78
90
|
try {
|
|
79
91
|
appendFileSync(path, gatedRunSummaryMarkdown(summary));
|
package/src/params.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* is a deploy-time CloudFormation parameter: it emits a `Parameters:` block and
|
|
7
7
|
* resolves when the STACK deploys. A build-time parameter resolves before the
|
|
8
8
|
* template is even synthesized — its value can change WHICH resources are
|
|
9
|
-
* produced at all (
|
|
9
|
+
* produced at all (a `tier` parameter selecting `light` vs `production` vs
|
|
10
10
|
* `production-ha`), which a deploy-time `Parameter` structurally cannot do.
|
|
11
11
|
*
|
|
12
12
|
* Project source never reads `process.env` directly to vary a build — that
|
package/src/project-root.ts
CHANGED
|
@@ -12,8 +12,8 @@ import { dirname, join, resolve } from "path";
|
|
|
12
12
|
* `src/<stack>` layout — `chant build src/<stack>` two or more levels below
|
|
13
13
|
* the project root — silently never found the root config: `buildParams`'
|
|
14
14
|
* declared `env:` mappings went inert, `ownership`/`lint.policies`/etc quietly
|
|
15
|
-
* fell back to defaults, and nothing warned
|
|
16
|
-
* `
|
|
15
|
+
* fell back to defaults, and nothing warned. That failure ran under every
|
|
16
|
+
* `npm run synth:*` of one project for two releases before anyone noticed it.
|
|
17
17
|
*
|
|
18
18
|
* `findProjectConfig` is the one walk every config-discovery call site now
|
|
19
19
|
* shares. It stops at the first of:
|