@intentius/chant 0.124.34 → 0.124.35

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 (169) hide show
  1. package/dist/cli/handlers/graph.js +2 -2
  2. package/dist/cli/handlers/pr.d.ts.map +1 -1
  3. package/dist/cli/handlers/pr.js +147 -51
  4. package/dist/cli/handlers/promote.d.ts.map +1 -1
  5. package/dist/cli/handlers/promote.js +23 -8
  6. package/dist/cli/handlers/release.d.ts +12 -0
  7. package/dist/cli/handlers/release.d.ts.map +1 -1
  8. package/dist/cli/handlers/release.js +125 -10
  9. package/dist/cli/handlers/run.d.ts +3 -1
  10. package/dist/cli/handlers/run.d.ts.map +1 -1
  11. package/dist/cli/handlers/run.js +12 -2
  12. package/dist/cli/main.d.ts.map +1 -1
  13. package/dist/cli/main.js +19 -1
  14. package/dist/cli/parse-args.d.ts.map +1 -1
  15. package/dist/cli/parse-args.js +17 -0
  16. package/dist/cli/registry.d.ts +14 -0
  17. package/dist/cli/registry.d.ts.map +1 -1
  18. package/dist/components/auto-release.d.ts +8 -1
  19. package/dist/components/auto-release.d.ts.map +1 -1
  20. package/dist/components/auto-release.js +3 -2
  21. package/dist/components/green-cover.d.ts +77 -0
  22. package/dist/components/green-cover.d.ts.map +1 -0
  23. package/dist/components/green-cover.js +153 -0
  24. package/dist/components/pr-pipeline.d.ts +34 -0
  25. package/dist/components/pr-pipeline.d.ts.map +1 -1
  26. package/dist/components/pr-pipeline.js +39 -5
  27. package/dist/components/promote.d.ts +4 -1
  28. package/dist/components/promote.d.ts.map +1 -1
  29. package/dist/components/promote.js +6 -3
  30. package/dist/components/release-promote.d.ts +9 -0
  31. package/dist/components/release-promote.d.ts.map +1 -1
  32. package/dist/components/release-promote.js +15 -0
  33. package/dist/config.d.ts +2 -0
  34. package/dist/config.d.ts.map +1 -1
  35. package/dist/deep-observation.d.ts +11 -0
  36. package/dist/deep-observation.d.ts.map +1 -1
  37. package/dist/graph-declared.d.ts +5 -1
  38. package/dist/graph-declared.d.ts.map +1 -1
  39. package/dist/graph-declared.js +7 -2
  40. package/dist/graph-detail.d.ts.map +1 -1
  41. package/dist/graph-detail.js +30 -1
  42. package/dist/graph-ir.d.ts.map +1 -1
  43. package/dist/graph-ir.js +13 -2
  44. package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -1
  45. package/dist/lifecycle/__fixtures__/publish-fakes.js +5 -1
  46. package/dist/lifecycle/compose-refs.d.ts +52 -0
  47. package/dist/lifecycle/compose-refs.d.ts.map +1 -0
  48. package/dist/lifecycle/compose-refs.js +115 -0
  49. package/dist/lifecycle/deep-observe.d.ts.map +1 -1
  50. package/dist/lifecycle/deep-observe.js +3 -2
  51. package/dist/lifecycle/green-apply.d.ts +39 -0
  52. package/dist/lifecycle/green-apply.d.ts.map +1 -0
  53. package/dist/lifecycle/green-apply.js +51 -0
  54. package/dist/lifecycle/publish-declaration.d.ts +4 -0
  55. package/dist/lifecycle/publish-declaration.d.ts.map +1 -1
  56. package/dist/lifecycle/publish-declaration.js +15 -0
  57. package/dist/lifecycle/publish-npm.d.ts +7 -4
  58. package/dist/lifecycle/publish-npm.d.ts.map +1 -1
  59. package/dist/lifecycle/publish-npm.js +60 -13
  60. package/dist/lifecycle/release-compose.d.ts +91 -0
  61. package/dist/lifecycle/release-compose.d.ts.map +1 -0
  62. package/dist/lifecycle/release-compose.js +235 -0
  63. package/dist/lifecycle/release-cut.d.ts +8 -0
  64. package/dist/lifecycle/release-cut.d.ts.map +1 -1
  65. package/dist/lifecycle/release-cut.js +2 -0
  66. package/dist/lifecycle/release-publish.d.ts +2 -0
  67. package/dist/lifecycle/release-publish.d.ts.map +1 -1
  68. package/dist/lifecycle/release-publish.js +2 -1
  69. package/dist/lifecycle/release-store.d.ts +15 -0
  70. package/dist/lifecycle/release-store.d.ts.map +1 -1
  71. package/dist/lifecycle/release-store.js +5 -1
  72. package/dist/wave-runtime.mjs +225 -223
  73. package/dist/workspace/checks/ci-workflow.d.ts.map +1 -1
  74. package/dist/workspace/checks/ci-workflow.js +8 -1
  75. package/dist/workspace/ci-green-cli.d.ts.map +1 -1
  76. package/dist/workspace/ci-green-cli.js +5 -3
  77. package/dist/workspace/ci-green-workflow.d.ts +18 -2
  78. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  79. package/dist/workspace/ci-green-workflow.js +27 -5
  80. package/dist/workspace/ci-green.d.ts +31 -0
  81. package/dist/workspace/ci-green.d.ts.map +1 -1
  82. package/dist/workspace/ci-green.js +78 -4
  83. package/dist/workspace/ci-run.d.ts +6 -0
  84. package/dist/workspace/ci-run.d.ts.map +1 -1
  85. package/dist/workspace/ci-run.js +2 -1
  86. package/dist/workspace/ci-serve.d.ts +94 -13
  87. package/dist/workspace/ci-serve.d.ts.map +1 -1
  88. package/dist/workspace/ci-serve.js +248 -30
  89. package/dist/workspace/ci-workflow.d.ts +4 -4
  90. package/dist/workspace/ci-workflow.d.ts.map +1 -1
  91. package/dist/workspace/ci-workflow.js +2 -2
  92. package/dist/workspace/delivery-metrics.d.ts +3 -1
  93. package/dist/workspace/delivery-metrics.d.ts.map +1 -1
  94. package/dist/workspace/delivery-metrics.js +12 -3
  95. package/dist/workspace/member-commands.d.ts.map +1 -1
  96. package/dist/workspace/member-commands.js +4 -0
  97. package/dist/workspace/nested-graph.d.ts.map +1 -1
  98. package/dist/workspace/nested-graph.js +1 -0
  99. package/dist/workspace/release-candidates.d.ts +28 -0
  100. package/dist/workspace/release-candidates.d.ts.map +1 -1
  101. package/dist/workspace/release-candidates.js +38 -2
  102. package/dist/workspace/release-candidates.schema.json +51 -0
  103. package/dist/workspace/releases.schema.json +30 -0
  104. package/package.json +1 -1
  105. package/src/cli/handlers/graph.ts +2 -2
  106. package/src/cli/handlers/pr-green.test.ts +230 -0
  107. package/src/cli/handlers/pr.ts +148 -66
  108. package/src/cli/handlers/promote.test.ts +34 -0
  109. package/src/cli/handlers/promote.ts +22 -8
  110. package/src/cli/handlers/release-compose.e2e.test.ts +133 -0
  111. package/src/cli/handlers/release.ts +112 -10
  112. package/src/cli/handlers/run.ts +12 -1
  113. package/src/cli/main.ts +19 -1
  114. package/src/cli/parse-args.ts +13 -0
  115. package/src/cli/registry.ts +14 -0
  116. package/src/codegen/release-wiring.test.ts +56 -9
  117. package/src/components/auto-release.test.ts +22 -0
  118. package/src/components/auto-release.ts +9 -2
  119. package/src/components/green-cover.test.ts +170 -0
  120. package/src/components/green-cover.ts +186 -0
  121. package/src/components/pr-pipeline.test.ts +14 -4
  122. package/src/components/pr-pipeline.ts +56 -5
  123. package/src/components/promote.test.ts +7 -0
  124. package/src/components/promote.ts +9 -4
  125. package/src/components/release-promote.test.ts +24 -1
  126. package/src/components/release-promote.ts +15 -0
  127. package/src/deep-observation.ts +8 -0
  128. package/src/graph-declared.test.ts +18 -0
  129. package/src/graph-declared.ts +8 -1
  130. package/src/graph-detail.test.ts +68 -1
  131. package/src/graph-detail.ts +29 -1
  132. package/src/graph-ir.ts +12 -4
  133. package/src/lifecycle/__fixtures__/publish-fakes.ts +5 -1
  134. package/src/lifecycle/compose-refs.ts +125 -0
  135. package/src/lifecycle/deep-observe.test.ts +20 -0
  136. package/src/lifecycle/deep-observe.ts +4 -2
  137. package/src/lifecycle/green-apply.ts +71 -0
  138. package/src/lifecycle/publish-declaration.ts +15 -0
  139. package/src/lifecycle/publish-npm.ts +55 -13
  140. package/src/lifecycle/publish-targets.test.ts +45 -0
  141. package/src/lifecycle/release-compose.test.ts +125 -0
  142. package/src/lifecycle/release-compose.ts +312 -0
  143. package/src/lifecycle/release-cut.ts +6 -0
  144. package/src/lifecycle/release-publish.ts +4 -1
  145. package/src/lifecycle/release-store.ts +16 -1
  146. package/src/workspace/checks/ci-workflow.test.ts +12 -2
  147. package/src/workspace/checks/ci-workflow.ts +7 -1
  148. package/src/workspace/ci-green-cli.ts +5 -3
  149. package/src/workspace/ci-green-workflow.test.ts +52 -0
  150. package/src/workspace/ci-green-workflow.ts +34 -5
  151. package/src/workspace/ci-green.test.ts +33 -0
  152. package/src/workspace/ci-green.ts +85 -4
  153. package/src/workspace/ci-run.test.ts +18 -13
  154. package/src/workspace/ci-run.ts +8 -1
  155. package/src/workspace/ci-serve-land.e2e.test.ts +138 -0
  156. package/src/workspace/ci-serve-land.test.ts +176 -0
  157. package/src/workspace/ci-serve.test.ts +77 -43
  158. package/src/workspace/ci-serve.ts +268 -34
  159. package/src/workspace/ci-workflow.ts +4 -4
  160. package/src/workspace/delivery-metrics.ts +12 -3
  161. package/src/workspace/graph-contract.test.ts +3 -2
  162. package/src/workspace/member-commands.test.ts +11 -4
  163. package/src/workspace/member-commands.ts +3 -0
  164. package/src/workspace/nested-graph.test.ts +4 -0
  165. package/src/workspace/nested-graph.ts +1 -0
  166. package/src/workspace/release-candidates.schema.json +51 -0
  167. package/src/workspace/release-candidates.test.ts +30 -3
  168. package/src/workspace/release-candidates.ts +54 -2
  169. package/src/workspace/releases.schema.json +30 -0
