@intentius/chant 0.124.31 → 0.124.33

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.
Files changed (509) hide show
  1. package/bin/chant +7 -2
  2. package/dist/ci-jobs.d.ts +4 -0
  3. package/dist/ci-jobs.d.ts.map +1 -1
  4. package/dist/ci-jobs.js +9 -2
  5. package/dist/cli/commands/check-lexicon-plugin.d.ts +7 -4
  6. package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
  7. package/dist/cli/commands/check-lexicon-plugin.js +10 -7
  8. package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
  9. package/dist/cli/commands/check-lexicon.js +18 -12
  10. package/dist/cli/commands/import.d.ts +10 -0
  11. package/dist/cli/commands/import.d.ts.map +1 -1
  12. package/dist/cli/commands/import.js +37 -0
  13. package/dist/cli/commands/init-lexicon/templates/project.d.ts.map +1 -1
  14. package/dist/cli/commands/init-lexicon/templates/project.js +4 -3
  15. package/dist/cli/commands/onboard.d.ts.map +1 -1
  16. package/dist/cli/commands/onboard.js +8 -4
  17. package/dist/cli/commands/update.d.ts.map +1 -1
  18. package/dist/cli/commands/update.js +2 -1
  19. package/dist/cli/dependencies.d.ts +18 -0
  20. package/dist/cli/dependencies.d.ts.map +1 -0
  21. package/dist/cli/dependencies.js +120 -0
  22. package/dist/cli/handlers/build.d.ts.map +1 -1
  23. package/dist/cli/handlers/build.js +38 -4
  24. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  25. package/dist/cli/handlers/fan-out.js +12 -4
  26. package/dist/cli/handlers/graph.d.ts.map +1 -1
  27. package/dist/cli/handlers/graph.js +16 -6
  28. package/dist/cli/handlers/lifecycle-health.d.ts +16 -0
  29. package/dist/cli/handlers/lifecycle-health.d.ts.map +1 -0
  30. package/dist/cli/handlers/lifecycle-health.js +150 -0
  31. package/dist/cli/handlers/lifecycle.d.ts +26 -0
  32. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  33. package/dist/cli/handlers/lifecycle.js +1 -1
  34. package/dist/cli/handlers/lint.d.ts.map +1 -1
  35. package/dist/cli/handlers/lint.js +6 -0
  36. package/dist/cli/handlers/operator.d.ts +2 -2
  37. package/dist/cli/handlers/operator.js +3 -3
  38. package/dist/cli/handlers/pr.d.ts +16 -0
  39. package/dist/cli/handlers/pr.d.ts.map +1 -1
  40. package/dist/cli/handlers/pr.js +610 -32
  41. package/dist/cli/handlers/promote.d.ts.map +1 -1
  42. package/dist/cli/handlers/promote.js +19 -2
  43. package/dist/cli/handlers/release.d.ts +16 -1
  44. package/dist/cli/handlers/release.d.ts.map +1 -1
  45. package/dist/cli/handlers/release.js +83 -11
  46. package/dist/cli/handlers/run.d.ts +13 -1
  47. package/dist/cli/handlers/run.d.ts.map +1 -1
  48. package/dist/cli/handlers/run.js +38 -15
  49. package/dist/cli/main.d.ts.map +1 -1
  50. package/dist/cli/main.js +121 -33
  51. package/dist/cli/parse-args.d.ts.map +1 -1
  52. package/dist/cli/parse-args.js +37 -0
  53. package/dist/cli/registry.d.ts +29 -6
  54. package/dist/cli/registry.d.ts.map +1 -1
  55. package/dist/cli/registry.js +6 -2
  56. package/dist/codegen/generate-post-synth-barrel.js +2 -2
  57. package/dist/codegen/lexicon-regen.d.ts +4 -0
  58. package/dist/codegen/lexicon-regen.d.ts.map +1 -1
  59. package/dist/codegen/lexicon-regen.js +1 -1
  60. package/dist/codegen/pinned-upgrade.js +2 -2
  61. package/dist/components/capability.d.ts +44 -3
  62. package/dist/components/capability.d.ts.map +1 -1
  63. package/dist/components/capability.js +21 -0
  64. package/dist/components/changed-files.d.ts +7 -1
  65. package/dist/components/changed-files.d.ts.map +1 -1
  66. package/dist/components/changed-files.js +9 -1
  67. package/dist/components/deploy-inputs.d.ts +91 -0
  68. package/dist/components/deploy-inputs.d.ts.map +1 -0
  69. package/dist/components/deploy-inputs.js +184 -0
  70. package/dist/components/driver.d.ts +38 -0
  71. package/dist/components/driver.d.ts.map +1 -1
  72. package/dist/components/driver.js +56 -6
  73. package/dist/components/fan-out-record.d.ts +6 -1
  74. package/dist/components/fan-out-record.d.ts.map +1 -1
  75. package/dist/components/fan-out-record.js +24 -0
  76. package/dist/components/fan-out-run.d.ts +20 -0
  77. package/dist/components/fan-out-run.d.ts.map +1 -1
  78. package/dist/components/fan-out-run.js +21 -1
  79. package/dist/components/gate-plan.d.ts +8 -0
  80. package/dist/components/gate-plan.d.ts.map +1 -1
  81. package/dist/components/gate-plan.js +6 -0
  82. package/dist/components/pr-pipeline.d.ts +98 -12
  83. package/dist/components/pr-pipeline.d.ts.map +1 -1
  84. package/dist/components/pr-pipeline.js +146 -23
  85. package/dist/components/pr-run.d.ts +128 -30
  86. package/dist/components/pr-run.d.ts.map +1 -1
  87. package/dist/components/pr-run.js +290 -70
  88. package/dist/components/release-compile.d.ts +37 -2
  89. package/dist/components/release-compile.d.ts.map +1 -1
  90. package/dist/components/release-compile.js +64 -8
  91. package/dist/components/release-promote.d.ts +17 -3
  92. package/dist/components/release-promote.d.ts.map +1 -1
  93. package/dist/components/release-promote.js +79 -18
  94. package/dist/components/verbs/bom-writer.d.ts +1 -1
  95. package/dist/components/verbs/bom-writer.d.ts.map +1 -1
  96. package/dist/components/verbs/lockfile-sbom-generator.d.ts +20 -0
  97. package/dist/components/verbs/lockfile-sbom-generator.d.ts.map +1 -1
  98. package/dist/components/verbs/lockfile-sbom-generator.js +41 -4
  99. package/dist/components/wave-plan.d.ts +15 -2
  100. package/dist/components/wave-plan.d.ts.map +1 -1
  101. package/dist/components/wave-plan.js +44 -5
  102. package/dist/discovery/fold-import.d.ts.map +1 -1
  103. package/dist/discovery/fold-import.js +16 -6
  104. package/dist/discovery/sandbox/bundle.d.ts.map +1 -1
  105. package/dist/discovery/sandbox/bundle.js +6 -0
  106. package/dist/discovery/specifier-resolve.d.ts.map +1 -1
  107. package/dist/discovery/specifier-resolve.js +8 -2
  108. package/dist/fold/fold.d.ts.map +1 -1
  109. package/dist/fold/fold.js +68 -1
  110. package/dist/fold/subset.d.ts +37 -0
  111. package/dist/fold/subset.d.ts.map +1 -1
  112. package/dist/fold/subset.js +88 -0
  113. package/dist/graph-detail.d.ts.map +1 -1
  114. package/dist/graph-detail.js +32 -7
  115. package/dist/health.d.ts +110 -0
  116. package/dist/health.d.ts.map +1 -0
  117. package/dist/health.js +105 -0
  118. package/dist/health.schema.json +191 -0
  119. package/dist/lexicon-module.d.ts +10 -0
  120. package/dist/lexicon-module.d.ts.map +1 -1
  121. package/dist/lexicon-module.js +53 -8
  122. package/dist/lexicon-plugin-helpers.d.ts.map +1 -1
  123. package/dist/lexicon-plugin-helpers.js +6 -4
  124. package/dist/lexicon.d.ts +29 -0
  125. package/dist/lexicon.d.ts.map +1 -1
  126. package/dist/lifecycle/affected.d.ts.map +1 -1
  127. package/dist/lifecycle/affected.js +7 -1
  128. package/dist/lifecycle/merge-record.d.ts +104 -0
  129. package/dist/lifecycle/merge-record.d.ts.map +1 -0
  130. package/dist/lifecycle/merge-record.js +102 -0
  131. package/dist/lifecycle/publish-attachments.d.ts +8 -5
  132. package/dist/lifecycle/publish-attachments.d.ts.map +1 -1
  133. package/dist/lifecycle/publish-attachments.js +27 -13
  134. package/dist/lifecycle/publish-npm.d.ts +3 -2
  135. package/dist/lifecycle/publish-npm.d.ts.map +1 -1
  136. package/dist/lifecycle/publish-npm.js +4 -3
  137. package/dist/lifecycle/release-at.d.ts +40 -0
  138. package/dist/lifecycle/release-at.d.ts.map +1 -0
  139. package/dist/lifecycle/release-at.js +83 -0
  140. package/dist/lifecycle/release-cut.d.ts.map +1 -1
  141. package/dist/lifecycle/release-cut.js +23 -12
  142. package/dist/lifecycle/release-ledger.d.ts +21 -0
  143. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  144. package/dist/lifecycle/release-ledger.js +24 -0
  145. package/dist/lifecycle/release-publish.d.ts +28 -12
  146. package/dist/lifecycle/release-publish.d.ts.map +1 -1
  147. package/dist/lifecycle/release-publish.js +29 -17
  148. package/dist/lifecycle/release-store.d.ts +25 -2
  149. package/dist/lifecycle/release-store.d.ts.map +1 -1
  150. package/dist/lifecycle/release-store.js +40 -13
  151. package/dist/lifecycle/run-ledger.d.ts.map +1 -1
  152. package/dist/lifecycle/run-ledger.js +1 -0
  153. package/dist/lifecycle/work-dir.d.ts +45 -0
  154. package/dist/lifecycle/work-dir.d.ts.map +1 -0
  155. package/dist/lifecycle/work-dir.js +78 -0
  156. package/dist/lint/discover.d.ts +17 -9
  157. package/dist/lint/discover.d.ts.map +1 -1
  158. package/dist/lint/discover.js +62 -54
  159. package/dist/lint/rules/op/index.d.ts +2 -1
  160. package/dist/lint/rules/op/index.d.ts.map +1 -1
  161. package/dist/lint/rules/op/index.js +4 -2
  162. package/dist/lint/rules/op/ops018-shell-image-digest.d.ts +10 -0
  163. package/dist/lint/rules/op/ops018-shell-image-digest.d.ts.map +1 -0
  164. package/dist/lint/rules/op/ops018-shell-image-digest.js +38 -0
  165. package/dist/module-source.d.ts +57 -0
  166. package/dist/module-source.d.ts.map +1 -0
  167. package/dist/module-source.js +104 -0
  168. package/dist/op/activities/activity-contracts.d.ts +5 -0
  169. package/dist/op/activities/activity-contracts.d.ts.map +1 -1
  170. package/dist/op/activities/activity-contracts.js +3 -0
  171. package/dist/op/activities/factory.js +1 -1
  172. package/dist/op/activities/shell.d.ts +38 -0
  173. package/dist/op/activities/shell.d.ts.map +1 -1
  174. package/dist/op/activities/shell.js +89 -3
  175. package/dist/op/builders.d.ts +7 -0
  176. package/dist/op/builders.d.ts.map +1 -1
  177. package/dist/op/builders.js +7 -0
  178. package/dist/op/discover.d.ts.map +1 -1
  179. package/dist/op/discover.js +13 -3
  180. package/dist/op/gate.d.ts.map +1 -1
  181. package/dist/op/gate.js +3 -0
  182. package/dist/op/op-waves-run.d.ts.map +1 -1
  183. package/dist/op/op-waves-run.js +20 -5
  184. package/dist/op/operator.d.ts +2 -2
  185. package/dist/op/operator.js +2 -2
  186. package/dist/op/runtime.d.ts +2 -0
  187. package/dist/op/runtime.d.ts.map +1 -1
  188. package/dist/op/steward.d.ts +6 -4
  189. package/dist/op/steward.d.ts.map +1 -1
  190. package/dist/op/steward.js +5 -3
  191. package/dist/op/work-lease-run.d.ts +20 -7
  192. package/dist/op/work-lease-run.d.ts.map +1 -1
  193. package/dist/op/work-lease-run.js +56 -12
  194. package/dist/pr-forge.d.ts +10 -0
  195. package/dist/pr-forge.d.ts.map +1 -1
  196. package/dist/pr-forge.js +39 -0
  197. package/dist/pr-loop.d.ts +155 -7
  198. package/dist/pr-loop.d.ts.map +1 -1
  199. package/dist/pr-loop.js +137 -11
  200. package/dist/pr-report-url.d.ts +4 -4
  201. package/dist/pr-report-url.d.ts.map +1 -1
  202. package/dist/pr-report-url.js +5 -5
  203. package/dist/runner-start.d.ts +179 -0
  204. package/dist/runner-start.d.ts.map +1 -0
  205. package/dist/runner-start.js +277 -0
  206. package/dist/ts-loader.d.ts +38 -4
  207. package/dist/ts-loader.d.ts.map +1 -1
  208. package/dist/ts-loader.js +190 -16
  209. package/dist/wave-runtime.mjs +238 -231
  210. package/dist/workspace/chant-migrations/fountain-retired-kinds.d.ts +34 -0
  211. package/dist/workspace/chant-migrations/fountain-retired-kinds.d.ts.map +1 -0
  212. package/dist/workspace/chant-migrations/fountain-retired-kinds.js +176 -0
  213. package/dist/workspace/chant-migrations.d.ts.map +1 -1
  214. package/dist/workspace/chant-migrations.js +2 -0
  215. package/dist/workspace/check.schema.json +70 -2
  216. package/dist/workspace/checks/boxes.d.ts +6 -6
  217. package/dist/workspace/checks/boxes.js +9 -9
  218. package/dist/workspace/checks/security.d.ts +35 -0
  219. package/dist/workspace/checks/security.d.ts.map +1 -0
  220. package/dist/workspace/checks/security.js +305 -0
  221. package/dist/workspace/checks.d.ts +2 -0
  222. package/dist/workspace/checks.d.ts.map +1 -1
  223. package/dist/workspace/checks.js +5 -0
  224. package/dist/workspace/ci-builds.d.ts +163 -0
  225. package/dist/workspace/ci-builds.d.ts.map +1 -0
  226. package/dist/workspace/ci-builds.js +315 -0
  227. package/dist/workspace/ci-green-cli.d.ts +2 -1
  228. package/dist/workspace/ci-green-cli.d.ts.map +1 -1
  229. package/dist/workspace/ci-green-cli.js +25 -5
  230. package/dist/workspace/ci-green-forge.d.ts +18 -4
  231. package/dist/workspace/ci-green-forge.d.ts.map +1 -1
  232. package/dist/workspace/ci-green-forge.js +12 -0
  233. package/dist/workspace/ci-green-workflow.d.ts +55 -1
  234. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  235. package/dist/workspace/ci-green-workflow.js +128 -1
  236. package/dist/workspace/ci-green.d.ts +117 -16
  237. package/dist/workspace/ci-green.d.ts.map +1 -1
  238. package/dist/workspace/ci-green.js +358 -43
  239. package/dist/workspace/ci-last-green.schema.json +49 -0
  240. package/dist/workspace/ci-list.schema.json +47 -7
  241. package/dist/workspace/ci-report-url.d.ts +18 -0
  242. package/dist/workspace/ci-report-url.d.ts.map +1 -0
  243. package/dist/workspace/ci-report-url.js +33 -0
  244. package/dist/workspace/ci-run-index.d.ts +13 -1
  245. package/dist/workspace/ci-run-index.d.ts.map +1 -1
  246. package/dist/workspace/ci-run-index.js +6 -4
  247. package/dist/workspace/ci-run-index.schema.json +6 -4
  248. package/dist/workspace/ci-run.d.ts +85 -6
  249. package/dist/workspace/ci-run.d.ts.map +1 -1
  250. package/dist/workspace/ci-run.js +262 -64
  251. package/dist/workspace/ci-runner-key.d.ts +16 -3
  252. package/dist/workspace/ci-runner-key.d.ts.map +1 -1
  253. package/dist/workspace/ci-runner-key.js +30 -10
  254. package/dist/workspace/ci-runner-start.d.ts +77 -0
  255. package/dist/workspace/ci-runner-start.d.ts.map +1 -0
  256. package/dist/workspace/ci-runner-start.js +185 -0
  257. package/dist/workspace/ci-serve.d.ts +130 -11
  258. package/dist/workspace/ci-serve.d.ts.map +1 -1
  259. package/dist/workspace/ci-serve.js +323 -40
  260. package/dist/workspace/declaration.d.ts +25 -0
  261. package/dist/workspace/declaration.d.ts.map +1 -1
  262. package/dist/workspace/declaration.js +14 -2
  263. package/dist/workspace/declaration.schema.json +30 -2
  264. package/dist/workspace/export.d.ts +1 -1
  265. package/dist/workspace/export.d.ts.map +1 -1
  266. package/dist/workspace/export.js +7 -3
  267. package/dist/workspace/ls.d.ts +8 -1
  268. package/dist/workspace/ls.d.ts.map +1 -1
  269. package/dist/workspace/ls.js +2 -1
  270. package/dist/workspace/ls.schema.json +9 -2
  271. package/dist/workspace/member-pipeline.d.ts +1 -0
  272. package/dist/workspace/member-pipeline.d.ts.map +1 -1
  273. package/dist/workspace/member-pipeline.js +2 -0
  274. package/dist/workspace/merge-record.schema.json +49 -0
  275. package/dist/workspace/pin-integrity.d.ts.map +1 -1
  276. package/dist/workspace/pin-integrity.js +3 -2
  277. package/dist/workspace/pr-report.schema.json +75 -8
  278. package/dist/workspace/reason-codes.d.ts +18 -1
  279. package/dist/workspace/reason-codes.d.ts.map +1 -1
  280. package/dist/workspace/reason-codes.js +20 -2
  281. package/dist/workspace/release-candidates.d.ts +129 -0
  282. package/dist/workspace/release-candidates.d.ts.map +1 -0
  283. package/dist/workspace/release-candidates.js +233 -0
  284. package/dist/workspace/release-candidates.schema.json +353 -0
  285. package/dist/workspace/run-event.schema.json +3 -1
  286. package/dist/workspace/security.d.ts +40 -0
  287. package/dist/workspace/security.d.ts.map +1 -0
  288. package/dist/workspace/security.js +99 -0
  289. package/dist/workspace/status.schema.json +3 -1
  290. package/dist/workspace/write-scope.d.ts +9 -0
  291. package/dist/workspace/write-scope.d.ts.map +1 -1
  292. package/dist/workspace/write-scope.js +11 -1
  293. package/package.json +8 -1
  294. package/src/__fixtures__/pr-loop/pr-apply-wave-waiting.note.golden.md +48 -0
  295. package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +1 -1
  296. package/src/ci-jobs.ts +11 -2
  297. package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +3 -3
  298. package/src/cli/commands/audit.test.ts +2 -2
  299. package/src/cli/commands/check-lexicon-plugin.test.ts +9 -0
  300. package/src/cli/commands/check-lexicon-plugin.ts +11 -8
  301. package/src/cli/commands/check-lexicon.test.ts +1 -1
  302. package/src/cli/commands/check-lexicon.ts +16 -11
  303. package/src/cli/commands/import.ts +40 -0
  304. package/src/cli/commands/init-lexicon/templates/project.ts +4 -3
  305. package/src/cli/commands/init-lexicon.test.ts +8 -5
  306. package/src/cli/commands/onboard.test.ts +45 -0
  307. package/src/cli/commands/onboard.ts +8 -4
  308. package/src/cli/commands/update.test.ts +6 -0
  309. package/src/cli/commands/update.ts +4 -1
  310. package/src/cli/compiled-cli.e2e.test.ts +76 -11
  311. package/src/cli/dependencies.e2e.test.ts +101 -0
  312. package/src/cli/dependencies.test.ts +93 -0
  313. package/src/cli/dependencies.ts +122 -0
  314. package/src/cli/handlers/build.test.ts +105 -0
  315. package/src/cli/handlers/build.ts +35 -4
  316. package/src/cli/handlers/fan-out.test.ts +73 -0
  317. package/src/cli/handlers/fan-out.ts +11 -4
  318. package/src/cli/handlers/graph.test.ts +76 -0
  319. package/src/cli/handlers/graph.ts +19 -12
  320. package/src/cli/handlers/lifecycle-health.test.ts +123 -0
  321. package/src/cli/handlers/lifecycle-health.ts +157 -0
  322. package/src/cli/handlers/lifecycle.ts +1 -1
  323. package/src/cli/handlers/lint.test.ts +42 -0
  324. package/src/cli/handlers/lint.ts +6 -0
  325. package/src/cli/handlers/operator.ts +3 -3
  326. package/src/cli/handlers/pr-deploy-inputs.test.ts +209 -0
  327. package/src/cli/handlers/pr-record.test.ts +201 -0
  328. package/src/cli/handlers/pr-waves.test.ts +449 -0
  329. package/src/cli/handlers/pr.test.ts +156 -0
  330. package/src/cli/handlers/pr.ts +648 -33
  331. package/src/cli/handlers/promote.test.ts +43 -1
  332. package/src/cli/handlers/promote.ts +19 -3
  333. package/src/cli/handlers/release-cut-at.e2e.test.ts +115 -0
  334. package/src/cli/handlers/release-publish-targets.e2e.test.ts +2 -2
  335. package/src/cli/handlers/release-verify.e2e.test.ts +12 -10
  336. package/src/cli/handlers/release.e2e.test.ts +19 -28
  337. package/src/cli/handlers/release.ts +81 -11
  338. package/src/cli/handlers/run-components-exit.test.ts +99 -0
  339. package/src/cli/handlers/run-signer.test.ts +79 -0
  340. package/src/cli/handlers/run.ts +34 -16
  341. package/src/cli/main.test.ts +18 -0
  342. package/src/cli/main.ts +120 -33
  343. package/src/cli/parse-args.ts +28 -0
  344. package/src/cli/registry.ts +35 -8
  345. package/src/codegen/generate-post-synth-barrel.ts +2 -2
  346. package/src/codegen/lexicon-regen.ts +1 -1
  347. package/src/codegen/pinned-upgrade.ts +2 -2
  348. package/src/codegen/post-synth-barrel-guards.test.ts +6 -11
  349. package/src/components/capability.ts +51 -3
  350. package/src/components/changed-files.test.ts +16 -1
  351. package/src/components/changed-files.ts +9 -1
  352. package/src/components/deploy-inputs.test.ts +108 -0
  353. package/src/components/deploy-inputs.ts +225 -0
  354. package/src/components/driver.test.ts +36 -1
  355. package/src/components/driver.ts +87 -4
  356. package/src/components/fan-out-record.ts +29 -1
  357. package/src/components/fan-out-run.test.ts +35 -0
  358. package/src/components/fan-out-run.ts +40 -1
  359. package/src/components/gate-plan.ts +9 -0
  360. package/src/components/pr-pipeline.test.ts +100 -0
  361. package/src/components/pr-pipeline.ts +184 -28
  362. package/src/components/pr-run.test.ts +323 -18
  363. package/src/components/pr-run.ts +355 -76
  364. package/src/components/release-compile.test.ts +34 -0
  365. package/src/components/release-compile.ts +89 -8
  366. package/src/components/release-promote.test.ts +55 -2
  367. package/src/components/release-promote.ts +93 -23
  368. package/src/components/verbs/bom-writer.ts +1 -1
  369. package/src/components/verbs/lockfile-sbom-generator.test.ts +36 -0
  370. package/src/components/verbs/lockfile-sbom-generator.ts +43 -5
  371. package/src/components/wave-plan.ts +48 -8
  372. package/src/discovery/fold-host-method.test.ts +87 -0
  373. package/src/discovery/fold-import.ts +15 -5
  374. package/src/discovery/fold-package-composite.test.ts +27 -0
  375. package/src/discovery/fold-specifiers.test.ts +8 -0
  376. package/src/discovery/sandbox/bundle.ts +6 -0
  377. package/src/discovery/specifier-resolve.ts +8 -2
  378. package/src/fold/fold.test.ts +72 -0
  379. package/src/fold/fold.ts +71 -0
  380. package/src/fold/subset.test.ts +31 -0
  381. package/src/fold/subset.ts +99 -0
  382. package/src/graph-detail.test.ts +57 -0
  383. package/src/graph-detail.ts +33 -7
  384. package/src/health.schema.json +191 -0
  385. package/src/health.test.ts +62 -0
  386. package/src/health.ts +178 -0
  387. package/src/lexicon-dist.e2e.test.ts +254 -0
  388. package/src/lexicon-module.test.ts +47 -0
  389. package/src/lexicon-module.ts +49 -7
  390. package/src/lexicon-plugin-helpers.ts +6 -4
  391. package/src/lexicon.ts +43 -1
  392. package/src/lifecycle/affected.test.ts +7 -0
  393. package/src/lifecycle/affected.ts +6 -1
  394. package/src/lifecycle/merge-record.test.ts +111 -0
  395. package/src/lifecycle/merge-record.ts +154 -0
  396. package/src/lifecycle/publish-attachments.ts +25 -13
  397. package/src/lifecycle/publish-npm.ts +4 -3
  398. package/src/lifecycle/publish-targets.test.ts +34 -4
  399. package/src/lifecycle/release-at.test.ts +48 -0
  400. package/src/lifecycle/release-at.ts +100 -0
  401. package/src/lifecycle/release-cut.test.ts +41 -0
  402. package/src/lifecycle/release-cut.ts +22 -11
  403. package/src/lifecycle/release-ledger.ts +34 -0
  404. package/src/lifecycle/release-publish.test.ts +43 -13
  405. package/src/lifecycle/release-publish.ts +38 -18
  406. package/src/lifecycle/release-store.ts +57 -13
  407. package/src/lifecycle/run-ledger.test.ts +13 -0
  408. package/src/lifecycle/run-ledger.ts +1 -0
  409. package/src/lifecycle/work-dir.test.ts +77 -0
  410. package/src/lifecycle/work-dir.ts +82 -0
  411. package/src/lint/discover.test.ts +46 -2
  412. package/src/lint/discover.ts +55 -49
  413. package/src/lint/rules/op/index.ts +4 -2
  414. package/src/lint/rules/op/ops018-shell-image-digest.test.ts +60 -0
  415. package/src/lint/rules/op/ops018-shell-image-digest.ts +48 -0
  416. package/src/module-source.test.ts +85 -0
  417. package/src/module-source.ts +112 -0
  418. package/src/op/activities/activity-contracts.ts +3 -0
  419. package/src/op/activities/factory.ts +1 -1
  420. package/src/op/activities/shell-container.e2e.test.ts +67 -0
  421. package/src/op/activities/shell.test.ts +44 -1
  422. package/src/op/activities/shell.ts +110 -3
  423. package/src/op/builders.ts +7 -0
  424. package/src/op/discover-root.test.ts +31 -2
  425. package/src/op/discover.ts +14 -4
  426. package/src/op/gate.test.ts +30 -0
  427. package/src/op/gate.ts +3 -0
  428. package/src/op/op-waves-run.ts +20 -5
  429. package/src/op/op-waves.test.ts +49 -0
  430. package/src/op/operator.ts +2 -2
  431. package/src/op/runtime.ts +2 -0
  432. package/src/op/step-console.test.ts +4 -2
  433. package/src/op/steward.ts +6 -4
  434. package/src/op/work-lease-run.test.ts +88 -2
  435. package/src/op/work-lease-run.ts +52 -12
  436. package/src/pr-forge-bundle.test.ts +2 -2
  437. package/src/pr-forge.test.ts +42 -0
  438. package/src/pr-forge.ts +40 -0
  439. package/src/pr-loop-bundle.test.ts +2 -1
  440. package/src/pr-loop.test.ts +146 -1
  441. package/src/pr-loop.ts +278 -17
  442. package/src/pr-report-url.ts +7 -7
  443. package/src/runner-start-bundle.test.ts +29 -0
  444. package/src/runner-start.test.ts +179 -0
  445. package/src/runner-start.ts +329 -0
  446. package/src/terraform/__fixtures__/advise.test.ts +21 -2
  447. package/src/ts-loader.test.ts +89 -1
  448. package/src/ts-loader.ts +180 -13
  449. package/src/workspace/changes.test.ts +1 -1
  450. package/src/workspace/chant-migrations/fountain-retired-kinds.test.ts +33 -0
  451. package/src/workspace/chant-migrations/fountain-retired-kinds.ts +190 -0
  452. package/src/workspace/chant-migrations.e2e.test.ts +5 -0
  453. package/src/workspace/chant-migrations.ts +2 -0
  454. package/src/workspace/check-contract.test.ts +3 -2
  455. package/src/workspace/check.schema.json +70 -2
  456. package/src/workspace/checks/boxes.ts +9 -9
  457. package/src/workspace/checks/security.test.ts +138 -0
  458. package/src/workspace/checks/security.ts +305 -0
  459. package/src/workspace/checks.ts +5 -0
  460. package/src/workspace/ci-builds.e2e.test.ts +208 -0
  461. package/src/workspace/ci-builds.test.ts +174 -0
  462. package/src/workspace/ci-builds.ts +385 -0
  463. package/src/workspace/ci-green-builds.test.ts +180 -0
  464. package/src/workspace/ci-green-cli.test.ts +54 -0
  465. package/src/workspace/ci-green-cli.ts +26 -5
  466. package/src/workspace/ci-green-forge.ts +30 -4
  467. package/src/workspace/ci-green-runs.test.ts +53 -11
  468. package/src/workspace/ci-green-workflow.test.ts +84 -1
  469. package/src/workspace/ci-green-workflow.ts +139 -2
  470. package/src/workspace/ci-green.test.ts +6 -3
  471. package/src/workspace/ci-green.ts +408 -48
  472. package/src/workspace/ci-last-green.schema.json +49 -0
  473. package/src/workspace/ci-list.schema.json +47 -7
  474. package/src/workspace/ci-report-url.test.ts +220 -0
  475. package/src/workspace/ci-report-url.ts +33 -0
  476. package/src/workspace/ci-run-index.schema.json +6 -4
  477. package/src/workspace/ci-run-index.test.ts +42 -3
  478. package/src/workspace/ci-run-index.ts +19 -5
  479. package/src/workspace/ci-run.test.ts +203 -8
  480. package/src/workspace/ci-run.ts +295 -63
  481. package/src/workspace/ci-runner-key.test.ts +55 -17
  482. package/src/workspace/ci-runner-key.ts +36 -11
  483. package/src/workspace/ci-runner-start.test.ts +151 -0
  484. package/src/workspace/ci-runner-start.ts +193 -0
  485. package/src/workspace/ci-serve-builds.test.ts +86 -0
  486. package/src/workspace/ci-serve.test.ts +209 -6
  487. package/src/workspace/ci-serve.ts +341 -42
  488. package/src/workspace/declaration.schema.json +30 -2
  489. package/src/workspace/declaration.test.ts +40 -0
  490. package/src/workspace/declaration.ts +40 -3
  491. package/src/workspace/export.ts +6 -3
  492. package/src/workspace/ls.schema.json +9 -2
  493. package/src/workspace/ls.ts +10 -4
  494. package/src/workspace/member-pipeline.ts +2 -1
  495. package/src/workspace/merge-record.schema.json +49 -0
  496. package/src/workspace/pin-integrity.test.ts +5 -0
  497. package/src/workspace/pin-integrity.ts +3 -2
  498. package/src/workspace/pr-report.schema.json +75 -8
  499. package/src/workspace/reason-codes.test.ts +2 -0
  500. package/src/workspace/reason-codes.ts +20 -2
  501. package/src/workspace/release-candidates.schema.json +353 -0
  502. package/src/workspace/release-candidates.test.ts +106 -0
  503. package/src/workspace/release-candidates.ts +315 -0
  504. package/src/workspace/run-event.schema.json +3 -1
  505. package/src/workspace/security.test.ts +70 -0
  506. package/src/workspace/security.ts +118 -0
  507. package/src/workspace/status.schema.json +3 -1
  508. package/src/workspace/write-scope.test.ts +29 -1
  509. package/src/workspace/write-scope.ts +12 -1
