@williamthorsen/release-kit 14.2.1 โ 14.2.3
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 +77 -0
- package/.readyup/kits/default.js +142 -152
- package/.readyup/kits/npm-auto-publish.js +183 -184
- package/.readyup/manifest.json +83 -9
- package/CHANGELOG.md +24 -0
- package/README.md +7 -1
- package/dist/esm/applyChangelogOverrides.d.ts +50 -0
- package/dist/esm/applyChangelogOverrides.js +162 -0
- package/dist/esm/attachChangelogDiagnostics.d.ts +1 -1
- package/dist/esm/bin/release-kit.js +6 -238
- package/dist/esm/buildChangelogEntries.d.ts +20 -31
- package/dist/esm/buildChangelogEntries.js +71 -188
- package/dist/esm/buildChangelogItem.d.ts +56 -0
- package/dist/esm/buildChangelogItem.js +119 -0
- package/dist/esm/buildReleasedResult.d.ts +20 -0
- package/dist/esm/buildReleasedResult.js +78 -0
- package/dist/esm/changelogJsonUtils.d.ts +1 -1
- package/dist/esm/changelogOverrides.d.ts +29 -143
- package/dist/esm/changelogOverrides.js +35 -467
- package/dist/esm/configSchema.d.ts +225 -0
- package/dist/esm/configSchema.js +103 -0
- package/dist/esm/createGithubReleaseCommand.js +4 -3
- package/dist/esm/decideDirectReleases.d.ts +30 -0
- package/dist/esm/decideDirectReleases.js +66 -0
- package/dist/esm/defaults.js +1 -4
- package/dist/esm/defineConfig.d.ts +2 -2
- package/dist/esm/deriveReleaseNotesConfig.d.ts +2 -1
- package/dist/esm/deriveReleaseNotesConfig.js +1 -1
- package/dist/esm/determineBumpType.js +4 -3
- package/dist/esm/enumerateReleaseWindows.js +4 -4
- package/dist/esm/formatPrepareFiles.d.ts +11 -0
- package/dist/esm/formatPrepareFiles.js +55 -0
- package/dist/esm/formatPrepareWarnings.d.ts +26 -0
- package/dist/esm/formatPrepareWarnings.js +72 -0
- package/dist/esm/help/initHelp.d.ts +4 -0
- package/dist/esm/help/initHelp.js +31 -0
- package/dist/esm/help/overridesHelp.d.ts +4 -0
- package/dist/esm/help/overridesHelp.js +32 -0
- package/dist/esm/help/releaseStepsHelp.d.ts +12 -0
- package/dist/esm/help/releaseStepsHelp.js +91 -0
- package/dist/esm/help/syncLabelsHelp.d.ts +8 -0
- package/dist/esm/help/syncLabelsHelp.js +55 -0
- package/dist/esm/help/usage.d.ts +2 -0
- package/dist/esm/help/usage.js +29 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/init/initCommand.js +3 -7
- package/dist/esm/loadChangelogOverrides.d.ts +31 -0
- package/dist/esm/loadChangelogOverrides.js +138 -0
- package/dist/esm/loadConfig.d.ts +0 -40
- package/dist/esm/loadConfig.js +0 -242
- package/dist/esm/loadValidatedConfig.d.ts +1 -1
- package/dist/esm/mergeConfig.d.ts +41 -0
- package/dist/esm/mergeConfig.js +118 -0
- package/dist/esm/monorepoConfigAssertions.d.ts +49 -0
- package/dist/esm/monorepoConfigAssertions.js +126 -0
- package/dist/esm/planChangelogFiles.d.ts +16 -0
- package/dist/esm/planChangelogFiles.js +41 -0
- package/dist/esm/prepareArgs.d.ts +55 -0
- package/dist/esm/prepareArgs.js +69 -0
- package/dist/esm/prepareCommand.d.ts +0 -48
- package/dist/esm/prepareCommand.js +11 -77
- package/dist/esm/prepareComposite.d.ts +16 -0
- package/dist/esm/prepareComposite.js +39 -0
- package/dist/esm/prepareRunContext.d.ts +38 -0
- package/dist/esm/prepareRunContext.js +39 -0
- package/dist/esm/prepareTarget.d.ts +2 -7
- package/dist/esm/prepareTarget.js +2 -118
- package/dist/esm/previewTagPrefixes.d.ts +1 -1
- package/dist/esm/releasePrepareTargets.js +13 -207
- package/dist/esm/renderReleaseNotes.js +6 -5
- package/dist/esm/reportPrepare.js +3 -123
- package/dist/esm/resolveCommandTags.d.ts +1 -1
- package/dist/esm/resolveCommandTags.js +2 -1
- package/dist/esm/resolveReleaseDeclaration.d.ts +2 -1
- package/dist/esm/resolveReleaseTargets.d.ts +2 -1
- package/dist/esm/resolveReleaseTargets.js +2 -1
- package/dist/esm/stripScope.js +4 -3
- package/dist/esm/sync-labels/generateCommand.d.ts +1 -1
- package/dist/esm/sync-labels/resolveLabels.d.ts +1 -1
- package/dist/esm/topologicalSort.d.ts +12 -0
- package/dist/esm/topologicalSort.js +60 -0
- package/dist/esm/types.d.ts +1 -225
- package/dist/esm/types.js +1 -103
- package/dist/esm/validateAllChangelogOverrides.d.ts +56 -0
- package/dist/esm/validateAllChangelogOverrides.js +138 -0
- package/dist/esm/validateConfig.d.ts +1 -1
- package/dist/esm/validateConfig.js +7 -9
- package/dist/esm/validateOverridesCommand.d.ts +1 -1
- package/dist/esm/validateOverridesCommand.js +2 -1
- package/package.json +4 -4
|
@@ -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.42.0";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
// .readyup/kits/npm-auto-publish.ts
|
|
@@ -13,16 +13,10 @@ import {
|
|
|
13
13
|
fileContains,
|
|
14
14
|
fileExists,
|
|
15
15
|
getJsonValue,
|
|
16
|
-
isRecord as isRecord2,
|
|
17
16
|
readFile,
|
|
18
17
|
readJsonFile
|
|
19
18
|
} from "readyup/check-utils";
|
|
20
19
|
|
|
21
|
-
// src/init/hasProvenance.ts
|
|
22
|
-
function hasProvenance(workflowContent) {
|
|
23
|
-
return /^[^#]*provenance:\s*['"]?true['"]?/im.test(workflowContent);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
20
|
// src/npmRegistry.ts
|
|
27
21
|
import { execFileSync } from "node:child_process";
|
|
28
22
|
|
|
@@ -87,10 +81,169 @@ function runNpmJson(args) {
|
|
|
87
81
|
}
|
|
88
82
|
}
|
|
89
83
|
|
|
90
|
-
// .readyup/
|
|
84
|
+
// .readyup/lib/npm-trust.ts
|
|
85
|
+
import { isRecord as isRecord2 } from "readyup/check-utils";
|
|
86
|
+
|
|
87
|
+
// src/init/hasProvenance.ts
|
|
88
|
+
function hasProvenance(workflowContent) {
|
|
89
|
+
return /^[^#]*provenance:\s*['"]?true['"]?/im.test(workflowContent);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// .readyup/lib/npm-trust.ts
|
|
91
93
|
var OTP_ERROR_CODE = "EOTP";
|
|
92
94
|
var PUBLISH_WORKFLOW_FILE = "publish.yaml";
|
|
93
95
|
var NO_GITHUB_REMOTE_FIX = "Add an origin remote that points to the GitHub repo, then run this check again";
|
|
96
|
+
function classifyNpmAuth(result) {
|
|
97
|
+
if (result.exitOk) {
|
|
98
|
+
return { status: "authenticated" };
|
|
99
|
+
}
|
|
100
|
+
const error = readNpmError(result.stdout);
|
|
101
|
+
if (error === void 0) {
|
|
102
|
+
return { status: "unreachable", detail: "The npm registry query failed without a readable error payload" };
|
|
103
|
+
}
|
|
104
|
+
if (AUTH_ERROR_CODES.has(error.code)) {
|
|
105
|
+
return { status: "unauthenticated", detail: `The npm registry rejected the session (${error.code})` };
|
|
106
|
+
}
|
|
107
|
+
if (UNREACHABLE_ERROR_CODES.has(error.code)) {
|
|
108
|
+
return { status: "unreachable", detail: `Cannot reach the npm registry (${error.code})` };
|
|
109
|
+
}
|
|
110
|
+
return { status: "unreachable", detail: `The npm registry query failed (${error.code}): ${error.summary}` };
|
|
111
|
+
}
|
|
112
|
+
function classifyProvenanceSetting(workflowContent, visibility) {
|
|
113
|
+
if (workflowContent === void 0) {
|
|
114
|
+
return {
|
|
115
|
+
ok: false,
|
|
116
|
+
detail: "Cannot read .github/workflows/publish.yaml",
|
|
117
|
+
fix: "Check the file's permissions"
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (typeof visibility !== "string") {
|
|
121
|
+
return { ok: false, detail: visibility.detail, fix: NO_GITHUB_REMOTE_FIX };
|
|
122
|
+
}
|
|
123
|
+
if (visibility === "unknown") {
|
|
124
|
+
return {
|
|
125
|
+
ok: false,
|
|
126
|
+
detail: "The GitHub CLI could not report the repo's visibility",
|
|
127
|
+
fix: "Install and authenticate the GitHub CLI: gh auth login"
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const provenance = hasProvenance(workflowContent);
|
|
131
|
+
if (visibility === "public" && !provenance) {
|
|
132
|
+
return {
|
|
133
|
+
ok: false,
|
|
134
|
+
detail: "The repo is public and publish.yaml does not set provenance: true",
|
|
135
|
+
fix: "Set provenance: true in .github/workflows/publish.yaml; public repos should generate provenance attestations"
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (visibility === "private" && provenance) {
|
|
139
|
+
return {
|
|
140
|
+
ok: false,
|
|
141
|
+
detail: "The repo is private and publish.yaml sets provenance: true",
|
|
142
|
+
fix: "Make the GitHub repo public; OIDC publishing with provenance requires a public repo"
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return { ok: true };
|
|
146
|
+
}
|
|
147
|
+
function classifyTrustCapability(auth, probe) {
|
|
148
|
+
if (auth.status !== "authenticated") {
|
|
149
|
+
return { ok: false, detail: auth.detail };
|
|
150
|
+
}
|
|
151
|
+
return probe?.status === "unanswerable" ? { ok: false, detail: probe.detail } : { ok: true };
|
|
152
|
+
}
|
|
153
|
+
function classifyTrustQuery(result, expectedRepo, expectedFile) {
|
|
154
|
+
if (!result.exitOk) {
|
|
155
|
+
const error = readNpmError(result.stdout);
|
|
156
|
+
if (error === void 0) {
|
|
157
|
+
return { status: "error", detail: "The npm trust query failed without a readable error payload" };
|
|
158
|
+
}
|
|
159
|
+
if (error.code === "E404") {
|
|
160
|
+
return { status: "not-configured" };
|
|
161
|
+
}
|
|
162
|
+
if (AUTH_ERROR_CODES.has(error.code) || error.code === OTP_ERROR_CODE) {
|
|
163
|
+
return {
|
|
164
|
+
status: "unanswerable",
|
|
165
|
+
detail: `The npm session cannot answer trust queries (${error.code}): ${error.summary}`
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (UNREACHABLE_ERROR_CODES.has(error.code)) {
|
|
169
|
+
return { status: "unanswerable", detail: `Cannot reach the npm registry (${error.code})` };
|
|
170
|
+
}
|
|
171
|
+
return { status: "error", detail: `The npm trust query failed (${error.code}): ${error.summary}` };
|
|
172
|
+
}
|
|
173
|
+
const relationships = readTrustRelationships(result.stdout);
|
|
174
|
+
if (relationships === void 0) {
|
|
175
|
+
return { status: "error", detail: "The npm trust query returned a payload that this check cannot read" };
|
|
176
|
+
}
|
|
177
|
+
if (relationships.length === 0) {
|
|
178
|
+
return { status: "not-configured" };
|
|
179
|
+
}
|
|
180
|
+
if (!expectedRepo.ok) {
|
|
181
|
+
return {
|
|
182
|
+
status: "error",
|
|
183
|
+
detail: `Cannot compare the trusted publisher with this repo; found ${describeTrustRelationships(relationships)}`
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const isMatch = relationships.some(
|
|
187
|
+
(relationship) => relationship.type === "github" && relationship.repository === expectedRepo.value && relationship.file === expectedFile
|
|
188
|
+
);
|
|
189
|
+
return isMatch ? { status: "configured" } : {
|
|
190
|
+
status: "mismatched",
|
|
191
|
+
detail: `Expected github ${expectedRepo.value} (${expectedFile}); found ${describeTrustRelationships(relationships)}`
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function describeNpmPackageLookup(lookup) {
|
|
195
|
+
if (lookup.status === "published") {
|
|
196
|
+
return { ok: true };
|
|
197
|
+
}
|
|
198
|
+
if (lookup.status === "unpublished") {
|
|
199
|
+
return { ok: false, detail: "The npm registry does not list this package" };
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
ok: false,
|
|
203
|
+
detail: lookup.detail,
|
|
204
|
+
fix: "Restore access to the npm registry, then run this check again"
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function describeTrustedPublisher(result, packageName, ownerRepo) {
|
|
208
|
+
if (result.status === "configured") {
|
|
209
|
+
return { ok: true };
|
|
210
|
+
}
|
|
211
|
+
const detail = result.status === "not-configured" ? "The npm registry does not list any trusted publisher for this package" : result.detail;
|
|
212
|
+
return ownerRepo.ok ? { ok: false, detail, fix: formatTrustCommand(packageName, ownerRepo.value) } : { ok: false, detail: `${detail}. ${ownerRepo.detail}`, fix: NO_GITHUB_REMOTE_FIX };
|
|
213
|
+
}
|
|
214
|
+
function formatTrustCommand(packageName, ownerRepo) {
|
|
215
|
+
return `Run: npm trust github ${packageName} --repo ${ownerRepo} --file ${PUBLISH_WORKFLOW_FILE}`;
|
|
216
|
+
}
|
|
217
|
+
function parseGitHubOwnerRepo(url) {
|
|
218
|
+
const match = /git@github\.com:(.+?)(?:\.git)?$/.exec(url) ?? /github\.com\/(.+?)(?:\.git)?$/.exec(url);
|
|
219
|
+
const ownerRepo = match?.[1];
|
|
220
|
+
return ownerRepo === void 0 ? { ok: false, detail: `The origin remote does not point to GitHub: ${url}` } : { ok: true, value: ownerRepo };
|
|
221
|
+
}
|
|
222
|
+
function describeTrustRelationships(relationships) {
|
|
223
|
+
return relationships.map((relationship) => {
|
|
224
|
+
const type = typeof relationship.type === "string" ? relationship.type : "(unknown)";
|
|
225
|
+
const repository = typeof relationship.repository === "string" ? relationship.repository : "(unknown)";
|
|
226
|
+
const file = typeof relationship.file === "string" ? relationship.file : "(unknown)";
|
|
227
|
+
return `${type} ${repository} (${file})`;
|
|
228
|
+
}).join(", ");
|
|
229
|
+
}
|
|
230
|
+
function readTrustRelationships(stdout) {
|
|
231
|
+
let parsed;
|
|
232
|
+
try {
|
|
233
|
+
parsed = JSON.parse(stdout);
|
|
234
|
+
} catch {
|
|
235
|
+
return void 0;
|
|
236
|
+
}
|
|
237
|
+
if (Array.isArray(parsed)) {
|
|
238
|
+
return parsed.filter((entry) => isRecord2(entry) && "type" in entry);
|
|
239
|
+
}
|
|
240
|
+
if (!isRecord2(parsed)) {
|
|
241
|
+
return void 0;
|
|
242
|
+
}
|
|
243
|
+
return "type" in parsed ? [parsed] : [];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// .readyup/kits/npm-auto-publish.ts
|
|
94
247
|
var repoChecklist = defineRdyChecklist({
|
|
95
248
|
name: "repo",
|
|
96
249
|
checks: [
|
|
@@ -139,25 +292,28 @@ var packagesChecklist = defineRdyChecklist({
|
|
|
139
292
|
fix: "Ensure pnpm-workspace.yaml lists package globs, or that a root package.json exists"
|
|
140
293
|
}
|
|
141
294
|
],
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
295
|
+
checks: [
|
|
296
|
+
{
|
|
297
|
+
name: "Repo publishes at least one package",
|
|
298
|
+
skip: () => skipIfNothingPublishable(),
|
|
299
|
+
check: () => true,
|
|
300
|
+
// Built when the checklist runs, so that the kit declares the same checks wherever it is imported. The session
|
|
301
|
+
// gate is a sibling of the workspace rows, not their parent, so a session that cannot answer trust queries
|
|
302
|
+
// suppresses only the trusted-publisher rows and leaves the package.json checks reporting.
|
|
303
|
+
checks: () => [
|
|
304
|
+
buildSessionCheck(),
|
|
305
|
+
...discoverWorkspaces({ filter: belongsInPackagesChecklist }).map(
|
|
306
|
+
(workspace) => buildWorkspaceCheck(workspace)
|
|
307
|
+
)
|
|
308
|
+
]
|
|
149
309
|
}
|
|
150
|
-
|
|
151
|
-
sessionCheck,
|
|
152
|
-
...discoverWorkspaces({ filter: belongsInPackagesChecklist }).map((workspace) => buildWorkspaceCheck(workspace))
|
|
153
|
-
];
|
|
154
|
-
}
|
|
310
|
+
]
|
|
155
311
|
});
|
|
156
312
|
var npm_auto_publish_default = defineRdyKit({
|
|
157
313
|
fixLocation: "inline",
|
|
158
|
-
// The release that introduced `
|
|
159
|
-
//
|
|
160
|
-
minReadyupVersion: "0.
|
|
314
|
+
// The release that introduced a function-valued `checks`, which builds the per-package rows. An older runner rejects
|
|
315
|
+
// it when validating the kit.
|
|
316
|
+
minReadyupVersion: "0.42.0",
|
|
161
317
|
checklists: [repoChecklist, packagesChecklist]
|
|
162
318
|
});
|
|
163
319
|
function belongsInPackagesChecklist(workspace) {
|
|
@@ -166,7 +322,6 @@ function belongsInPackagesChecklist(workspace) {
|
|
|
166
322
|
function buildSessionCheck() {
|
|
167
323
|
return {
|
|
168
324
|
name: "npm session can answer trust queries",
|
|
169
|
-
skip: () => skipIfNothingPublishable(),
|
|
170
325
|
check: () => {
|
|
171
326
|
const capability = getCachedTrustCapability();
|
|
172
327
|
return capability.ok ? { ok: true } : { ok: false, detail: capability.detail };
|
|
@@ -202,7 +357,7 @@ function buildWorkspaceCheck(workspace) {
|
|
|
202
357
|
// as unpublished would advise publishing a package that is already there.
|
|
203
358
|
skip: () => {
|
|
204
359
|
const auth = getCachedNpmAuthStatus();
|
|
205
|
-
return auth.status === "unreachable"
|
|
360
|
+
return auth.status === "unreachable" && auth.detail;
|
|
206
361
|
},
|
|
207
362
|
check: () => describeNpmPackageLookup(lookUpNpmPackage(displayName, readPublishRegistry(workspace))),
|
|
208
363
|
fix: `Run "npm publish --access public" from ${workspace.dir} to bootstrap the package on npm`,
|
|
@@ -211,7 +366,7 @@ function buildWorkspaceCheck(workspace) {
|
|
|
211
366
|
name: "trusted publisher configured",
|
|
212
367
|
skip: () => {
|
|
213
368
|
const capability = getCachedTrustCapability();
|
|
214
|
-
return capability.ok
|
|
369
|
+
return !capability.ok && capability.detail;
|
|
215
370
|
},
|
|
216
371
|
check: () => describeTrustedPublisher(getTrustQueryResult(displayName), displayName, getCachedOwnerRepo()),
|
|
217
372
|
fix: formatTrustCommand(displayName, "<owner>/<repo>")
|
|
@@ -247,135 +402,6 @@ function checkProvenanceMatchesVisibility() {
|
|
|
247
402
|
}
|
|
248
403
|
return classifyProvenanceSetting(content, visibility);
|
|
249
404
|
}
|
|
250
|
-
function classifyNpmAuth(result) {
|
|
251
|
-
if (result.exitOk) {
|
|
252
|
-
return { status: "authenticated" };
|
|
253
|
-
}
|
|
254
|
-
const error = readNpmError(result.stdout);
|
|
255
|
-
if (error === void 0) {
|
|
256
|
-
return { status: "unreachable", detail: "The npm registry query failed without a readable error payload" };
|
|
257
|
-
}
|
|
258
|
-
if (AUTH_ERROR_CODES.has(error.code)) {
|
|
259
|
-
return { status: "unauthenticated", detail: `The npm registry rejected the session (${error.code})` };
|
|
260
|
-
}
|
|
261
|
-
if (UNREACHABLE_ERROR_CODES.has(error.code)) {
|
|
262
|
-
return { status: "unreachable", detail: `Cannot reach the npm registry (${error.code})` };
|
|
263
|
-
}
|
|
264
|
-
return { status: "unreachable", detail: `The npm registry query failed (${error.code}): ${error.summary}` };
|
|
265
|
-
}
|
|
266
|
-
function classifyProvenanceSetting(workflowContent, visibility) {
|
|
267
|
-
if (workflowContent === void 0) {
|
|
268
|
-
return {
|
|
269
|
-
ok: false,
|
|
270
|
-
detail: "Cannot read .github/workflows/publish.yaml",
|
|
271
|
-
fix: "Check the file's permissions"
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
if (typeof visibility !== "string") {
|
|
275
|
-
return { ok: false, detail: visibility.detail, fix: NO_GITHUB_REMOTE_FIX };
|
|
276
|
-
}
|
|
277
|
-
if (visibility === "unknown") {
|
|
278
|
-
return {
|
|
279
|
-
ok: false,
|
|
280
|
-
detail: "The GitHub CLI could not report the repo's visibility",
|
|
281
|
-
fix: "Install and authenticate the GitHub CLI: gh auth login"
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
const provenance = hasProvenance(workflowContent);
|
|
285
|
-
if (visibility === "public" && !provenance) {
|
|
286
|
-
return {
|
|
287
|
-
ok: false,
|
|
288
|
-
detail: "The repo is public and publish.yaml does not set provenance: true",
|
|
289
|
-
fix: "Set provenance: true in .github/workflows/publish.yaml; public repos should generate provenance attestations"
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
if (visibility === "private" && provenance) {
|
|
293
|
-
return {
|
|
294
|
-
ok: false,
|
|
295
|
-
detail: "The repo is private and publish.yaml sets provenance: true",
|
|
296
|
-
fix: "Make the GitHub repo public; OIDC publishing with provenance requires a public repo"
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
return { ok: true };
|
|
300
|
-
}
|
|
301
|
-
function classifyTrustCapability(auth, probe) {
|
|
302
|
-
if (auth.status !== "authenticated") {
|
|
303
|
-
return { ok: false, detail: auth.detail };
|
|
304
|
-
}
|
|
305
|
-
return probe?.status === "unanswerable" ? { ok: false, detail: probe.detail } : { ok: true };
|
|
306
|
-
}
|
|
307
|
-
function classifyTrustQuery(result, expectedRepo, expectedFile) {
|
|
308
|
-
if (!result.exitOk) {
|
|
309
|
-
const error = readNpmError(result.stdout);
|
|
310
|
-
if (error === void 0) {
|
|
311
|
-
return { status: "error", detail: "The npm trust query failed without a readable error payload" };
|
|
312
|
-
}
|
|
313
|
-
if (error.code === "E404") {
|
|
314
|
-
return { status: "not-configured" };
|
|
315
|
-
}
|
|
316
|
-
if (AUTH_ERROR_CODES.has(error.code) || error.code === OTP_ERROR_CODE) {
|
|
317
|
-
return {
|
|
318
|
-
status: "unanswerable",
|
|
319
|
-
detail: `The npm session cannot answer trust queries (${error.code}): ${error.summary}`
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
if (UNREACHABLE_ERROR_CODES.has(error.code)) {
|
|
323
|
-
return { status: "unanswerable", detail: `Cannot reach the npm registry (${error.code})` };
|
|
324
|
-
}
|
|
325
|
-
return { status: "error", detail: `The npm trust query failed (${error.code}): ${error.summary}` };
|
|
326
|
-
}
|
|
327
|
-
const relationships = readTrustRelationships(result.stdout);
|
|
328
|
-
if (relationships === void 0) {
|
|
329
|
-
return { status: "error", detail: "The npm trust query returned a payload that this check cannot read" };
|
|
330
|
-
}
|
|
331
|
-
if (relationships.length === 0) {
|
|
332
|
-
return { status: "not-configured" };
|
|
333
|
-
}
|
|
334
|
-
if (!expectedRepo.ok) {
|
|
335
|
-
return {
|
|
336
|
-
status: "error",
|
|
337
|
-
detail: `Cannot compare the trusted publisher with this repo; found ${describeTrustRelationships(relationships)}`
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
const isMatch = relationships.some(
|
|
341
|
-
(relationship) => relationship.type === "github" && relationship.repository === expectedRepo.value && relationship.file === expectedFile
|
|
342
|
-
);
|
|
343
|
-
return isMatch ? { status: "configured" } : {
|
|
344
|
-
status: "mismatched",
|
|
345
|
-
detail: `Expected github ${expectedRepo.value} (${expectedFile}); found ${describeTrustRelationships(relationships)}`
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
function describeNpmPackageLookup(lookup) {
|
|
349
|
-
if (lookup.status === "published") {
|
|
350
|
-
return { ok: true };
|
|
351
|
-
}
|
|
352
|
-
if (lookup.status === "unpublished") {
|
|
353
|
-
return { ok: false, detail: "The npm registry does not list this package" };
|
|
354
|
-
}
|
|
355
|
-
return {
|
|
356
|
-
ok: false,
|
|
357
|
-
detail: lookup.detail,
|
|
358
|
-
fix: "Restore access to the npm registry, then run this check again"
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
function describeTrustedPublisher(result, packageName, ownerRepo) {
|
|
362
|
-
if (result.status === "configured") {
|
|
363
|
-
return { ok: true };
|
|
364
|
-
}
|
|
365
|
-
const detail = result.status === "not-configured" ? "The npm registry does not list any trusted publisher for this package" : result.detail;
|
|
366
|
-
return ownerRepo.ok ? { ok: false, detail, fix: formatTrustCommand(packageName, ownerRepo.value) } : { ok: false, detail: `${detail}. ${ownerRepo.detail}`, fix: NO_GITHUB_REMOTE_FIX };
|
|
367
|
-
}
|
|
368
|
-
function describeTrustRelationships(relationships) {
|
|
369
|
-
return relationships.map((relationship) => {
|
|
370
|
-
const type = typeof relationship.type === "string" ? relationship.type : "(unknown)";
|
|
371
|
-
const repository = typeof relationship.repository === "string" ? relationship.repository : "(unknown)";
|
|
372
|
-
const file = typeof relationship.file === "string" ? relationship.file : "(unknown)";
|
|
373
|
-
return `${type} ${repository} (${file})`;
|
|
374
|
-
}).join(", ");
|
|
375
|
-
}
|
|
376
|
-
function formatTrustCommand(packageName, ownerRepo) {
|
|
377
|
-
return `Run: npm trust github ${packageName} --repo ${ownerRepo} --file ${PUBLISH_WORKFLOW_FILE}`;
|
|
378
|
-
}
|
|
379
405
|
var getCachedNpmAuthStatus = /* @__PURE__ */ (() => {
|
|
380
406
|
let cached;
|
|
381
407
|
return () => cached ??= classifyNpmAuth(runNpmJson(["whoami", "--json"]));
|
|
@@ -422,11 +448,6 @@ function isRepoPrivate(ownerRepo) {
|
|
|
422
448
|
}).trim();
|
|
423
449
|
return result === "true";
|
|
424
450
|
}
|
|
425
|
-
function parseGitHubOwnerRepo(url) {
|
|
426
|
-
const match = /git@github\.com:(.+?)(?:\.git)?$/.exec(url) ?? /github\.com\/(.+?)(?:\.git)?$/.exec(url);
|
|
427
|
-
const ownerRepo = match?.[1];
|
|
428
|
-
return ownerRepo === void 0 ? { ok: false, detail: `The origin remote does not point to GitHub: ${url}` } : { ok: true, value: ownerRepo };
|
|
429
|
-
}
|
|
430
451
|
function probeTrustQuery() {
|
|
431
452
|
const probeName = selectProbeName();
|
|
432
453
|
return probeName === void 0 ? void 0 : getTrustQueryResult(probeName);
|
|
@@ -435,21 +456,6 @@ function readPublishRegistry(workspace) {
|
|
|
435
456
|
const registry = getJsonValue(workspace.packageJson, "publishConfig", "registry");
|
|
436
457
|
return typeof registry === "string" ? registry : void 0;
|
|
437
458
|
}
|
|
438
|
-
function readTrustRelationships(stdout) {
|
|
439
|
-
let parsed;
|
|
440
|
-
try {
|
|
441
|
-
parsed = JSON.parse(stdout);
|
|
442
|
-
} catch {
|
|
443
|
-
return void 0;
|
|
444
|
-
}
|
|
445
|
-
if (Array.isArray(parsed)) {
|
|
446
|
-
return parsed.filter((entry) => isRecord2(entry) && "type" in entry);
|
|
447
|
-
}
|
|
448
|
-
if (!isRecord2(parsed)) {
|
|
449
|
-
return void 0;
|
|
450
|
-
}
|
|
451
|
-
return "type" in parsed ? [parsed] : [];
|
|
452
|
-
}
|
|
453
459
|
function resolveOwnerRepo() {
|
|
454
460
|
let url;
|
|
455
461
|
try {
|
|
@@ -470,22 +476,15 @@ function selectProbeName() {
|
|
|
470
476
|
}
|
|
471
477
|
function skipIfNothingPublishable() {
|
|
472
478
|
const publishable = discoverWorkspaces({ filter: (workspace) => workspace.isPackage });
|
|
473
|
-
return publishable.length
|
|
479
|
+
return publishable.length === 0 && "no publishable packages";
|
|
474
480
|
}
|
|
475
481
|
function skipIfNotPublishable(workspace) {
|
|
476
|
-
return workspace.isPackage
|
|
482
|
+
return !workspace.isPackage && "package.json#private is true";
|
|
477
483
|
}
|
|
478
484
|
export {
|
|
479
485
|
buildWorkspaceCheck,
|
|
480
|
-
classifyNpmAuth,
|
|
481
|
-
classifyProvenanceSetting,
|
|
482
|
-
classifyTrustCapability,
|
|
483
|
-
classifyTrustQuery,
|
|
484
486
|
npm_auto_publish_default as default,
|
|
485
|
-
describeNpmPackageLookup,
|
|
486
|
-
describeTrustedPublisher,
|
|
487
487
|
packagesChecklist,
|
|
488
|
-
parseGitHubOwnerRepo,
|
|
489
488
|
selectProbeName,
|
|
490
489
|
skipIfNotPublishable,
|
|
491
490
|
skipIfNothingPublishable
|
package/.readyup/manifest.json
CHANGED
|
@@ -2,18 +2,68 @@
|
|
|
2
2
|
"version": 1,
|
|
3
3
|
"kits": [
|
|
4
4
|
{
|
|
5
|
+
"checklistChecks": [
|
|
6
|
+
{
|
|
7
|
+
"checklist": "release-kit",
|
|
8
|
+
"checks": [
|
|
9
|
+
"@williamthorsen/release-kit in devDependencies",
|
|
10
|
+
"@williamthorsen/release-kit >= 14.2.3",
|
|
11
|
+
"release.yaml workflow exists",
|
|
12
|
+
"release.yaml matches template",
|
|
13
|
+
"release.yaml does not reference deprecated tag ref",
|
|
14
|
+
"publish.yaml workflow exists",
|
|
15
|
+
"publish.yaml matches template",
|
|
16
|
+
"publish.yaml does not reference deprecated tag ref",
|
|
17
|
+
"create-github-release.yaml matches template",
|
|
18
|
+
".config/release-kit.config.ts exports a config",
|
|
19
|
+
"releaseNotes config is consistent with changelogJson",
|
|
20
|
+
".config/release-kit.config.ts uses defineConfig",
|
|
21
|
+
"releaseNotes.shouldInjectIntoReadme is true",
|
|
22
|
+
"README contains release-notes section markers",
|
|
23
|
+
"repoLabels block declared in .config/release-kit.config.ts",
|
|
24
|
+
".github/labels.yaml exists",
|
|
25
|
+
"labels.yaml has current common preset",
|
|
26
|
+
"scope labels in .github/labels.yaml have no description",
|
|
27
|
+
"published packages ship CHANGELOG.md",
|
|
28
|
+
"published packages ship the changelog archives",
|
|
29
|
+
"changelog.json generation is enabled",
|
|
30
|
+
"published packages ship the changelog JSON",
|
|
31
|
+
"config does not use removed releaseNotes.shouldCreateGithubRelease",
|
|
32
|
+
"@changesets/cli not in devDependencies",
|
|
33
|
+
"sync-labels.yaml workflow exists",
|
|
34
|
+
"sync-labels.yaml matches template",
|
|
35
|
+
"sync-labels.yaml does not reference deprecated tag ref",
|
|
36
|
+
"retired .config/sync-labels.config.ts is absent"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
],
|
|
5
40
|
"checklists": [
|
|
6
41
|
"release-kit"
|
|
7
42
|
],
|
|
8
43
|
"esbuildVersion": "0.28.2",
|
|
9
44
|
"inputs": [
|
|
10
45
|
{
|
|
11
|
-
"hash": "
|
|
46
|
+
"hash": "ad3666b8",
|
|
12
47
|
"kind": "module",
|
|
13
48
|
"path": "kits/default.ts"
|
|
14
49
|
},
|
|
15
50
|
{
|
|
16
|
-
"hash": "
|
|
51
|
+
"hash": "45fc235f",
|
|
52
|
+
"kind": "module",
|
|
53
|
+
"path": "lib/changelog-checks.ts"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"hash": "be2c2cb3",
|
|
57
|
+
"kind": "module",
|
|
58
|
+
"path": "lib/config-checks.ts"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"hash": "290731d6",
|
|
62
|
+
"kind": "module",
|
|
63
|
+
"path": "lib/workflow-hashes.ts"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"hash": "b89073b8",
|
|
17
67
|
"kind": "inline",
|
|
18
68
|
"path": "../package.json",
|
|
19
69
|
"paths": [
|
|
@@ -48,12 +98,31 @@
|
|
|
48
98
|
],
|
|
49
99
|
"name": "default",
|
|
50
100
|
"path": "kits/default.js",
|
|
51
|
-
"readyupVersion": "0.
|
|
101
|
+
"readyupVersion": "0.42.0",
|
|
52
102
|
"source": "kits/default.ts",
|
|
53
|
-
"sourceHash": "
|
|
54
|
-
"targetHash": "
|
|
103
|
+
"sourceHash": "ad3666b8",
|
|
104
|
+
"targetHash": "9f5a50d9"
|
|
55
105
|
},
|
|
56
106
|
{
|
|
107
|
+
"checklistChecks": [
|
|
108
|
+
{
|
|
109
|
+
"checklist": "repo",
|
|
110
|
+
"checks": [
|
|
111
|
+
"publish.yaml exists",
|
|
112
|
+
"id-token: write permission declared",
|
|
113
|
+
"No legacy token references in workflow files",
|
|
114
|
+
"Provenance setting matches repo visibility"
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"checklist": "packages",
|
|
119
|
+
"checks": [
|
|
120
|
+
"packageManager field starts with \"pnpm\"",
|
|
121
|
+
"At least one workspace discovered",
|
|
122
|
+
"Repo publishes at least one package"
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
],
|
|
57
126
|
"checklists": [
|
|
58
127
|
"repo",
|
|
59
128
|
"packages"
|
|
@@ -61,10 +130,15 @@
|
|
|
61
130
|
"esbuildVersion": "0.28.2",
|
|
62
131
|
"inputs": [
|
|
63
132
|
{
|
|
64
|
-
"hash": "
|
|
133
|
+
"hash": "682fdd4a",
|
|
65
134
|
"kind": "module",
|
|
66
135
|
"path": "kits/npm-auto-publish.ts"
|
|
67
136
|
},
|
|
137
|
+
{
|
|
138
|
+
"hash": "05215737",
|
|
139
|
+
"kind": "module",
|
|
140
|
+
"path": "lib/npm-trust.ts"
|
|
141
|
+
},
|
|
68
142
|
{
|
|
69
143
|
"hash": "d360febf",
|
|
70
144
|
"kind": "module",
|
|
@@ -83,10 +157,10 @@
|
|
|
83
157
|
],
|
|
84
158
|
"name": "npm-auto-publish",
|
|
85
159
|
"path": "kits/npm-auto-publish.js",
|
|
86
|
-
"readyupVersion": "0.
|
|
160
|
+
"readyupVersion": "0.42.0",
|
|
87
161
|
"source": "kits/npm-auto-publish.ts",
|
|
88
|
-
"sourceHash": "
|
|
89
|
-
"targetHash": "
|
|
162
|
+
"sourceHash": "682fdd4a",
|
|
163
|
+
"targetHash": "04adb134"
|
|
90
164
|
}
|
|
91
165
|
]
|
|
92
166
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 14.2.3 โ 2026-10-18
|
|
6
|
+
|
|
7
|
+
### ๐ Bug fixes
|
|
8
|
+
|
|
9
|
+
- Fixes the issue that the manifest of the `npm-auto-publish` kit recorded a different list of checks depending on the directory from which `rdy compile` ran, by declaring one fixed check, "Repo publishes at least one package", under which `rdy run` builds the npm session check and the per-package rows. (#1081)
|
|
10
|
+
|
|
11
|
+
### โป๏ธ Refactoring
|
|
12
|
+
|
|
13
|
+
- Splits `types.ts`, `loadConfig.ts`, `changelogOverrides.ts`, and `buildChangelogEntries.ts` to bring each under the 300-line `max-lines` limit, moving the config zod schemas into `configSchema.ts`, config merging into `mergeConfig.ts`, the cross-target checks into `monorepoConfigAssertions.ts`, override parsing, application, and repo-wide validation into `loadChangelogOverrides.ts`, `applyChangelogOverrides.ts`, and `validateAllChangelogOverrides.ts`, and changelog-item construction into `buildChangelogItem.ts`. (#1067)
|
|
14
|
+
- Splits the `release-kit` bin, the `prepare` pipeline (`prepareCommand`, `prepareTarget`, `releasePrepareTargets`, and `reportPrepare`), and the `default` and `npm-auto-publish` readyup kits into smaller modules under `src`, `src/help`, and `.readyup/lib`, and recompiles the kit bundles without changing their check lists. (#1069)
|
|
15
|
+
- Rewrites the code that the new and widened rules in `eslint-plugin-unicorn` 78 report, mostly by changing `flatMap` callbacks to return a single value rather than a one-element array. (#1072)
|
|
16
|
+
|
|
17
|
+
### ๐งช Tests
|
|
18
|
+
|
|
19
|
+
- Splits the `release-kit` unit tests for `releasePrepareTargets`, `reportPrepare`, `prepareCommand`, `publishCommand`, `parseCommitMessage`, and `validateConfig` into `<subject>.<aspect>.unit.test.ts` files that each stay under the `max-lines` limit, and moves the mocks and fixtures that the split files share into modules under `src/test-utils/`. (#1066)
|
|
20
|
+
|
|
21
|
+
## 14.2.2 โ 2026-10-17
|
|
22
|
+
|
|
23
|
+
### ๐ฆ Dependencies
|
|
24
|
+
|
|
25
|
+
- Upgrades `@williamthorsen/eslint-config-typescript` from 18.0.0 to 19.0.0 and rewrites the code in `build-info`, `nmr-core`, `nmr`, and `release-kit` that its new and widened rules report, without changing behavior. (#1047)
|
|
26
|
+
- Upgrades `readyup` from 0.40.0 to 0.41.0 and recompiles the kits in `nmr`, `release-kit`, and `v11y-check`, whose manifests now record each checklist's check names under `checklistChecks`. (#1047)
|
|
27
|
+
- Upgrades `pnpm` to 12.11.2, `@types/node` to 24.19.2, `lefthook` to 2.2.1, `@williamthorsen/strict-lint` to 14.2.0, `@williamthorsen/tsconfig` to 0.11.0, `smol-toml` to 1.9.1, and `vite` to 8.3.4. (#1047)
|
|
28
|
+
|
|
5
29
|
## 14.2.1 โ 2026-10-13
|
|
6
30
|
|
|
7
31
|
### ๐ฆ Dependencies
|
package/README.md
CHANGED
|
@@ -6,7 +6,13 @@ Version-bumping and changelog-generation toolkit for release workflows.
|
|
|
6
6
|
|
|
7
7
|
Provides a self-contained CLI that auto-discovers workspaces from `pnpm-workspace.yaml`, parses conventional commits, determines version bumps, updates `package.json` files, and generates changelogs from the same commit history that decides each bump (with optional [editorial overrides](docs/editorial-overrides.md)).
|
|
8
8
|
|
|
9
|
-
<!-- section:release-notes
|
|
9
|
+
<!-- section:release-notes -->
|
|
10
|
+
## Release notes โ v14.2.3 (2026-10-18)
|
|
11
|
+
|
|
12
|
+
### ๐ Bug fixes
|
|
13
|
+
|
|
14
|
+
- Fixes the issue that the manifest of the `npm-auto-publish` kit recorded a different list of checks depending on the directory from which `rdy compile` ran, by declaring one fixed check, "Repo publishes at least one package", under which `rdy run` builds the npm session check and the per-package rows. (#1081)
|
|
15
|
+
<!-- /section:release-notes -->
|
|
10
16
|
|
|
11
17
|
## Installation
|
|
12
18
|
|