@intentius/chant 0.124.51 → 0.124.52
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/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +2 -1
- package/dist/components/capability.d.ts +9 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/covered-round.d.ts +173 -0
- package/dist/components/covered-round.d.ts.map +1 -0
- package/dist/components/covered-round.js +200 -0
- package/dist/components/driver.d.ts +8 -0
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/driver.js +8 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/pr-run.d.ts +21 -3
- package/dist/components/pr-run.d.ts.map +1 -1
- package/dist/components/pr-run.js +147 -16
- package/dist/components/wave-plan.d.ts +2 -0
- package/dist/components/wave-plan.d.ts.map +1 -1
- package/dist/components/wave-plan.js +4 -1
- package/dist/pr-loop.d.ts +36 -2
- package/dist/pr-loop.d.ts.map +1 -1
- package/dist/pr-loop.js +11 -2
- package/dist/wave-runtime.mjs +3 -3
- package/dist/workspace/pr-report.schema.json +25 -1
- package/package.json +1 -1
- package/src/cli/handlers/pr.ts +2 -1
- package/src/components/capability.ts +9 -0
- package/src/components/covered-round.test.ts +166 -0
- package/src/components/covered-round.ts +293 -0
- package/src/components/driver.ts +12 -0
- package/src/components/index.ts +17 -0
- package/src/components/pr-run.test.ts +212 -1
- package/src/components/pr-run.ts +166 -16
- package/src/components/wave-plan.ts +5 -2
- package/src/pr-loop.test.ts +14 -1
- package/src/pr-loop.ts +43 -4
- package/src/workspace/pr-report.schema.json +25 -1
package/src/pr-loop.ts
CHANGED
|
@@ -88,6 +88,9 @@ export const PR_REPORT_BEFORE_MERGE_FLOOR = "0.124.42";
|
|
|
88
88
|
/** The first chant whose plan report can carry `migrations` (#4407). */
|
|
89
89
|
export const PR_REPORT_MIGRATIONS_FLOOR = "0.124.49";
|
|
90
90
|
|
|
91
|
+
/** The first chant whose report can carry a member's `reads`, known at plan or not. */
|
|
92
|
+
export const PR_REPORT_READS_FLOOR = "0.124.52";
|
|
93
|
+
|
|
91
94
|
/** The gate a pull request's apply waits on, unless the pipeline names another. */
|
|
92
95
|
export const PR_APPLY_GATE = "pr-apply";
|
|
93
96
|
|
|
@@ -155,6 +158,16 @@ export type PrMemberStatus =
|
|
|
155
158
|
*/
|
|
156
159
|
| "waiting";
|
|
157
160
|
|
|
161
|
+
/** One upstream a member reads outputs of (`PrMember.reads`). */
|
|
162
|
+
export interface PrMemberRead {
|
|
163
|
+
/** The component (or stack) whose outputs it reads. */
|
|
164
|
+
upstream: string;
|
|
165
|
+
/** The output names it reads, sorted. `publish.<field>` for a published artifact. */
|
|
166
|
+
outputs: string[];
|
|
167
|
+
/** The ones its plan had no value for, sorted: known only after the upstream applies. Absent when every one was known. */
|
|
168
|
+
unknown?: string[];
|
|
169
|
+
}
|
|
170
|
+
|
|
158
171
|
export interface PrMember {
|
|
159
172
|
/** The member's name in the change set: a root, for a terraform-family step. */
|
|
160
173
|
member: string;
|
|
@@ -175,8 +188,10 @@ export interface PrMember {
|
|
|
175
188
|
/**
|
|
176
189
|
* The upstream outputs its plan read that the change's plans could not
|
|
177
190
|
* say (#3999), as `<component>.<output>`, sorted: known only after that
|
|
178
|
-
* upstream applies. The
|
|
179
|
-
*
|
|
191
|
+
* upstream applies. The apply plans the member again once they are known;
|
|
192
|
+
* the first approval covers that round when it does only what the preview
|
|
193
|
+
* showed with only these inputs filled in, and anything else waits for an
|
|
194
|
+
* approval of its own (`PrRound.covered`, `PrRound.notCovered`).
|
|
180
195
|
*/
|
|
181
196
|
unknownInputs?: string[];
|
|
182
197
|
/**
|
|
@@ -187,6 +202,15 @@ export interface PrMember {
|
|
|
187
202
|
* applies without a later round.
|
|
188
203
|
*/
|
|
189
204
|
buildInputs?: string[];
|
|
205
|
+
/**
|
|
206
|
+
* Every other component's output its steps read, one entry per upstream,
|
|
207
|
+
* by upstream: the output names, sorted, and under `unknown` the ones its
|
|
208
|
+
* plan had no value for. A read whose value the plan knew is here too, so
|
|
209
|
+
* a reader of the report sees each read between components from the plan
|
|
210
|
+
* on, not only the ones `unknownInputs` names. Added within contract 1 by
|
|
211
|
+
* chant {@link PR_REPORT_READS_FLOOR}.
|
|
212
|
+
*/
|
|
213
|
+
reads?: PrMemberRead[];
|
|
190
214
|
/** Apply stage (#3999): the round whose plan it applied or waits on, when not the first. */
|
|
191
215
|
round?: number;
|
|
192
216
|
/** Apply stage (#3999): why the first round's plan did not apply. */
|
|
@@ -210,6 +234,15 @@ export interface PrRound {
|
|
|
210
234
|
status: "applied" | "failed" | "waiting" | "plan-failed";
|
|
211
235
|
/** With `waiting`: why an approval that stands does not count (`--require-review`). */
|
|
212
236
|
message?: string;
|
|
237
|
+
/**
|
|
238
|
+
* The first approval covered this round's plan (#4419): no gate of its own was
|
|
239
|
+
* decided. `digest` is the first approval's, which the coverage is bound
|
|
240
|
+
* to; `filledInputs` are the inputs it previewed as unknown and this plan
|
|
241
|
+
* had a value for, as `<component>.<output>`.
|
|
242
|
+
*/
|
|
243
|
+
covered?: { digest: string; filledInputs: string[] };
|
|
244
|
+
/** Why the first approval did not cover this round, so it asked for its own (#4419). */
|
|
245
|
+
notCovered?: string;
|
|
213
246
|
/** The change-set document the round planned. */
|
|
214
247
|
changeSet: ChangeSetDocument;
|
|
215
248
|
}
|
|
@@ -719,8 +752,8 @@ export function renderPrNote(report: PrReport, options: { limit?: number; approv
|
|
|
719
752
|
if (unknown.length > 0) {
|
|
720
753
|
out.push(
|
|
721
754
|
"",
|
|
722
|
-
`Known only after apply: ${unknown.join("; ")}.
|
|
723
|
-
"The apply plans
|
|
755
|
+
`Known only after apply: ${unknown.join("; ")}. ` +
|
|
756
|
+
"The apply plans those members again once their upstream applied. When that plan does only what this one shows, with only those inputs filled in, this approval covers it; anything else asks for an approval of its own.",
|
|
724
757
|
);
|
|
725
758
|
}
|
|
726
759
|
const fromBuild = [...new Set(report.members.flatMap((m) => (m.buildInputs ?? []).map((ref) => `${code(m.component)} reads ${code(ref)}`)))];
|
|
@@ -733,6 +766,12 @@ export function renderPrNote(report: PrReport, options: { limit?: number; approv
|
|
|
733
766
|
}
|
|
734
767
|
for (const r of report.rounds ?? []) {
|
|
735
768
|
const what = `Round ${r.round} planned ${r.components.map(code).join(", ")} again after their upstream applied, digest ${code(r.digest)}`;
|
|
769
|
+
if (r.covered) {
|
|
770
|
+
const filled = r.covered.filledInputs.length > 0 ? `, with ${r.covered.filledInputs.map(code).join(", ")} filled in` : "";
|
|
771
|
+
out.push("", `${what}: covered by the approval of ${code(r.covered.digest)}${filled}, so it ${r.status === "applied" ? "applied" : "did not apply"} without a new approval${r.status === "failed" ? " (the apply failed)" : ""}.`);
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
if (r.notCovered) out.push("", `Round ${r.round}'s plan is not covered by the approval of ${code(report.digest)}: ${r.notCovered}.`);
|
|
736
775
|
if (r.status === "waiting") {
|
|
737
776
|
if (r.message) out.push("", `> ${r.message}`);
|
|
738
777
|
out.push("", `${what}. Not approved yet. Approve it, then run the apply again with the same \`--resume\` record:`, "", "```", prApproveCommand({ op: report.op, gate: r.gate, digest: r.digest }, options.approver ?? "<you>"), "```");
|
|
@@ -153,6 +153,16 @@
|
|
|
153
153
|
},
|
|
154
154
|
"status": { "enum": ["applied", "failed", "waiting", "plan-failed"] },
|
|
155
155
|
"message": { "type": "string", "description": "With waiting: why an approval that stands does not count under --require-review." },
|
|
156
|
+
"covered": {
|
|
157
|
+
"type": "object",
|
|
158
|
+
"required": ["digest", "filledInputs"],
|
|
159
|
+
"description": "Added within contract version 1 by #4419. The first approval covered this round's plan, so no gate of its own was decided and approval is the first one. The plan touched only components and logical ids the first plan previewed, with the same actions, and only inputs the first plan marked unknown differed.",
|
|
160
|
+
"properties": {
|
|
161
|
+
"digest": { "type": "string", "pattern": "^(?:jcs1-)?sha256:[0-9a-f]{64}$", "description": "The digest of the first approval, which the coverage is bound to: the report's digest." },
|
|
162
|
+
"filledInputs": { "type": "array", "items": { "type": "string" }, "description": "The inputs the first plan marked unknown that this plan had a value for, as <component>.<output>, sorted." }
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"notCovered": { "type": "string", "description": "Added within contract version 1 by #4419. Why an approval that stands for the first plan did not cover this round, so the round asked for its own." },
|
|
156
166
|
"changeSet": { "type": "object", "description": "The change-set document the round planned. Its digest equals digest." }
|
|
157
167
|
}
|
|
158
168
|
}
|
|
@@ -208,13 +218,27 @@
|
|
|
208
218
|
"unknownInputs": {
|
|
209
219
|
"type": "array",
|
|
210
220
|
"items": { "type": "string" },
|
|
211
|
-
"description": "#3999: the upstream outputs its plan read that the change's plans could not say, as <component>.<output>, sorted. Known only after that upstream applies
|
|
221
|
+
"description": "#3999: the upstream outputs its plan read that the change's plans could not say, as <component>.<output>, sorted. Known only after that upstream applies. The first approval covers the round that plans the member again when that plan does only what the preview showed, with only these inputs filled in; anything else waits for an approval of its own."
|
|
212
222
|
},
|
|
213
223
|
"buildInputs": {
|
|
214
224
|
"type": "array",
|
|
215
225
|
"items": { "type": "string" },
|
|
216
226
|
"description": "#3999: the published artifact identities its plan read from a build in the same change, as <component>.publish.<field>, sorted. Known only after the build runs and never approved again: the build's provenance binds them, so the member applies without a later round."
|
|
217
227
|
},
|
|
228
|
+
"reads": {
|
|
229
|
+
"type": "array",
|
|
230
|
+
"description": "Added within contract version 1, written by chant 0.124.52 and newer. Every other component's output its steps read, one entry per upstream: the output names, sorted, and under unknown the ones its plan had no value for. A read whose value the plan knew is listed too. Absent when it reads none.",
|
|
231
|
+
"items": {
|
|
232
|
+
"type": "object",
|
|
233
|
+
"required": ["upstream", "outputs"],
|
|
234
|
+
"additionalProperties": false,
|
|
235
|
+
"properties": {
|
|
236
|
+
"upstream": { "type": "string", "description": "The component (or stack) whose outputs it reads." },
|
|
237
|
+
"outputs": { "type": "array", "items": { "type": "string" }, "description": "The output names it reads, sorted. publish.<field> for a published artifact." },
|
|
238
|
+
"unknown": { "type": "array", "items": { "type": "string" }, "description": "The ones its plan had no value for, sorted: known only after the upstream applies. Absent when every one was known." }
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
},
|
|
218
242
|
"round": { "type": "integer", "minimum": 2, "description": "Apply stage (#3999): the round whose plan it applied or waits on, when not the first. planDigest and counts are that round's." },
|
|
219
243
|
"held": { "type": "string", "description": "Apply stage (#3999): why the first round's plan did not apply." }
|
|
220
244
|
}
|