package/dist/pr-loop.d.ts CHANGED
@@ -28,6 +28,16 @@
28
28
  * and decides the gate against the new digest. The same plan applies; a moved
29
29
  * plan stops with both digests named and nothing applied.
30
30
  *
31
+ * ## A gate per wave on merge
32
+ *
33
+ * With `--wave-gate <gate>` (#4003) the apply runs a wave at a time, and
34
+ * plans each wave after the one before it applied. Wave 1 applies under the
35
+ * pull request's approval. A later wave whose new plan the approved change
36
+ * set covers (`planCoveredBy`) applies under that approval too; one whose
37
+ * plan moved waits at `<gate>-wave-<k>`, under the same op, for an approval
38
+ * of its new plan. The report's `waves` says which wave applied under which
39
+ * approval.
40
+ *
31
41
  * ## Inside a workspace member
32
42
  *
33
43
  * Each workspace member that generates the pipeline (#3465) runs its own
@@ -43,6 +53,16 @@ export declare const PR_REPORT_SCHEMA_ID = "https://intentius.io/chant/schemas/w
43
53
  export declare const PR_REPORT_CONTRACT = 1;
44
54
  /** The first chant whose report can carry `deployedOutputs` (#4104). */
45
55
  export declare const PR_REPORT_DEPLOYED_OUTPUTS_FLOOR = "0.124.30";
56
+ /** The first chant whose report can carry `waveGate` and `waves` (#4003). */
57
+ export declare const PR_REPORT_WAVES_FLOOR = "0.124.32";
58
+ /**
59
+ * The first chant whose report can carry `plannedOutputs`, `rounds`, a
60
+ * member's `unknownInputs`, `buildInputs`, `round` and `held`, and the `waiting` statuses
61
+ * (#3999).
62
+ */
63
+ export declare const PR_REPORT_PLANNED_OUTPUTS_FLOOR = "0.124.32";
64
+ /** The chant that writes the `record` stage and the `recorded` status (#4168 step 1). */
65
+ export declare const PR_REPORT_RECORD_FLOOR = "0.124.33";
46
66
  /** The gate a pull request's apply waits on, unless the pipeline names another. */
47
67
  export declare const PR_APPLY_GATE = "pr-apply";
48
68
  /**
@@ -50,17 +70,27 @@ export declare const PR_APPLY_GATE = "pr-apply";
50
70
  * `pr-<number>-<member>` for a workspace member's pipeline (#3465).
51
71
  */
52
72
  export declare function prOp(pr: number, member?: string): string;
73
+ /**
74
+ * The gate a round of an apply waits on (#3999): the pull request's own
75
+ * gate for the first, and `<gate>-round-<n>` for each one planned after an
76
+ * upstream applied. A workspace's `identity.gates` entry for `gate` covers
77
+ * every round.
78
+ */
79
+ export declare function prRoundGate(gate: string, round: number): string;
53
80
  /** Whether `op` is a pull request's gate op, with or without a member. Member names follow the declaration's name pattern. */
54
81
  export declare const PR_GATE_OP: RegExp;
55
82
  /** The hidden line that marks the pull request's note, one per environment and, in a workspace, per member. */
56
83
  export declare function prNoteMarker(env: string, member?: string): string;
57
- /** The status contexts the two stages set on the commit. */
84
+ /** The status contexts the stages set on the commit. */
58
85
  export declare const PR_STATUS_CONTEXTS: {
59
86
  readonly plan: "chant/plan";
60
87
  readonly apply: "chant/apply";
88
+ readonly record: "chant/record";
61
89
  };
90
+ /** A pull-request loop stage: plan on the pull request, then record (#4168) or, opted in, apply on merge. */
91
+ export type PrStage = keyof typeof PR_STATUS_CONTEXTS;
62
92
  /** A stage's status context: `chant/plan`, or `chant/plan/<member>` for a workspace member's pipeline. */
63
- export declare function prStatusContext(stage: "plan" | "apply", member?: string): string;
93
+ export declare function prStatusContext(stage: PrStage, member?: string): string;
64
94
  /** Changes a member's plan proposes, by the actions a reviewer reads. */
65
95
  export interface PrMemberCounts {
66
96
  create: number;
@@ -79,7 +109,13 @@ export type PrMemberStatus =
79
109
  /** The apply failed. */
80
110
  | "failed"
81
111
  /** Not applied because a member it depends on failed. */
82
- | "blocked";
112
+ | "blocked"
113
+ /**
114
+ * Apply stage (#3999): held back because its plan read an upstream output
115
+ * that applied as another value, or was known only after apply. It waits
116
+ * on an approval of the plan the apply made for it afterwards (`rounds`).
117
+ */
118
+ | "waiting";
83
119
  export interface PrMember {
84
120
  /** The member's name in the change set: a root, for a terraform-family step. */
85
121
  member: string;
@@ -93,9 +129,47 @@ export interface PrMember {
93
129
  /**
94
130
  * Components this one depends on whose outputs changed when they applied
95
131
  * (apply stage). Its applied plan read the values from before, so the next
96
- * run plans it again.
132
+ * run plans it again. Not written since #3999, which holds such a member
133
+ * back and plans it again in the same apply (`held`, `round`).
97
134
  */
98
135
  inputsMoved?: string[];
136
+ /**
137
+ * The upstream outputs its plan read that the change's plans could not
138
+ * say (#3999), as `<component>.<output>`, sorted: known only after that
139
+ * upstream applies. The approval does not cover what this member does
140
+ * with them; the apply plans it again once they are known.
141
+ */
142
+ unknownInputs?: string[];
143
+ /**
144
+ * The published artifact identities its plan read from a build in the
145
+ * same change (#3999), as `<component>.publish.<field>`, sorted: an image
146
+ * digest, say. Known only after the build runs, but never approved again:
147
+ * the build's provenance and attestation bind the digest, so the member
148
+ * applies without a later round.
149
+ */
150
+ buildInputs?: string[];
151
+ /** Apply stage (#3999): the round whose plan it applied or waits on, when not the first. */
152
+ round?: number;
153
+ /** Apply stage (#3999): why the first round's plan did not apply. */
154
+ held?: string;
155
+ }
156
+ /** A round of plans an apply made after an upstream applied (#3999), the report's `rounds`. */
157
+ export interface PrRound {
158
+ /** 2 for the first plan made after an upstream applied, and on. */
159
+ round: number;
160
+ /** The gate it waits on: {@link prRoundGate}. */
161
+ gate: string;
162
+ /** The change-set digest of what the round planned. What its gate binds. */
163
+ digest: string;
164
+ /** The components planned again, in apply order. */
165
+ components: string[];
166
+ approval: PrApproval;
167
+ /** `waiting`: no approval stands for `digest`. `plan-failed`: a member failed to plan, so the round did not apply. */
168
+ status: "applied" | "failed" | "waiting" | "plan-failed";
169
+ /** With `waiting`: why an approval that stands does not count (`--require-review`). */
170
+ message?: string;
171
+ /** The change-set document the round planned. */
172
+ changeSet: ChangeSetDocument;
99
173
  }
100
174
  /** Where the approval stands for the planned digest. */
101
175
  export interface PrApproval {
@@ -114,6 +188,12 @@ export interface PrApproval {
114
188
  export type PrStatus =
115
189
  /** Plan stage: every member planned. */
116
190
  "planned"
191
+ /**
192
+ * Record stage (#4168): every member planned on the merged commit and the
193
+ * plan is kept with the merge record. Nothing applied; `approval` says
194
+ * whether the plan is the one approved.
195
+ */
196
+ | "recorded"
117
197
  /** Plan stage: a member failed to plan. Apply stage: the same, so nothing applied. */
118
198
  | "plan-failed"
119
199
  /** Nothing the change touches is deployed by a component. */
@@ -122,8 +202,19 @@ export type PrStatus =
122
202
  | "applied"
123
203
  /** Apply stage: a member failed to apply. Its dependents did not run. */
124
204
  | "failed"
205
+ /**
206
+ * Apply stage with `--wave-gate` and `--wave` (#4003): this wave applied,
207
+ * and a later wave of the change is still to run.
208
+ */
209
+ | "wave-applied"
125
210
  /** Apply stage: nothing applied, see `refusal`. */
126
- | "refused";
211
+ | "refused"
212
+ /**
213
+ * Apply stage (#3999): the approved plans applied, except members held
214
+ * back after an upstream applied. They wait on the approval of the plan
215
+ * the last of `rounds` made.
216
+ */
217
+ | "waiting";
127
218
  /** Why an apply refused. */
128
219
  export type PrRefusal =
129
220
  /** No approval stands for any plan of this pull request. */
@@ -132,8 +223,44 @@ export type PrRefusal =
132
223
  | "plan-changed"
133
224
  /** The approval names someone who has not approved the pull request on the forge. */
134
225
  | "not-a-reviewer"
226
+ /** The approval names the pull request's author, or an author or committer of one of its commits (#4000). */
227
+ | "author-approved"
135
228
  /** No pull request merged this commit, so there is no approval to read. */
136
- | "no-pull-request";
229
+ | "no-pull-request"
230
+ /** `--wave-gate` (#4003): the wave's new plan is not one the pull request approved, and no approval stands for it. */
231
+ | "wave-not-approved"
232
+ /** `--wave-gate`: an approval of the wave's gate stands for another digest, so its plan moved since. */
233
+ | "wave-plan-changed"
234
+ /** `--wave-gate` with `--wave <k>`: an earlier wave has work left, or no record says it applied. */
235
+ | "earlier-wave";
236
+ /**
237
+ * One wave of an apply with `--wave-gate` (#4003): what it planned, where it
238
+ * got to, and which approval it applied or waits under.
239
+ */
240
+ export interface PrWave {
241
+ /** 1-based, from the derivation (`selection.waves`). */
242
+ wave: number;
243
+ /** The components planned in it on the run that reached it. */
244
+ components: string[];
245
+ /** `applied`; `failed` or `plan-failed`; or `waiting` at its gate. */
246
+ status: "applied" | "failed" | "plan-failed" | "waiting";
247
+ /**
248
+ * `pull-request`: the approved change set covers the wave's plan, so it
249
+ * applies under the pull request's approval. `wave`: its plan moved, so it
250
+ * needs an approval of its own gate.
251
+ */
252
+ approval: "pull-request" | "wave";
253
+ /** The gate it applied or waits under: the pull request's, or `<wave gate>-wave-<k>`. */
254
+ gate: string;
255
+ /** The digest that gate binds: the pull request's change set, or the wave's new plan. */
256
+ digest: string;
257
+ /** Who approved that digest. */
258
+ approvedBy?: string[];
259
+ /** Waiting: an approval of the wave's gate stands for this other digest. */
260
+ approved?: string;
261
+ /** Why the approved change set does not cover the wave's plan, one line per member. */
262
+ moved?: string[];
263
+ }
137
264
  /**
138
265
  * The document `pr-plan` and `pr-apply` write (`pr-report.schema.json`).
139
266
  * The terragucci plan report (#3349) reads it; fields are only ever added.
@@ -141,7 +268,7 @@ export type PrRefusal =
141
268
  export interface PrReport {
142
269
  $schema: typeof PR_REPORT_SCHEMA_ID;
143
270
  contract: typeof PR_REPORT_CONTRACT;
144
- stage: "plan" | "apply";
271
+ stage: PrStage;
145
272
  /** The pull or merge request number, when known. */
146
273
  pr: number | null;
147
274
  env: string;
@@ -175,7 +302,28 @@ export interface PrReport {
175
302
  * {@link PR_REPORT_DEPLOYED_OUTPUTS_FLOOR}.
176
303
  */
177
304
  deployedOutputs?: Record<string, string[]>;
305
+ /**
306
+ * Per dependency in the change that a member was planned against (#3999),
307
+ * the names of the outputs its plan knows, sorted. An output it reads that
308
+ * is not here is known only after apply (a member's `unknownInputs`).
309
+ * Absent when no member read one. Added within contract 1 by chant
310
+ * {@link PR_REPORT_PLANNED_OUTPUTS_FLOOR}.
311
+ */
312
+ plannedOutputs?: Record<string, string[]>;
313
+ /**
314
+ * Apply stage (#3999): the rounds planned after an upstream applied, in
315
+ * order, each with its own gate and digest. Absent when nothing was held.
316
+ */
317
+ rounds?: PrRound[];
178
318
  approval: PrApproval;
319
+ /**
320
+ * The wave gate's base name with `--wave-gate` (#4003): wave k waits on
321
+ * `<waveGate>-wave-<k>` when its plan moved. Added within contract 1 by
322
+ * chant {@link PR_REPORT_WAVES_FLOOR}.
323
+ */
324
+ waveGate?: string;
325
+ /** With `waveGate`: each wave reached so far, in order. */
326
+ waves?: PrWave[];
179
327
  /** Component names: which changed, which run because they depend on one, and what the change touched that no component deploys. */
180
328
  selection: {
181
329
  changed: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"pr-loop.d.ts","sourceRoot":"","sources":["../src/pr-loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pr-loop.d.ts","sourceRoot":"","sources":["../src/pr-loop.ts"],"names":[],"mappings":"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"}
package/dist/pr-loop.js CHANGED
@@ -28,6 +28,16 @@
28
28
  * and decides the gate against the new digest. The same plan applies; a moved
29
29
  * plan stops with both digests named and nothing applied.
30
30
  *
31
+ * ## A gate per wave on merge
32
+ *
33
+ * With `--wave-gate <gate>` (#4003) the apply runs a wave at a time, and
34
+ * plans each wave after the one before it applied. Wave 1 applies under the
35
+ * pull request's approval. A later wave whose new plan the approved change
36
+ * set covers (`planCoveredBy`) applies under that approval too; one whose
37
+ * plan moved waits at `<gate>-wave-<k>`, under the same op, for an approval
38
+ * of its new plan. The report's `waves` says which wave applied under which
39
+ * approval.
40
+ *
31
41
  * ## Inside a workspace member
32
42
  *
33
43
  * Each workspace member that generates the pipeline (#3465) runs its own
@@ -43,6 +53,16 @@ export const PR_REPORT_SCHEMA_ID = "https://intentius.io/chant/schemas/workspace
43
53
  export const PR_REPORT_CONTRACT = 1;
44
54
  /** The first chant whose report can carry `deployedOutputs` (#4104). */
45
55
  export const PR_REPORT_DEPLOYED_OUTPUTS_FLOOR = "0.124.30";
56
+ /** The first chant whose report can carry `waveGate` and `waves` (#4003). */
57
+ export const PR_REPORT_WAVES_FLOOR = "0.124.32";
58
+ /**
59
+ * The first chant whose report can carry `plannedOutputs`, `rounds`, a
60
+ * member's `unknownInputs`, `buildInputs`, `round` and `held`, and the `waiting` statuses
61
+ * (#3999).
62
+ */
63
+ export const PR_REPORT_PLANNED_OUTPUTS_FLOOR = "0.124.32";
64
+ /** The chant that writes the `record` stage and the `recorded` status (#4168 step 1). */
65
+ export const PR_REPORT_RECORD_FLOOR = "0.124.33";
46
66
  /** The gate a pull request's apply waits on, unless the pipeline names another. */
47
67
  export const PR_APPLY_GATE = "pr-apply";
48
68
  /**
@@ -52,14 +72,23 @@ export const PR_APPLY_GATE = "pr-apply";
52
72
  export function prOp(pr, member) {
53
73
  return member ? `pr-${pr}-${member}` : `pr-${pr}`;
54
74
  }
75
+ /**
76
+ * The gate a round of an apply waits on (#3999): the pull request's own
77
+ * gate for the first, and `<gate>-round-<n>` for each one planned after an
78
+ * upstream applied. A workspace's `identity.gates` entry for `gate` covers
79
+ * every round.
80
+ */
81
+ export function prRoundGate(gate, round) {
82
+ return round <= 1 ? gate : `${gate}-round-${round}`;
83
+ }
55
84
  /** Whether `op` is a pull request's gate op, with or without a member. Member names follow the declaration's name pattern. */
56
85
  export const PR_GATE_OP = /^pr-\d+(?:-[a-z0-9][a-z0-9-]*)?$/;
57
86
  /** The hidden line that marks the pull request's note, one per environment and, in a workspace, per member. */
58
87
  export function prNoteMarker(env, member) {
59
88
  return member ? `<!-- chant-pr:${env}:${member} -->` : `<!-- chant-pr:${env} -->`;
60
89
  }
61
- /** The status contexts the two stages set on the commit. */
62
- export const PR_STATUS_CONTEXTS = { plan: "chant/plan", apply: "chant/apply" };
90
+ /** The status contexts the stages set on the commit. */
91
+ export const PR_STATUS_CONTEXTS = { plan: "chant/plan", apply: "chant/apply", record: "chant/record" };
63
92
  /** A stage's status context: `chant/plan`, or `chant/plan/<member>` for a workspace member's pipeline. */
64
93
  export function prStatusContext(stage, member) {
65
94
  return member ? `${PR_STATUS_CONTEXTS[stage]}/${member}` : PR_STATUS_CONTEXTS[stage];
@@ -101,6 +130,7 @@ const STATUS_WORDS = {
101
130
  applied: "applied",
102
131
  failed: "apply failed",
103
132
  blocked: "blocked",
133
+ waiting: "waiting on its new plan",
104
134
  };
105
135
  function headline(report) {
106
136
  const n = report.members.length;
@@ -110,15 +140,54 @@ function headline(report) {
110
140
  return "Nothing to plan: no component deploys what this change touches.";
111
141
  case "planned":
112
142
  return `Planned ${members}.`;
143
+ case "recorded":
144
+ return `Recorded the plan of ${members} on merge. Nothing applied: a release that carries this commit deploys it.`;
113
145
  case "plan-failed":
114
146
  return `Planning failed for ${report.members.filter((m) => m.status === "plan-failed").length} of ${members}, so nothing can apply.`;
115
147
  case "applied":
116
148
  return `Applied ${members}.`;
117
149
  case "failed":
118
150
  return `The apply failed: ${report.members.filter((m) => m.status === "failed").length} failed, ${report.members.filter((m) => m.status === "applied").length} applied.`;
119
- case "refused":
120
- return "The apply refused.";
151
+ case "wave-applied": {
152
+ const applied = (report.waves ?? []).filter((w) => w.status === "applied").map((w) => w.wave);
153
+ const total = report.selection.waves.length;
154
+ return `Applied wave ${applied.at(-1) ?? "?"} of ${total}. The next wave runs in its own job.`;
155
+ }
156
+ case "refused": {
157
+ const waiting = report.waves?.find((w) => w.status === "waiting");
158
+ return waiting ? `Wave ${waiting.wave} waits at its gate ${code(waiting.gate)}; nothing in it applied.` : "The apply refused.";
159
+ }
160
+ case "waiting":
161
+ return `Applied ${report.members.filter((m) => m.status === "applied").length} of ${members}; ${report.members.filter((m) => m.status === "waiting").length} wait on an approval of the plan made after their upstream applied.`;
162
+ }
163
+ }
164
+ /** Who a wave applied or waits under, as a table cell. */
165
+ function waveApproval(w) {
166
+ const whose = w.approval === "pull-request" ? "the pull request's" : "its own";
167
+ const by = w.approvedBy?.length ? ` by ${w.approvedBy.map(code).join(", ")}` : w.status === "waiting" ? ", not approved yet" : "";
168
+ return `${whose} ${code(w.gate)}${by}`;
169
+ }
170
+ /**
171
+ * The waves of an apply with `--wave-gate` (#4003): a row per wave reached,
172
+ * saying which approval it applied under, then for a wave that waits the
173
+ * reason its plan moved and the approve command for its new plan.
174
+ */
175
+ function waveLines(report, approver) {
176
+ const waves = report.waves ?? [];
177
+ if (waves.length === 0)
178
+ return [];
179
+ const out = ["", "| Wave | Components | Status | Approval |", "|---:|---|---|---|"];
180
+ for (const w of waves)
181
+ out.push(`| ${w.wave} | ${w.components.map(code).join(", ")} | ${w.status} | ${waveApproval(w)} |`);
182
+ for (const w of waves.filter((x) => x.status === "waiting")) {
183
+ out.push("", `Wave ${w.wave} was planned after the waves before it applied, and the approved plan does not cover it:`, "");
184
+ for (const why of w.moved ?? [])
185
+ out.push(`- ${why}`);
186
+ if (w.approved)
187
+ out.push("", `An approval of ${code(w.gate)} stands for ${code(w.approved)}, not for the plan now.`);
188
+ out.push("", `Read wave ${w.wave}'s plan, ${code(w.digest)}, and approve it with:`, "", "```", prApproveCommand({ op: report.op, gate: w.gate, digest: w.digest }, approver), "```", "", "Then run the wave's apply job again.");
121
189
  }
190
+ return out;
122
191
  }
123
192
  function approvalLines(report, approver) {
124
193
  const a = report.approval;
@@ -128,9 +197,9 @@ function approvalLines(report, approver) {
128
197
  return [`Approved by ${(a.approvedBy ?? []).map(code).join(", ")} for this digest.`];
129
198
  const lines = a.status === "changed"
130
199
  ? [`An approval stands for ${code(a.approved ?? "(none)")}, not for this digest: the plan changed since it was approved.`]
131
- : ["Not approved yet."];
200
+ : [report.stage === "record" ? "No approval stands for this plan. The release gate decides before it deploys." : "Not approved yet."];
132
201
  if (report.stage === "plan" && report.status === "planned") {
133
- lines.push("", "A reviewer who approved this pull request approves the plan with:", "", "```", prApproveCommand(report, approver), "```", "", "It applies on merge if the plan is still this one. If it moved, the apply refuses and names both digests.");
202
+ lines.push("", "A reviewer who approved this pull request approves the plan with:", "", "```", prApproveCommand(report, approver), "```", "", "On merge the plan is recorded, and a release deploys it. With apply on merge it applies if the plan is still this one; if it moved, the apply refuses and names both digests.");
134
203
  }
135
204
  return lines;
136
205
  }
@@ -144,7 +213,7 @@ export function renderPrNote(report, options = {}) {
144
213
  const limit = options.limit ?? GITHUB_COMMENT_LIMIT;
145
214
  const out = [
146
215
  prNoteMarker(report.env, report.member),
147
- `### chant ${report.stage === "plan" ? "plan" : "apply"} for ${code(report.env)}${report.member ? ` in member ${code(report.member)}` : ""}`,
216
+ `### chant ${report.stage} for ${code(report.env)}${report.member ? ` in member ${code(report.member)}` : ""}`,
148
217
  "",
149
218
  `${headline(report)} Head ${code(short(report.head))}, measured from ${code(short(report.base))}.`,
150
219
  ];
@@ -170,6 +239,7 @@ export function renderPrNote(report, options = {}) {
170
239
  out.push("", "A member whose inputs moved applied the plan it was approved with. The next run plans it against the new values.");
171
240
  }
172
241
  }
242
+ out.push(...waveLines(report, options.approver ?? "<you>"));
173
243
  if (report.selection.unclaimed.length > 0) {
174
244
  out.push("", `Changed, and deployed by no component: ${report.selection.unclaimed.map(code).join(", ")}.`);
175
245
  }
@@ -178,9 +248,39 @@ export function renderPrNote(report, options = {}) {
178
248
  const each = deployed.map(([dep, names]) => `${code(dep)} (${names.length > 0 ? names.map(code).join(", ") : "none yet"})`);
179
249
  out.push("", `Planned against outputs read from the deployed estate: ${each.join("; ")}.`);
180
250
  }
251
+ const planned = Object.entries(report.plannedOutputs ?? {});
252
+ if (planned.length > 0) {
253
+ const each = planned.map(([dep, names]) => `${code(dep)} (${names.length > 0 ? names.map(code).join(", ") : "none known"})`);
254
+ out.push("", `Planned against the outputs this change's plans say its upstreams will have: ${each.join("; ")}.`);
255
+ }
256
+ const unknown = [...new Set(report.members.flatMap((m) => (m.unknownInputs ?? []).map((ref) => `${code(m.component)} reads ${code(ref)}`)))];
257
+ if (unknown.length > 0) {
258
+ out.push("", `Known only after apply: ${unknown.join("; ")}. This approval does not cover what those members do with them. ` +
259
+ "The apply plans them again once their upstream applied and asks for an approval of that plan.");
260
+ }
261
+ const fromBuild = [...new Set(report.members.flatMap((m) => (m.buildInputs ?? []).map((ref) => `${code(m.component)} reads ${code(ref)}`)))];
262
+ if (fromBuild.length > 0) {
263
+ out.push("", `From this pull request's build: ${fromBuild.join("; ")}. The image digest comes from this pull request's build, whose provenance binds it, ` +
264
+ "so those members apply with it once the build ran, without a second approval.");
265
+ }
266
+ for (const r of report.rounds ?? []) {
267
+ const what = `Round ${r.round} planned ${r.components.map(code).join(", ")} again after their upstream applied, digest ${code(r.digest)}`;
268
+ if (r.status === "waiting") {
269
+ if (r.message)
270
+ out.push("", `> ${r.message}`);
271
+ 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>"), "```");
272
+ }
273
+ else {
274
+ out.push("", `${what}: ${r.status === "applied" ? `applied, approved by ${(r.approval.approvedBy ?? []).map(code).join(", ")}` : r.status === "plan-failed" ? "a member failed to plan" : "the apply failed"}.`);
275
+ }
276
+ }
181
277
  if (report.status !== "nothing") {
182
278
  out.push("", `Plan digest: ${code(report.digest)}`, "", ...approvalLines(report, options.approver ?? "<you>"));
183
279
  }
280
+ // #4003: with a gate per wave, a later wave's plan on merge may differ from this one.
281
+ if (report.stage === "plan" && report.status === "planned" && report.waveGate) {
282
+ out.push("", `On merge each wave after the first is planned again once the waves before it apply, and a wave whose plan moved stops at its own gate, ${code(`${report.waveGate}-wave-<k>`)}, for approval.`);
283
+ }
184
284
  const head = out.join("\n") + "\n";
185
285
  if (report.status === "nothing" || report.changeSet.members.length === 0)
186
286
  return head;
@@ -207,23 +307,49 @@ export function prStatusDescription(report) {
207
307
  case "plan-failed":
208
308
  text = `a member failed to plan${digest}`;
209
309
  break;
310
+ case "recorded":
311
+ text = `recorded ${n} member${n === 1 ? "" : "s"}: ${report.approval.status === "approved" ? "the approved plan" : report.approval.status === "changed" ? "the plan differs from the approved one" : "no approval for this plan"}${digest}`;
312
+ break;
210
313
  case "applied":
211
314
  text = `applied ${n} member${n === 1 ? "" : "s"}${digest}`;
212
315
  break;
316
+ case "wave-applied": {
317
+ const last = (report.waves ?? []).filter((w) => w.status === "applied").at(-1);
318
+ text = `applied wave ${last?.wave ?? "?"} of ${report.selection.waves.length}${last ? ` under ${last.approval === "pull-request" ? "the pull request's approval" : `${last.gate}`}` : ""}`;
319
+ break;
320
+ }
213
321
  case "failed":
214
322
  text = `apply failed for ${report.members.filter((m) => m.status === "failed").map((m) => m.member).join(", ")}`;
215
323
  break;
216
- case "refused":
217
- text = `refused: ${report.refusal === "plan-changed" ? "the plan changed after review" : report.refusal === "not-a-reviewer" ? "the approver has not approved the pull request" : report.refusal === "no-pull-request" ? "no pull request merged this commit" : "the plan is not approved"}`;
324
+ case "waiting":
325
+ text = `waiting: ${report.members.filter((m) => m.status === "waiting").map((m) => m.member).join(", ")} planned again after an upstream applied, not approved yet`;
218
326
  break;
327
+ case "refused": {
328
+ const waiting = report.waves?.find((w) => w.status === "waiting");
329
+ if (waiting && (report.refusal === "wave-not-approved" || report.refusal === "wave-plan-changed")) {
330
+ text = `wave ${waiting.wave} waits at ${waiting.gate}: ${report.refusal === "wave-plan-changed" ? "its plan changed after its approval" : "its plan moved, approve it"}`;
331
+ break;
332
+ }
333
+ if (report.refusal === "earlier-wave") {
334
+ text = "refused: an earlier wave has not applied";
335
+ break;
336
+ }
337
+ text = `refused: ${report.refusal === "plan-changed" ? "the plan changed after review" : report.refusal === "not-a-reviewer" ? "the approver has not approved the pull request" : report.refusal === "author-approved" ? "the approver wrote the change" : report.refusal === "no-pull-request" ? "no pull request merged this commit" : "the plan is not approved"}`;
338
+ break;
339
+ }
219
340
  }
220
341
  return text.length > 140 ? text.slice(0, 137) + "..." : text;
221
342
  }
222
343
  /** The commit status state for a report: success, failure, or pending while it waits on approval. */
223
344
  export function prStatusState(report) {
224
- if (report.status === "planned" || report.status === "applied" || report.status === "nothing")
345
+ // #4168 decision 1: a merge whose plan differs from the approved one is recorded, and its status fails.
346
+ if (report.status === "recorded")
347
+ return report.approval.status === "changed" ? "failure" : "success";
348
+ if (report.status === "planned" || report.status === "applied" || report.status === "wave-applied" || report.status === "nothing")
225
349
  return "success";
226
- if (report.status === "refused" && report.refusal === "not-approved")
350
+ if (report.status === "refused" && (report.refusal === "not-approved" || report.refusal === "wave-not-approved"))
351
+ return "pending";
352
+ if (report.status === "waiting")
227
353
  return "pending";
228
354
  return "failure";
229
355
  }
@@ -44,14 +44,14 @@ export type ReportTarget = {
44
44
  bucket: string;
45
45
  prefix: string;
46
46
  };
47
- /** `--report-url` read, or why it can't be. */
48
- export declare function parseReportUrl(raw: string): ReportTarget | {
47
+ /** `--report-url` read, or why it can't be. `name` is what the error calls the value: the flag, or `ci.reportUrl` (#4160). */
48
+ export declare function parseReportUrl(raw: string, name?: string): ReportTarget | {
49
49
  error: string;
50
50
  };
51
51
  /** The key a stage's files are kept under, below the URL: `<pr>/<commit>[/<member>]`. */
52
52
  export declare function reportKey(pr: number | null, commit: string, member?: string): string;
53
53
  /** The events file of a stage. */
54
- export declare const reportEventsFile: (stage: "plan" | "apply") => string;
54
+ export declare const reportEventsFile: (stage: "plan" | "apply" | "record") => string;
55
55
  /** Puts one object: `key` below the URL. Rejects with a line a person can read. */
56
56
  export type ReportPut = (key: string, body: string, contentType: string) => Promise<void>;
57
57
  /** Runs the AWS CLI with `args` and `stdin`, rejecting with its error line on a non-zero exit. */
@@ -83,7 +83,7 @@ export interface PrReportUpload {
83
83
  export declare function openPrReportUpload(input: {
84
84
  target: ReportTarget;
85
85
  key: string;
86
- stage: "plan" | "apply";
86
+ stage: "plan" | "apply" | "record";
87
87
  warn: (message: string) => void;
88
88
  put?: ReportPut;
89
89
  }): PrReportUpload;
@@ -1 +1 @@
1
- {"version":3,"file":"pr-report-url.d.ts","sourceRoot":"","sources":["../src/pr-report-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAOH,mCAAmC;AACnC,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,+CAA+C;AAC/C,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAkB5E;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED,kCAAkC;AAClC,eAAO,MAAM,gBAAgB,UAAW,MAAM,GAAG,OAAO,KAAG,MAAoC,CAAC;AAEhG,mFAAmF;AACnF,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1F,kGAAkG;AAClG,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAItE,2BAA2B;AAC3B,eAAO,MAAM,UAAU,EAAE,MAmBrB,CAAC;AAEL,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,GAAE,MAAmB,GAAG,SAAS,CAcnF;AAED,6JAA6J;AAC7J,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAEhE,8GAA8G;AAC9G,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE1D,4EAA4E;AAC5E,eAAO,MAAM,WAAW,EAAE,OAiBtB,CAAC;AAKL,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,GAAE,OAAqB,GAAG,SAAS,CAoBrF;AAED,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oGAAoG;IACpG,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,8EAA8E;IAC9E,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,+FAA+F;IAC/F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAQD,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,GAAG,CAAC,EAAE,SAAS,CAAC;CACjB,GAAG,cAAc,CA6DjB"}
1
+ {"version":3,"file":"pr-report-url.d.ts","sourceRoot":"","sources":["../src/pr-report-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAOH,mCAAmC;AACnC,MAAM,MAAM,YAAY,GACpB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,8HAA8H;AAC9H,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAiB,GAAG,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAkBnG;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED,kCAAkC;AAClC,eAAO,MAAM,gBAAgB,UAAW,MAAM,GAAG,OAAO,GAAG,QAAQ,KAAG,MAAoC,CAAC;AAE3G,mFAAmF;AACnF,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1F,kGAAkG;AAClG,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAItE,2BAA2B;AAC3B,eAAO,MAAM,UAAU,EAAE,MAmBrB,CAAC;AAEL,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,GAAE,MAAmB,GAAG,SAAS,CAcnF;AAED,6JAA6J;AAC7J,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAEhE,8GAA8G;AAC9G,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE1D,4EAA4E;AAC5E,eAAO,MAAM,WAAW,EAAE,OAiBtB,CAAC;AAKL,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,GAAE,OAAqB,GAAG,SAAS,CAoBrF;AAED,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oGAAoG;IACpG,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,8EAA8E;IAC9E,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,+FAA+F;IAC/F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAQD,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACnC,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,GAAG,CAAC,EAAE,SAAS,CAAC;CACjB,GAAG,cAAc,CA6DjB"}
@@ -37,8 +37,8 @@ import { spawn } from "node:child_process";
37
37
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
38
38
  import { dirname, isAbsolute, join } from "node:path";
39
39
  import { fileURLToPath } from "node:url";
40
- /** `--report-url` read, or why it can't be. */
41
- export function parseReportUrl(raw) {
40
+ /** `--report-url` read, or why it can't be. `name` is what the error calls the value: the flag, or `ci.reportUrl` (#4160). */
41
+ export function parseReportUrl(raw, name = "--report-url") {
42
42
  const url = raw.trim();
43
43
  if (url.startsWith("file://")) {
44
44
  let dir;
@@ -46,10 +46,10 @@ export function parseReportUrl(raw) {
46
46
  dir = fileURLToPath(url);
47
47
  }
48
48
  catch (err) {
49
- return { error: `--report-url ${url}: ${err instanceof Error ? err.message : String(err)}` };
49
+ return { error: `${name} ${url}: ${err instanceof Error ? err.message : String(err)}` };
50
50
  }
51
51
  if (!isAbsolute(dir))
52
- return { error: `--report-url ${url}: a file URL names an absolute directory` };
52
+ return { error: `${name} ${url}: a file URL names an absolute directory` };
53
53
  return { scheme: "file", url: url.replace(/\/+$/, ""), dir };
54
54
  }
55
55
  const s3 = /^s3:\/\/([^/]+)\/?(.*)$/.exec(url);
@@ -57,7 +57,7 @@ export function parseReportUrl(raw) {
57
57
  const prefix = s3[2].replace(/\/+$/, "");
58
58
  return { scheme: "s3", url: `s3://${s3[1]}${prefix ? `/${prefix}` : ""}`, bucket: s3[1], prefix };
59
59
  }
60
- return { error: `--report-url ${url}: takes an s3://<bucket>/<prefix> or file://<directory> URL` };
60
+ return { error: `${name} ${url}: takes an s3://<bucket>/<prefix> or file://<directory> URL` };
61
61
  }
62
62
  /** The key a stage's files are kept under, below the URL: `<pr>/<commit>[/<member>]`. */
63
63
  export function reportKey(pr, commit, member) {