@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
@@ -15,7 +15,14 @@
15
15
  * ./promote.ts: a literal path in a deploy step's `template`, `manifest` or
16
16
  * `values` field ({@link TEMPLATE_FIELDS}), read after the environment's build
17
17
  * command has run. A path with the `archive:` prefix names the file after it.
18
- * A path that names a directory, such as a chart, is not a template.
18
+ *
19
+ * Since #4155 a cut also records the other local paths a deploy step names
20
+ * ({@link recordedInputRefs}: a Helm chart, a kustomize directory, a sync's
21
+ * source tree, the fields `./deploy-inputs.ts` lists). A directory is
22
+ * recorded file by file and named in the target's `trees`; a file that is not
23
+ * UTF-8 is recorded as base64. Such a path that does not exist after the
24
+ * build, as a chart named from a repository, is not recorded, and the
25
+ * promote leaves it as written.
19
26
  *
20
27
  * A project with no components (#4046) is compiled the way `chant build --env
21
28
  * <env> -o <output>` builds it ({@link compileBuildOutput}): every file that
@@ -24,6 +31,7 @@
24
31
  * back from disk, so a file an earlier build left behind is never recorded.
25
32
  */
26
33
  import { spawn, spawnSync } from "node:child_process";
34
+ import { isUtf8 } from "node:buffer";
27
35
  import { existsSync, readFileSync, statSync } from "node:fs";
28
36
  import { isAbsolute, relative, resolve } from "node:path";
29
37
  import { loadChantConfig } from "../config.js";
@@ -36,7 +44,8 @@ import { ARCHIVE_STEP_KINDS, BUILD_STEP_KINDS, PUBLISH_STEP_KINDS } from "./prom
36
44
  import { DriverRunFailure, runInterpretDriver } from "./driver.js";
37
45
  import { memoryGateLedgerPort } from "../op/gate.js";
38
46
  /** The deploy step fields whose literal file paths are a component's templates. */
39
- export const TEMPLATE_FIELDS = ["template", "manifest", "values"];
47
+ export { TEMPLATE_FIELDS } from "./deploy-inputs.js";
48
+ import { DEPLOY_INPUT_FIELDS, directoryFiles, ignoredByGit, TEMPLATE_FIELDS, walkFiles } from "./deploy-inputs.js";
40
49
  /** The prefix a step may write before an archive-relative template path. */
41
50
  const ARCHIVE_PREFIX = "archive:";
42
51
  function isGate(step) {
@@ -79,6 +88,33 @@ export function templateRefs(component) {
79
88
  }
80
89
  return out;
81
90
  }
91
+ /** Every literal path a component's deploy names that a cut records: {@link templateRefs}, plus each kind's own fields in `DEPLOY_INPUT_FIELDS`. */
92
+ export function recordedInputRefs(component) {
93
+ const out = [];
94
+ for (const { phase, step } of stepsOf(component.deploy)) {
95
+ if (BUILD_STEP_KINDS.includes(step.kind) || PUBLISH_STEP_KINDS.includes(step.kind))
96
+ continue;
97
+ for (const field of recordedFields(step.kind)) {
98
+ const raw = step[field];
99
+ for (const value of Array.isArray(raw) ? raw : [raw]) {
100
+ if (!isLiteralPath(value))
101
+ continue;
102
+ const path = value.startsWith(ARCHIVE_PREFIX) ? value.slice(ARCHIVE_PREFIX.length) : value;
103
+ out.push({ component: component.name, phase, kind: step.kind, field, value, path, required: TEMPLATE_FIELDS.includes(field) });
104
+ }
105
+ }
106
+ }
107
+ return out;
108
+ }
109
+ /** The fields of a step of `kind` whose paths a cut records and a promote points at the recorded copy. */
110
+ export function recordedFields(kind) {
111
+ return [...TEMPLATE_FIELDS, ...(DEPLOY_INPUT_FIELDS[kind] ?? [])];
112
+ }
113
+ /** A file's bytes as a template: its text when it is UTF-8, else base64. */
114
+ export function templateOf(component, path, file) {
115
+ const bytes = readFileSync(file);
116
+ return isUtf8(bytes) ? { component, path, content: bytes.toString("utf-8") } : { component, path, content: bytes.toString("base64"), encoding: "base64" };
117
+ }
82
118
  /** A component's build-time steps ({@link BUILD_STEP_KINDS}), each as declared, in composition order. */
83
119
  export function buildStepsOf(component) {
84
120
  return stepsOf(component.deploy).map((s) => s.step).filter((s) => BUILD_STEP_KINDS.includes(s.kind));
@@ -122,6 +158,8 @@ export function withOnlyArchiveSteps(component) {
122
158
  const deploy = component.deploy.map(keep).filter((p) => p !== undefined);
123
159
  return deploy.length > 0 ? { name: component.name, dependsOn: [], deploy } : undefined;
124
160
  }
161
+ /** The variable a cut's label reaches the build through (#4168). */
162
+ export const RELEASE_LABEL_ENV = "CHANT_RELEASE_LABEL";
125
163
  /**
126
164
  * Where a project with no components writes its build output when the cut
127
165
  * names no `-o`. YAML, since the k8s and helm serializers write YAML whatever
@@ -185,21 +223,33 @@ export async function compileEnvironment(inputs, env) {
185
223
  return compileBuildOutput(inputs, env, config);
186
224
  const rel = (p) => (isAbsolute(p) ? relative(inputs.projectDir, p) : p);
187
225
  const templates = [];
226
+ const trees = [];
188
227
  const seen = new Set();
189
228
  for (const { component } of components) {
190
- for (const ref of templateRefs(component)) {
229
+ for (const ref of recordedInputRefs(component)) {
191
230
  const key = `${ref.component}\u0000${ref.path}`;
192
231
  if (seen.has(key))
193
232
  continue;
194
233
  seen.add(key);
195
234
  const file = resolve(inputs.projectDir, ref.path);
196
235
  if (!existsSync(file)) {
236
+ if (!ref.required)
237
+ continue;
197
238
  throw new ReleaseCompileError(`component "${ref.component}": its ${ref.kind} step in phase "${ref.phase}" reads ${ref.field} "${ref.value}", ` +
198
239
  `and no such file exists after the build for "${env}"`);
199
240
  }
200
- if (!statSync(file).isFile())
241
+ if (statSync(file).isFile()) {
242
+ templates.push(templateOf(ref.component, ref.path, file));
201
243
  continue;
202
- templates.push({ component: ref.component, path: ref.path, content: readFileSync(file, "utf-8") });
244
+ }
245
+ // #4155: a directory, file by file. One git ignores is the build's output, recorded whole.
246
+ const files = ignoredByGit(inputs.projectDir, ref.path) ? walkFiles(inputs.projectDir, ref.path) : directoryFiles(inputs.projectDir, ref.path);
247
+ const dir = ref.path.replace(/\/+$/, "");
248
+ for (const f of files) {
249
+ const under = relative(resolve(inputs.projectDir, dir), resolve(inputs.projectDir, f)).split("\\").join("/");
250
+ templates.push(templateOf(ref.component, `${dir}/${under}`, resolve(inputs.projectDir, f)));
251
+ }
252
+ trees.push({ component: ref.component, path: dir });
203
253
  }
204
254
  }
205
255
  return {
@@ -211,6 +261,7 @@ export async function compileEnvironment(inputs, env) {
211
261
  buildInputs: Object.fromEntries(components.map(({ component }) => [component.name, buildInputPaths(component)])),
212
262
  componentFiles: Object.fromEntries(components.map(({ component, file }) => [component.name, rel(file)])),
213
263
  templates,
264
+ trees,
214
265
  };
215
266
  }
216
267
  /**
@@ -325,10 +376,15 @@ export function ownChantCommand() {
325
376
  const main = process.argv[1] ?? "";
326
377
  return [process.execPath, ...process.execArgv, main];
327
378
  }
328
- function runChild(command, args, cwd, env) {
379
+ function runChild(command, args, cwd, env, releaseLabel) {
329
380
  return new Promise((resolvePromise, reject) => {
330
381
  const [bin, ...lead] = command;
331
- const child = spawn(bin, [...lead, ...args], { cwd, stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, CHANT_ENV: env } });
382
+ const childEnv = { ...process.env, CHANT_ENV: env };
383
+ // A label never leaks in from the caller's shell: only the cut sets it.
384
+ delete childEnv[RELEASE_LABEL_ENV];
385
+ if (releaseLabel !== undefined)
386
+ childEnv[RELEASE_LABEL_ENV] = releaseLabel;
387
+ const child = spawn(bin, [...lead, ...args], { cwd, stdio: ["ignore", "pipe", "pipe"], env: childEnv });
332
388
  const out = [];
333
389
  const err = [];
334
390
  child.stdout.on("data", (c) => out.push(c));
@@ -361,7 +417,7 @@ export function spawnTargetCompiler(inputs, command = ownChantCommand()) {
361
417
  return args;
362
418
  };
363
419
  const call = async (env, extra) => {
364
- const run = await runChild(command, ["release", "compile", "--env", env, ...common(), ...extra, "--json"], inputs.projectDir, env);
420
+ const run = await runChild(command, ["release", "compile", "--env", env, ...common(), ...extra, "--json"], inputs.projectDir, env, inputs.releaseLabel);
365
421
  if (run.code !== 0)
366
422
  throw new ReleaseCompileError(`compiling "${env}" failed (exit ${run.code})`);
367
423
  try {
@@ -11,9 +11,19 @@
11
11
  * under `.chant/release-templates/<digest>/` in the member's directory and the
12
12
  * step reads them from there. The path is relative and fixed by the digest,
13
13
  * so a gate approval bound to the promote's plan still matches on a re-run.
14
+ *
15
+ * A release cut since #4155 (a target with `trees`) records every local path
16
+ * a deploy step names (`recordedInputRefs`), directories file by file. A
17
+ * promote points each of them at the recorded copy: a directory is written
18
+ * under `.chant/release-templates/<digest>/<name>/`, its digest taken over its
19
+ * files the way a gate's directory digest is (`./deploy-inputs.ts`). A path
20
+ * outside the template fields that the release does not record, such as a
21
+ * chart named from a repository, is left as written. A target cut before
22
+ * #4155 is pinned as it was then: template fields only, other paths read from
23
+ * the checkout.
14
24
  */
15
25
  import type { DriverComponent } from "./driver.js";
16
- import type { Release, ReleaseTarget } from "../lifecycle/release-store.js";
26
+ import { type Release, type ReleaseTarget } from "../lifecycle/release-store.js";
17
27
  import type { ReleaseRecord } from "../lifecycle/release-ledger.js";
18
28
  import type { BuildArchiveManifest } from "./verbs/build-archive.js";
19
29
  /** Where a promote under a release writes the recorded templates, relative to the member's directory. */
@@ -22,8 +32,12 @@ export declare const RELEASE_TEMPLATES_DIR = ".chant/release-templates";
22
32
  export interface PinnedTemplate {
23
33
  /** Relative to the member's directory. */
24
34
  path: string;
35
+ /** The text, or the base64 of the bytes under `encoding: "base64"`. */
25
36
  content: string;
37
+ encoding?: "base64";
26
38
  }
39
+ /** Reads a recorded template's stored copy by digest: its text, or its base64 under `base64`. */
40
+ export type TemplateReader = (digest: string, encoding?: "base64") => Promise<string | null>;
27
41
  /** The release's target for `env`, or an error naming the environments it has. */
28
42
  export declare function targetFor(release: Release, env: string): {
29
43
  target: ReleaseTarget;
@@ -38,7 +52,7 @@ export declare function isImplicitRelease(release: Release): boolean;
38
52
  * the promote is refused: a template the target does not record, one whose
39
53
  * bytes are missing, or one whose bytes do not hash to the target's digest.
40
54
  */
41
- export declare function pinReleaseTemplates(components: readonly DriverComponent[], release: Release, target: ReleaseTarget, readTemplate: (digest: string) => Promise<string | null>): Promise<{
55
+ export declare function pinReleaseTemplates(components: readonly DriverComponent[], release: Release, target: ReleaseTarget, readTemplate: TemplateReader): Promise<{
42
56
  components: DriverComponent[];
43
57
  files: PinnedTemplate[];
44
58
  } | {
@@ -53,7 +67,7 @@ export declare function pinReleaseTemplates(components: readonly DriverComponent
53
67
  * member's directory; a template whose bytes are missing or don't hash to the
54
68
  * target's digest is refused, as {@link pinReleaseTemplates} refuses one.
55
69
  */
56
- export declare function targetFiles(release: Release, target: ReleaseTarget, readTemplate: (digest: string) => Promise<string | null>): Promise<{
70
+ export declare function targetFiles(release: Release, target: ReleaseTarget, readTemplate: TemplateReader): Promise<{
57
71
  files: PinnedTemplate[];
58
72
  } | {
59
73
  errors: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"release-promote.d.ts","sourceRoot":"","sources":["../../src/components/release-promote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAuC,MAAM,UAAU,CAAC;AAErF,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,yGAAyG;AACzG,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAEhE,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAMtG;AAED,sIAAsI;AACtI,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAG3D;AAUD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,SAAS,eAAe,EAAE,EACtC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GACvD,OAAO,CAAC;IAAE,UAAU,EAAE,eAAe,EAAE,CAAC;IAAC,KAAK,EAAE,cAAc,EAAE,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAiD5F;AAED;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GACvD,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA2B7D;AAED,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAMxF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAQzF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,EACpE,YAAY,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAC7E,OAAO,CAAC,MAAM,EAAE,CAAC,CAmBnB"}
1
+ {"version":3,"file":"release-promote.d.ts","sourceRoot":"","sources":["../../src/components/release-promote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAuC,MAAM,UAAU,CAAC;AAErF,OAAO,EAAuB,KAAK,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEnG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAElE,yGAAyG;AACzG,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAEhE,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,iGAAiG;AACjG,MAAM,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE7F,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAMtG;AAED,sIAAsI;AACtI,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAG3D;AAUD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,SAAS,eAAe,EAAE,EACtC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,cAAc,GAC3B,OAAO,CAAC;IAAE,UAAU,EAAE,eAAe,EAAE,CAAC;IAAC,KAAK,EAAE,cAAc,EAAE,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAyD5F;AA+CD;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,cAAc,GAC3B,OAAO,CAAC;IAAE,KAAK,EAAE,cAAc,EAAE,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CA2B7D;AAED,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAMxF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,cAAc,EAAE,GAAG,IAAI,CAUzF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,aAAa,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,EACpE,YAAY,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,GAC7E,OAAO,CAAC,MAAM,EAAE,CAAC,CAmBnB"}
@@ -11,11 +11,22 @@
11
11
  * under `.chant/release-templates/<digest>/` in the member's directory and the
12
12
  * step reads them from there. The path is relative and fixed by the digest,
13
13
  * so a gate approval bound to the promote's plan still matches on a re-run.
14
+ *
15
+ * A release cut since #4155 (a target with `trees`) records every local path
16
+ * a deploy step names (`recordedInputRefs`), directories file by file. A
17
+ * promote points each of them at the recorded copy: a directory is written
18
+ * under `.chant/release-templates/<digest>/<name>/`, its digest taken over its
19
+ * files the way a gate's directory digest is (`./deploy-inputs.ts`). A path
20
+ * outside the template fields that the release does not record, such as a
21
+ * chart named from a repository, is left as written. A target cut before
22
+ * #4155 is pinned as it was then: template fields only, other paths read from
23
+ * the checkout.
14
24
  */
15
25
  import { mkdirSync, readdirSync, rmSync, rmdirSync, writeFileSync } from "node:fs";
16
26
  import { basename, dirname, join } from "node:path";
17
- import { contentDigest } from "../content-digest.js";
18
- import { TEMPLATE_FIELDS, templateRefs } from "./release-compile.js";
27
+ import { recordedFields, recordedInputRefs, TEMPLATE_FIELDS, templateRefs } from "./release-compile.js";
28
+ import { templateBytesDigest } from "../lifecycle/release-store.js";
29
+ import { computePlanDigest } from "../lifecycle/plan-digest.js";
19
30
  /** Where a promote under a release writes the recorded templates, relative to the member's directory. */
20
31
  export const RELEASE_TEMPLATES_DIR = ".chant/release-templates";
21
32
  /** The release's target for `env`, or an error naming the environments it has. */
@@ -48,29 +59,41 @@ export async function pinReleaseTemplates(components, release, target, readTempl
48
59
  const errors = [];
49
60
  const files = [];
50
61
  const out = [];
62
+ // #4155: a target with `trees` records every deploy input; one without was cut before and records template fields only.
63
+ const full = target.trees !== undefined;
51
64
  for (const component of components) {
52
65
  const replace = new Map();
53
- for (const ref of templateRefs(component)) {
66
+ const refs = full ? recordedInputRefs(component) : templateRefs(component).map((r) => ({ ...r, required: true }));
67
+ for (const ref of refs) {
54
68
  if (replace.has(ref.value))
55
69
  continue;
70
+ const dir = ref.path.replace(/\/+$/, "");
71
+ const tree = full ? target.trees.find((t) => t.component === component.name && t.path === dir) : undefined;
72
+ if (tree) {
73
+ const pinned = await pinTree(component.name, tree.path, target, readTemplate);
74
+ if ("errors" in pinned)
75
+ errors.push(...pinned.errors);
76
+ else {
77
+ files.push(...pinned.files);
78
+ replace.set(ref.value, pinned.path);
79
+ }
80
+ continue;
81
+ }
56
82
  const recorded = target.templates.find((t) => t.component === component.name && t.path === ref.path);
57
83
  if (!recorded) {
84
+ if (!ref.required)
85
+ continue;
58
86
  errors.push(`component "${component.name}" reads ${ref.field} "${ref.value}", which release ${release.releaseDigest} does not record for "${target.env}"; ` +
59
87
  `this checkout's deploy is not the one the release was compiled from (commit ${release.commit.slice(0, 12)})`);
60
88
  continue;
61
89
  }
