@williamthorsen/release-kit 10.5.0 โ 10.7.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.
- package/.meta/changelog.json +1570 -0
- package/.readyup/kits/default.js +127 -4
- package/.readyup/kits/npm-auto-publish.js +87 -23
- package/.readyup/manifest.json +14 -9
- package/CHANGELOG.md +83 -0
- package/README.md +68 -963
- package/dist/esm/bin/release-kit.js +4 -3
- package/dist/esm/buildChangelogEntries.js +5 -0
- package/dist/esm/buildDependencyGraph.d.ts +6 -5
- package/dist/esm/buildDependencyGraph.js +5 -1
- package/dist/esm/changelogJsonUtils.d.ts +5 -7
- package/dist/esm/changelogJsonUtils.js +0 -13
- package/dist/esm/changelogOverrides.js +8 -0
- package/dist/esm/extractMigration.d.ts +14 -0
- package/dist/esm/extractMigration.js +18 -0
- package/dist/esm/init/scaffold.js +14 -6
- package/dist/esm/packsPath.d.ts +15 -0
- package/dist/esm/packsPath.js +47 -0
- package/dist/esm/planVersionBump.d.ts +2 -1
- package/dist/esm/planVersionBump.js +4 -0
- package/dist/esm/propagateBumps.d.ts +1 -3
- package/dist/esm/propagateBumps.js +2 -2
- package/dist/esm/releasePrepare.js +0 -16
- package/dist/esm/releasePrepareMono.js +3 -24
- package/dist/esm/reportPrepare.js +4 -2
- package/dist/esm/runGitCliff.d.ts +16 -23
- package/dist/esm/runGitCliff.js +4 -10
- package/dist/esm/sync-labels/resolveLabels.d.ts +5 -3
- package/dist/esm/sync-labels/resolveLabels.js +21 -6
- package/dist/esm/types.d.ts +13 -2
- package/dist/esm/validateConfig.js +1 -1
- package/docs/api.md +73 -0
- package/docs/changelogs.md +70 -0
- package/docs/configuration.md +105 -0
- package/docs/editorial-overrides.md +144 -0
- package/docs/labels.md +83 -0
- package/docs/project-releases.md +74 -0
- package/docs/publishing.md +30 -0
- package/docs/readiness-checks.md +18 -0
- package/docs/releasing.md +108 -0
- package/docs/work-types.md +121 -0
- package/package.json +16 -12
- package/dist/esm/readCurrentVersion.d.ts +0 -2
- package/dist/esm/readCurrentVersion.js +0 -18
package/.readyup/kits/default.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @noformat -- @generated. Do not edit. Compiled by rdy. */
|
|
2
2
|
/* eslint-disable */
|
|
3
|
-
export const __readyupVersion = "0.
|
|
3
|
+
export const __readyupVersion = "0.36.0";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
// .readyup/kits/default.ts
|
|
@@ -50,9 +50,55 @@ function detectRepoType() {
|
|
|
50
50
|
return "single-package";
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// src/packsPath.ts
|
|
54
|
+
function packsPath(filesField, path) {
|
|
55
|
+
if (!isStringArray(filesField)) return true;
|
|
56
|
+
const prefixes = listAncestorPrefixes(path);
|
|
57
|
+
return filesField.some((entry) => {
|
|
58
|
+
const pattern = compileEntry(entry);
|
|
59
|
+
return pattern !== void 0 && prefixes.some((prefix) => pattern.test(prefix));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
var GLOB_TOKEN_PATTERN = /\*\*\/|\*\*|\*|\?|[^*?]+/g;
|
|
63
|
+
function compileEntry(entry) {
|
|
64
|
+
if (entry.startsWith("!")) return void 0;
|
|
65
|
+
const normalized = entry.replace(/^\.?\//, "").replace(/\/+$/, "");
|
|
66
|
+
if (normalized === "") return void 0;
|
|
67
|
+
return new RegExp(`^${translateGlob(normalized)}$`);
|
|
68
|
+
}
|
|
69
|
+
function isStringArray(value) {
|
|
70
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
71
|
+
}
|
|
72
|
+
function listAncestorPrefixes(path) {
|
|
73
|
+
const segments = path.split("/");
|
|
74
|
+
return segments.map((_segment, index) => segments.slice(0, index + 1).join("/"));
|
|
75
|
+
}
|
|
76
|
+
function translateGlob(pattern) {
|
|
77
|
+
let source = "";
|
|
78
|
+
for (const [token] of pattern.matchAll(GLOB_TOKEN_PATTERN)) {
|
|
79
|
+
switch (token) {
|
|
80
|
+
case "**/":
|
|
81
|
+
source += String.raw`(?:[^/]*\/)*`;
|
|
82
|
+
break;
|
|
83
|
+
case "**":
|
|
84
|
+
source += ".*";
|
|
85
|
+
break;
|
|
86
|
+
case "*":
|
|
87
|
+
source += "[^/]*";
|
|
88
|
+
break;
|
|
89
|
+
case "?":
|
|
90
|
+
source += "[^/]";
|
|
91
|
+
break;
|
|
92
|
+
default:
|
|
93
|
+
source += RegExp.escape(token);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return source;
|
|
97
|
+
}
|
|
98
|
+
|
|
53
99
|
// .readyup/kits/default.ts
|
|
54
100
|
function getMinVersion() {
|
|
55
|
-
const picked = { "version": "10.
|
|
101
|
+
const picked = { "version": "10.7.0" };
|
|
56
102
|
if (typeof picked["version"] !== "string") {
|
|
57
103
|
throw new TypeError("release-kit/package.json: 'version' must be a string");
|
|
58
104
|
}
|
|
@@ -61,6 +107,7 @@ function getMinVersion() {
|
|
|
61
107
|
function hasPublishablePackages() {
|
|
62
108
|
return discoverWorkspaces({ filter: (w) => w.isPackage }).length > 0;
|
|
63
109
|
}
|
|
110
|
+
var DEFAULT_CHANGELOG_JSON_PATH = ".meta/changelog.json";
|
|
64
111
|
var CONFIG_EXPORT_PATTERNS = [
|
|
65
112
|
/export\s+default\b/,
|
|
66
113
|
/export\s+(?:const|let|var)\s+config\b/,
|
|
@@ -74,6 +121,8 @@ var RELEASE_WORKFLOW_HASH_MONOREPO = "0a9724b7b3c5e24087fd3a8f36fed8e990d699267f
|
|
|
74
121
|
var RELEASE_WORKFLOW_HASH_SINGLE = "a3d19bbc1ba8bb30622e53c590137b97e3179e80988c0967737b021cdaeab73f";
|
|
75
122
|
var PUBLISH_WORKFLOW_HASH_MONOREPO = "0afa9ffe914f3dc8f043e68252ebc604c8cc1a953422fcea37a909a4def370ee";
|
|
76
123
|
var PUBLISH_WORKFLOW_HASH_SINGLE = "6f31183e0a1e66be791a19266c3b028dadbd9fe010f7fc4452f3f8970c937b43";
|
|
124
|
+
var CREATE_GITHUB_RELEASE_WORKFLOW_HASH_MONOREPO = "c455d88c93d855737c96079945ff729a9d094f846519c24afbefe83a425c1d7f";
|
|
125
|
+
var CREATE_GITHUB_RELEASE_WORKFLOW_HASH_SINGLE = "f595831ff28f8b3a01d97e6cb0cfe100262f7a8821091c6c458b0c0224cebba8";
|
|
77
126
|
var default_default = defineRdyKit({
|
|
78
127
|
checklists: [
|
|
79
128
|
{
|
|
@@ -148,6 +197,16 @@ var default_default = defineRdyKit({
|
|
|
148
197
|
}
|
|
149
198
|
]
|
|
150
199
|
},
|
|
200
|
+
{
|
|
201
|
+
name: "create-github-release.yaml matches template",
|
|
202
|
+
severity: "warn",
|
|
203
|
+
skip: () => !fileExists(".github/workflows/create-github-release.yaml") ? "no create-github-release workflow (GitHub Releases not adopted)" : false,
|
|
204
|
+
check: () => {
|
|
205
|
+
const hash = detectRepoType() === "monorepo" ? CREATE_GITHUB_RELEASE_WORKFLOW_HASH_MONOREPO : CREATE_GITHUB_RELEASE_WORKFLOW_HASH_SINGLE;
|
|
206
|
+
return fileMatchesHash(".github/workflows/create-github-release.yaml", hash);
|
|
207
|
+
},
|
|
208
|
+
fix: "Run `release-kit init --force` to regenerate create-github-release.yaml from the current template"
|
|
209
|
+
},
|
|
151
210
|
{
|
|
152
211
|
name: ".config/release-kit.config.ts exports a config",
|
|
153
212
|
severity: "error",
|
|
@@ -204,12 +263,38 @@ var default_default = defineRdyKit({
|
|
|
204
263
|
}
|
|
205
264
|
]
|
|
206
265
|
},
|
|
266
|
+
// Deliberately outside the config gate above: that check skips where the config file is absent, and a repo
|
|
267
|
+
// with no config file still defaults `changelogJson.enabled` to true and still publishes tarballs.
|
|
268
|
+
{
|
|
269
|
+
name: "published packages ship CHANGELOG.md",
|
|
270
|
+
severity: "warn",
|
|
271
|
+
skip: () => !hasPublishablePackages() ? "no publishable packages" : false,
|
|
272
|
+
check: () => packagesShipChangelog(),
|
|
273
|
+
fix: 'Add "CHANGELOG.md" to the files field of each affected package.json'
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
name: "changelog.json generation is enabled",
|
|
277
|
+
severity: "recommend",
|
|
278
|
+
skip: () => !hasPublishablePackages() ? "no publishable packages" : false,
|
|
279
|
+
check: () => changelogJsonIsEnabled(),
|
|
280
|
+
fix: "Remove changelogJson.enabled: false from .config/release-kit.config.ts so release-kit writes the machine-readable changelog that upgrade tooling reads before CHANGELOG.md",
|
|
281
|
+
checks: [
|
|
282
|
+
{
|
|
283
|
+
name: "published packages ship the changelog JSON",
|
|
284
|
+
severity: "warn",
|
|
285
|
+
check: () => packagesShipChangelogJson(),
|
|
286
|
+
get fix() {
|
|
287
|
+
return `Add "${resolveChangelogJsonOutputPath()}" to the files field of each affected package.json`;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
]
|
|
291
|
+
},
|
|
207
292
|
{
|
|
208
293
|
name: "config does not use removed releaseNotes.shouldCreateGithubRelease",
|
|
209
294
|
severity: "error",
|
|
210
295
|
quiet: true,
|
|
211
296
|
check: () => fileDoesNotContain(".config/release-kit.config.ts", /shouldCreateGithubRelease/),
|
|
212
|
-
fix: "Remove 'shouldCreateGithubRelease' from .config/release-kit.config.ts. Adoption of GitHub Releases is now signaled by installing the create-github-release workflow
|
|
297
|
+
fix: "Remove 'shouldCreateGithubRelease' from .config/release-kit.config.ts. Adoption of GitHub Releases is now signaled by installing the create-github-release workflow, which `release-kit init` scaffolds."
|
|
213
298
|
},
|
|
214
299
|
{
|
|
215
300
|
name: "git-cliff not in devDependencies",
|
|
@@ -264,6 +349,11 @@ var default_default = defineRdyKit({
|
|
|
264
349
|
}
|
|
265
350
|
]
|
|
266
351
|
});
|
|
352
|
+
function changelogJsonIsEnabled() {
|
|
353
|
+
const content = readFile(".config/release-kit.config.ts");
|
|
354
|
+
if (content === void 0) return true;
|
|
355
|
+
return !/changelogJson\s*:\s*\{[^}]*enabled\s*:\s*false/.test(content);
|
|
356
|
+
}
|
|
267
357
|
function configFileExportsConfig() {
|
|
268
358
|
const content = readFile(".config/release-kit.config.ts");
|
|
269
359
|
if (content === void 0) return false;
|
|
@@ -276,6 +366,12 @@ function labelsHaveCurrentPresetHash(presetName, expectedHash) {
|
|
|
276
366
|
const match = pattern.exec(content);
|
|
277
367
|
return match !== null && match[1] === expectedHash;
|
|
278
368
|
}
|
|
369
|
+
function packagesShipChangelog() {
|
|
370
|
+
return reportWorkspacesOmitting("CHANGELOG.md");
|
|
371
|
+
}
|
|
372
|
+
function packagesShipChangelogJson() {
|
|
373
|
+
return reportWorkspacesOmitting(resolveChangelogJsonOutputPath());
|
|
374
|
+
}
|
|
279
375
|
function readmeHasReleaseNotesMarkers(content) {
|
|
280
376
|
return content.includes("<!-- section:release-notes -->") && content.includes("<!-- /section:release-notes -->");
|
|
281
377
|
}
|
|
@@ -308,16 +404,43 @@ function releaseNotesInjectsIntoReadme() {
|
|
|
308
404
|
if (content === void 0) return false;
|
|
309
405
|
return /shouldInjectIntoReadme\s*:\s*true/.test(content);
|
|
310
406
|
}
|
|
407
|
+
function reportWorkspacesOmitting(path) {
|
|
408
|
+
const failing = [];
|
|
409
|
+
const packageWorkspaces = discoverWorkspaces({ filter: (w) => w.isPackage });
|
|
410
|
+
for (const { dir, packageJson } of packageWorkspaces) {
|
|
411
|
+
if (!packsPath(packageJson["files"], path)) {
|
|
412
|
+
failing.push(dir === "." ? "package.json" : `${dir}/package.json`);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (failing.length === 0) return true;
|
|
416
|
+
return {
|
|
417
|
+
ok: false,
|
|
418
|
+
detail: `files field omits ${path}: ${failing.join(", ")}`
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
function resolveChangelogJsonOutputPath() {
|
|
422
|
+
const content = readFile(".config/release-kit.config.ts");
|
|
423
|
+
if (content === void 0) return DEFAULT_CHANGELOG_JSON_PATH;
|
|
424
|
+
const match = /changelogJson\s*:\s*\{[^}]*outputPath\s*:\s*['"]([^'"]+)['"]/.exec(content);
|
|
425
|
+
return match?.[1] ?? DEFAULT_CHANGELOG_JSON_PATH;
|
|
426
|
+
}
|
|
311
427
|
export {
|
|
312
428
|
CLIFF_TEMPLATE_HASH,
|
|
313
429
|
COMMON_PRESET_HASH,
|
|
430
|
+
CREATE_GITHUB_RELEASE_WORKFLOW_HASH_MONOREPO,
|
|
431
|
+
CREATE_GITHUB_RELEASE_WORKFLOW_HASH_SINGLE,
|
|
432
|
+
DEFAULT_CHANGELOG_JSON_PATH,
|
|
314
433
|
PUBLISH_WORKFLOW_HASH_MONOREPO,
|
|
315
434
|
PUBLISH_WORKFLOW_HASH_SINGLE,
|
|
316
435
|
RELEASE_WORKFLOW_HASH_MONOREPO,
|
|
317
436
|
RELEASE_WORKFLOW_HASH_SINGLE,
|
|
318
437
|
SYNC_LABELS_WORKFLOW_HASH,
|
|
438
|
+
changelogJsonIsEnabled,
|
|
319
439
|
configFileExportsConfig,
|
|
320
440
|
default_default as default,
|
|
441
|
+
packagesShipChangelog,
|
|
442
|
+
packagesShipChangelogJson,
|
|
321
443
|
readmeHasReleaseNotesMarkers,
|
|
322
|
-
readmesHaveReleaseNotesMarkers
|
|
444
|
+
readmesHaveReleaseNotesMarkers,
|
|
445
|
+
resolveChangelogJsonOutputPath
|
|
323
446
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @noformat -- @generated. Do not edit. Compiled by rdy. */
|
|
2
2
|
/* eslint-disable */
|
|
3
|
-
export const __readyupVersion = "0.
|
|
3
|
+
export const __readyupVersion = "0.36.0";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
// .readyup/kits/npm-auto-publish.ts
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
readJsonFile
|
|
19
19
|
} from "readyup/check-utils";
|
|
20
20
|
var AUTH_ERROR_CODES = /* @__PURE__ */ new Set(["E401", "ENEEDAUTH"]);
|
|
21
|
+
var OTP_ERROR_CODE = "EOTP";
|
|
21
22
|
var PUBLISH_WORKFLOW_FILE = "publish.yaml";
|
|
22
23
|
var UNREACHABLE_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
23
24
|
"EAI_AGAIN",
|
|
@@ -77,24 +78,19 @@ var packagesChecklist = defineRdyChecklist({
|
|
|
77
78
|
fix: "Ensure pnpm-workspace.yaml lists package globs, or that a root package.json exists"
|
|
78
79
|
}
|
|
79
80
|
],
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
},
|
|
88
|
-
// readyup reads `fix` before it consults `skip`, and again when it validates the kit, so a getter here would
|
|
89
|
-
// reach the registry on every run regardless of the skip. Per-outcome wording goes in the check's detail.
|
|
90
|
-
fix: 'Restore a usable npm session: log in with "npm login", or restore access to the registry, which the trusted-publisher check queries directly',
|
|
91
|
-
get checks() {
|
|
92
|
-
return discoverWorkspaces({ filter: belongsInPackagesChecklist }).map(
|
|
93
|
-
(workspace) => buildWorkspaceCheck(workspace)
|
|
94
|
-
);
|
|
95
|
-
}
|
|
81
|
+
// The gate stands beside the workspace rows rather than above them, so a session that cannot answer trust queries
|
|
82
|
+
// suppresses the trusted-publisher rows alone and leaves the package.json checks reporting. The rows no longer
|
|
83
|
+
// hang beneath the gate's skip, so a repo that publishes nothing has to be held to its one line here.
|
|
84
|
+
get checks() {
|
|
85
|
+
const sessionCheck = buildSessionCheck();
|
|
86
|
+
if (skipIfNothingPublishable() !== false) {
|
|
87
|
+
return [sessionCheck];
|
|
96
88
|
}
|
|
97
|
-
|
|
89
|
+
return [
|
|
90
|
+
sessionCheck,
|
|
91
|
+
...discoverWorkspaces({ filter: belongsInPackagesChecklist }).map((workspace) => buildWorkspaceCheck(workspace))
|
|
92
|
+
];
|
|
93
|
+
}
|
|
98
94
|
});
|
|
99
95
|
var npm_auto_publish_default = defineRdyKit({
|
|
100
96
|
fixLocation: "inline",
|
|
@@ -103,6 +99,19 @@ var npm_auto_publish_default = defineRdyKit({
|
|
|
103
99
|
function belongsInPackagesChecklist(workspace) {
|
|
104
100
|
return !workspace.isRoot || workspace.isPackage;
|
|
105
101
|
}
|
|
102
|
+
function buildSessionCheck() {
|
|
103
|
+
return {
|
|
104
|
+
name: "npm session can answer trust queries",
|
|
105
|
+
skip: () => skipIfNothingPublishable(),
|
|
106
|
+
check: () => {
|
|
107
|
+
const capability = getCachedTrustCapability();
|
|
108
|
+
return capability.ok ? { ok: true } : { ok: false, detail: capability.detail };
|
|
109
|
+
},
|
|
110
|
+
// A plain string rather than a getter, because readyup takes outcome-specific wording in `detail`, which the
|
|
111
|
+
// check above already carries.
|
|
112
|
+
fix: 'Restore a usable npm session: log in with "npm login", supplying the one-time password when prompted, or restore access to the registry, which the trusted-publisher check queries directly'
|
|
113
|
+
};
|
|
114
|
+
}
|
|
106
115
|
function buildWorkspaceCheck(workspace) {
|
|
107
116
|
const displayName = workspace.name ?? "(unnamed)";
|
|
108
117
|
const pkgJsonPath = path.join(workspace.dir, "package.json");
|
|
@@ -126,11 +135,22 @@ function buildWorkspaceCheck(workspace) {
|
|
|
126
135
|
children.push(
|
|
127
136
|
{
|
|
128
137
|
name: "published to npm",
|
|
138
|
+
// `npm view` reads the registry without a session, so a missing login or a missing one-time password leaves
|
|
139
|
+
// this answerable. An unreachable registry does not: the lookup fails for every package, and reporting that
|
|
140
|
+
// as unpublished would advise publishing a package that is already there.
|
|
141
|
+
skip: () => {
|
|
142
|
+
const auth = getCachedNpmAuthStatus();
|
|
143
|
+
return auth.status === "unreachable" ? auth.detail : false;
|
|
144
|
+
},
|
|
129
145
|
check: () => isPublishedToNpm(displayName),
|
|
130
146
|
fix: `Run "npm publish --access public" from ${workspace.dir} to bootstrap the package on npm`,
|
|
131
147
|
checks: [
|
|
132
148
|
{
|
|
133
149
|
name: "trusted publisher configured",
|
|
150
|
+
skip: () => {
|
|
151
|
+
const capability = getCachedTrustCapability();
|
|
152
|
+
return capability.ok ? false : capability.detail;
|
|
153
|
+
},
|
|
134
154
|
check: () => checkTrustedPublisher(displayName),
|
|
135
155
|
get fix() {
|
|
136
156
|
return `Run: npm trust github ${displayName} --repo ${getCachedOwnerRepo()} --file ${PUBLISH_WORKFLOW_FILE}`;
|
|
@@ -180,11 +200,7 @@ function checkProvenanceMatchesVisibility() {
|
|
|
180
200
|
return { ok: true };
|
|
181
201
|
}
|
|
182
202
|
function checkTrustedPublisher(packageName) {
|
|
183
|
-
const result =
|
|
184
|
-
runNpmJson(`npm trust list ${packageName} --json`),
|
|
185
|
-
getCachedOwnerRepo(),
|
|
186
|
-
PUBLISH_WORKFLOW_FILE
|
|
187
|
-
);
|
|
203
|
+
const result = getTrustQueryResult(packageName);
|
|
188
204
|
switch (result.status) {
|
|
189
205
|
case "configured":
|
|
190
206
|
return { ok: true };
|
|
@@ -210,6 +226,12 @@ function classifyNpmAuth(result) {
|
|
|
210
226
|
}
|
|
211
227
|
return { status: "unreachable", detail: `The npm registry query failed (${error.code}): ${error.summary}` };
|
|
212
228
|
}
|
|
229
|
+
function classifyTrustCapability(auth, probe) {
|
|
230
|
+
if (auth.status !== "authenticated") {
|
|
231
|
+
return { ok: false, detail: auth.detail };
|
|
232
|
+
}
|
|
233
|
+
return probe?.status === "unanswerable" ? { ok: false, detail: probe.detail } : { ok: true };
|
|
234
|
+
}
|
|
213
235
|
function classifyTrustQuery(result, expectedRepo, expectedFile) {
|
|
214
236
|
if (!result.exitOk) {
|
|
215
237
|
const error = readNpmError(result.stdout);
|
|
@@ -219,6 +241,15 @@ function classifyTrustQuery(result, expectedRepo, expectedFile) {
|
|
|
219
241
|
if (error.code === "E404") {
|
|
220
242
|
return { status: "not-configured" };
|
|
221
243
|
}
|
|
244
|
+
if (AUTH_ERROR_CODES.has(error.code) || error.code === OTP_ERROR_CODE) {
|
|
245
|
+
return {
|
|
246
|
+
status: "unanswerable",
|
|
247
|
+
detail: `The npm session cannot answer trust queries (${error.code}): ${error.summary}`
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
if (UNREACHABLE_ERROR_CODES.has(error.code)) {
|
|
251
|
+
return { status: "unanswerable", detail: `Cannot reach the npm registry (${error.code})` };
|
|
252
|
+
}
|
|
222
253
|
return { status: "error", detail: `The npm trust query failed (${error.code}): ${error.summary}` };
|
|
223
254
|
}
|
|
224
255
|
const relationships = readTrustRelationships(result.stdout);
|
|
@@ -252,6 +283,10 @@ var getCachedOwnerRepo = /* @__PURE__ */ (() => {
|
|
|
252
283
|
let cached;
|
|
253
284
|
return () => cached ??= getOwnerRepo();
|
|
254
285
|
})();
|
|
286
|
+
var getCachedTrustCapability = /* @__PURE__ */ (() => {
|
|
287
|
+
let cached;
|
|
288
|
+
return () => cached ??= resolveTrustCapability();
|
|
289
|
+
})();
|
|
255
290
|
function getOwnerRepo() {
|
|
256
291
|
const url = execSync("git remote get-url origin", {
|
|
257
292
|
encoding: "utf8"
|
|
@@ -266,6 +301,20 @@ function getOwnerRepo() {
|
|
|
266
301
|
}
|
|
267
302
|
throw new Error(`Cannot parse GitHub owner/repo from remote URL: ${url}`);
|
|
268
303
|
}
|
|
304
|
+
var trustQueryResults = /* @__PURE__ */ new Map();
|
|
305
|
+
function getTrustQueryResult(packageName) {
|
|
306
|
+
const cached = trustQueryResults.get(packageName);
|
|
307
|
+
if (cached !== void 0) {
|
|
308
|
+
return cached;
|
|
309
|
+
}
|
|
310
|
+
const result = classifyTrustQuery(
|
|
311
|
+
runNpmJson(`npm trust list ${packageName} --json`),
|
|
312
|
+
getCachedOwnerRepo(),
|
|
313
|
+
PUBLISH_WORKFLOW_FILE
|
|
314
|
+
);
|
|
315
|
+
trustQueryResults.set(packageName, result);
|
|
316
|
+
return result;
|
|
317
|
+
}
|
|
269
318
|
function hasTokenReferences() {
|
|
270
319
|
const workflowDir = path.resolve(process.cwd(), ".github/workflows");
|
|
271
320
|
if (!existsSync(workflowDir)) {
|
|
@@ -301,6 +350,10 @@ function isRepoPrivate() {
|
|
|
301
350
|
function parseProvenanceSetting(workflowContent) {
|
|
302
351
|
return /^[^#]*provenance:\s*['"]?true['"]?/im.test(workflowContent);
|
|
303
352
|
}
|
|
353
|
+
function probeTrustQuery() {
|
|
354
|
+
const probeName = selectProbeName();
|
|
355
|
+
return probeName === void 0 ? void 0 : getTrustQueryResult(probeName);
|
|
356
|
+
}
|
|
304
357
|
function readNpmError(stdout) {
|
|
305
358
|
let parsed;
|
|
306
359
|
try {
|
|
@@ -329,6 +382,10 @@ function readTrustRelationships(stdout) {
|
|
|
329
382
|
}
|
|
330
383
|
return "type" in parsed ? [parsed] : [];
|
|
331
384
|
}
|
|
385
|
+
function resolveTrustCapability() {
|
|
386
|
+
const auth = getCachedNpmAuthStatus();
|
|
387
|
+
return classifyTrustCapability(auth, auth.status === "authenticated" ? probeTrustQuery() : void 0);
|
|
388
|
+
}
|
|
332
389
|
function runNpmJson(command) {
|
|
333
390
|
try {
|
|
334
391
|
return { exitOk: true, stdout: execSync(command, { encoding: "utf8", stdio: "pipe" }) };
|
|
@@ -337,6 +394,11 @@ function runNpmJson(command) {
|
|
|
337
394
|
return { exitOk: false, stdout };
|
|
338
395
|
}
|
|
339
396
|
}
|
|
397
|
+
function selectProbeName() {
|
|
398
|
+
return discoverWorkspaces({ filter: (workspace) => workspace.isPackage }).find(
|
|
399
|
+
(workspace) => workspace.name !== void 0
|
|
400
|
+
)?.name;
|
|
401
|
+
}
|
|
340
402
|
function skipIfNothingPublishable() {
|
|
341
403
|
const publishable = discoverWorkspaces({ filter: (workspace) => workspace.isPackage });
|
|
342
404
|
return publishable.length > 0 ? false : "no publishable packages";
|
|
@@ -347,9 +409,11 @@ function skipIfNotPublishable(workspace) {
|
|
|
347
409
|
export {
|
|
348
410
|
buildWorkspaceCheck,
|
|
349
411
|
classifyNpmAuth,
|
|
412
|
+
classifyTrustCapability,
|
|
350
413
|
classifyTrustQuery,
|
|
351
414
|
npm_auto_publish_default as default,
|
|
352
415
|
packagesChecklist,
|
|
416
|
+
selectProbeName,
|
|
353
417
|
skipIfNotPublishable,
|
|
354
418
|
skipIfNothingPublishable
|
|
355
419
|
};
|
package/.readyup/manifest.json
CHANGED
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
"esbuildVersion": "0.28.2",
|
|
9
9
|
"inputs": [
|
|
10
10
|
{
|
|
11
|
-
"hash": "
|
|
11
|
+
"hash": "55ff5731",
|
|
12
12
|
"kind": "module",
|
|
13
13
|
"path": "kits/default.ts"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
|
-
"hash": "
|
|
16
|
+
"hash": "a373c49d",
|
|
17
17
|
"kind": "inline",
|
|
18
18
|
"path": "../package.json",
|
|
19
19
|
"paths": [
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
"kind": "module",
|
|
31
31
|
"path": "../src/init/parseJsonRecord.ts"
|
|
32
32
|
},
|
|
33
|
+
{
|
|
34
|
+
"hash": "b798d024",
|
|
35
|
+
"kind": "module",
|
|
36
|
+
"path": "../src/packsPath.ts"
|
|
37
|
+
},
|
|
33
38
|
{
|
|
34
39
|
"hash": "646fe51b",
|
|
35
40
|
"kind": "module",
|
|
@@ -38,10 +43,10 @@
|
|
|
38
43
|
],
|
|
39
44
|
"name": "default",
|
|
40
45
|
"path": "kits/default.js",
|
|
41
|
-
"readyupVersion": "0.
|
|
46
|
+
"readyupVersion": "0.36.0",
|
|
42
47
|
"source": "kits/default.ts",
|
|
43
|
-
"sourceHash": "
|
|
44
|
-
"targetHash": "
|
|
48
|
+
"sourceHash": "55ff5731",
|
|
49
|
+
"targetHash": "68976fc8"
|
|
45
50
|
},
|
|
46
51
|
{
|
|
47
52
|
"checklists": [
|
|
@@ -51,17 +56,17 @@
|
|
|
51
56
|
"esbuildVersion": "0.28.2",
|
|
52
57
|
"inputs": [
|
|
53
58
|
{
|
|
54
|
-
"hash": "
|
|
59
|
+
"hash": "2f1fb68c",
|
|
55
60
|
"kind": "module",
|
|
56
61
|
"path": "kits/npm-auto-publish.ts"
|
|
57
62
|
}
|
|
58
63
|
],
|
|
59
64
|
"name": "npm-auto-publish",
|
|
60
65
|
"path": "kits/npm-auto-publish.js",
|
|
61
|
-
"readyupVersion": "0.
|
|
66
|
+
"readyupVersion": "0.36.0",
|
|
62
67
|
"source": "kits/npm-auto-publish.ts",
|
|
63
|
-
"sourceHash": "
|
|
64
|
-
"targetHash": "
|
|
68
|
+
"sourceHash": "2f1fb68c",
|
|
69
|
+
"targetHash": "cbabceb3"
|
|
65
70
|
}
|
|
66
71
|
]
|
|
67
72
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,89 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 10.7.0 โ 2026-09-15
|
|
6
|
+
|
|
7
|
+
### ๐ Features
|
|
8
|
+
|
|
9
|
+
- Fix scaffold error handling and cover every scaffolded workflow (#806)
|
|
10
|
+
|
|
11
|
+
- Adds a `create-github-release.yaml matches template` check to release-kit's ReadyUp kit, which warns when `.github/workflows/create-github-release.yaml` differs from the template for the detected repo type and skips in a repo that has not installed that workflow.
|
|
12
|
+
- Stops `v11y init --force` from replacing an existing `.config/v11y-check.config.json` with the defaults, which discarded the repo's thresholds and the allowlist maintained by `v11y sync`.
|
|
13
|
+
|
|
14
|
+
Migration: To reset `.config/v11y-check.config.json` to its defaults, delete the file and run `v11y init`, because `v11y init --force` now overwrites only `.github/workflows/audit.yaml`.
|
|
15
|
+
|
|
16
|
+
### ๐ Bug fixes
|
|
17
|
+
|
|
18
|
+
- Gate the trusted-publisher checks on trust-query capability (#786)
|
|
19
|
+
|
|
20
|
+
- Fixes the issue that the `npm-auto-publish` kit advised `npm trust github โฆ` for every package when the npm session lacked the two-factor authentication that trust queries need.
|
|
21
|
+
|
|
22
|
+
- Treat label names that differ only in case as one label (#808)
|
|
23
|
+
|
|
24
|
+
- Fixes the issue that `sync-labels generate` wrote a preset's `bug` and a local `Bug` to `.github/labels.yaml` as two labels, which made the first sync fail to create the second and every later sync rename the existing label back and forth.
|
|
25
|
+
- Lets a `labels` entry change a preset label's casing: `Bug` replaces a preset's `bug` and appears in the output as `Bug`, and `Bug: null` removes it.
|
|
26
|
+
- Makes `labels` keys that differ only in case a config error that names each group, such as `'bug' and 'Bug'`, since folding them would discard all but one without any sign in the output.
|
|
27
|
+
|
|
28
|
+
Migration: Keep one of any keys in the `labels` record that differ only in case, and delete the others.
|
|
29
|
+
|
|
30
|
+
### โป๏ธ Refactoring
|
|
31
|
+
|
|
32
|
+
- Remove the redundant, soft-failing version read from release prepare (#811)
|
|
33
|
+
|
|
34
|
+
- Deletes `readCurrentVersion` from `release-kit`, moving into `planVersionSet` the check that a `--set-version` target exceeds the current version and recording each workspace's version in the `DependencyGraph` passed to `propagateBumps`.
|
|
35
|
+
- Stops prepare from printing a warning before it fails on an unreadable `package.json`, and replaces `failed to read current version` for a missing `version` under `--set-version` with an error from `planVersionSet` that reports the missing `version` field.
|
|
36
|
+
|
|
37
|
+
### โ๏ธ Tooling
|
|
38
|
+
|
|
39
|
+
- Upgrade eslint-config-typescript to v17 and adopt its ignore lists (#797)
|
|
40
|
+
|
|
41
|
+
- Declares `vitest` as `catalog:` in every workspace that imports it, with the pnpm catalog pinning 4.1.11, because v17 no longer exempts `vitest` from `n/no-extraneous-import`.
|
|
42
|
+
- Builds the global ignores in `eslint.config.ts` from the published `commonIgnores` and `toolIgnores`, which also exclude `pnpm-lock.yaml` and each `.readyup/manifest.json`, so the `eslint --fix` in `nmr lint` can no longer rewrite a kit manifest and make the next build's `rdy verify` fail.
|
|
43
|
+
|
|
44
|
+
### ๐ Documentation
|
|
45
|
+
|
|
46
|
+
- Trim the release-kit README and move reference detail into shipped docs (#802)
|
|
47
|
+
|
|
48
|
+
- Adds `docs` to the published `files` of `@williamthorsen/release-kit` and a `!docs/*.v*.md` exclusion to both it and `@williamthorsen/nmr`, because `pnpm pack` would otherwise include the release-notes previews that a local checkout holds.
|
|
49
|
+
- Adds `--version` to the options that `release-kit --help` lists, and points the hints for the removed `releaseNotes.shouldCreateGithubRelease` field at `release-kit init` instead of the README.
|
|
50
|
+
|
|
51
|
+
## 10.6.0 โ 2026-09-08
|
|
52
|
+
|
|
53
|
+
### ๐ Features
|
|
54
|
+
|
|
55
|
+
- Report a package whose tarball would omit its changelog (#768)
|
|
56
|
+
|
|
57
|
+
Adds ReadyUp checks to verify that every published package bundles its changelog files: the human-readable `CHANGELOG.md` and the machine-readable `changelog.json`.
|
|
58
|
+
|
|
59
|
+
- Add a migration field to changelog.json items (#770)
|
|
60
|
+
|
|
61
|
+
Adds an optional `migration` field to entries in the `.meta/changelog.json` that `release-kit` generates. If a commit body contains a labeled migration step, that content is copied to the `migration` field.
|
|
62
|
+
|
|
63
|
+
### ๐ Bug fixes
|
|
64
|
+
|
|
65
|
+
- Pin git-cliff and remove the per-run npx cache refresh (#776)
|
|
66
|
+
|
|
67
|
+
Fixes an issue where git-cliff's version was unpinned, resulting in a per-run cache refresh. An exact version is now pinned.
|
|
68
|
+
|
|
69
|
+
Removes the per-run cache refresh, which re-ran `npx` without `--prefer-offline` once per prepare and forced a registry round trip. An exact version leaves npm nothing to revalidate, so a prepare run no longer waits on registry latency.
|
|
70
|
+
|
|
71
|
+
Also silences git-cliff's INFO output, in particular the crates.io update notice.
|
|
72
|
+
|
|
73
|
+
### โป๏ธ Refactoring
|
|
74
|
+
|
|
75
|
+
- Remove the unwired isChangelogItem type guard (#771)
|
|
76
|
+
|
|
77
|
+
Removes the unused `isChangelogItem` from `release-kit`'s `changelogJsonUtils.ts`, together with its tests.
|
|
78
|
+
|
|
79
|
+
Documentation is updated to record the boundary on `isChangelogEntry`: Entries parsed from `.meta/changelog.json` are shape-checked at the top level only, and strict validation applies only to the human-authored `.meta/changelog-overrides.json`.
|
|
80
|
+
|
|
81
|
+
### ๐งช Tests
|
|
82
|
+
|
|
83
|
+
- Read console spy output with listConsoleLines rather than by hand (#781)
|
|
84
|
+
|
|
85
|
+
- Replaces the hand-rolled reads of a console spy's `mock.calls` in the `nmr`, `release-kit`, and `v11y-check` test suites with `listConsoleLines` from `@williamthorsen/toolbelt.vitest/candidate`.
|
|
86
|
+
- Clears the `toolbelt.vitest/no-console-calls-read` recommendation that `rdy run --packages` reported.
|
|
87
|
+
|
|
5
88
|
## 10.5.0 โ 2026-09-01
|
|
6
89
|
|
|
7
90
|
### ๐ Features
|