@williamthorsen/release-kit 18.1.1 → 18.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  /** @noformat -- @generated. Do not edit. Compiled by rdy. */
2
2
  /* eslint-disable */
3
- export const __readyupVersion = "0.45.1";
3
+ export const __readyupVersion = "0.46.2";
4
4
 
5
5
 
6
6
  // .readyup/kits/default.ts
@@ -16,7 +16,429 @@ import {
16
16
  } from "readyup/check-utils";
17
17
 
18
18
  // src/init/detectRepoType.ts
19
- import { existsSync, readFileSync } from "node:fs";
19
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
20
+
21
+ // ../../node_modules/.pnpm/@williamthorsen+toolbelt.errors@0.10.1/node_modules/@williamthorsen/toolbelt.errors/dist/esm/4-release/isError.js
22
+ function isError(error) {
23
+ return error instanceof Error || Object.prototype.toString.call(error) === "[object Error]";
24
+ }
25
+
26
+ // ../../node_modules/.pnpm/@williamthorsen+toolbelt.errors@0.10.1/node_modules/@williamthorsen/toolbelt.errors/dist/esm/4-release/describeError.js
27
+ function describeError(error) {
28
+ try {
29
+ if (isError(error) && typeof error.message === "string" && error.message !== "") {
30
+ return error.message;
31
+ }
32
+ return String(error);
33
+ } catch {
34
+ return "[unstringifiable value]";
35
+ }
36
+ }
37
+
38
+ // ../nmr-core/dist/esm/files/updateManagedFile.js
39
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
40
+ import { dirname } from "node:path";
41
+
42
+ // ../../node_modules/.pnpm/diff@9.0.0/node_modules/diff/libesm/diff/base.js
43
+ var Diff = class {
44
+ diff(oldStr, newStr, options = {}) {
45
+ let callback;
46
+ if (typeof options === "function") {
47
+ callback = options;
48
+ options = {};
49
+ } else if ("callback" in options) {
50
+ callback = options.callback;
51
+ }
52
+ const oldString = this.castInput(oldStr, options);
53
+ const newString = this.castInput(newStr, options);
54
+ const oldTokens = this.removeEmpty(this.tokenize(oldString, options));
55
+ const newTokens = this.removeEmpty(this.tokenize(newString, options));
56
+ return this.diffWithOptionsObj(oldTokens, newTokens, options, callback);
57
+ }
58
+ diffWithOptionsObj(oldTokens, newTokens, options, callback) {
59
+ var _a;
60
+ const done = (value) => {
61
+ value = this.postProcess(value, options);
62
+ if (callback) {
63
+ setTimeout(function() {
64
+ callback(value);
65
+ }, 0);
66
+ return void 0;
67
+ } else {
68
+ return value;
69
+ }
70
+ };
71
+ const newLen = newTokens.length, oldLen = oldTokens.length;
72
+ let editLength = 1;
73
+ let maxEditLength = newLen + oldLen;
74
+ if (options.maxEditLength != null) {
75
+ maxEditLength = Math.min(maxEditLength, options.maxEditLength);
76
+ }
77
+ const maxExecutionTime = (_a = options.timeout) !== null && _a !== void 0 ? _a : Infinity;
78
+ const abortAfterTimestamp = Date.now() + maxExecutionTime;
79
+ const bestPath = [{ oldPos: -1, lastComponent: void 0 }];
80
+ let newPos = this.extractCommon(bestPath[0], newTokens, oldTokens, 0, options);
81
+ if (bestPath[0].oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
82
+ return done(this.buildValues(bestPath[0].lastComponent, newTokens, oldTokens));
83
+ }
84
+ let minDiagonalToConsider = -Infinity, maxDiagonalToConsider = Infinity;
85
+ const execEditLength = () => {
86
+ for (let diagonalPath = Math.max(minDiagonalToConsider, -editLength); diagonalPath <= Math.min(maxDiagonalToConsider, editLength); diagonalPath += 2) {
87
+ let basePath;
88
+ const removePath = bestPath[diagonalPath - 1], addPath = bestPath[diagonalPath + 1];
89
+ if (removePath) {
90
+ bestPath[diagonalPath - 1] = void 0;
91
+ }
92
+ let canAdd = false;
93
+ if (addPath) {
94
+ const addPathNewPos = addPath.oldPos - diagonalPath;
95
+ canAdd = addPath && 0 <= addPathNewPos && addPathNewPos < newLen;
96
+ }
97
+ const canRemove = removePath && removePath.oldPos + 1 < oldLen;
98
+ if (!canAdd && !canRemove) {
99
+ bestPath[diagonalPath] = void 0;
100
+ continue;
101
+ }
102
+ if (!canRemove || canAdd && removePath.oldPos < addPath.oldPos) {
103
+ basePath = this.addToPath(addPath, true, false, 0, options);
104
+ } else {
105
+ basePath = this.addToPath(removePath, false, true, 1, options);
106
+ }
107
+ newPos = this.extractCommon(basePath, newTokens, oldTokens, diagonalPath, options);
108
+ if (basePath.oldPos + 1 >= oldLen && newPos + 1 >= newLen) {
109
+ return done(this.buildValues(basePath.lastComponent, newTokens, oldTokens)) || true;
110
+ } else {
111
+ bestPath[diagonalPath] = basePath;
112
+ if (basePath.oldPos + 1 >= oldLen) {
113
+ maxDiagonalToConsider = Math.min(maxDiagonalToConsider, diagonalPath - 1);
114
+ }
115
+ if (newPos + 1 >= newLen) {
116
+ minDiagonalToConsider = Math.max(minDiagonalToConsider, diagonalPath + 1);
117
+ }
118
+ }
119
+ }
120
+ editLength++;
121
+ };
122
+ if (callback) {
123
+ (function exec() {
124
+ setTimeout(function() {
125
+ if (editLength > maxEditLength || Date.now() > abortAfterTimestamp) {
126
+ return callback(void 0);
127
+ }
128
+ if (!execEditLength()) {
129
+ exec();
130
+ }
131
+ }, 0);
132
+ })();
133
+ } else {
134
+ while (editLength <= maxEditLength && Date.now() <= abortAfterTimestamp) {
135
+ const ret = execEditLength();
136
+ if (ret) {
137
+ return ret;
138
+ }
139
+ }
140
+ }
141
+ }
142
+ addToPath(path, added, removed, oldPosInc, options) {
143
+ const last = path.lastComponent;
144
+ if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
145
+ return {
146
+ oldPos: path.oldPos + oldPosInc,
147
+ lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
148
+ };
149
+ } else {
150
+ return {
151
+ oldPos: path.oldPos + oldPosInc,
152
+ lastComponent: { count: 1, added, removed, previousComponent: last }
153
+ };
154
+ }
155
+ }
156
+ extractCommon(basePath, newTokens, oldTokens, diagonalPath, options) {
157
+ const newLen = newTokens.length, oldLen = oldTokens.length;
158
+ let oldPos = basePath.oldPos, newPos = oldPos - diagonalPath, commonCount = 0;
159
+ while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(oldTokens[oldPos + 1], newTokens[newPos + 1], options)) {
160
+ newPos++;
161
+ oldPos++;
162
+ commonCount++;
163
+ if (options.oneChangePerToken) {
164
+ basePath.lastComponent = { count: 1, previousComponent: basePath.lastComponent, added: false, removed: false };
165
+ }
166
+ }
167
+ if (commonCount && !options.oneChangePerToken) {
168
+ basePath.lastComponent = { count: commonCount, previousComponent: basePath.lastComponent, added: false, removed: false };
169
+ }
170
+ basePath.oldPos = oldPos;
171
+ return newPos;
172
+ }
173
+ equals(left, right, options) {
174
+ if (options.comparator) {
175
+ return options.comparator(left, right);
176
+ } else {
177
+ return left === right || !!options.ignoreCase && left.toLowerCase() === right.toLowerCase();
178
+ }
179
+ }
180
+ removeEmpty(array) {
181
+ const ret = [];
182
+ for (let i = 0; i < array.length; i++) {
183
+ if (array[i]) {
184
+ ret.push(array[i]);
185
+ }
186
+ }
187
+ return ret;
188
+ }
189
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
190
+ castInput(value, options) {
191
+ return value;
192
+ }
193
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
194
+ tokenize(value, options) {
195
+ return Array.from(value);
196
+ }
197
+ join(chars) {
198
+ return chars.join("");
199
+ }
200
+ postProcess(changeObjects, options) {
201
+ return changeObjects;
202
+ }
203
+ get useLongestToken() {
204
+ return false;
205
+ }
206
+ buildValues(lastComponent, newTokens, oldTokens) {
207
+ const components = [];
208
+ let nextComponent;
209
+ while (lastComponent) {
210
+ components.push(lastComponent);
211
+ nextComponent = lastComponent.previousComponent;
212
+ delete lastComponent.previousComponent;
213
+ lastComponent = nextComponent;
214
+ }
215
+ components.reverse();
216
+ const componentLen = components.length;
217
+ let componentPos = 0, newPos = 0, oldPos = 0;
218
+ for (; componentPos < componentLen; componentPos++) {
219
+ const component = components[componentPos];
220
+ if (!component.removed) {
221
+ if (!component.added && this.useLongestToken) {
222
+ let value = newTokens.slice(newPos, newPos + component.count);
223
+ value = value.map(function(value2, i) {
224
+ const oldValue = oldTokens[oldPos + i];
225
+ return oldValue.length > value2.length ? oldValue : value2;
226
+ });
227
+ component.value = this.join(value);
228
+ } else {
229
+ component.value = this.join(newTokens.slice(newPos, newPos + component.count));
230
+ }
231
+ newPos += component.count;
232
+ if (!component.added) {
233
+ oldPos += component.count;
234
+ }
235
+ } else {
236
+ component.value = this.join(oldTokens.slice(oldPos, oldPos + component.count));
237
+ oldPos += component.count;
238
+ }
239
+ }
240
+ return components;
241
+ }
242
+ };
243
+
244
+ // ../../node_modules/.pnpm/diff@9.0.0/node_modules/diff/libesm/diff/line.js
245
+ var LineDiff = class extends Diff {
246
+ constructor() {
247
+ super(...arguments);
248
+ this.tokenize = tokenize;
249
+ }
250
+ equals(left, right, options) {
251
+ if (options.ignoreWhitespace) {
252
+ if (!options.newlineIsToken || !left.includes("\n")) {
253
+ left = left.trim();
254
+ }
255
+ if (!options.newlineIsToken || !right.includes("\n")) {
256
+ right = right.trim();
257
+ }
258
+ } else if (options.ignoreNewlineAtEof && !options.newlineIsToken) {
259
+ if (left.endsWith("\n")) {
260
+ left = left.slice(0, -1);
261
+ }
262
+ if (right.endsWith("\n")) {
263
+ right = right.slice(0, -1);
264
+ }
265
+ }
266
+ return super.equals(left, right, options);
267
+ }
268
+ };
269
+ var lineDiff = new LineDiff();
270
+ function diffLines(oldStr, newStr, options) {
271
+ return lineDiff.diff(oldStr, newStr, options);
272
+ }
273
+ function tokenize(value, options) {
274
+ if (options.stripTrailingCr) {
275
+ value = value.replace(/\r\n/g, "\n");
276
+ }
277
+ const retLines = [], linesAndNewlines = value.split(/(\n|\r\n)/);
278
+ if (!linesAndNewlines[linesAndNewlines.length - 1]) {
279
+ linesAndNewlines.pop();
280
+ }
281
+ for (let i = 0; i < linesAndNewlines.length; i++) {
282
+ const line = linesAndNewlines[i];
283
+ if (i % 2 && !options.newlineIsToken) {
284
+ retLines[retLines.length - 1] += line;
285
+ } else {
286
+ retLines.push(line);
287
+ }
288
+ }
289
+ return retLines;
290
+ }
291
+
292
+ // ../../node_modules/.pnpm/diff@9.0.0/node_modules/diff/libesm/patch/create.js
293
+ function structuredPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader, options) {
294
+ let optionsObj;
295
+ if (!options) {
296
+ optionsObj = {};
297
+ } else if (typeof options === "function") {
298
+ optionsObj = { callback: options };
299
+ } else {
300
+ optionsObj = options;
301
+ }
302
+ if (typeof optionsObj.context === "undefined") {
303
+ optionsObj.context = 4;
304
+ }
305
+ const context = optionsObj.context;
306
+ if (optionsObj.newlineIsToken) {
307
+ throw new Error("newlineIsToken may not be used with patch-generation functions, only with diffing functions");
308
+ }
309
+ if (!optionsObj.callback) {
310
+ return diffLinesResultToPatch(diffLines(oldStr, newStr, optionsObj));
311
+ } else {
312
+ const { callback } = optionsObj;
313
+ diffLines(oldStr, newStr, Object.assign(Object.assign({}, optionsObj), { callback: (diff) => {
314
+ const patch = diffLinesResultToPatch(diff);
315
+ callback(patch);
316
+ } }));
317
+ }
318
+ function diffLinesResultToPatch(diff) {
319
+ if (!diff) {
320
+ return;
321
+ }
322
+ diff.push({ value: "", lines: [] });
323
+ function contextLines(lines) {
324
+ return lines.map(function(entry) {
325
+ return " " + entry;
326
+ });
327
+ }
328
+ const hunks = [];
329
+ let oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
330
+ for (let i = 0; i < diff.length; i++) {
331
+ const current = diff[i], lines = current.lines || splitLines(current.value);
332
+ current.lines = lines;
333
+ if (current.added || current.removed) {
334
+ if (!oldRangeStart) {
335
+ const prev = diff[i - 1];
336
+ oldRangeStart = oldLine;
337
+ newRangeStart = newLine;
338
+ if (prev) {
339
+ curRange = context > 0 ? contextLines(prev.lines.slice(-context)) : [];
340
+ oldRangeStart -= curRange.length;
341
+ newRangeStart -= curRange.length;
342
+ }
343
+ }
344
+ for (const line of lines) {
345
+ curRange.push((current.added ? "+" : "-") + line);
346
+ }
347
+ if (current.added) {
348
+ newLine += lines.length;
349
+ } else {
350
+ oldLine += lines.length;
351
+ }
352
+ } else {
353
+ if (oldRangeStart) {
354
+ if (lines.length <= context * 2 && i < diff.length - 2) {
355
+ for (const line of contextLines(lines)) {
356
+ curRange.push(line);
357
+ }
358
+ } else {
359
+ const contextSize = Math.min(lines.length, context);
360
+ for (const line of contextLines(lines.slice(0, contextSize))) {
361
+ curRange.push(line);
362
+ }
363
+ const hunk = {
364
+ oldStart: oldRangeStart,
365
+ oldLines: oldLine - oldRangeStart + contextSize,
366
+ newStart: newRangeStart,
367
+ newLines: newLine - newRangeStart + contextSize,
368
+ lines: curRange
369
+ };
370
+ hunks.push(hunk);
371
+ oldRangeStart = 0;
372
+ newRangeStart = 0;
373
+ curRange = [];
374
+ }
375
+ }
376
+ oldLine += lines.length;
377
+ newLine += lines.length;
378
+ }
379
+ }
380
+ for (const hunk of hunks) {
381
+ for (let i = 0; i < hunk.lines.length; i++) {
382
+ if (hunk.lines[i].endsWith("\n")) {
383
+ hunk.lines[i] = hunk.lines[i].slice(0, -1);
384
+ } else {
385
+ hunk.lines.splice(i + 1, 0, "\");
386
+ i++;
387
+ }
388
+ }
389
+ }
390
+ return {
391
+ oldFileName,
392
+ newFileName,
393
+ oldHeader,
394
+ newHeader,
395
+ hunks
396
+ };
397
+ }
398
+ }
399
+ function splitLines(text) {
400
+ const hasTrailingNl = text.endsWith("\n");
401
+ const result = text.split("\n").map((line) => line + "\n");
402
+ if (hasTrailingNl) {
403
+ result.pop();
404
+ } else {
405
+ result.push(result.pop().slice(0, -1));
406
+ }
407
+ return result;
408
+ }
409
+
410
+ // ../nmr-core/dist/esm/files/updateManagedFile.js
411
+ function updateManagedFile(filePath, content, options) {
412
+ let existingContent;
413
+ if (existsSync(filePath)) {
414
+ try {
415
+ existingContent = readFileSync(filePath, "utf8");
416
+ } catch (error) {
417
+ return { filePath, outcome: "failed", error: describeError(error) };
418
+ }
419
+ if (existingContent === content) {
420
+ return { filePath, outcome: "up-to-date" };
421
+ }
422
+ }
423
+ const result = existingContent === void 0 ? { filePath, outcome: "created" } : { filePath, outcome: "updated", diff: formatHunks(existingContent, content) };
424
+ if (options.isDryRun) {
425
+ return result;
426
+ }
427
+ try {
428
+ mkdirSync(dirname(filePath), { recursive: true });
429
+ writeFileSync(filePath, content, "utf8");
430
+ } catch (error) {
431
+ return { filePath, outcome: "failed", error: describeError(error) };
432
+ }
433
+ return result;
434
+ }
435
+ function formatHunks(oldContent, newContent) {
436
+ const { hunks } = structuredPatch("", "", oldContent, newContent, void 0, void 0, { context: 3 });
437
+ return hunks.flatMap((hunk) => [
438
+ `@@ -${String(hunk.oldStart)},${String(hunk.oldLines)} +${String(hunk.newStart)},${String(hunk.newLines)} @@`,
439
+ ...hunk.lines.filter((line) => !line.startsWith("\\"))
440
+ ]).join("\n");
441
+ }
20
442
 
21
443
  // ../nmr-core/dist/esm/portable/isRecord.js
22
444
  function isRecord(value) {
@@ -36,11 +458,11 @@ function parseJsonRecord(jsonText) {
36
458
 
37
459
  // src/init/detectRepoType.ts
38
460
  function detectRepoType() {
39
- if (existsSync("pnpm-workspace.yaml")) {
461
+ if (existsSync2("pnpm-workspace.yaml")) {
40
462
  return "monorepo";
41
463
  }
42
- if (existsSync("package.json")) {
43
- const manifestJson = readFileSync("package.json", "utf8");
464
+ if (existsSync2("package.json")) {
465
+ const manifestJson = readFileSync2("package.json", "utf8");
44
466
  const packageJson = parseJsonRecord(manifestJson);
45
467
  if (packageJson !== void 0 && Array.isArray(packageJson["workspaces"])) {
46
468
  return "monorepo";
@@ -49,6 +471,150 @@ function detectRepoType() {
49
471
  return "single-package";
50
472
  }
51
473
 
474
+ // src/init/managed-workflows.ts
475
+ import { existsSync as existsSync3, readFileSync as readFileSync3 } from "node:fs";
476
+
477
+ // src/init/hasProvenance.ts
478
+ function hasProvenance(workflowContent) {
479
+ return /^[^#]*provenance:\s*['"]?true['"]?/im.test(workflowContent);
480
+ }
481
+
482
+ // src/init/templates.ts
483
+ function renderPublishWorkflow(repoType, { shouldGenerateProvenance = true } = {}) {
484
+ const tagPattern = repoType === "monorepo" ? "'*-v[0-9]*.[0-9]*.[0-9]*'" : "'v[0-9]*.[0-9]*.[0-9]*'";
485
+ return `# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
486
+ name: Publish
487
+
488
+ on:
489
+ push:
490
+ tags:
491
+ - ${tagPattern}
492
+
493
+ permissions:
494
+ id-token: write
495
+ contents: read
496
+
497
+ jobs:
498
+ publish:
499
+ uses: williamthorsen/node-monorepo-tools/.github/workflows/publish.reusable.yaml@workflow/publish-v1
500
+ with:
501
+ ${shouldGenerateProvenance ? " provenance: true\n" : ""} tags: \${{ github.ref_name }}
502
+ `;
503
+ }
504
+ function renderCreateGithubReleaseWorkflow(repoType) {
505
+ const tagPattern = repoType === "monorepo" ? "'*-v[0-9]*.[0-9]*.[0-9]*'" : "'v[0-9]*.[0-9]*.[0-9]*'";
506
+ return `# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
507
+ name: Create GitHub release
508
+
509
+ on:
510
+ push:
511
+ tags:
512
+ - ${tagPattern}
513
+
514
+ permissions:
515
+ contents: write
516
+
517
+ jobs:
518
+ create-github-release:
519
+ uses: williamthorsen/node-monorepo-tools/.github/workflows/create-github-release.reusable.yaml@workflow/create-github-release-v1
520
+ with:
521
+ tag: \${{ github.ref_name }}
522
+ `;
523
+ }
524
+ function renderReleaseWorkflow(repoType) {
525
+ if (repoType === "monorepo") {
526
+ return `# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
527
+ name: Release
528
+
529
+ on:
530
+ workflow_dispatch:
531
+ inputs:
532
+ only:
533
+ description: 'Release targets to release, with their dependents (comma-separated, leave empty for all)'
534
+ required: false
535
+ type: string
536
+ bump:
537
+ description: 'Version bump type (auto detects it from commits)'
538
+ required: false
539
+ type: choice
540
+ default: auto
541
+ options:
542
+ - auto
543
+ - patch
544
+ - minor
545
+ - major
546
+ force:
547
+ description: 'Force a release even when there are not any commits, or any bump-worthy commits, since the last release (defaults to patch; combine with --bump for a different level)'
548
+ required: false
549
+ type: boolean
550
+ default: false
551
+
552
+ permissions:
553
+ contents: write
554
+ packages: read
555
+
556
+ jobs:
557
+ release:
558
+ uses: williamthorsen/node-monorepo-tools/.github/workflows/release.reusable.yaml@workflow/release-v1
559
+ with:
560
+ only: \${{ inputs.only }}
561
+ bump: \${{ inputs.bump != 'auto' && inputs.bump || '' }}
562
+ force: \${{ inputs.force }}
563
+ `;
564
+ }
565
+ return `# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
566
+ name: Release
567
+
568
+ on:
569
+ workflow_dispatch:
570
+ inputs:
571
+ bump:
572
+ description: 'Version bump type (auto detects it from commits)'
573
+ required: false
574
+ type: choice
575
+ default: auto
576
+ options:
577
+ - auto
578
+ - patch
579
+ - minor
580
+ - major
581
+ force:
582
+ description: 'Force a release even when there are not any commits, or any bump-worthy commits, since the last release (defaults to patch; combine with --bump for a different level)'
583
+ required: false
584
+ type: boolean
585
+ default: false
586
+
587
+ permissions:
588
+ contents: write
589
+ packages: read
590
+
591
+ jobs:
592
+ release:
593
+ uses: williamthorsen/node-monorepo-tools/.github/workflows/release.reusable.yaml@workflow/release-v1
594
+ with:
595
+ bump: \${{ inputs.bump != 'auto' && inputs.bump || '' }}
596
+ force: \${{ inputs.force }}
597
+ `;
598
+ }
599
+
600
+ // src/init/scaffold.ts
601
+ var PUBLISH_WORKFLOW_PATH = ".github/workflows/publish.yaml";
602
+
603
+ // src/init/managed-workflows.ts
604
+ function renderExpectedCreateGithubReleaseWorkflow(repoType) {
605
+ return renderCreateGithubReleaseWorkflow(repoType);
606
+ }
607
+ function renderExpectedPublishWorkflow(repoType) {
608
+ return renderPublishWorkflow(repoType, { shouldGenerateProvenance: readProvenanceSetting() });
609
+ }
610
+ function renderExpectedReleaseWorkflow(repoType) {
611
+ return renderReleaseWorkflow(repoType);
612
+ }
613
+ function readProvenanceSetting() {
614
+ if (!existsSync3(PUBLISH_WORKFLOW_PATH)) return true;
615
+ return hasProvenance(readFileSync3(PUBLISH_WORKFLOW_PATH, "utf8"));
616
+ }
617
+
52
618
  // .readyup/lib/changelog-checks.ts
53
619
  import { discoverWorkspaces, readFile } from "readyup/check-utils";
54
620
 
@@ -222,19 +788,29 @@ function stripYamlQuotes(value) {
222
788
  return match?.[2] ?? value;
223
789
  }
224
790
 
791
+ // .readyup/lib/template-checks.ts
792
+ function fileMatchesTemplate(filePath, expected) {
793
+ const result = updateManagedFile(filePath, expected, { isDryRun: true });
794
+ switch (result.outcome) {
795
+ case "up-to-date":
796
+ return { ok: true };
797
+ case "updated":
798
+ return { ok: false, detail: `${filePath} differs from the template:
799
+ ${result.diff ?? ""}` };
800
+ case "created":
801
+ return { ok: false, detail: `${filePath} is missing` };
802
+ case "failed":
803
+ return { ok: false, detail: `${filePath} could not be read: ${result.error ?? "unknown error"}` };
804
+ }
805
+ }
806
+
225
807
  // .readyup/lib/workflow-hashes.ts
226
808
  var COMMON_PRESET_HASH = "945ee6d9f69365b0c8c5e20e9fed5b7ef7eee418fa28bf3602a21a48d293ed03";
227
809
  var SYNC_LABELS_WORKFLOW_HASH = "0a88829d154c0de7cdd4246fede99e9311a89ab4199034dbe601663d641ab1e4";
228
- var RELEASE_WORKFLOW_HASH_MONOREPO = "f63f4cabb57f94ee6550f17a9874c7a346d46554595ddbcd46fdd3208d613437";
229
- var RELEASE_WORKFLOW_HASH_SINGLE = "d26dd4ca186632b388ea46bd885721124c03d19918e511baa40821d2d760da69";
230
- var PUBLISH_WORKFLOW_HASH_MONOREPO = "0afa9ffe914f3dc8f043e68252ebc604c8cc1a953422fcea37a909a4def370ee";
231
- var PUBLISH_WORKFLOW_HASH_SINGLE = "6f31183e0a1e66be791a19266c3b028dadbd9fe010f7fc4452f3f8970c937b43";
232
- var CREATE_GITHUB_RELEASE_WORKFLOW_HASH_MONOREPO = "cd8f8aa8ad1d3d080e5d5826baa1f70c0be019c5233fdb0d22aa31f11664852a";
233
- var CREATE_GITHUB_RELEASE_WORKFLOW_HASH_SINGLE = "d6de961de913c67b08dfa7e07f73499ae57102919c124aa50836de08443ae26b";
234
810
 
235
811
  // .readyup/kits/default.ts
236
812
  function getMinVersion() {
237
- const picked = { "version": "18.1.1" };
813
+ const picked = { "version": "18.2.0" };
238
814
  if (typeof picked["version"] !== "string") {
239
815
  throw new TypeError("release-kit/package.json: 'version' must be a string");
240
816
  }
@@ -277,10 +853,7 @@ var default_default = defineRdyKit({
277
853
  {
278
854
  name: "release.yaml matches template",
279
855
  severity: "warn",
280
- check: () => {
281
- const hash = detectRepoType() === "monorepo" ? RELEASE_WORKFLOW_HASH_MONOREPO : RELEASE_WORKFLOW_HASH_SINGLE;
282
- return fileMatchesHash(".github/workflows/release.yaml", hash);
283
- },
856
+ check: () => fileMatchesTemplate(".github/workflows/release.yaml", renderExpectedReleaseWorkflow(detectRepoType())),
284
857
  fix: "Run `release-kit update-templates` to regenerate release.yaml from the current template"
285
858
  },
286
859
  {
@@ -302,10 +875,7 @@ var default_default = defineRdyKit({
302
875
  {
303
876
  name: "publish.yaml matches template",
304
877
  severity: "warn",
305
- check: () => {
306
- const hash = detectRepoType() === "monorepo" ? PUBLISH_WORKFLOW_HASH_MONOREPO : PUBLISH_WORKFLOW_HASH_SINGLE;
307
- return fileMatchesHash(".github/workflows/publish.yaml", hash);
308
- },
878
+ check: () => fileMatchesTemplate(".github/workflows/publish.yaml", renderExpectedPublishWorkflow(detectRepoType())),
309
879
  fix: "Run `release-kit update-templates` to regenerate publish.yaml from the current template"
310
880
  },
311
881
  {
@@ -321,10 +891,10 @@ var default_default = defineRdyKit({
321
891
  name: "create-github-release.yaml matches template",
322
892
  severity: "warn",
323
893
  skip: () => !fileExists(".github/workflows/create-github-release.yaml") && "no create-github-release workflow (GitHub Releases not adopted)",
324
- check: () => {
325
- const hash = detectRepoType() === "monorepo" ? CREATE_GITHUB_RELEASE_WORKFLOW_HASH_MONOREPO : CREATE_GITHUB_RELEASE_WORKFLOW_HASH_SINGLE;
326
- return fileMatchesHash(".github/workflows/create-github-release.yaml", hash);
327
- },
894
+ check: () => fileMatchesTemplate(
895
+ ".github/workflows/create-github-release.yaml",
896
+ renderExpectedCreateGithubReleaseWorkflow(detectRepoType())
897
+ ),
328
898
  fix: "Run `release-kit update-templates` to regenerate create-github-release.yaml from the current template"
329
899
  },
330
900
  {
@@ -349,6 +919,7 @@ var default_default = defineRdyKit({
349
919
  {
350
920
  name: "releaseNotes.shouldInjectIntoReadme is true",
351
921
  severity: "warn",
922
+ skip: () => !hasPublishablePackages() && "no publishable packages",
352
923
  check: () => releaseNotesInjectsIntoReadme(),
353
924
  fix: "Set releaseNotes.shouldInjectIntoReadme to true in .config/release-kit.config.ts",
354
925
  checks: [
@@ -461,13 +1032,6 @@ var default_default = defineRdyKit({
461
1032
  quiet: true,
462
1033
  check: () => fileDoesNotContain(".github/workflows/sync-labels.yaml", /@sync-labels-workflow-v[0-9]/),
463
1034
  fix: "Update sync-labels.yaml to use @workflow/sync-labels-v1 (run `release-kit update-templates` to regenerate, or replace the ref manually)"
464
- },
465
- {
466
- name: "retired .config/sync-labels.config.ts is absent",
467
- severity: "error",
468
- quiet: true,
469
- check: () => !fileExists(".config/sync-labels.config.ts"),
470
- fix: "Move the labels into the repoLabels block of .config/release-kit.config.ts, then delete .config/sync-labels.config.ts"
471
1035
  }
472
1036
  ]
473
1037
  }