62
- const content = await readTemplate(recorded.digest);
63
- if (content === null) {
64
- errors.push(`component "${component.name}": the bytes of template "${ref.path}" (${recorded.digest}) are not on the chant/lifecycle branch; fetch it and try again`);
65
- continue;
66
- }
67
- const got = contentDigest(content);
68
- if (got !== recorded.digest) {
69
- errors.push(`component "${component.name}": template "${ref.path}" hashes to ${got}, but the release's target for "${target.env}" records ${recorded.digest}; refusing to deploy it`);
90
+ const read = await readChecked(component.name, ref.path, recorded, target, readTemplate);
91
+ if ("error" in read) {
92
+ errors.push(read.error);
70
93
  continue;
71
94
  }
72
95
  const path = join(RELEASE_TEMPLATES_DIR, recorded.digest.replace(/:/g, "_"), basename(ref.path));
73
- files.push({ path, content });
96
+ files.push({ path, content: read.content, ...(recorded.encoding ? { encoding: recorded.encoding } : {}) });
74
97
  replace.set(ref.value, path);
75
98
  }
76
99
  const rewrite = (phase) => ({
@@ -81,7 +104,7 @@ export async function pinReleaseTemplates(components, release, target, readTempl
81
104
  if (isGate(step))
82
105
  return step;
83
106
  const next = { ...step };
84
- for (const field of TEMPLATE_FIELDS) {
107
+ for (const field of full ? recordedFields(step.kind) : TEMPLATE_FIELDS) {
85
108
  const v = next[field];
86
109
  if (typeof v === "string" && replace.has(v))
87
110
  next[field] = replace.get(v);
@@ -95,6 +118,42 @@ export async function pinReleaseTemplates(components, release, target, readTempl
95
118
  }
96
119
  return errors.length > 0 ? { errors } : { components: out, files };
97
120
  }
121
+ /** One recorded template's stored copy, checked against its digest. */
122
+ async function readChecked(component, path, recorded, target, readTemplate) {
123
+ const who = component === null ? "" : `component "${component}": `;
124
+ const content = await readTemplate(recorded.digest, recorded.encoding);
125
+ if (content === null)
126
+ return { error: `${who}the bytes of template "${path}" (${recorded.digest}) are not on the chant/lifecycle branch; fetch it and try again` };
127
+ const got = templateBytesDigest(content, recorded.encoding);
128
+ if (got !== recorded.digest) {
129
+ return { error: `${who}template "${path}" hashes to ${got}, but the release's target for "${target.env}" records ${recorded.digest}; refusing to deploy it` };
130
+ }
131
+ return { content };
132
+ }
133
+ /**
134
+ * A recorded directory's files, under `.chant/release-templates/<digest>/<name>/`
135
+ * (#4155). The digest is taken over the files' paths from the directory and
136
+ * their bytes, as a gate's directory digest is, so the path names the tree.
137
+ */
138
+ async function pinTree(component, dir, target, readTemplate) {
139
+ const prefix = `${dir}/`;
140
+ const entries = target.templates.filter((t) => t.component === component && t.path.startsWith(prefix));
141
+ const errors = [];
142
+ const read = [];
143
+ for (const e of entries) {
144
+ const got = await readChecked(component, e.path, e, target, readTemplate);
145
+ if ("error" in got)
146
+ errors.push(got.error);
147
+ else
148
+ read.push({ rel: e.path.slice(prefix.length), content: got.content, digest: e.digest, ...(e.encoding ? { encoding: e.encoding } : {}) });
149
+ }
150
+ if (errors.length > 0)
151
+ return { errors };
152
+ read.sort((a, b) => (a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0));
153
+ const digest = computePlanDigest("directory", read.map(({ rel, digest }) => ({ path: rel, digest })));
154
+ const path = join(RELEASE_TEMPLATES_DIR, digest.replace(/:/g, "_"), basename(dir));
155
+ return { path, files: read.map((r) => ({ path: join(path, r.rel), content: r.content, ...(r.encoding ? { encoding: r.encoding } : {}) })) };
156
+ }
98
157
  /**
99
158
  * The files a release's target records, read back by digest and checked, for
100
159
  * `chant release export` (#4046). A project with no components has no deploy
@@ -113,12 +172,12 @@ export async function targetFiles(release, target, readTemplate) {
113
172
  errors.push(`${who}template "${t.path}" is not a path inside the member's directory; refusing to write it`);
114
173
  continue;
115
174
  }
116
- const content = await readTemplate(t.digest);
175
+ const content = await readTemplate(t.digest, t.encoding);
117
176
  if (content === null) {
118
177
  errors.push(`${who}the bytes of template "${t.path}" (${t.digest}) are not on the chant/lifecycle branch; fetch it and try again`);
119
178
  continue;
120
179
  }
121
- const got = contentDigest(content);
180
+ const got = templateBytesDigest(content, t.encoding);
122
181
  if (got !== t.digest) {
123
182
  errors.push(`${who}template "${t.path}" hashes to ${got}, but release ${release.releaseDigest} records ${t.digest} for "${target.env}"; refusing to write it`);
124
183
  continue;
@@ -129,7 +188,7 @@ export async function targetFiles(release, target, readTemplate) {
129
188
  errors.push(`two components record different bytes at "${t.path}" for "${target.env}", so they can't both be written there`);
130
189
  continue;
131
190
  }
132
- files.push({ path: t.path, content });
191
+ files.push({ path: t.path, content, ...(t.encoding ? { encoding: t.encoding } : {}) });
133
192
  }
134
193
  return errors.length > 0 ? { errors } : { files };
135
194
  }
@@ -138,7 +197,7 @@ export function writePinnedTemplates(dir, files) {
138
197
  for (const f of files) {
139
198
  const full = join(dir, f.path);
140
199
  mkdirSync(dirname(full), { recursive: true });
141
- writeFileSync(full, f.content);
200
+ writeFileSync(full, f.encoding === "base64" ? Buffer.from(f.content, "base64") : f.content);
142
201
  }
143
202
  }
144
203
  /**
@@ -148,8 +207,10 @@ export function writePinnedTemplates(dir, files) {
148
207
  * again from the release.
149
208
  */
150
209
  export function removePinnedTemplates(dir, files) {
210
+ // Each file sits under `.chant/release-templates/<digest>/`, a recorded tree's deeper; that digest directory goes.
211
+ const prefix = RELEASE_TEMPLATES_DIR.split("/").length;
151
212
  for (const f of files)
152
- rmSync(dirname(join(dir, f.path)), { recursive: true, force: true });
213
+ rmSync(join(dir, ...f.path.split(/[\\/]/).slice(0, prefix + 1)), { recursive: true, force: true });
153
214
  const root = join(dir, RELEASE_TEMPLATES_DIR);
154
215
  try {
155
216
  if (readdirSync(root).length === 0)
@@ -68,7 +68,7 @@ export interface BomPackage {
68
68
  /** Version string, when known. Omitted for resources with no version concept (e.g. a CFN resource). */
69
69
  version?: string;
70
70
  /** Package manager / ecosystem this entry came from (e.g. "npm", "maven"), surfaced in SPDX's `externalRefs`/CycloneDX's `purl` when derivable. */
71
- type?: "npm" | "maven" | "config" | "external-reference";
71
+ type?: "npm" | "maven" | "cargo" | "config" | "external-reference";
72
72
  /** Package URL (purl), when derivable — e.g. `pkg:npm/left-pad@1.3.0`. */
73
73
  purl?: string;
74
74
  /** SPDX download location, when known. Defaults to `"NOASSERTION"` per the SPDX spec's requirement that every package declare one. */
@@ -1 +1 @@
1
- {"version":3,"file":"bom-writer.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/bom-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAIrE;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,2HAA2H;IAC3H,IAAI,EAAE,MAAM,CAAC;IACb,uGAAuG;IACvG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mJAAmJ;IACnJ,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,oBAAoB,CAAC;IACzD,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sIAAsI;IACtI,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0JAA0J;IAC1J,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+MAA+M;IAC/M,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED,oGAAoG;AACpG,MAAM,WAAW,QAAQ;IACvB,yFAAyF;IACzF,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2IAA2I;IAC3I,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,gIAAgI;IAChI,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;CACjC;AAyDD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAE,MAAM,IAAuB,GAAG,MAAM,CAyErF;AAsBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAE,MAAM,IAAuB,GAAG,MAAM,CAgE1F;AAUD,+NAA+N;AAC/N,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,QAAQ,EACf,GAAG,CAAC,EAAE,MAAM,IAAI,GACf;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAG1D"}
1
+ {"version":3,"file":"bom-writer.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/bom-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAIrE;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,2HAA2H;IAC3H,IAAI,EAAE,MAAM,CAAC;IACb,uGAAuG;IACvG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mJAAmJ;IACnJ,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,oBAAoB,CAAC;IACnE,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sIAAsI;IACtI,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0JAA0J;IAC1J,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,iGAAiG;IACjG,WAAW,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+MAA+M;IAC/M,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,QAAQ,EAAE,UAAU,EAAE,CAAC;CACxB;AAED,oGAAoG;AACpG,MAAM,WAAW,QAAQ;IACvB,yFAAyF;IACzF,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2IAA2I;IAC3I,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,gIAAgI;IAChI,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,cAAc,EAAE,CAAC;CACjC;AAyDD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAE,MAAM,IAAuB,GAAG,MAAM,CAyErF;AAsBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAE,MAAM,IAAuB,GAAG,MAAM,CAgE1F;AAUD,+NAA+N;AAC/N,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,QAAQ,EACf,GAAG,CAAC,EAAE,MAAM,IAAI,GACf;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAG1D"}
@@ -55,6 +55,26 @@ export declare function parseNpmPackageLock(content: string): BomPackage[];
55
55
  * inheritance chain.
56
56
  */
57
57
  export declare function parsePomXml(content: string): BomPackage[];
58
+ /**
59
+ * Parse a `Cargo.lock` (version 3 or 4) into a flat `BomPackage[]`: one
60
+ * entry per `[[package]]` with a `source`, so the workspace's own crates,
61
+ * which have none, are left out as the npm parser leaves out the root.
62
+ * A dependency is named `name` or `name version` in the lock; only the name
63
+ * is kept. A small line reader, not a TOML parser: the lock is written by
64
+ * cargo in one fixed shape.
65
+ */
66
+ export declare function parseCargoLock(content: string): BomPackage[];
67
+ /** Each lockfile kind's parser and file name. */
68
+ export declare const LOCKFILE_PARSERS: {
69
+ readonly npm: typeof parseNpmPackageLock;
70
+ readonly maven: typeof parsePomXml;
71
+ readonly cargo: typeof parseCargoLock;
72
+ };
73
+ export declare const LOCKFILE_NAMES: {
74
+ readonly npm: "package-lock.json";
75
+ readonly maven: "pom.xml";
76
+ readonly cargo: "Cargo.lock";
77
+ };
58
78
  export interface LockfileSbomGeneratorOptions {
59
79
  /** Where generated SBOM documents are written on disk, as a sibling of the scanned path (see `sbomOutputPath`). Default: alongside the scanned manifest, named `sbom.<format>.json`. */
60
80
  outDir?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"lockfile-sbom-generator.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/lockfile-sbom-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,KAAK,EAMV,aAAa,EACd,MAAM,kBAAkB,CAAC;AAe1B;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAkCjE;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CA8BzD;AAID,MAAM,WAAW,4BAA4B;IAC3C,wLAAwL;IACxL,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAgBD,qIAAqI;AACrI,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,4BAAiC,GAAG,aAAa,CA0CrG;AAED,gMAAgM;AAChM,eAAO,MAAM,qBAAqB,EAAE,aAA6C,CAAC"}
1
+ {"version":3,"file":"lockfile-sbom-generator.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/lockfile-sbom-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAEzD,OAAO,KAAK,EAMV,aAAa,EACd,MAAM,kBAAkB,CAAC;AAe1B;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAkCjE;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CA8BzD;AAID;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAsB5D;AAED,iDAAiD;AACjD,eAAO,MAAM,gBAAgB;aAAK,GAAG;aAAuB,KAAK;aAAe,KAAK;CAA2B,CAAC;AACjH,eAAO,MAAM,cAAc;aAAK,GAAG,EAAE,mBAAmB;aAAE,KAAK,EAAE,SAAS;aAAE,KAAK,EAAE,YAAY;CAAW,CAAC;AAI3G,MAAM,WAAW,4BAA4B;IAC3C,wLAAwL;IACxL,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAgBD,qIAAqI;AACrI,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,GAAE,4BAAiC,GAAG,aAAa,CA0CrG;AAED,gMAAgM;AAChM,eAAO,MAAM,qBAAqB,EAAE,aAA6C,CAAC"}
@@ -125,9 +125,46 @@ export function parsePomXml(content) {
125
125
  }
126
126
  return packages.sort((a, b) => a.name.localeCompare(b.name));
127
127
  }
128
+ // ── Cargo.lock (Rust, #4168 decision 12) ────────────────────────────────────
129
+ /**
130
+ * Parse a `Cargo.lock` (version 3 or 4) into a flat `BomPackage[]`: one
131
+ * entry per `[[package]]` with a `source`, so the workspace's own crates,
132
+ * which have none, are left out as the npm parser leaves out the root.
133
+ * A dependency is named `name` or `name version` in the lock; only the name
134
+ * is kept. A small line reader, not a TOML parser: the lock is written by
135
+ * cargo in one fixed shape.
136
+ */
137
+ export function parseCargoLock(content) {
138
+ const seen = new Map();
139
+ const blocks = content.split(/^\[\[package\]\]\s*$/m).slice(1);
140
+ for (const block of blocks) {
141
+ const body = block.split(/^\[/m)[0] ?? "";
142
+ const field = (key) => new RegExp(`^${key}\\s*=\\s*"([^"]*)"`, "m").exec(body)?.[1];
143
+ const name = field("name");
144
+ const version = field("version");
145
+ if (!name || field("source") === undefined)
146
+ continue;
147
+ const deps = /^dependencies\s*=\s*\[([\s\S]*?)\]/m.exec(body)?.[1];
148
+ const dependsOn = deps ? [...deps.matchAll(/"([^"\s]+)[^"]*"/g)].map((m) => m[1]) : [];
149
+ const key = `${name}@${version ?? ""}`;
150
+ if (seen.has(key))
151
+ continue;
152
+ seen.set(key, {
153
+ name,
154
+ version,
155
+ type: "cargo",
156
+ purl: version ? `pkg:cargo/${encodeURIComponent(name)}@${version}` : undefined,
157
+ dependsOn: dependsOn.length ? [...new Set(dependsOn)] : undefined,
158
+ });
159
+ }
160
+ return [...seen.values()].sort((a, b) => a.name.localeCompare(b.name) || (a.version ?? "").localeCompare(b.version ?? ""));
161
+ }
162
+ /** Each lockfile kind's parser and file name. */
163
+ export const LOCKFILE_PARSERS = { npm: parseNpmPackageLock, maven: parsePomXml, cargo: parseCargoLock };
164
+ export const LOCKFILE_NAMES = { npm: "package-lock.json", maven: "pom.xml", cargo: "Cargo.lock" };
128
165
  /** Locate the first readable lockfile/manifest under `dir` this generator knows how to parse, in preference order (npm before Maven — most chant components are Node-first). Returns `undefined` if none is found. */
129
166
  function findManifest(dir) {
130
- for (const [kind, filename] of [["npm", "package-lock.json"], ["maven", "pom.xml"]]) {
167
+ for (const [kind, filename] of [["npm", "package-lock.json"], ["maven", "pom.xml"], ["cargo", "Cargo.lock"]]) {
131
168
  const candidate = join(dir, filename);
132
169
  try {
133
170
  readFileSync(candidate, "utf-8");
@@ -160,12 +197,12 @@ export function createLockfileSbomGenerator(options = {}) {
160
197
  function generateFromDir(dir, subjectName, digest, format = DEFAULT_SBOM_FORMAT) {
161
198
  const manifest = findManifest(dir);
162
199
  if (!manifest) {
163
- throw new Error(`no supported lockfile/manifest found under "${dir}" (looked for package-lock.json, pom.xml) — ` +
200
+ throw new Error(`no supported lockfile/manifest found under "${dir}" (looked for package-lock.json, pom.xml, Cargo.lock) — ` +
164
201
  `the hermetic lockfile SBOM backend requires a lockfile on disk; use the deep-scan path (#610) for images with no lockfile`);
165
202
  }
166
203
  const content = readFileSync(manifest.path, "utf-8");
167
- const packages = manifest.kind === "npm" ? parseNpmPackageLock(content) : parsePomXml(content);
168
- const generatorName = manifest.kind === "npm" ? "chant-lockfile-sbom/package-lock.json" : "chant-lockfile-sbom/pom.xml";
204
+ const packages = LOCKFILE_PARSERS[manifest.kind](content);
205
+ const generatorName = `chant-lockfile-sbom/${LOCKFILE_NAMES[manifest.kind]}`;
169
206
  const doc = writeBom(format, { subjectName, subjectId: digest ?? manifest.path, packages, generator: generatorName }, now);
170
207
  const outDir = options.outDir ?? dir;
171
208
  mkdirSync(outDir, { recursive: true });
@@ -13,30 +13,43 @@
13
13
  * (`componentPlanDigest`, ./gate-plan.ts, #2574), so a wave mixing roots and
14
14
  * other components still has one digest that moves when any of them does.
15
15
  *
16
+ * The files a step without a `plan` deploys from are bound too (#4155,
17
+ * ./deploy-inputs.ts). A component with no plannable step folds them into its
18
+ * composition digest. A component with one gets a member more,
19
+ * `<component>#inputs`, over its other steps' files, so a `lambda-deploy`
20
+ * source or a Helm chart beside a `cfn-deploy` moves the wave's digest. A step
21
+ * whose content chant can't name is a hole on that member, so the plan note
22
+ * lists it as unbound.
23
+ *
16
24
  * Known limit: a step input that reads an earlier step of the same
17
25
  * component (`@Phase.field`) has no value before the component runs, so it
18
26
  * plans as `undefined`. Cross-component wiring (`stackOutput()`,
19
27
  * `@<component>.publish.*`) resolves.
20
28
  */
21
29
  import { type DriverComponent, type DriverPhase, type DriverStep } from "./driver.js";
22
- import type { CapabilityRegistry, DeployContext } from "./capability.js";
30
+ import type { CapabilityRegistry, DeployContext, PlannedOutputs } from "./capability.js";
23
31
  import type { WaveMember } from "../gated-waves.js";
24
32
  import type { ChangeSetPart } from "../change-set.js";
25
33
  /**
26
34
  * What planning one component produced: its members, what its steps hand to
27
35
  * `run`, and each member's change-set part (#3183), or why it could not plan.
28
36
  * A member whose capability returns no part gets one with no entries, so the
29
- * parts always cover the members.
37
+ * parts always cover the members. `outputs` is what its steps' plans say the
38
+ * component will expose once applied (#3999), merged the way the driver
39
+ * merges a run's outputs; absent when no step's plan says.
30
40
  */
31
41
  export type WaveComponentPlan = {
32
42
  component: string;
33
43
  members: WaveMember[];
34
44
  plans: Record<string, unknown>;
35
45
  parts: ChangeSetPart[];
46
+ outputs?: PlannedOutputs;
36
47
  } | {
37
48
  component: string;
38
49
  error: string;
39
50
  };
51
+ /** The member a planning component's other steps add (#4155): their files, under the component's name. */
52
+ export declare const inputsMemberName: (component: string) => string;
40
53
  /** Every capability step in a composition, nested phases included, gates left out. */
41
54
  export declare function capabilitySteps(phases: readonly DriverPhase[]): DriverStep[];
42
55
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"wave-plan.d.ts","sourceRoot":"","sources":["../../src/components/wave-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAA6C,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAE9H,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAA;CAAE,GACpG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAUzC,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,UAAU,EAAE,CAc5E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,aAAa,EAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxD,aAAa,CAGf;AAED,oHAAoH;AACpH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,EAAE,aAAa,EAClB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxD,OAAO,CAAC,iBAAiB,CAAC,CAgC5B;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,EAAE,aAAa,EAClB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxD,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAU9C;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,EAChD,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,aAAa,EAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC/C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAYnC"}
1
+ {"version":3,"file":"wave-plan.d.ts","sourceRoot":"","sources":["../../src/components/wave-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAA6C,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AAI9H,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,cAAc,CAAA;CAAE,GAC9H;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAWzC,0GAA0G;AAC1G,eAAO,MAAM,gBAAgB,cAAe,MAAM,KAAG,MAA+B,CAAC;AAErF,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,UAAU,EAAE,CAc5E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,aAAa,EAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxD,aAAa,CAGf;AAED,oHAAoH;AACpH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,EAAE,aAAa,EAClB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxD,OAAO,CAAC,iBAAiB,CAAC,CAgD5B;AAUD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,eAAe,EAC1B,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,EAAE,aAAa,EAClB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxD,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAU9C;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,EAChD,QAAQ,EAAE,kBAAkB,EAC5B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,aAAa,EAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC/C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAYnC"}