@williamthorsen/release-kit 15.0.3 → 16.1.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 +93 -0
- package/.readyup/kits/default.js +14 -14
- package/.readyup/kits/npm-auto-publish.js +4 -4
- package/.readyup/manifest.json +13 -13
- package/CHANGELOG.md +27 -0
- package/README.md +12 -3
- package/dist/esm/applyChangelogOverrides.js +6 -6
- package/dist/esm/assertReleasesOnNpm.js +11 -11
- package/dist/esm/assertTaggedBaseline.js +5 -5
- package/dist/esm/assertTarballsComplete.d.ts +9 -0
- package/dist/esm/assertTarballsComplete.js +52 -0
- package/dist/esm/bin/release-kit.js +16 -16
- package/dist/esm/buildChangelogEntries.d.ts +19 -19
- package/dist/esm/buildChangelogEntries.js +40 -36
- package/dist/esm/buildChangelogItem.js +24 -24
- package/dist/esm/buildDependencyGraph.js +23 -23
- package/dist/esm/buildReleasedResult.js +21 -19
- package/dist/esm/buildSyntheticChangelogEntry.js +2 -2
- package/dist/esm/bumpVersion.js +8 -8
- package/dist/esm/changelogArchive.d.ts +1 -1
- package/dist/esm/changelogArchive.js +2 -2
- package/dist/esm/changelogJsonFile.js +5 -5
- package/dist/esm/changelogJsonUtils.js +3 -3
- package/dist/esm/changelogOverrides.d.ts +5 -5
- package/dist/esm/changelogOverrides.js +23 -23
- package/dist/esm/classifyChangelogCommit.js +4 -4
- package/dist/esm/commitCommand.js +3 -3
- package/dist/esm/compareVersions.js +13 -13
- package/dist/esm/configSchema.d.ts +3 -2
- package/dist/esm/configSchema.js +2 -1
- package/dist/esm/createGithubRelease.d.ts +4 -4
- package/dist/esm/createGithubRelease.js +10 -10
- package/dist/esm/createGithubReleaseCommand.js +9 -9
- package/dist/esm/createTags.d.ts +2 -2
- package/dist/esm/createTags.js +8 -8
- package/dist/esm/decideDirectReleases.d.ts +5 -5
- package/dist/esm/decideDirectReleases.js +25 -25
- package/dist/esm/decideRelease.d.ts +1 -1
- package/dist/esm/decideRelease.js +2 -2
- package/dist/esm/deriveDirectoryConfig.d.ts +1 -1
- package/dist/esm/deriveDirectoryConfig.js +18 -18
- package/dist/esm/deriveWorkspaceConfig.js +4 -4
- package/dist/esm/detectPackageManager.d.ts +2 -0
- package/dist/esm/detectPackageManager.js +8 -5
- package/dist/esm/detectUndeclaredTagPrefixes.js +6 -6
- package/dist/esm/enumerateReleaseWindows.d.ts +1 -1
- package/dist/esm/enumerateReleaseWindows.js +7 -7
- package/dist/esm/findMissingManifestPaths.d.ts +14 -0
- package/dist/esm/findMissingManifestPaths.js +90 -0
- package/dist/esm/findTransitiveDependents.js +5 -5
- package/dist/esm/findUnroutedEntryScopes.js +11 -11
- package/dist/esm/format.d.ts +1 -1
- package/dist/esm/format.js +1 -1
- package/dist/esm/formatPrepareFiles.d.ts +3 -3
- package/dist/esm/formatPrepareFiles.js +10 -10
- package/dist/esm/formatPrepareWarnings.js +6 -6
- package/dist/esm/hasPrettierConfig.js +2 -2
- package/dist/esm/init/checks.js +5 -3
- package/dist/esm/init/detectRepoType.js +3 -3
- package/dist/esm/init/initCommand.d.ts +4 -4
- package/dist/esm/init/initCommand.js +7 -7
- package/dist/esm/init/parseJsonRecord.d.ts +1 -1
- package/dist/esm/init/parseJsonRecord.js +4 -4
- package/dist/esm/init/scaffold.d.ts +4 -4
- package/dist/esm/init/scaffold.js +15 -15
- package/dist/esm/init/templates.d.ts +10 -10
- package/dist/esm/init/templates.js +5 -5
- package/dist/esm/init/updateTemplatesCommand.d.ts +2 -2
- package/dist/esm/init/updateTemplatesCommand.js +14 -12
- package/dist/esm/injectReleaseNotesIntoReadme.d.ts +1 -1
- package/dist/esm/injectReleaseNotesIntoReadme.js +6 -6
- package/dist/esm/injectSection.js +8 -8
- package/dist/esm/loadChangelogOverrides.d.ts +1 -1
- package/dist/esm/loadChangelogOverrides.js +9 -9
- package/dist/esm/loadConfig.d.ts +3 -3
- package/dist/esm/loadConfig.js +10 -10
- package/dist/esm/loadValidatedConfig.js +4 -4
- package/dist/esm/mergeConfig.d.ts +1 -1
- package/dist/esm/mergeConfig.js +27 -27
- package/dist/esm/monorepoConfigAssertions.js +15 -15
- package/dist/esm/npmRegistry.js +4 -4
- package/dist/esm/packFromCleanCheckout.d.ts +11 -0
- package/dist/esm/packFromCleanCheckout.js +81 -0
- package/dist/esm/packsPath.js +3 -3
- package/dist/esm/parseChangeRecordBlock.js +33 -33
- package/dist/esm/parseCommitMessage.js +5 -5
- package/dist/esm/planChangelogFiles.js +8 -8
- package/dist/esm/planReleaseNotesPreviews.js +10 -10
- package/dist/esm/planVersionBump.js +24 -16
- package/dist/esm/prepareArgs.d.ts +9 -9
- package/dist/esm/prepareArgs.js +11 -11
- package/dist/esm/prepareCommand.js +27 -24
- package/dist/esm/prepareComposite.d.ts +4 -4
- package/dist/esm/prepareComposite.js +16 -16
- package/dist/esm/{releasePrepareTargets.d.ts → prepareReleaseTargets.d.ts} +9 -9
- package/dist/esm/{releasePrepareTargets.js → prepareReleaseTargets.js} +40 -40
- package/dist/esm/prepareRunContext.d.ts +1 -1
- package/dist/esm/prepareRunContext.js +5 -5
- package/dist/esm/prepareTarget.d.ts +3 -3
- package/dist/esm/prepareTarget.js +41 -39
- package/dist/esm/previewTagPrefixes.js +19 -19
- package/dist/esm/propagateBumps.js +8 -8
- package/dist/esm/publish.d.ts +3 -3
- package/dist/esm/publish.js +6 -11
- package/dist/esm/publishCommand.d.ts +3 -3
- package/dist/esm/publishCommand.js +28 -20
- package/dist/esm/pushCommand.js +8 -8
- package/dist/esm/pushRelease.d.ts +1 -1
- package/dist/esm/pushRelease.js +2 -2
- package/dist/esm/readChangelogSections.d.ts +1 -1
- package/dist/esm/readChangelogSections.js +16 -16
- package/dist/esm/releasePlan.js +25 -25
- package/dist/esm/renderChangelogMarkdown.d.ts +4 -4
- package/dist/esm/renderChangelogMarkdown.js +18 -15
- package/dist/esm/renderReleaseNotes.d.ts +1 -1
- package/dist/esm/renderReleaseNotes.js +16 -16
- package/dist/esm/reportPrepare.js +34 -34
- package/dist/esm/resolveCommandTags.js +9 -9
- package/dist/esm/resolveReleaseDeclaration.d.ts +2 -2
- package/dist/esm/resolveReleaseDeclaration.js +22 -22
- package/dist/esm/resolveReleaseTags.js +17 -15
- package/dist/esm/resolveReleaseTargets.js +2 -2
- package/dist/esm/showTagPrefixesCommand.js +4 -4
- package/dist/esm/sync-labels/generateCommand.d.ts +3 -3
- package/dist/esm/sync-labels/generateCommand.js +10 -10
- package/dist/esm/sync-labels/initCommand.d.ts +3 -3
- package/dist/esm/sync-labels/initCommand.js +15 -15
- package/dist/esm/sync-labels/presets.js +3 -3
- package/dist/esm/sync-labels/resolveLabels.js +13 -13
- package/dist/esm/sync-labels/templates.d.ts +2 -2
- package/dist/esm/sync-labels/templates.js +1 -1
- package/dist/esm/tagCommand.js +4 -4
- package/dist/esm/topologicalSort.d.ts +2 -2
- package/dist/esm/topologicalSort.js +7 -7
- package/dist/esm/types.d.ts +3 -3
- package/dist/esm/validateAllChangelogOverrides.js +9 -9
- package/dist/esm/validateConfig.d.ts +1 -1
- package/dist/esm/validateConfig.js +60 -50
- package/dist/esm/validateOverridesCommand.js +2 -2
- package/docs/changelogs.md +5 -5
- package/docs/configuration.md +16 -15
- package/docs/publishing.md +4 -0
- package/docs/releasing.md +6 -0
- package/docs/work-types.md +1 -1
- package/package.json +2 -2
- package/presets/labels/common.yaml +3 -0
package/.meta/changelog.json
CHANGED
|
@@ -1,4 +1,97 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "16.1.0",
|
|
4
|
+
"date": "2026-11-03",
|
|
5
|
+
"sections": [
|
|
6
|
+
{
|
|
7
|
+
"title": "🎉 Features",
|
|
8
|
+
"audience": "all",
|
|
9
|
+
"items": [
|
|
10
|
+
{
|
|
11
|
+
"description": "Makes `prepare` and `publish` refuse a release, dry runs included, when a tarball packed from a clean checkout of HEAD lacks a file named by the package's `main`, `types`, `bin`, or `exports`, which keeps a package with missing build output from reaching the registry. (#1147)",
|
|
12
|
+
"hash": "c730654140e89d52ac7430987497d8b954fa7f00",
|
|
13
|
+
"entry": 1
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"description": "Adds the `devExportConditions` config key, which lists the export conditions that resolve only inside the repo and whose targets the tarball check does not require, in addition to `source`. (#1147)",
|
|
17
|
+
"hash": "c730654140e89d52ac7430987497d8b954fa7f00",
|
|
18
|
+
"entry": 2
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"description": "Adds a `content` label to the `common` label preset, for consumer-facing material such as copy, images, or displayed data rather than functionality. (#1150)",
|
|
22
|
+
"hash": "8c7b990041e5744c26547fe0ce8c9305f0f7c6f4",
|
|
23
|
+
"entry": 1
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"version": "16.0.0",
|
|
31
|
+
"date": "2026-10-28",
|
|
32
|
+
"sections": [
|
|
33
|
+
{
|
|
34
|
+
"title": "🎉 Features",
|
|
35
|
+
"audience": "all",
|
|
36
|
+
"items": [
|
|
37
|
+
{
|
|
38
|
+
"description": "Renames the `changelogMarkdown.keepVersions` config key to `changelogMarkdown.keptVersionCount` and makes config validation reject the old key with an error that names the replacement. (#1134)",
|
|
39
|
+
"breaking": true,
|
|
40
|
+
"migration": "Rename `changelogMarkdown.keepVersions` to `changelogMarkdown.keptVersionCount` in `.config/release-kit.config.ts`, keeping the same value.",
|
|
41
|
+
"hash": "3d44603845a461295a5a62eee60cf151b5291f1a",
|
|
42
|
+
"entry": 1
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"title": "♻️ Refactoring",
|
|
48
|
+
"audience": "dev",
|
|
49
|
+
"items": [
|
|
50
|
+
{
|
|
51
|
+
"description": "Renames the boolean options, fields, and parameters in `release-kit` to take an `is`, `has`, `does`, or `should` prefix, such as `dryRun` to `isDryRun` and `exists` to `doesExist`, and leaves every CLI flag spelling unchanged. (#1132)",
|
|
52
|
+
"hash": "dcb78f0657c580eb7c7be94859e4185ae9f3d3be",
|
|
53
|
+
"entry": 1
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"description": "Renames the values and type fields declared in `release-kit`'s source files from the first alphabetically through `prepareTarget.ts` so that each name ends with its kind, such as `parsedJson` for `parsed` and `unreleasedReading` for the history field `unreleased`, without changing behavior. (#1133)",
|
|
57
|
+
"hash": "eae8b6458dca1927393d64626d4731fc7c9f9df1",
|
|
58
|
+
"entry": 1
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"description": "Renames values and type fields across release-kit's source so that each name ends with its kind, such as `applied` to `appliedWrites` and `TargetPrepareOptions.only` to `onlyTargetIds`. (#1134)",
|
|
62
|
+
"hash": "3d44603845a461295a5a62eee60cf151b5291f1a",
|
|
63
|
+
"entry": 2
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"description": "Renames `release-kit`'s source functions and test helpers so that each name starts with a transitive verb that states its action, for example `releasePrepareTargets` to `prepareReleaseTargets` (with its module and test files), `publishWorkflow` to `renderPublishWorkflow`, and `toChangelogEntries` to `convertToChangelogEntries`, without changing the exports of `.` or `./config`. (#1137)",
|
|
67
|
+
"hash": "a84d9ce0652754a417b85c3f9cd14a6e400c7b51",
|
|
68
|
+
"entry": 1
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"description": "Renames identifiers in `release-kit` so that each measurement ends with its unit, such as `timestamp` becoming `timestampSec` on `ReleaseWindow` and `SUBJECT_COLUMN_BUDGET` becoming `SUBJECT_BUDGET_COLUMNS`, and so that obscure abbreviations are spelled out, such as `pkg` becoming `packageJson` and `dep` becoming `dependency`. (#1138)",
|
|
72
|
+
"hash": "f75938c0bfe9365a76b15aa6b4b9d195046c8c78",
|
|
73
|
+
"entry": 1
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"title": "🧪 Tests",
|
|
79
|
+
"audience": "dev",
|
|
80
|
+
"items": [
|
|
81
|
+
{
|
|
82
|
+
"description": "Renames the values declared in release-kit's `src/__tests__` files, from the first one alphabetically through `prepareCommand.unit.test.ts`, so that each name ends with its kind, such as `underlying` to `underlyingError` and `unreleased` to `unreleasedReading`. (#1135)",
|
|
83
|
+
"hash": "b98d26e24e86835ce6edc78f53a964bcc84472fb",
|
|
84
|
+
"entry": 1
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"description": "Suffixes the values declared in release-kit's remaining tests with their kind, such as `known` to `knownFlags`, `silent` to `silencedConsole`, and `actual` to `actualModule`, in the `src/__tests__` files after `prepareCommand.unit.test.ts` and the tests under `src/init/__tests__` and `src/sync-labels/__tests__`. (#1136)",
|
|
88
|
+
"hash": "1e947eb5c2d168ffd3d1cf9cf8b0b4e720eaf991",
|
|
89
|
+
"entry": 1
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
2
95
|
{
|
|
3
96
|
"version": "15.0.3",
|
|
4
97
|
"date": "2026-10-27",
|
package/.readyup/kits/default.js
CHANGED
|
@@ -24,14 +24,14 @@ function isRecord(value) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// src/init/parseJsonRecord.ts
|
|
27
|
-
function parseJsonRecord(
|
|
28
|
-
let
|
|
27
|
+
function parseJsonRecord(jsonText) {
|
|
28
|
+
let parsedJson;
|
|
29
29
|
try {
|
|
30
|
-
|
|
30
|
+
parsedJson = JSON.parse(jsonText);
|
|
31
31
|
} catch {
|
|
32
32
|
return void 0;
|
|
33
33
|
}
|
|
34
|
-
return isRecord(
|
|
34
|
+
return isRecord(parsedJson) ? parsedJson : void 0;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
// src/init/detectRepoType.ts
|
|
@@ -40,9 +40,9 @@ function detectRepoType() {
|
|
|
40
40
|
return "monorepo";
|
|
41
41
|
}
|
|
42
42
|
if (existsSync("package.json")) {
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
43
|
+
const manifestJson = readFileSync("package.json", "utf8");
|
|
44
|
+
const packageJson = parseJsonRecord(manifestJson);
|
|
45
|
+
if (packageJson !== void 0 && Array.isArray(packageJson["workspaces"])) {
|
|
46
46
|
return "monorepo";
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -67,9 +67,9 @@ function packsPath(filesField, path) {
|
|
|
67
67
|
var GLOB_TOKEN_PATTERN = /\*\*\/|\*\*|\*|\?|[^*?]+/g;
|
|
68
68
|
function compileEntry(entry) {
|
|
69
69
|
if (entry.startsWith("!")) return void 0;
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
72
|
-
return new RegExp(`^${translateGlob(
|
|
70
|
+
const normalizedEntry = entry.replace(/^\.?\//, "").replace(/\/+$/, "");
|
|
71
|
+
if (normalizedEntry === "") return void 0;
|
|
72
|
+
return new RegExp(`^${translateGlob(normalizedEntry)}$`);
|
|
73
73
|
}
|
|
74
74
|
function isStringArray(value) {
|
|
75
75
|
return Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
@@ -105,7 +105,7 @@ function translateGlob(pattern) {
|
|
|
105
105
|
function changelogArchivesAreEnabled() {
|
|
106
106
|
const content = readFile(".config/release-kit.config.ts");
|
|
107
107
|
if (content === void 0) return false;
|
|
108
|
-
return /changelogMarkdown\s*:\s*\{[^}]*
|
|
108
|
+
return /changelogMarkdown\s*:\s*\{[^}]*keptVersionCount\s*:/.test(content);
|
|
109
109
|
}
|
|
110
110
|
function changelogJsonIsEnabled() {
|
|
111
111
|
const content = readFile(".config/release-kit.config.ts");
|
|
@@ -223,7 +223,7 @@ function stripYamlQuotes(value) {
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
// .readyup/lib/workflow-hashes.ts
|
|
226
|
-
var COMMON_PRESET_HASH = "
|
|
226
|
+
var COMMON_PRESET_HASH = "5c6d7efcc8744d9d30720d24e345b04e03f2b28677ad0c6782020d91731b8aa4";
|
|
227
227
|
var SYNC_LABELS_WORKFLOW_HASH = "0a88829d154c0de7cdd4246fede99e9311a89ab4199034dbe601663d641ab1e4";
|
|
228
228
|
var RELEASE_WORKFLOW_HASH_MONOREPO = "f63f4cabb57f94ee6550f17a9874c7a346d46554595ddbcd46fdd3208d613437";
|
|
229
229
|
var RELEASE_WORKFLOW_HASH_SINGLE = "d26dd4ca186632b388ea46bd885721124c03d19918e511baa40821d2d760da69";
|
|
@@ -234,7 +234,7 @@ var CREATE_GITHUB_RELEASE_WORKFLOW_HASH_SINGLE = "d6de961de913c67b08dfa7e07f7349
|
|
|
234
234
|
|
|
235
235
|
// .readyup/kits/default.ts
|
|
236
236
|
function getMinVersion() {
|
|
237
|
-
const picked = { "version": "
|
|
237
|
+
const picked = { "version": "16.1.0" };
|
|
238
238
|
if (typeof picked["version"] !== "string") {
|
|
239
239
|
throw new TypeError("release-kit/package.json: 'version' must be a string");
|
|
240
240
|
}
|
|
@@ -405,7 +405,7 @@ var default_default = defineRdyKit({
|
|
|
405
405
|
severity: "warn",
|
|
406
406
|
skip: () => {
|
|
407
407
|
if (!hasPublishablePackages()) return "no publishable packages";
|
|
408
|
-
return !changelogArchivesAreEnabled() && "changelogMarkdown.
|
|
408
|
+
return !changelogArchivesAreEnabled() && "changelogMarkdown.keptVersionCount is not set";
|
|
409
409
|
},
|
|
410
410
|
check: () => packagesShipChangelogArchives(),
|
|
411
411
|
fix: 'Add "changelogs/" to the files field of each affected package.json, so that the links from CHANGELOG.md to its archive files resolve in the published package'
|
|
@@ -60,16 +60,16 @@ function lookUpNpmPackage(packageName, registry) {
|
|
|
60
60
|
return classifyNpmPackageLookup(runNpmJson(args));
|
|
61
61
|
}
|
|
62
62
|
function readNpmError(stdout) {
|
|
63
|
-
let
|
|
63
|
+
let parsedJson;
|
|
64
64
|
try {
|
|
65
|
-
|
|
65
|
+
parsedJson = JSON.parse(stdout);
|
|
66
66
|
} catch {
|
|
67
67
|
return void 0;
|
|
68
68
|
}
|
|
69
|
-
if (!isRecord(
|
|
69
|
+
if (!isRecord(parsedJson) || !isRecord(parsedJson["error"]) || typeof parsedJson["error"]["code"] !== "string") {
|
|
70
70
|
return void 0;
|
|
71
71
|
}
|
|
72
|
-
const { code, summary } =
|
|
72
|
+
const { code, summary } = parsedJson["error"];
|
|
73
73
|
return { code, summary: typeof summary === "string" ? summary : "" };
|
|
74
74
|
}
|
|
75
75
|
function runNpmJson(args) {
|
package/.readyup/manifest.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"checklist": "release-kit",
|
|
8
8
|
"checks": [
|
|
9
9
|
"@williamthorsen/release-kit in devDependencies",
|
|
10
|
-
"@williamthorsen/release-kit >=
|
|
10
|
+
"@williamthorsen/release-kit >= 16.1.0",
|
|
11
11
|
"release.yaml workflow exists",
|
|
12
12
|
"release.yaml matches template",
|
|
13
13
|
"release.yaml does not reference deprecated tag ref",
|
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
"esbuildVersion": "0.28.2",
|
|
44
44
|
"inputs": [
|
|
45
45
|
{
|
|
46
|
-
"hash": "
|
|
46
|
+
"hash": "56566d0b",
|
|
47
47
|
"kind": "module",
|
|
48
48
|
"path": "kits/default.ts"
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
|
-
"hash": "
|
|
51
|
+
"hash": "dafe3ffb",
|
|
52
52
|
"kind": "module",
|
|
53
53
|
"path": "lib/changelog-checks.ts"
|
|
54
54
|
},
|
|
@@ -58,12 +58,12 @@
|
|
|
58
58
|
"path": "lib/config-checks.ts"
|
|
59
59
|
},
|
|
60
60
|
{
|
|
61
|
-
"hash": "
|
|
61
|
+
"hash": "f652dae3",
|
|
62
62
|
"kind": "module",
|
|
63
63
|
"path": "lib/workflow-hashes.ts"
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
|
-
"hash": "
|
|
66
|
+
"hash": "b44f7148",
|
|
67
67
|
"kind": "inline",
|
|
68
68
|
"path": "../package.json",
|
|
69
69
|
"paths": [
|
|
@@ -71,22 +71,22 @@
|
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
|
-
"hash": "
|
|
74
|
+
"hash": "694186f4",
|
|
75
75
|
"kind": "module",
|
|
76
76
|
"path": "../src/changelogArchive.ts"
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
|
-
"hash": "
|
|
79
|
+
"hash": "65fa2f33",
|
|
80
80
|
"kind": "module",
|
|
81
81
|
"path": "../src/init/detectRepoType.ts"
|
|
82
82
|
},
|
|
83
83
|
{
|
|
84
|
-
"hash": "
|
|
84
|
+
"hash": "9ca0f6bf",
|
|
85
85
|
"kind": "module",
|
|
86
86
|
"path": "../src/init/parseJsonRecord.ts"
|
|
87
87
|
},
|
|
88
88
|
{
|
|
89
|
-
"hash": "
|
|
89
|
+
"hash": "2210df36",
|
|
90
90
|
"kind": "module",
|
|
91
91
|
"path": "../src/packsPath.ts"
|
|
92
92
|
},
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"path": "kits/default.js",
|
|
101
101
|
"readyupVersion": "0.44.0",
|
|
102
102
|
"source": "kits/default.ts",
|
|
103
|
-
"sourceHash": "
|
|
104
|
-
"targetHash": "
|
|
103
|
+
"sourceHash": "56566d0b",
|
|
104
|
+
"targetHash": "5f810bb7"
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
"checklistChecks": [
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
"path": "../src/init/hasProvenance.ts"
|
|
146
146
|
},
|
|
147
147
|
{
|
|
148
|
-
"hash": "
|
|
148
|
+
"hash": "bb8746b3",
|
|
149
149
|
"kind": "module",
|
|
150
150
|
"path": "../src/npmRegistry.ts"
|
|
151
151
|
},
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
"readyupVersion": "0.44.0",
|
|
161
161
|
"source": "kits/npm-auto-publish.ts",
|
|
162
162
|
"sourceHash": "682fdd4a",
|
|
163
|
-
"targetHash": "
|
|
163
|
+
"targetHash": "84f31b6d"
|
|
164
164
|
}
|
|
165
165
|
]
|
|
166
166
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 16.1.0 — 2026-11-03
|
|
6
|
+
|
|
7
|
+
### 🎉 Features
|
|
8
|
+
|
|
9
|
+
- Makes `prepare` and `publish` refuse a release, dry runs included, when a tarball packed from a clean checkout of HEAD lacks a file named by the package's `main`, `types`, `bin`, or `exports`, which keeps a package with missing build output from reaching the registry. (#1147)
|
|
10
|
+
- Adds the `devExportConditions` config key, which lists the export conditions that resolve only inside the repo and whose targets the tarball check does not require, in addition to `source`. (#1147)
|
|
11
|
+
- Adds a `content` label to the `common` label preset, for consumer-facing material such as copy, images, or displayed data rather than functionality. (#1150)
|
|
12
|
+
|
|
13
|
+
## 16.0.0 — 2026-10-28
|
|
14
|
+
|
|
15
|
+
### 🎉 Features
|
|
16
|
+
|
|
17
|
+
- 🚨 **Breaking:** Renames the `changelogMarkdown.keepVersions` config key to `changelogMarkdown.keptVersionCount` and makes config validation reject the old key with an error that names the replacement. (#1134)
|
|
18
|
+
|
|
19
|
+
### ♻️ Refactoring
|
|
20
|
+
|
|
21
|
+
- Renames the boolean options, fields, and parameters in `release-kit` to take an `is`, `has`, `does`, or `should` prefix, such as `dryRun` to `isDryRun` and `exists` to `doesExist`, and leaves every CLI flag spelling unchanged. (#1132)
|
|
22
|
+
- Renames the values and type fields declared in `release-kit`'s source files from the first alphabetically through `prepareTarget.ts` so that each name ends with its kind, such as `parsedJson` for `parsed` and `unreleasedReading` for the history field `unreleased`, without changing behavior. (#1133)
|
|
23
|
+
- Renames values and type fields across release-kit's source so that each name ends with its kind, such as `applied` to `appliedWrites` and `TargetPrepareOptions.only` to `onlyTargetIds`. (#1134)
|
|
24
|
+
- Renames `release-kit`'s source functions and test helpers so that each name starts with a transitive verb that states its action, for example `releasePrepareTargets` to `prepareReleaseTargets` (with its module and test files), `publishWorkflow` to `renderPublishWorkflow`, and `toChangelogEntries` to `convertToChangelogEntries`, without changing the exports of `.` or `./config`. (#1137)
|
|
25
|
+
- Renames identifiers in `release-kit` so that each measurement ends with its unit, such as `timestamp` becoming `timestampSec` on `ReleaseWindow` and `SUBJECT_COLUMN_BUDGET` becoming `SUBJECT_BUDGET_COLUMNS`, and so that obscure abbreviations are spelled out, such as `pkg` becoming `packageJson` and `dep` becoming `dependency`. (#1138)
|
|
26
|
+
|
|
27
|
+
### 🧪 Tests
|
|
28
|
+
|
|
29
|
+
- Renames the values declared in release-kit's `src/__tests__` files, from the first one alphabetically through `prepareCommand.unit.test.ts`, so that each name ends with its kind, such as `underlying` to `underlyingError` and `unreleased` to `unreleasedReading`. (#1135)
|
|
30
|
+
- Suffixes the values declared in release-kit's remaining tests with their kind, such as `known` to `knownFlags`, `silent` to `silencedConsole`, and `actual` to `actualModule`, in the `src/__tests__` files after `prepareCommand.unit.test.ts` and the tests under `src/init/__tests__` and `src/sync-labels/__tests__`. (#1136)
|
|
31
|
+
|
|
5
32
|
## 15.0.3 — 2026-10-27
|
|
6
33
|
|
|
7
34
|
### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -6,7 +6,15 @@ 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 — v16.1.0 (2026-11-03)
|
|
11
|
+
|
|
12
|
+
### 🎉 Features
|
|
13
|
+
|
|
14
|
+
- Makes `prepare` and `publish` refuse a release, dry runs included, when a tarball packed from a clean checkout of HEAD lacks a file named by the package's `main`, `types`, `bin`, or `exports`, which keeps a package with missing build output from reaching the registry. (#1147)
|
|
15
|
+
- Adds the `devExportConditions` config key, which lists the export conditions that resolve only inside the repo and whose targets the tarball check does not require, in addition to `source`. (#1147)
|
|
16
|
+
- Adds a `content` label to the `common` label preset, for consumer-facing material such as copy, images, or displayed data rather than functionality. (#1150)
|
|
17
|
+
<!-- /section:release-notes -->
|
|
10
18
|
|
|
11
19
|
## Installation
|
|
12
20
|
|
|
@@ -65,8 +73,9 @@ Every command other than `--version` and `--help` first locates the repo root an
|
|
|
65
73
|
1. **Workspace discovery**: Reads `pnpm-workspace.yaml` and resolves its `packages` patterns to find workspace directories, applying pnpm's semantics: A `!`-prefixed entry excludes what it matches, wherever it appears in the list. Each directory containing a `package.json` becomes a workspace. The repo is treated as a single-package project when it doesn't contain a workspace file, and when the workspace file doesn't declare a `packages` list: a file kept for `catalog:` or `overrides:` alone, which pnpm likewise resolves to the root package. A workspace file that declares patterns that don't resolve to any package is an error naming the condition that emptied it.
|
|
66
74
|
2. **Config loading**: Loads `.config/release-kit.config.ts` (if present) from the repo root, or the file named by `--config` relative to the invocation directory, and merges it with discovered defaults.
|
|
67
75
|
3. **Commit analysis**: For each workspace, reads the history once, builds the changelog items of the commits since the last version tag, and takes the bump as the highest level that those items call for.
|
|
68
|
-
4. **
|
|
69
|
-
5. **
|
|
76
|
+
4. **Tarball check**: Packs each publishable package that the release includes from a clean checkout of HEAD, and refuses the release when a tarball lacks a file that the package's manifest names; see [Packages whose tarball would lack a manifest file](docs/releasing.md#packages-whose-tarball-would-lack-a-manifest-file).
|
|
77
|
+
5. **Version bump + changelog**: Bumps `package.json` versions, builds structured `ChangelogEntry[]` from the commits between each pair of release tags, applies any [editorial overrides](docs/editorial-overrides.md) from per-scope `.meta/changelog-overrides.json` files, and renders both `CHANGELOG.md` and `.meta/changelog.json` from that single source, so the two always agree.
|
|
78
|
+
6. **Release tags file**: Writes computed tags to `tmp/.release-tags` for the release workflow to read when tagging and pushing.
|
|
70
79
|
|
|
71
80
|
[Changelogs](docs/changelogs.md) covers what a published tarball includes, the `changelog.json` item schema, and which commits appear in a changelog.
|
|
72
81
|
|
|
@@ -55,10 +55,10 @@ export function resolveOverrideKey(overrideKey, positionsByHash) {
|
|
|
55
55
|
if (hashes.length > 1) {
|
|
56
56
|
return { kind: 'ambiguous', hashes };
|
|
57
57
|
}
|
|
58
|
-
const
|
|
58
|
+
const availablePositions = [...(positionsByHash.get(hash) ?? [])];
|
|
59
59
|
const positions = entry === undefined
|
|
60
|
-
?
|
|
61
|
-
:
|
|
60
|
+
? availablePositions.toSorted((left, right) => (left ?? 0) - (right ?? 0))
|
|
61
|
+
: availablePositions.filter((position) => position === entry);
|
|
62
62
|
return positions.length === 0 ? { kind: 'none' } : { kind: 'items', hash, positions };
|
|
63
63
|
}
|
|
64
64
|
function applyOverridesToItems(items, itemIdToOverride) {
|
|
@@ -133,10 +133,10 @@ function resolveOverrideKeys(positionsByHash, overrides) {
|
|
|
133
133
|
}
|
|
134
134
|
const { hash, positions } = resolution;
|
|
135
135
|
if (parseOverrideKey(overrideKey).entry === undefined && positions.length > 1) {
|
|
136
|
-
const
|
|
137
|
-
if (
|
|
136
|
+
const setFields = ['description', 'body'].filter((field) => override[field] !== undefined);
|
|
137
|
+
if (setFields.length > 0) {
|
|
138
138
|
const ordinalKeys = positions.map((position) => `${overrideKey}:${position}`).join(', ');
|
|
139
|
-
errors.push(`Override key '${overrideKey}' sets ${
|
|
139
|
+
errors.push(`Override key '${overrideKey}' sets ${setFields.join(' and ')} on a commit with several items; use ${ordinalKeys}`);
|
|
140
140
|
continue;
|
|
141
141
|
}
|
|
142
142
|
}
|
|
@@ -4,8 +4,8 @@ import { isPublishableManifest } from "./isPublishableManifest.js";
|
|
|
4
4
|
import { lookUpNpmPackage } from "./npmRegistry.js";
|
|
5
5
|
import { isRecord } from "./typeGuards.js";
|
|
6
6
|
export function assertReleasesOnNpm(workspacePaths) {
|
|
7
|
-
const
|
|
8
|
-
const
|
|
7
|
+
const unpublishedCandidates = [];
|
|
8
|
+
const unverifiableCandidates = [];
|
|
9
9
|
for (const workspacePath of workspacePaths) {
|
|
10
10
|
const candidate = buildNpmCandidate(workspacePath);
|
|
11
11
|
if (candidate === undefined) {
|
|
@@ -13,16 +13,16 @@ export function assertReleasesOnNpm(workspacePaths) {
|
|
|
13
13
|
}
|
|
14
14
|
const lookup = lookUpNpmPackage(candidate.name, candidate.registry);
|
|
15
15
|
if (lookup.status === 'unpublished') {
|
|
16
|
-
|
|
16
|
+
unpublishedCandidates.push(candidate);
|
|
17
17
|
}
|
|
18
18
|
else if (lookup.status === 'unverifiable') {
|
|
19
|
-
|
|
19
|
+
unverifiableCandidates.push({ candidate, detail: lookup.detail });
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
if (
|
|
22
|
+
if (unpublishedCandidates.length === 0 && unverifiableCandidates.length === 0) {
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
|
-
throw new Error(describeRefusal(
|
|
25
|
+
throw new Error(describeRefusal(unpublishedCandidates, unverifiableCandidates));
|
|
26
26
|
}
|
|
27
27
|
function buildNpmCandidate(workspacePath) {
|
|
28
28
|
const manifest = JSON.parse(readFileSync(join(workspacePath, 'package.json'), 'utf8'));
|
|
@@ -37,19 +37,19 @@ function buildNpmCandidate(workspacePath) {
|
|
|
37
37
|
...(typeof registry === 'string' && { registry }),
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
-
function describeRefusal(
|
|
40
|
+
function describeRefusal(unpublishedCandidates, unverifiableCandidates) {
|
|
41
41
|
const sections = ['Cannot prepare the release: npm must already have every package that the release publishes.'];
|
|
42
|
-
if (
|
|
42
|
+
if (unpublishedCandidates.length > 0) {
|
|
43
43
|
sections.push([
|
|
44
44
|
'Not on npm yet:',
|
|
45
|
-
...
|
|
45
|
+
...unpublishedCandidates.map(({ name, workspacePath }) => ` - ${name}: run "npm publish --access public" from ${workspacePath}`),
|
|
46
46
|
'Then register each one as a trusted publisher; "rdy run --from npm:@williamthorsen/release-kit npm-auto-publish" prints the command.',
|
|
47
47
|
].join('\n'));
|
|
48
48
|
}
|
|
49
|
-
if (
|
|
49
|
+
if (unverifiableCandidates.length > 0) {
|
|
50
50
|
sections.push([
|
|
51
51
|
'Could not confirm on npm:',
|
|
52
|
-
...
|
|
52
|
+
...unverifiableCandidates.map(({ candidate, detail }) => ` - ${candidate.name}: ${detail}`),
|
|
53
53
|
].join('\n'));
|
|
54
54
|
}
|
|
55
55
|
return sections.join('\n\n');
|
|
@@ -4,10 +4,10 @@ import { readChangelogEntries } from "./changelogJsonUtils.js";
|
|
|
4
4
|
import { readCurrentVersion } from "./planVersionBump.js";
|
|
5
5
|
import { readChangelogSections } from "./readChangelogSections.js";
|
|
6
6
|
export function assertTaggedBaseline(findings) {
|
|
7
|
-
const
|
|
8
|
-
if (
|
|
7
|
+
const untaggedFindings = findings.filter((finding) => finding !== undefined);
|
|
8
|
+
if (untaggedFindings.length === 0)
|
|
9
9
|
return;
|
|
10
|
-
const lines =
|
|
10
|
+
const lines = untaggedFindings.map(({ label, version, tag }) => ` - ${label}: ${version} (create tag ${tag})`);
|
|
11
11
|
throw new Error([
|
|
12
12
|
'The current version is recorded in the changelog, but its tag is not the previous tag reachable from HEAD:',
|
|
13
13
|
...lines,
|
|
@@ -31,9 +31,9 @@ export function findUntaggedBaseline(target, config) {
|
|
|
31
31
|
function readRecordedVersions(changelogPaths, config) {
|
|
32
32
|
const versions = new Set();
|
|
33
33
|
for (const changelogPath of changelogPaths) {
|
|
34
|
-
const {
|
|
34
|
+
const { versionedSections } = readChangelogSections(join(changelogPath, 'CHANGELOG.md'));
|
|
35
35
|
const entries = readChangelogEntries(resolveChangelogJsonPath(config, changelogPath)) ?? [];
|
|
36
|
-
for (const { version } of [...
|
|
36
|
+
for (const { version } of [...versionedSections, ...entries]) {
|
|
37
37
|
versions.add(version);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { packFromCleanCheckout } from './packFromCleanCheckout.js';
|
|
2
|
+
/**
|
|
3
|
+
* Throws when the tarball of a publishable package among the given workspaces would lack a file that its manifest
|
|
4
|
+
* names, or when the packages cannot be packed from a clean checkout of HEAD.
|
|
5
|
+
*
|
|
6
|
+
* Each workspace path is repo-relative and is read from the current directory. A private package is not packed, and
|
|
7
|
+
* an empty list doesn't clone anything.
|
|
8
|
+
*/
|
|
9
|
+
export declare function assertTarballsComplete(workspacePaths: readonly string[], devExportConditions: readonly string[], pack?: typeof packFromCleanCheckout): void;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { describeError } from '@williamthorsen/toolbelt.errors';
|
|
4
|
+
import { detectPackageManager } from "./detectPackageManager.js";
|
|
5
|
+
import { findMissingManifestPaths } from "./findMissingManifestPaths.js";
|
|
6
|
+
import { isPublishableManifest } from "./isPublishableManifest.js";
|
|
7
|
+
import { packFromCleanCheckout } from "./packFromCleanCheckout.js";
|
|
8
|
+
import { isRecord } from "./typeGuards.js";
|
|
9
|
+
export function assertTarballsComplete(workspacePaths, devExportConditions, pack = packFromCleanCheckout) {
|
|
10
|
+
const candidates = workspacePaths
|
|
11
|
+
.map((workspacePath) => ({ workspacePath, manifest: readManifest(workspacePath) }))
|
|
12
|
+
.filter(({ manifest }) => isPublishableManifest(manifest));
|
|
13
|
+
if (candidates.length === 0) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
process.stderr.write(`Checking the tarballs of ${candidates.length} ${candidates.length === 1 ? 'package' : 'packages'} from a clean checkout of HEAD...\n`);
|
|
17
|
+
let filesByWorkspace;
|
|
18
|
+
try {
|
|
19
|
+
filesByWorkspace = pack(candidates.map(({ workspacePath }) => workspacePath), detectPackageManager());
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
throw new Error(`Cannot release: The packages could not be packed from a clean checkout of HEAD.\n${describeError(error)}`, { cause: error });
|
|
23
|
+
}
|
|
24
|
+
const incompletePackages = candidates
|
|
25
|
+
.map(({ workspacePath, manifest }) => ({
|
|
26
|
+
workspacePath,
|
|
27
|
+
manifest,
|
|
28
|
+
missingPaths: findMissingManifestPaths(manifest, filesByWorkspace.get(workspacePath) ?? [], devExportConditions),
|
|
29
|
+
}))
|
|
30
|
+
.filter(({ missingPaths }) => missingPaths.length > 0);
|
|
31
|
+
if (incompletePackages.length === 0) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
throw new Error(describeRefusal(incompletePackages));
|
|
35
|
+
}
|
|
36
|
+
function describeRefusal(incompletePackages) {
|
|
37
|
+
const sections = ['Cannot release: The tarball of every package must contain each file that its manifest names.'];
|
|
38
|
+
for (const { workspacePath, manifest, missingPaths } of incompletePackages) {
|
|
39
|
+
const name = typeof manifest['name'] === 'string' ? manifest['name'] : workspacePath;
|
|
40
|
+
sections.push([
|
|
41
|
+
`${name} (${workspacePath}) lacks:`,
|
|
42
|
+
...missingPaths.map(({ location, path }) => ` - ${path} (${location})`),
|
|
43
|
+
].join('\n'));
|
|
44
|
+
}
|
|
45
|
+
sections.push('Build these files in the package\'s publish lifecycle, such as in a "prepack" script. ' +
|
|
46
|
+
'If an export condition is for development only, list it in the "devExportConditions" config key.');
|
|
47
|
+
return sections.join('\n\n');
|
|
48
|
+
}
|
|
49
|
+
function readManifest(workspacePath) {
|
|
50
|
+
const manifest = JSON.parse(readFileSync(join(workspacePath, 'package.json'), 'utf8'));
|
|
51
|
+
return isRecord(manifest) ? manifest : {};
|
|
52
|
+
}
|
|
@@ -127,12 +127,12 @@ if (command === 'init') {
|
|
|
127
127
|
}
|
|
128
128
|
enterRepoRootOrExit();
|
|
129
129
|
const initFlagSchema = {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
isDryRun: { long: '--dry-run', type: 'boolean' },
|
|
131
|
+
shouldForce: { long: '--force', type: 'boolean' },
|
|
132
|
+
shouldScaffoldConfig: { long: '--with-config', type: 'boolean' },
|
|
133
133
|
};
|
|
134
|
-
const {
|
|
135
|
-
const exitCode = initCommand({
|
|
134
|
+
const { isDryRun, shouldForce, shouldScaffoldConfig } = parseArgsOrExit(flags, initFlagSchema).flags;
|
|
135
|
+
const exitCode = initCommand({ isDryRun, shouldForce, styles, shouldScaffoldConfig });
|
|
136
136
|
process.exit(exitCode);
|
|
137
137
|
}
|
|
138
138
|
if (command === 'update-templates') {
|
|
@@ -142,10 +142,10 @@ if (command === 'update-templates') {
|
|
|
142
142
|
}
|
|
143
143
|
enterRepoRootOrExit();
|
|
144
144
|
const updateTemplatesFlagSchema = {
|
|
145
|
-
|
|
145
|
+
isDryRun: { long: '--dry-run', type: 'boolean' },
|
|
146
146
|
};
|
|
147
|
-
const {
|
|
148
|
-
const exitCode = updateTemplatesCommand({
|
|
147
|
+
const { isDryRun } = parseArgsOrExit(flags, updateTemplatesFlagSchema).flags;
|
|
148
|
+
const exitCode = updateTemplatesCommand({ isDryRun, styles });
|
|
149
149
|
process.exit(exitCode);
|
|
150
150
|
}
|
|
151
151
|
if (command === 'sync-labels') {
|
|
@@ -163,15 +163,15 @@ if (command === 'sync-labels') {
|
|
|
163
163
|
const { invocationDir } = enterRepoRootOrExit();
|
|
164
164
|
const syncLabelsInitFlagSchema = {
|
|
165
165
|
...configFlagSchema,
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
isDryRun: { long: '--dry-run', type: 'boolean' },
|
|
167
|
+
shouldForce: { long: '--force', type: 'boolean' },
|
|
168
168
|
};
|
|
169
|
-
const { config,
|
|
169
|
+
const { config, isDryRun, shouldForce } = parseArgsOrExit(subflags, syncLabelsInitFlagSchema).flags;
|
|
170
170
|
const configPath = resolveConfigFlag(config, invocationDir);
|
|
171
171
|
const exitCode = await syncLabelsInitCommand({
|
|
172
172
|
...(configPath !== undefined && { configPath }),
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
isDryRun,
|
|
174
|
+
shouldForce,
|
|
175
175
|
styles,
|
|
176
176
|
});
|
|
177
177
|
process.exit(exitCode);
|
|
@@ -184,11 +184,11 @@ if (command === 'sync-labels') {
|
|
|
184
184
|
const { invocationDir } = enterRepoRootOrExit();
|
|
185
185
|
const generateFlagSchema = {
|
|
186
186
|
...configFlagSchema,
|
|
187
|
-
|
|
187
|
+
shouldCheck: { long: '--check', type: 'boolean' },
|
|
188
188
|
};
|
|
189
|
-
const {
|
|
189
|
+
const { shouldCheck, config } = parseArgsOrExit(subflags, generateFlagSchema).flags;
|
|
190
190
|
const configPath = resolveConfigFlag(config, invocationDir);
|
|
191
|
-
const exitCode = await generateCommand({
|
|
191
|
+
const exitCode = await generateCommand({ shouldCheck, ...(configPath !== undefined && { configPath }), styles });
|
|
192
192
|
process.exit(exitCode);
|
|
193
193
|
}
|
|
194
194
|
if (subcommand === 'sync') {
|