@@ -42,10 +42,13 @@
42
42
  * npm makes the first version of a new package `latest` whatever tag it is
43
43
  * published under, so a package's first release is visible when it stages.
44
44
  *
45
- * Credentials are npm's own. chant reads no npm token and writes no `.npmrc`:
46
- * npm authenticates with the registry's `_authToken` in the user's or the
47
- * CI's npm config (`actions/setup-node` writes one that reads
48
- * `NODE_AUTH_TOKEN`), or by trusted publishing. npm runs with the run's
45
+ * Credentials are npm's own: npm authenticates with the registry's
46
+ * `_authToken` in the user's or the CI's npm config (`actions/setup-node`
47
+ * writes one that reads `NODE_AUTH_TOKEN`), or by trusted publishing. The one
48
+ * exception is `tokenEnv` (#4040): when a publish fails to authenticate, the
49
+ * package is published again with that variable's token in a throwaway npm
50
+ * user config, never on the command line, and without `--provenance` if the
51
+ * registry refuses the attestation on the token path. npm runs with the run's
49
52
  * environment, and everything it prints is redacted before chant prints it.
50
53
  */
51
54
  import { execFileSync, spawn } from "node:child_process";
@@ -55,6 +58,8 @@ import { join } from "node:path";
55
58
  import { packageSbom } from "./publish-attachments.js";
56
59
  import { checkReleaseDigest, fileDigest, isDir, memberFile, publishTargetKey } from "./publish-targets.js";
57
60
  import { NPM_STAGE_TAG, PublishTargetError } from "./release-publish.js";
61
+ /** npm's output when a publish could not authenticate, as publish-packages.sh matches it. */
62
+ const NPM_AUTH_FAILED = /ENEEDAUTH|E401|need auth/;
58
63
  /** Read a package's name and version, from its directory or its packed `.tgz`, and find the SBOM it carries. */
59
64
  function readPackage(ctx, path, sbom) {
60
65
  const abs = memberFile(ctx.cwd, path);
@@ -119,9 +124,9 @@ export function npmAuditInstallArgs(decl) {
119
124
  export function npmAuditSignaturesArgs(decl) {
120
125
  return ["audit", "signatures", ...(decl.registry ? ["--registry", decl.registry] : [])];
121
126
  }
122
- function run(bin, args, ctx, cwd = ctx.cwd) {
127
+ function run(bin, args, ctx, cwd = ctx.cwd, env = ctx.env) {
123
128
  return new Promise((resolvePromise, reject) => {
124
- const child = spawn(bin, args, { cwd, env: ctx.env, stdio: ["ignore", "pipe", "pipe"] });
129
+ const child = spawn(bin, args, { cwd, env, stdio: ["ignore", "pipe", "pipe"] });
125
130
  const output = [];
126
131
  let partial = { out: "", err: "" };
127
132
  const take = (key) => (chunk) => {
@@ -148,9 +153,12 @@ export function npmTarget(decl, deps) {
148
153
  const registry = decl.registry ?? "the registry npm's config names";
149
154
  const shown = (tag) => `${registry}, dist-tag ${tag}`;
150
155
  const revealTag = (ctx) => ctx.tag ?? "latest";
151
- const npm = async (ctx, args, cwd) => {
156
+ // Under `stage: false` a package goes straight to the reveal tag, and the reveal moves no tag (#4040).
157
+ const staging = decl.stage !== false;
158
+ const stageTag = (ctx) => (staging ? NPM_STAGE_TAG : revealTag(ctx));
159
+ const npm = async (ctx, args, cwd, env) => {
152
160
  try {
153
- return await run(bin, args, ctx, cwd);
161
+ return await run(bin, args, ctx, cwd, env);
154
162
  }
155
163
  catch (err) {
156
164
  throw new PublishTargetError("publish-npm-failed", ctx.redactor.redact(`npm could not be run: ${err instanceof Error ? err.message : String(err)}`), "Install npm, or put it on PATH.");
@@ -161,9 +169,40 @@ export function npmTarget(decl, deps) {
161
169
  const r = await npm(ctx, ["view", `${pkg.name}@${pkg.version}`, "version", ...(decl.registry ? ["--registry", decl.registry] : [])]);
162
170
  return r.code === 0 && r.output.some((l) => l.trim() === pkg.version || l.trim() === JSON.stringify(pkg.version));
163
171
  };
172
+ /**
173
+ * The `tokenEnv` retry (#4040): a publish that failed to authenticate runs
174
+ * again with the token in a throwaway user config, and once more without
175
+ * `--provenance` when the token path refuses the attestation.
176
+ */
177
+ const withToken = async (ctx, pkg, args, failed) => {
178
+ const token = decl.tokenEnv ? ctx.env[decl.tokenEnv] : undefined;
179
+ if (!token || !failed.output.some((l) => NPM_AUTH_FAILED.test(l)))
180
+ return failed;
181
+ ctx.log(`${pkg.name}@${pkg.version} could not authenticate; publishing again with ${decl.tokenEnv}`);
182
+ const dir = mkdtempSync(join(tmpdir(), "chant-npm-token-"));
183
+ try {
184
+ const userconfig = join(dir, ".npmrc");
185
+ const host = (decl.registry ?? "https://registry.npmjs.org/").replace(/^https?:/, "").replace(/\/?$/, "/");
186
+ writeFileSync(userconfig, `${host}:_authToken=${token}\n`, { mode: 0o600 });
187
+ const env = { ...ctx.env, NPM_CONFIG_USERCONFIG: userconfig };
188
+ let result = await npm(ctx, args, undefined, env);
189
+ for (const line of result.output)
190
+ ctx.log(` ${line}`);
191
+ if (result.code !== 0 && args.includes("--provenance") && result.output.some((l) => /^npm (error|ERR!).*(provenance|attestation)/i.test(l))) {
192
+ ctx.log(`${pkg.name}@${pkg.version}: the registry refused provenance on the token path; publishing without an attestation`);
193
+ result = await npm(ctx, args.filter((a) => a !== "--provenance"), undefined, env);
194
+ for (const line of result.output)
195
+ ctx.log(` ${line}`);
196
+ }
197
+ return result;
198
+ }
199
+ finally {
200
+ rmSync(dir, { recursive: true, force: true });
201
+ }
202
+ };
164
203
  const read = (ctx) => decl.packages.map((p) => readPackage(ctx, p, decl.sbom));
165
204
  const extra = (pkg) => ({ ...(pkg.digest ? { digest: pkg.digest } : {}), ...(pkg.sbom ? { sbom: pkg.sbom } : {}) });
166
- const plan = async (ctx) => read(ctx).map((pkg) => ({ name: `${pkg.name}@${pkg.version}`, destination: `${shown(NPM_STAGE_TAG)}, then ${revealTag(ctx)}`, ...extra(pkg) }));
205
+ const plan = async (ctx) => read(ctx).map((pkg) => ({ name: `${pkg.name}@${pkg.version}`, destination: staging ? `${shown(NPM_STAGE_TAG)}, then ${revealTag(ctx)}` : shown(revealTag(ctx)), ...extra(pkg) }));
167
206
  /**
168
207
  * In CI, install what was published into an empty directory and run
169
208
  * `npm audit signatures` there (#4049), which checks each package's
@@ -199,20 +238,22 @@ export function npmTarget(decl, deps) {
199
238
  const pkgs = read(ctx);
200
239
  const items = [];
201
240
  for (const pkg of pkgs) {
202
- const item = { name: `${pkg.name}@${pkg.version}`, destination: shown(NPM_STAGE_TAG), ...extra(pkg) };
241
+ const item = { name: `${pkg.name}@${pkg.version}`, destination: shown(stageTag(ctx)), ...extra(pkg) };
203
242
  if (await onRegistry(ctx, pkg)) {
204
243
  ctx.log(`${item.name} is already on the registry; not published again`);
205
244
  items.push({ ...item, present: true });
206
245
  continue;
207
246
  }
208
- const args = npmPublishArgs(decl, pkg.abs, ctx);
247
+ const args = npmPublishArgs(decl, pkg.abs, ctx, stageTag(ctx));
209
248
  ctx.log(`npm publish ${pkg.path} ${args.slice(2).join(" ")}`);
210
- const result = await npm(ctx, args);
249
+ let result = await npm(ctx, args);
211
250
  for (const line of result.output)
212
251
  ctx.log(` ${line}`);
252
+ if (result.code !== 0)
253
+ result = await withToken(ctx, pkg, args, result);
213
254
  if (result.code !== 0) {
214
255
  const done = items.map((i) => i.name);
215
- throw new PublishTargetError("publish-npm-failed", `npm publish of ${item.name} exited ${result.code}${done.length > 0 ? `, after ${done.join(", ")} were staged under ${NPM_STAGE_TAG}` : ", before any package was staged"}: ${result.output.at(-1) ?? "npm printed nothing"}`);
256
+ throw new PublishTargetError("publish-npm-failed", `npm publish of ${item.name} exited ${result.code}${done.length > 0 ? `, after ${done.join(", ")} were ${staging ? "staged" : "published"} under ${stageTag(ctx)}` : `, before any package was ${staging ? "staged" : "published"}`}: ${result.output.at(-1) ?? "npm printed nothing"}`);
216
257
  }
217
258
  items.push(item);
218
259
  }
@@ -222,6 +263,12 @@ export function npmTarget(decl, deps) {
222
263
  const tag = revealTag(ctx);
223
264
  const pkgs = read(ctx);
224
265
  const items = [];
266
+ if (!staging) {
267
+ // Already under the reveal tag since the stage; only the audit is left.
268
+ if (ctx.provenance.oidc)
269
+ await audit(ctx, pkgs);
270
+ return { target: this.name, destination: this.destination, items: pkgs.map((pkg) => ({ name: `${pkg.name}@${pkg.version}`, destination: shown(tag), ...extra(pkg) })) };
271
+ }
225
272
  // The declared order: the first package is the set's core, and its tag moves first.
226
273
  for (const pkg of pkgs) {
227
274
  const args = npmDistTagArgs(decl, pkg.name, pkg.version, tag);
@@ -0,0 +1,91 @@
1
+ /**
2
+ * `chant release compose` (#4168 4.3, mode b): a release of chosen changes
3
+ * on a base, when trunk carries work that is not ready to ship.
4
+ *
5
+ * The changes are named by pull request (`--pr <n>`) or work item
6
+ * (`--work <id>`) and found on trunk's first-parent line after the base:
7
+ * a pull request by the merge record `_merges/<sha>.json` on
8
+ * `chant/lifecycle` (./merge-record.ts) or the squash subject `... (#n)`,
9
+ * a work item by the commit's `Chant-Record: work:<id>` trailers or a merge
10
+ * record that names it. Each commit is cherry-picked in trunk order onto the
11
+ * base, in a temporary detached worktree, with a `Chant-Composed-From: <sha>`
12
+ * trailer, and the result goes on the branch `chant/compose/<name>`, pushed
13
+ * so the forge's CI builds it (decision 6).
14
+ *
15
+ * It only appends. A branch that exists is composed onto from its tip, with
16
+ * the base it already has; a change it already carries is skipped. On a
17
+ * conflict it stops, names the change and the files, and writes nothing: a
18
+ * person resolves it in a pull request to the compose branch.
19
+ *
20
+ * Without `yes` it is a dry run: the picks are made in the temporary
21
+ * worktree, so a conflict shows now, and no ref is moved or pushed.
22
+ */
23
+ export type ComposeCode = "not-a-git-repository" | "compose-name-invalid" | "compose-nothing-chosen" | "compose-base-unknown" | "compose-base-differs" | "compose-branch-diverged" | "compose-source-unknown" | "compose-conflict" | "compose-push-refused";
24
+ export declare class ComposeError extends Error {
25
+ readonly code: ComposeCode;
26
+ readonly fix?: string | undefined;
27
+ /** With `compose-conflict`: the change that did not apply and the files it conflicts in. */
28
+ readonly conflict?: {
29
+ commit: string;
30
+ subject: string;
31
+ files: string[];
32
+ } | undefined;
33
+ constructor(code: ComposeCode, message: string, fix?: string | undefined,
34
+ /** With `compose-conflict`: the change that did not apply and the files it conflicts in. */
35
+ conflict?: {
36
+ commit: string;
37
+ subject: string;
38
+ files: string[];
39
+ } | undefined);
40
+ }
41
+ export interface ComposeRequest {
42
+ cwd: string;
43
+ name: string;
44
+ /** A release label or digest, or a commit. Required when the branch does not exist yet. */
45
+ base?: string;
46
+ prs: readonly number[];
47
+ works: readonly string[];
48
+ /** Move the branch and push it. Otherwise a dry run. */
49
+ yes: boolean;
50
+ /** The trunk branch, `ci.green.branch` as the cut resolves it. */
51
+ trunk: {
52
+ remote: string;
53
+ branch: string;
54
+ };
55
+ /** Push the branch to the trunk's remote with `yes`. Default true. */
56
+ push?: boolean;
57
+ }
58
+ /** One trunk commit a compose picks, and why. */
59
+ export interface ComposeSource {
60
+ commit: string;
61
+ subject: string;
62
+ pr: number | null;
63
+ work: string[];
64
+ /** The `--pr` and `--work` values that chose it. */
65
+ chosenBy: string[];
66
+ }
67
+ export interface ComposeResult {
68
+ name: string;
69
+ branch: string;
70
+ base: string;
71
+ /** The branch's tip before the compose, or null when it is new. */
72
+ from: string | null;
73
+ /** The commits picked now, in trunk order. */
74
+ picked: ComposeSource[];
75
+ /** Chosen commits the branch already carries. */
76
+ already: ComposeSource[];
77
+ /** The branch's tip after the picks. Under a dry run, the tip it would have. */
78
+ tip: string;
79
+ /** Whether the branch was moved here. False under a dry run. */
80
+ written: boolean;
81
+ /** Whether it was pushed. */
82
+ pushed: boolean;
83
+ }
84
+ /** The branch a compose name lives on. */
85
+ export declare function composeBranchName(name: string): string;
86
+ /**
87
+ * Compose the chosen changes onto the base, on `chant/compose/<name>`.
88
+ * Throws {@link ComposeError} before any ref moves.
89
+ */
90
+ export declare function composeRelease(req: ComposeRequest): Promise<ComposeResult>;
91
+ //# sourceMappingURL=release-compose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-compose.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAQH,MAAM,MAAM,WAAW,GACnB,sBAAsB,GACtB,sBAAsB,GACtB,wBAAwB,GACxB,sBAAsB,GACtB,sBAAsB,GACtB,yBAAyB,GACzB,wBAAwB,GACxB,kBAAkB,GAClB,sBAAsB,CAAC;AAE3B,qBAAa,YAAa,SAAQ,KAAK;IAEnC,QAAQ,CAAC,IAAI,EAAE,WAAW;IAE1B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM;IACrB,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE;IAL1E,YACW,IAAI,EAAE,WAAW,EAC1B,OAAO,EAAE,MAAM,EACN,GAAG,CAAC,EAAE,MAAM,YAAA;IACrB,4FAA4F;IACnF,QAAQ,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,YAAA,EAIzE;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,wDAAwD;IACxD,GAAG,EAAE,OAAO,CAAC;IACb,kEAAkE;IAClE,KAAK,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,sEAAsE;IACtE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,oDAAoD;IACpD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,8CAA8C;IAC9C,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,iDAAiD;IACjD,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC;IACZ,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,MAAM,EAAE,OAAO,CAAC;CACjB;AAmBD,0CAA0C;AAC1C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAsCD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAkHhF"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * `chant release compose` (#4168 4.3, mode b): a release of chosen changes
3
+ * on a base, when trunk carries work that is not ready to ship.
4
+ *
5
+ * The changes are named by pull request (`--pr <n>`) or work item
6
+ * (`--work <id>`) and found on trunk's first-parent line after the base:
7
+ * a pull request by the merge record `_merges/<sha>.json` on
8
+ * `chant/lifecycle` (./merge-record.ts) or the squash subject `... (#n)`,
9
+ * a work item by the commit's `Chant-Record: work:<id>` trailers or a merge
10
+ * record that names it. Each commit is cherry-picked in trunk order onto the
11
+ * base, in a temporary detached worktree, with a `Chant-Composed-From: <sha>`
12
+ * trailer, and the result goes on the branch `chant/compose/<name>`, pushed
13
+ * so the forge's CI builds it (decision 6).
14
+ *
15
+ * It only appends. A branch that exists is composed onto from its tip, with
16
+ * the base it already has; a change it already carries is skipped. On a
17
+ * conflict it stops, names the change and the files, and writes nothing: a
18
+ * person resolves it in a pull request to the compose branch.
19
+ *
20
+ * Without `yes` it is a dry run: the picks are made in the temporary
21
+ * worktree, so a conflict shows now, and no ref is moved or pushed.
22
+ */
23
+ import { execFileSync, spawnSync } from "node:child_process";
24
+ import { mkdtempSync, realpathSync, rmSync } from "node:fs";
25
+ import { tmpdir } from "node:os";
26
+ import { join } from "node:path";
27
+ import { COMPOSE_BRANCH_PREFIX, COMPOSED_FROM_TRAILER, compositionOnTrunk } from "./compose-refs.js";
28
+ export class ComposeError extends Error {
29
+ constructor(code, message, fix,
30
+ /** With `compose-conflict`: the change that did not apply and the files it conflicts in. */
31
+ conflict) {
32
+ super(message);
33
+ this.code = code;
34
+ this.fix = fix;
35
+ this.conflict = conflict;
36
+ this.name = "ComposeError";
37
+ }
38
+ }
39
+ const NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
40
+ const PR_IN_SUBJECT = /\(#(\d+)\)\s*$/;
41
+ function git(cwd, args, env) {
42
+ return execFileSync("git", args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], maxBuffer: 64 * 1024 * 1024, ...(env ? { env } : {}) }).trim();
43
+ }
44
+ function tryGit(cwd, args) {
45
+ try {
46
+ return git(cwd, args);
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ const isAncestor = (top, a, b) => spawnSync("git", ["merge-base", "--is-ancestor", a, b], { cwd: top, stdio: "ignore" }).status === 0;
53
+ /** The branch a compose name lives on. */
54
+ export function composeBranchName(name) {
55
+ return `${COMPOSE_BRANCH_PREFIX}${name}`;
56
+ }
57
+ async function resolveBase(top, cwd, ref) {
58
+ const { resolveRelease } = await import("./release-store.js");
59
+ const found = await resolveRelease(ref, { cwd }).catch(() => null);
60
+ if (found)
61
+ return found.release.commit;
62
+ const sha = tryGit(top, ["rev-parse", "--verify", "--quiet", `${ref}^{commit}`]);
63
+ if (!sha) {
64
+ throw new ComposeError("compose-base-unknown", `--base ${ref} names no release of this member and no commit this clone has`, "Name a release label (chant release list) or a commit, after fetching it.");
65
+ }
66
+ return sha;
67
+ }
68
+ /** The merge record of `sha`, as stored, or null. */
69
+ async function mergeRecordOf(cwd, sha) {
70
+ const { readBlobFromPath } = await import("./git.js");
71
+ const text = await readBlobFromPath("_merges", `${sha}.json`, { cwd }).catch(() => null);
72
+ if (text === null)
73
+ return null;
74
+ try {
75
+ const parsed = JSON.parse(text);
76
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
77
+ }
78
+ catch {
79
+ return null;
80
+ }
81
+ }
82
+ /** The pull request and work items a merge record names. */
83
+ function fromMergeRecord(merge) {
84
+ if (!merge)
85
+ return { pr: null, work: [] };
86
+ const source = merge.source;
87
+ const pr = source?.kind === "pull-request" && typeof source.pr === "number" ? source.pr : typeof merge.pr === "number" ? merge.pr : null;
88
+ const work = source?.kind === "work-item" && Array.isArray(source.records)
89
+ ? source.records.filter((r) => !!r && typeof r === "object" && r.kind === "work").map((r) => r.id)
90
+ : [];
91
+ return { pr, work };
92
+ }
93
+ /**
94
+ * Compose the chosen changes onto the base, on `chant/compose/<name>`.
95
+ * Throws {@link ComposeError} before any ref moves.
96
+ */
97
+ export async function composeRelease(req) {
98
+ const top = tryGit(req.cwd, ["rev-parse", "--show-toplevel"]);
99
+ if (!top)
100
+ throw new ComposeError("not-a-git-repository", "a compose picks commits, and this directory is not in a git repository");
101
+ if (!NAME.test(req.name)) {
102
+ throw new ComposeError("compose-name-invalid", `"${req.name}" can't name a compose branch: use letters, digits, dots, dashes and underscores, starting with a letter or digit`);
103
+ }
104
+ if (req.prs.length === 0 && req.works.length === 0) {
105
+ throw new ComposeError("compose-nothing-chosen", "a compose needs the changes it carries", "Name them: --pr <n> or --work <id>, each as often as needed.");
106
+ }
107
+ const { remote } = req.trunk;
108
+ const branch = composeBranchName(req.name);
109
+ const remoteRef = `refs/remotes/${remote}/${branch}`;
110
+ const localRef = `refs/heads/${branch}`;
111
+ // The branch as the remote has it, when the remote is reachable; a new branch is absent there.
112
+ if (tryGit(top, ["remote", "get-url", remote]) !== null)
113
+ tryGit(top, ["fetch", "--quiet", "--no-tags", remote, `+${localRef}:${remoteRef}`]);
114
+ const remoteTip = tryGit(top, ["rev-parse", "--verify", "--quiet", `${remoteRef}^{commit}`]);
115
+ const localTip = tryGit(top, ["rev-parse", "--verify", "--quiet", `${localRef}^{commit}`]);
116
+ if (remoteTip && localTip && !isAncestor(top, localTip, remoteTip) && !isAncestor(top, remoteTip, localTip)) {
117
+ throw new ComposeError("compose-branch-diverged", `${branch} here and on ${remote} have diverged, and a compose only appends`, `Keep the remote's: git branch -f ${branch} ${remote}/${branch}`);
118
+ }
119
+ const from = remoteTip && localTip ? (isAncestor(top, localTip, remoteTip) ? remoteTip : localTip) : (remoteTip ?? localTip);
120
+ const trunkRef = tryGit(top, ["rev-parse", "--verify", "--quiet", `refs/remotes/${remote}/${req.trunk.branch}^{commit}`]) ??
121
+ tryGit(top, ["rev-parse", "--verify", "--quiet", `refs/heads/${req.trunk.branch}^{commit}`]);
122
+ if (!trunkRef)
123
+ throw new ComposeError("compose-source-unknown", `this clone has neither ${remote}/${req.trunk.branch} nor ${req.trunk.branch}, so there is no trunk to pick from`);
124
+ // What the branch carries: back to trunk, past a commit a person made on it, such as a resolved conflict.
125
+ const existing = from ? compositionOnTrunk(top, from, trunkRef, branch) : null;
126
+ let base;
127
+ if (from) {
128
+ base = existing?.base ?? from;
129
+ if (req.base !== undefined) {
130
+ const asked = await resolveBase(top, req.cwd, req.base);
131
+ if (asked !== base) {
132
+ throw new ComposeError("compose-base-differs", `${branch} is composed on ${base.slice(0, 12)}, and --base names ${asked.slice(0, 12)}; a compose only appends to its branch`, `Drop --base to add to ${branch}, or compose under another name.`);
133
+ }
134
+ }
135
+ }
136
+ else {
137
+ if (req.base === undefined)
138
+ throw new ComposeError("compose-base-unknown", `${branch} does not exist yet, so the compose needs --base`, "Name the release or commit to compose on: --base <label|sha>");
139
+ base = await resolveBase(top, req.cwd, req.base);
140
+ }
141
+ // Trunk's first-parent commits after the base, oldest first.
142
+ const line = (tryGit(top, ["rev-list", "--first-parent", "--reverse", trunkRef, `^${base}`]) ?? "").split("\n").filter(Boolean);
143
+ const { commitDetails } = await import("../workspace/intent.js");
144
+ const { recordTrailers } = await import("../workspace/release-candidates.js");
145
+ const details = commitDetails(top, line);
146
+ const chosen = new Map();
147
+ const choose = (sha, by, pr, work) => {
148
+ const entry = chosen.get(sha) ?? { commit: sha, subject: details.get(sha)?.subject ?? "", pr, work, chosenBy: [] };
149
+ if (!entry.chosenBy.includes(by))
150
+ entry.chosenBy.push(by);
151
+ chosen.set(sha, entry);
152
+ };
153
+ const unmatched = new Set([...req.prs.map((n) => `--pr ${n}`), ...req.works.map((w) => `--work ${w}`)]);
154
+ for (const sha of line) {
155
+ const d = details.get(sha);
156
+ const merge = fromMergeRecord(await mergeRecordOf(req.cwd, sha));
157
+ const subjectPr = PR_IN_SUBJECT.exec(d?.subject ?? "");
158
+ const pr = merge.pr ?? (subjectPr ? Number(subjectPr[1]) : null);
159
+ const work = [...new Set([...recordTrailers(d?.trailers ?? {}).work, ...merge.work])];
160
+ for (const n of req.prs) {
161
+ if (pr === n) {
162
+ choose(sha, `--pr ${n}`, pr, work);
163
+ unmatched.delete(`--pr ${n}`);
164
+ }
165
+ }
166
+ for (const w of req.works) {
167
+ if (work.includes(w)) {
168
+ choose(sha, `--work ${w}`, pr, work);
169
+ unmatched.delete(`--work ${w}`);
170
+ }
171
+ }
172
+ }
173
+ if (unmatched.size > 0) {
174
+ throw new ComposeError("compose-source-unknown", `${[...unmatched].join(", ")} names no commit on ${remote}/${req.trunk.branch} after ${base.slice(0, 12)}`, "A pull request is found by its merge record or its squash subject (#n), and a work item by a Chant-Record: work:<id> trailer. Fetch trunk and chant/lifecycle if it merged elsewhere.");
175
+ }
176
+ // Trunk order, and what the branch already carries.
177
+ const carried = new Set(existing?.sources ?? []);
178
+ const ordered = line.filter((sha) => chosen.has(sha)).map((sha) => chosen.get(sha));
179
+ const already = ordered.filter((s) => carried.has(s.commit));
180
+ const picked = ordered.filter((s) => !carried.has(s.commit));
181
+ const tip = picked.length === 0 ? (from ?? base) : pickOnto(top, from ?? base, picked);
182
+ let written = false;
183
+ let pushed = false;
184
+ if (req.yes && picked.length > 0) {
185
+ git(top, ["update-ref", "-m", `chant release compose ${req.name}`, localRef, tip, localTip ?? ""]);
186
+ written = true;
187
+ }
188
+ if (req.yes && (req.push ?? true) && tryGit(top, ["remote", "get-url", remote]) !== null && tip !== remoteTip) {
189
+ try {
190
+ git(top, ["push", "--quiet", remote, `${tip}:${localRef}`]);
191
+ tryGit(top, ["update-ref", remoteRef, tip]);
192
+ pushed = true;
193
+ }
194
+ catch (err) {
195
+ const stderr = err.stderr?.toString().trim() ?? String(err);
196
+ throw new ComposeError("compose-push-refused", `${branch} was composed here at ${tip.slice(0, 12)} and ${remote} refused the push: ${stderr}`, `Push it by hand once the remote allows it: git push ${remote} ${branch}`);
197
+ }
198
+ }
199
+ return { name: req.name, branch, base, from, picked, already, tip, written, pushed };
200
+ }
201
+ /**
202
+ * Cherry-pick `sources` in order onto `start` in a temporary detached
203
+ * worktree, each with its trailer, and return the last commit. Throws
204
+ * `compose-conflict` naming the change and its files when one does not
205
+ * apply. The worktree is removed either way.
206
+ */
207
+ function pickOnto(top, start, sources) {
208
+ const realTop = realpathSync(top);
209
+ const dir = mkdtempSync(join(tmpdir(), "chant-compose-"));
210
+ git(realTop, ["worktree", "add", "--detach", "--quiet", dir, start]);
211
+ try {
212
+ for (const s of sources) {
213
+ const parents = (tryGit(dir, ["rev-list", "--parents", "-n", "1", s.commit]) ?? "").split(" ").length - 1;
214
+ const args = ["cherry-pick", "--allow-empty", "--keep-redundant-commits", ...(parents > 1 ? ["-m", "1"] : []), s.commit];
215
+ const run = spawnSync("git", args, { cwd: dir, encoding: "utf-8" });
216
+ if (run.status !== 0) {
217
+ const files = (tryGit(dir, ["diff", "--name-only", "--diff-filter=U"]) ?? "").split("\n").filter(Boolean);
218
+ tryGit(dir, ["cherry-pick", "--abort"]);
219
+ const what = [s.pr !== null ? `#${s.pr}` : null, ...s.work.map((w) => `work:${w}`)].filter(Boolean).join(", ");
220
+ throw new ComposeError("compose-conflict", `${s.commit.slice(0, 12)} (${s.subject}${what ? `; ${what}` : ""}) does not apply on the composed commits${files.length > 0 ? `: it conflicts in ${files.join(", ")}` : `: ${(run.stderr || run.stdout).trim()}`}. Nothing was written`, "Resolve it by hand in a pull request to the compose branch, or compose without that change.", { commit: s.commit, subject: s.subject, files });
221
+ }
222
+ git(dir, ["commit", "--quiet", "--amend", "--no-edit", "--allow-empty", "--no-verify", "--trailer", `${COMPOSED_FROM_TRAILER}: ${s.commit}`]);
223
+ }
224
+ return git(dir, ["rev-parse", "HEAD"]);
225
+ }
226
+ finally {
227
+ try {
228
+ git(realTop, ["worktree", "remove", "--force", dir]);
229
+ }
230
+ catch {
231
+ rmSync(dir, { recursive: true, force: true });
232
+ tryGit(realTop, ["worktree", "prune"]);
233
+ }
234
+ }
235
+ }
@@ -60,6 +60,14 @@ export interface CutRequest {
60
60
  * must be the principal the signers file lists the key for.
61
61
  */
62
62
  sign?: string | true;
63
+ /** The composition of a composed commit (#4168 4.3), recorded on the cut. */
64
+ composed?: {
65
+ branch: string;
66
+ base: string;
67
+ sources: string[];
68
+ };
69
+ /** The publish channel recorded on the cut (#4168 4.3), in place of `latest`. */
70
+ channel?: string;
63
71
  }
64
72
  export interface CutResult {
65
73
  release: Release;
@@ -1 +1 @@
1
- {"version":3,"file":"release-cut.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-cut.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"release-cut.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-cut.ts"],"names":[],"mappings":"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"}
@@ -366,6 +366,8 @@ export async function cutRelease(req) {
366
366
  runId: ci?.runId ?? `local-${Date.parse(timestamp)}`,
367
367
  runOrigin: ci?.runOrigin ?? { forge: "local" },
368
368
  signature,
369
+ ...(req.composed ? { composed: req.composed } : {}),
370
+ ...(req.channel ? { channel: req.channel } : {}),
369
371
  }, { cwd });
370
372
  return {
371
373
  release,
@@ -245,6 +245,8 @@ export interface PublishPlan {
245
245
  redactor: Redactor;
246
246
  /** Whether a target with no SBOM source is refused (`publish-sbom-missing`): the workspace opts into `supply-chain` (#4168). Otherwise it publishes without one. */
247
247
  requireSbom: boolean;
248
+ /** The channel a cut of the release names (#4168 4.3), the tag moved in place of `latest`, or null. */
249
+ channel: string | null;
248
250
  }
249
251
  /**
250
252
  * Resolve `ref` (a label or a digest) in the member at `cwd` and decide
@@ -1 +1 @@
1
- {"version":3,"file":"release-publish.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-publish.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"release-publish.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-publish.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtE,0FAA0F;AAC1F,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,IAAI,EAAE,OAAO,CAAC;IACd,sDAAsD;IACtD,EAAE,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC/B,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,eAAe,CAYtF;AAED,mEAAmE;AACnE,MAAM,WAAW,WAAW;IAC1B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kHAAkH;IAClH,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC;IACnC,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,6GAA6G;AAC7G,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,+FAA+F;IAC/F,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,iCAAiC;AACjC,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,iEAAiE;AACjE,MAAM,WAAW,WAAW;IAC1B,kFAAkF;IAClF,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wDAAwD;AACxD,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;CAAE,KAClH,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE;QAAE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAEtH,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kIAAkI;IAClI,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,eAAe,CAAC;IAC5B,oGAAoG;IACpG,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,iDAAiD;IACjD,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,6FAA6F;IAC7F,QAAQ,EAAE,QAAQ,CAAC;IACnB,wDAAwD;IACxD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wEAAwE;AACxE,qBAAa,kBAAmB,SAAQ,KAAK;IAEzC,QAAQ,CAAC,IAAI,EAAE,MAAM;IAErB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM;IAHvB,YACW,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACN,GAAG,CAAC,EAAE,MAAM,YAAA,EAItB;CACF;AAED,4HAA4H;AAC5H,eAAO,MAAM,aAAa,SAAS,CAAC;AAEpC;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;IAC9B,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,kGAAkG;IAClG,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;OAMG;IACH,IAAI,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAClD;;;;;;;OAOG;IACH,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAClD;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7E;AAED,iGAAiG;AACjG,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAKzG;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,IAAI,EACA,mBAAmB,GACnB,iBAAiB,GACjB,kBAAkB,GAClB,8BAA8B,GAC9B,4BAA4B,GAC5B,wBAAwB,GACxB,uBAAuB,GACvB,wBAAwB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,8GAA8G;AAC9G,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,6EAA6E;IAC7E,SAAS,EAAE;QAAE,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACxH,UAAU,EAAE,eAAe,CAAC;IAC5B,gIAAgI;IAChI,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,mHAAmH;IACnH,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,mGAAmG;IACnG,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IACvB,iEAAiE;IACjE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,8DAA8D;IAC9D,QAAQ,EAAE,QAAQ,CAAC;IACnB,oKAAoK;IACpK,WAAW,EAAE,OAAO,CAAC;IACrB,uGAAuG;IACvG,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,GAAG,OAAO,CAAC,WAAW,GAAG;IAAE,OAAO,EAAE,cAAc,CAAA;CAAE,CAAC,CAwGrD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAmBvG;AAUD,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,GAAG,cAAc,CAcjK;AAED,mCAAmC;AACnC,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,+FAA+F;IAC/F,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAA;KAAE,CAAC,CAAC;IAChE,2GAA2G;IAC3G,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,0GAA0G;AAC1G,qBAAa,eAAgB,SAAQ,kBAAkB;IAKnD,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE;IAN7B,YACE,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,GAAG,SAAS,EACd,IAAI,EAAE,OAAO,GAAG,QAAQ,EACxB,MAAM,EAAE,MAAM,EAAE,EAChB,QAAQ,EAAE,MAAM,EAAE,EAI5B;CACF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;IAClC,GAAG,EAAE,cAAc,CAAC;IACpB,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB,GAAG,OAAO,CAAC,UAAU,CAAC,CAiFtB"}
@@ -189,7 +189,8 @@ export async function preparePublish(req) {
189
189
  const member = ledger.members.length > 0 ? ledger.members.join("/") : null;
190
190
  const releaseTag = label !== null ? releaseTagName(member, label) : null;
191
191
  const redactor = createRedactor(env, targets.flatMap((t) => t.credentialEnv));
192
- return { release, label, signature, provenance, warning, signatureWarning, cut, releaseTag, targets, redactor, requireSbom: groups.has("supply-chain") };
192
+ const channel = [...cuts].reverse().find((c) => c.channel)?.channel ?? null;
193
+ return { release, label, signature, provenance, warning, signatureWarning, cut, releaseTag, targets, redactor, requireSbom: groups.has("supply-chain"), channel };
193
194
  }
194
195
  /**
195
196
  * A publish with a target reads files from the checkout it runs in: package
@@ -126,6 +126,21 @@ export interface ReleaseCut {
126
126
  * unsigned cut, and on every cut written before 0.124.28.
127
127
  */
128
128
  signature: string | null;
129
+ /**
130
+ * A cut of a composed commit (#4168 4.3): its compose branch, the base it
131
+ * was composed on, and the trunk commits picked onto the base, oldest
132
+ * first. Absent on a cut of a trunk commit.
133
+ */
134
+ composed?: {
135
+ branch: string;
136
+ base: string;
137
+ sources: string[];
138
+ };
139
+ /**
140
+ * The channel the release publishes to (#4168 4.3): the npm dist-tag or
141
+ * image tag a publish moves in place of `latest`. Absent for `latest`.
142
+ */
143
+ channel?: string;
129
144
  }
130
145
  /** The parts of a release a digest is computed from. */
131
146
  export type ReleaseSubject = Pick<Release, "member" | "commit" | "artifactDigests" | "targets">;
@@ -1 +1 @@
1
- {"version":3,"file":"release-store.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"release-store.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAKH,OAAO,EASL,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,uFAAuF;AACvF,eAAO,MAAM,YAAY,cAAc,CAAC;AACxC,+CAA+C;AAC/C,eAAO,MAAM,SAAS,eAAe,CAAC;AACtC,6FAA6F;AAC7F,eAAO,MAAM,gBAAgB,cAAc,CAAC;AAE5C,0GAA0G;AAC1G,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,6FAA6F;AAC7F,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,0GAA0G;AAC1G,MAAM,WAAW,eAAe;IAC9B,qFAAqF;IACrF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,kHAAkH;AAClH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,gDAAgD;AAChD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,+FAA+F;IAC/F,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,uFAAuF;IACvF,KAAK,CAAC,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,0DAA0D;AAC1D,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,CAAC,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,wGAAwG;IACxG,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,0CAA0C;AAC1C,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CAAC,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;OAGG;IACH,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/D;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,iBAAiB,GAAG,SAAS,CAAC,CAAC;AAIhG,qKAAqK;AACrK,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,cAAc,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAmBxE;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAajE;AAED,2EAA2E;AAC3E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAEpE;AAED,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAG5D;AAED,8EAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAE7D;AAMD,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,MAAM,CAEhF;AAKD,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG9D;AAED,gFAAgF;AAChF,qBAAa,iBAAkB,SAAQ,KAAK;IAExC,QAAQ,CAAC,IAAI,EAAE,qBAAqB,GAAG,0BAA0B,GAAG,uBAAuB;IAD7F,YACW,IAAI,EAAE,qBAAqB,GAAG,0BAA0B,GAAG,uBAAuB,EAC3F,OAAO,EAAE,MAAM,EAIhB;CACF;AAED,wDAAwD;AACxD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,SAAS,eAAe,EAAE,EACrC,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CA6BtD;AAED,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAmCzD;AAED,kIAAkI;AAClI,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAMhG;AAED,iFAAiF;AACjF,wBAAsB,eAAe,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAWhH;AAED,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA4BxF;AAED,+BAA+B;AAC/B,wBAAsB,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAExG;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAI/E;AAED,kCAAkC;AAClC,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,UAAU,CAAA;CAAE;AACrC,iGAAiG;GAC/F;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAI9C;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EACjH,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC,UAAU,CAAC,CAmDrB;AAED,yHAAyH;AACzH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE5H;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAAC,CAQnI"}
@@ -239,7 +239,9 @@ export function parseCuts(text) {
239
239
  typeof c.timestamp === "string" &&
240
240
  (c.runOrigin === null || (typeof c.runOrigin === "object" && typeof c.runOrigin?.forge === "string")) &&
241
241
  (c.signature === null || c.signature === undefined || typeof c.signature === "string") &&
242
- (c.runId === null || c.runId === undefined || typeof c.runId === "string");
242
+ (c.runId === null || c.runId === undefined || typeof c.runId === "string") &&
243
+ (c.channel === undefined || typeof c.channel === "string") &&
244
+ (c.composed === undefined || (typeof c.composed === "object" && c.composed !== null && typeof c.composed.base === "string" && Array.isArray(c.composed.sources)));
243
245
  if (!ok) {
244
246
  malformed++;
245
247
  continue;
@@ -309,6 +311,8 @@ export async function appendCut(input, opts) {
309
311
  runId: input.runId ?? null,
310
312
  runOrigin: input.runOrigin,
311
313
  signature: input.signature ?? null,
314
+ ...(input.composed ? { composed: input.composed } : {}),
315
+ ...(input.channel ? { channel: input.channel } : {}),
312
316
  };
313
317
  const content = `${existing ? `${existing.replace(/\n$/, "")}\n` : ""}${JSON.stringify(cut, sortedJsonReplacer)}\n`;
314
318
  try {