@pob/version 5.2.0 → 6.0.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/LICENSE +21 -15
- package/README.md +147 -10
- package/dist/index-node.mjs +1482 -0
- package/dist/index-node.mjs.map +1 -0
- package/package.json +78 -19
- package/src/commands/version.test.ts +120 -0
- package/src/commands/version.ts +956 -0
- package/src/index.ts +13 -0
- package/src/missing-types.d.ts +10 -0
- package/src/pm/BunPackageManager.ts +29 -0
- package/src/pm/PackageManager.ts +90 -0
- package/src/pm/PnpmPackageManager.ts +23 -0
- package/src/pm/YarnPackageManager.ts +44 -0
- package/src/utils/UsageError.ts +6 -0
- package/src/utils/bumpTypeUtils.test.ts +65 -0
- package/src/utils/bumpTypeUtils.ts +111 -0
- package/src/utils/conventionalChangelogUtils.test.ts +762 -0
- package/src/utils/conventionalChangelogUtils.ts +104 -0
- package/src/utils/conventionalCommitConfigUtils.ts +19 -0
- package/src/utils/execCommand.ts +214 -0
- package/src/utils/generatorUtils.ts +11 -0
- package/src/utils/gitUtils.ts +193 -0
- package/src/utils/githubUtils.ts +120 -0
- package/src/utils/mapUtils.ts +7 -0
- package/src/utils/mapWorkspaces.test.ts +89 -0
- package/src/utils/packageDependenciesUtils.test.ts +25 -0
- package/src/utils/packageDependenciesUtils.ts +80 -0
- package/src/utils/packageUtils.test.ts +32 -0
- package/src/utils/packageUtils.ts +129 -0
- package/src/utils/updateChangelog.ts +39 -0
- package/src/utils/workspaceUtils.ts +142 -0
- package/.editorconfig +0 -13
- package/.eslintrc.json +0 -7
- package/CHANGELOG.md +0 -125
- package/generate-index.js +0 -13
- package/lib/index.d.ts +0 -8
- package/lib/index.js +0 -5
|
@@ -0,0 +1,956 @@
|
|
|
1
|
+
/* eslint-disable complexity */
|
|
2
|
+
|
|
3
|
+
import { Option, program } from "commander";
|
|
4
|
+
import { LoggerCLI } from "nightingale";
|
|
5
|
+
import { satisfies } from "semver";
|
|
6
|
+
import {
|
|
7
|
+
autoDetectPackageManager,
|
|
8
|
+
getPackageManager,
|
|
9
|
+
} from "../pm/PackageManager.ts";
|
|
10
|
+
import { UsageError } from "../utils/UsageError.ts";
|
|
11
|
+
import type { BumpType } from "../utils/bumpTypeUtils.ts";
|
|
12
|
+
import {
|
|
13
|
+
calcBumpRange,
|
|
14
|
+
calcBumpType,
|
|
15
|
+
getHighestBumpType,
|
|
16
|
+
incrementVersion,
|
|
17
|
+
} from "../utils/bumpTypeUtils.ts";
|
|
18
|
+
import {
|
|
19
|
+
createCommitsParser,
|
|
20
|
+
generateChangelog,
|
|
21
|
+
recommendBump,
|
|
22
|
+
} from "../utils/conventionalChangelogUtils.ts";
|
|
23
|
+
import { loadConventionalCommitConfig } from "../utils/conventionalCommitConfigUtils.ts";
|
|
24
|
+
import { asyncIterableToArray } from "../utils/generatorUtils.ts";
|
|
25
|
+
import type { GitTagVersion } from "../utils/gitUtils.ts";
|
|
26
|
+
import {
|
|
27
|
+
createGitCommit,
|
|
28
|
+
createGitTag,
|
|
29
|
+
getDirtyFiles,
|
|
30
|
+
getGitCommits,
|
|
31
|
+
getGitCurrentBranch,
|
|
32
|
+
getGitLatestTagVersion,
|
|
33
|
+
isBehindRemote,
|
|
34
|
+
pushCommitsAndTags,
|
|
35
|
+
} from "../utils/gitUtils.ts";
|
|
36
|
+
import {
|
|
37
|
+
createGhRelease,
|
|
38
|
+
ensureGhCliAvailable,
|
|
39
|
+
parseGithubRepoUrl,
|
|
40
|
+
} from "../utils/githubUtils.ts";
|
|
41
|
+
import {
|
|
42
|
+
PackageDependencyDescriptorUtils,
|
|
43
|
+
PackageDescriptorNameUtils,
|
|
44
|
+
} from "../utils/packageDependenciesUtils.ts";
|
|
45
|
+
import type { PackageDependencyDescriptor } from "../utils/packageDependenciesUtils.ts";
|
|
46
|
+
import type { Workspace } from "../utils/packageUtils.ts";
|
|
47
|
+
import {
|
|
48
|
+
createProjectWorkspace,
|
|
49
|
+
createWorkspace,
|
|
50
|
+
findRootWorkspace,
|
|
51
|
+
writePkg,
|
|
52
|
+
} from "../utils/packageUtils.ts";
|
|
53
|
+
import { updateChangelogFile } from "../utils/updateChangelog.ts";
|
|
54
|
+
import type { DependencyType } from "../utils/workspaceUtils.ts";
|
|
55
|
+
import {
|
|
56
|
+
buildDependenciesMaps,
|
|
57
|
+
buildTopologicalOrderBatches,
|
|
58
|
+
getWorkspaceName,
|
|
59
|
+
} from "../utils/workspaceUtils.ts";
|
|
60
|
+
|
|
61
|
+
export interface VersionCommandOptions {
|
|
62
|
+
cwd: string;
|
|
63
|
+
includesRoot: boolean;
|
|
64
|
+
dryRun: boolean;
|
|
65
|
+
force?: "major" | "minor" | "patch";
|
|
66
|
+
prerelease?: string;
|
|
67
|
+
json: boolean;
|
|
68
|
+
preset: string;
|
|
69
|
+
tagVersionPrefix: string;
|
|
70
|
+
changelog: string;
|
|
71
|
+
commitMessage: string;
|
|
72
|
+
createRelease: boolean;
|
|
73
|
+
bumpDependentsHighestAs: "major" | "minor" | "patch";
|
|
74
|
+
alwaysBumpPeerDependencies: boolean;
|
|
75
|
+
gitRemote: string;
|
|
76
|
+
ignoreChanges?: string;
|
|
77
|
+
verbose?: boolean;
|
|
78
|
+
cwdIsRoot?: boolean;
|
|
79
|
+
packageManager?: "bun" | "yarn";
|
|
80
|
+
publish?: boolean;
|
|
81
|
+
publishProvenance?: boolean;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface BumpableWorkspace {
|
|
85
|
+
workspace: Workspace;
|
|
86
|
+
previousTag?: string;
|
|
87
|
+
workspaceName: string;
|
|
88
|
+
isRoot: boolean;
|
|
89
|
+
version: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
interface ChangedWorkspace {
|
|
93
|
+
bumpReason?: string;
|
|
94
|
+
bumpType: BumpType;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface NoVersionToUpdateWorkspace {
|
|
98
|
+
// for legacy configuration not using workspaces ranges https://yarnpkg.com/features/workspaces#workspace-ranges-workspace
|
|
99
|
+
dependenciesToBump: [DependencyType, PackageDependencyDescriptor, string][];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
interface BumpedWorkspace extends ChangedWorkspace, NoVersionToUpdateWorkspace {
|
|
103
|
+
bumpForDependenciesReasons?: string[];
|
|
104
|
+
hasChanged: boolean;
|
|
105
|
+
currentVersion: string;
|
|
106
|
+
newVersion: string;
|
|
107
|
+
newTag: string | null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const todayInYYYYMMDD = (): string => {
|
|
111
|
+
// sv-SEis used for yyyy-mm-dd format
|
|
112
|
+
const dateFormatter = Intl.DateTimeFormat("sv-SE", {
|
|
113
|
+
timeZone: "UTC",
|
|
114
|
+
});
|
|
115
|
+
return dateFormatter.format(new Date());
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export const versionCommandAction = async (
|
|
119
|
+
options: VersionCommandOptions,
|
|
120
|
+
{ logger = new LoggerCLI("@pob/version", { json: options.json }) } = {},
|
|
121
|
+
): Promise<void> => {
|
|
122
|
+
const rootWorkspace = await (options.cwdIsRoot
|
|
123
|
+
? createWorkspace(options.cwd)
|
|
124
|
+
: findRootWorkspace(options.cwd));
|
|
125
|
+
|
|
126
|
+
if (!rootWorkspace) {
|
|
127
|
+
throw new UsageError("Could not find root workspace from this path.");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const packageManager = options.packageManager
|
|
131
|
+
? getPackageManager(rootWorkspace, options.packageManager)
|
|
132
|
+
: autoDetectPackageManager(rootWorkspace);
|
|
133
|
+
|
|
134
|
+
const project = await createProjectWorkspace(rootWorkspace);
|
|
135
|
+
|
|
136
|
+
if (!options.dryRun) {
|
|
137
|
+
const dirtyFiles = await getDirtyFiles(project.root);
|
|
138
|
+
if (dirtyFiles) {
|
|
139
|
+
throw new Error(
|
|
140
|
+
`Dirty Files:\n${dirtyFiles}\n\nThere are uncommitted changes in the git repository. Please commit or stash them first.`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const rootWorkspaceChildren = [...project.children.values()];
|
|
146
|
+
let rootNewVersion = "";
|
|
147
|
+
let rootNewTag = "";
|
|
148
|
+
const isMonorepo = rootWorkspaceChildren.length > 0;
|
|
149
|
+
const isMonorepoVersionIndependent = isMonorepo && !rootWorkspace.pkg.version;
|
|
150
|
+
const workspaces =
|
|
151
|
+
!(isMonorepo && !rootWorkspaceChildren) || options.includesRoot
|
|
152
|
+
? [rootWorkspace, ...rootWorkspaceChildren]
|
|
153
|
+
: rootWorkspaceChildren;
|
|
154
|
+
|
|
155
|
+
if (options.prerelease) {
|
|
156
|
+
throw new UsageError("--prerelease is not supported yet.");
|
|
157
|
+
}
|
|
158
|
+
if (options.ignoreChanges) {
|
|
159
|
+
throw new UsageError("--ignore-changes is not supported yet.");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const [conventionalCommitConfig, parsedRepoUrl, gitCurrentBranch] =
|
|
163
|
+
await Promise.all([
|
|
164
|
+
loadConventionalCommitConfig(rootWorkspace, options.preset),
|
|
165
|
+
options.createRelease
|
|
166
|
+
? parseGithubRepoUrl(rootWorkspace)
|
|
167
|
+
: Promise.resolve(null),
|
|
168
|
+
getGitCurrentBranch(rootWorkspace),
|
|
169
|
+
// ensure gh CLI is available early to fail fast if necessary
|
|
170
|
+
options.createRelease
|
|
171
|
+
? ensureGhCliAvailable(rootWorkspace)
|
|
172
|
+
: Promise.resolve(undefined),
|
|
173
|
+
]);
|
|
174
|
+
|
|
175
|
+
const rootPreviousVersionTagPromise =
|
|
176
|
+
options.force || isMonorepoVersionIndependent
|
|
177
|
+
? null
|
|
178
|
+
: getGitLatestTagVersion(rootWorkspace, {
|
|
179
|
+
prefix: options.tagVersionPrefix,
|
|
180
|
+
skipUnstable: true,
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const buildTagName = (workspace: Workspace, version: string): string =>
|
|
184
|
+
`${
|
|
185
|
+
isMonorepo && workspace !== rootWorkspace
|
|
186
|
+
? `${getWorkspaceName(workspace)}@`
|
|
187
|
+
: options.tagVersionPrefix
|
|
188
|
+
}${version}`;
|
|
189
|
+
|
|
190
|
+
const changedWorkspaces = new Map<Workspace, ChangedWorkspace>();
|
|
191
|
+
const dependenciesMap = isMonorepo ? buildDependenciesMaps(project) : null;
|
|
192
|
+
|
|
193
|
+
const bumpableWorkspaces: BumpableWorkspace[] = [];
|
|
194
|
+
|
|
195
|
+
logger.group(
|
|
196
|
+
options.force
|
|
197
|
+
? "Check all workspaces (force option)"
|
|
198
|
+
: "Finding changed workspaces",
|
|
199
|
+
() => {
|
|
200
|
+
// check workspaces and create bumpableWorkspaces
|
|
201
|
+
|
|
202
|
+
for (const workspace of workspaces) {
|
|
203
|
+
const workspaceName = getWorkspaceName(workspace);
|
|
204
|
+
const isRoot = workspace === rootWorkspace;
|
|
205
|
+
if (isRoot && isMonorepo && isMonorepoVersionIndependent) continue;
|
|
206
|
+
|
|
207
|
+
const version = workspace.pkg.version;
|
|
208
|
+
|
|
209
|
+
if (!version || version === "0.0.0") {
|
|
210
|
+
if (
|
|
211
|
+
(isRoot || isMonorepoVersionIndependent) &&
|
|
212
|
+
(!isMonorepo || !isMonorepoVersionIndependent)
|
|
213
|
+
) {
|
|
214
|
+
throw new UsageError(
|
|
215
|
+
'package.json has no version in its manifest. For the first release, set to "1.0.0-pre" or "0.1.0-pre".',
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
logger.info(`${workspaceName}: skipped (no version)`);
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
bumpableWorkspaces.push({
|
|
224
|
+
workspace,
|
|
225
|
+
workspaceName,
|
|
226
|
+
isRoot,
|
|
227
|
+
version,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (bumpableWorkspaces.length > 0) {
|
|
232
|
+
logger.info("Found bumpable workspaces", {
|
|
233
|
+
count: bumpableWorkspaces.length,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
const previousTagVersionByWorkspace = new Map<
|
|
240
|
+
Workspace,
|
|
241
|
+
GitTagVersion | null
|
|
242
|
+
>(
|
|
243
|
+
await Promise.all(
|
|
244
|
+
bumpableWorkspaces.map(async ({ workspace, workspaceName, isRoot }) => {
|
|
245
|
+
const packageOption =
|
|
246
|
+
isMonorepo && isMonorepoVersionIndependent
|
|
247
|
+
? workspaceName
|
|
248
|
+
: undefined;
|
|
249
|
+
|
|
250
|
+
const tagPrefix = packageOption
|
|
251
|
+
? `${packageOption}@`
|
|
252
|
+
: options.tagVersionPrefix;
|
|
253
|
+
|
|
254
|
+
const previousTagAndVersion = await (isRoot ||
|
|
255
|
+
!isMonorepoVersionIndependent
|
|
256
|
+
? rootPreviousVersionTagPromise
|
|
257
|
+
: getGitLatestTagVersion(rootWorkspace, {
|
|
258
|
+
path: workspace.relativeCwd,
|
|
259
|
+
prefix: tagPrefix,
|
|
260
|
+
skipUnstable: true,
|
|
261
|
+
}));
|
|
262
|
+
|
|
263
|
+
return [workspace, previousTagAndVersion] as const;
|
|
264
|
+
}),
|
|
265
|
+
),
|
|
266
|
+
);
|
|
267
|
+
|
|
268
|
+
if (options.dryRun) {
|
|
269
|
+
logger.info("Previous tags", {
|
|
270
|
+
previousTagByWorkspace: Object.fromEntries(
|
|
271
|
+
[...previousTagVersionByWorkspace.entries()].map(
|
|
272
|
+
([workspace, previousTagVersion]) => [
|
|
273
|
+
getWorkspaceName(workspace),
|
|
274
|
+
previousTagVersion?.tag,
|
|
275
|
+
],
|
|
276
|
+
),
|
|
277
|
+
),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const parseCommits = createCommitsParser(conventionalCommitConfig);
|
|
282
|
+
|
|
283
|
+
const commitsByWorkspace = options.force
|
|
284
|
+
? undefined
|
|
285
|
+
: new Map(
|
|
286
|
+
await Promise.all(
|
|
287
|
+
bumpableWorkspaces.map(async ({ workspace }) => {
|
|
288
|
+
const previousTagVersion =
|
|
289
|
+
previousTagVersionByWorkspace.get(workspace);
|
|
290
|
+
|
|
291
|
+
const commits = await asyncIterableToArray(
|
|
292
|
+
parseCommits(
|
|
293
|
+
getGitCommits(rootWorkspace, {
|
|
294
|
+
path: workspace.relativeCwd,
|
|
295
|
+
from: previousTagVersion?.tag || undefined,
|
|
296
|
+
}),
|
|
297
|
+
),
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
return [workspace, commits] as const;
|
|
301
|
+
}),
|
|
302
|
+
),
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
await logger.group("Finding changed workspaces", async () => {
|
|
306
|
+
for (const { workspace, workspaceName } of bumpableWorkspaces) {
|
|
307
|
+
let bumpType: BumpType | null = null;
|
|
308
|
+
let bumpReason: string | undefined;
|
|
309
|
+
|
|
310
|
+
if (options.force) {
|
|
311
|
+
bumpType = options.force;
|
|
312
|
+
bumpReason = "forced by --force flag";
|
|
313
|
+
} else {
|
|
314
|
+
const commits = commitsByWorkspace?.get(workspace);
|
|
315
|
+
|
|
316
|
+
// No changes found for this package
|
|
317
|
+
if (!commits || commits.length === 0) {
|
|
318
|
+
logger.info(`${workspaceName}: skipped (no changes)`);
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const { releaseType, reason } = await recommendBump(
|
|
323
|
+
commits,
|
|
324
|
+
conventionalCommitConfig,
|
|
325
|
+
);
|
|
326
|
+
bumpReason = reason;
|
|
327
|
+
|
|
328
|
+
if (releaseType) {
|
|
329
|
+
bumpType = releaseType satisfies BumpType;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (bumpType) {
|
|
334
|
+
if (isMonorepo && !workspace.pkg.name) {
|
|
335
|
+
throw new Error("Workspace name is required");
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const currentVersion = workspace.pkg.version;
|
|
339
|
+
|
|
340
|
+
if (!currentVersion) {
|
|
341
|
+
throw new UsageError(
|
|
342
|
+
`Invalid "${getWorkspaceName(workspace)}" version`,
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
changedWorkspaces.set(workspace, {
|
|
347
|
+
bumpType,
|
|
348
|
+
bumpReason,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (changedWorkspaces.size === 0) {
|
|
354
|
+
logger.info("No changed workspaces");
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
const bumpedWorkspaces = new Map<Workspace, BumpedWorkspace>();
|
|
359
|
+
const noVersionToUpdateWorkspaces = new Map<
|
|
360
|
+
Workspace,
|
|
361
|
+
NoVersionToUpdateWorkspace
|
|
362
|
+
>();
|
|
363
|
+
const batches = dependenciesMap
|
|
364
|
+
? buildTopologicalOrderBatches(project, dependenciesMap)
|
|
365
|
+
: [[rootWorkspace]];
|
|
366
|
+
|
|
367
|
+
logger.group("Preparing bumping", () => {
|
|
368
|
+
for (const batch of batches) {
|
|
369
|
+
for (const workspace of batch) {
|
|
370
|
+
const currentVersion = workspace.pkg.version;
|
|
371
|
+
|
|
372
|
+
if (!currentVersion && !workspace.pkg.private) {
|
|
373
|
+
throw new UsageError(
|
|
374
|
+
`Invalid "${getWorkspaceName(workspace)}" version`,
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const changedWorkspace = changedWorkspaces.get(workspace);
|
|
379
|
+
let bumpType: BumpType | null = null;
|
|
380
|
+
const bumpReasons: string[] = [];
|
|
381
|
+
const dependenciesToBump: BumpedWorkspace["dependenciesToBump"] = [];
|
|
382
|
+
|
|
383
|
+
if (changedWorkspace) {
|
|
384
|
+
bumpType = changedWorkspace.bumpType;
|
|
385
|
+
bumpReasons.push(changedWorkspace.bumpReason || "by commits");
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const dependencies = dependenciesMap?.get(workspace);
|
|
389
|
+
|
|
390
|
+
if (dependencies) {
|
|
391
|
+
for (const [
|
|
392
|
+
dependencyWorkspace,
|
|
393
|
+
dependencyType,
|
|
394
|
+
dependencyDescriptor,
|
|
395
|
+
] of dependencies) {
|
|
396
|
+
const dependencyBumpedWorkspace =
|
|
397
|
+
bumpedWorkspaces.get(dependencyWorkspace);
|
|
398
|
+
|
|
399
|
+
if (!dependencyBumpedWorkspace) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (
|
|
404
|
+
dependencyType === "peerDependencies" &&
|
|
405
|
+
!options.alwaysBumpPeerDependencies &&
|
|
406
|
+
// skip when peerdependency with a new version satisfied by the existing range.
|
|
407
|
+
satisfies(
|
|
408
|
+
dependencyBumpedWorkspace.newVersion,
|
|
409
|
+
dependencyDescriptor.selector,
|
|
410
|
+
{
|
|
411
|
+
includePrerelease: true,
|
|
412
|
+
},
|
|
413
|
+
)
|
|
414
|
+
) {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const newRange = calcBumpRange(
|
|
419
|
+
workspace,
|
|
420
|
+
dependencyDescriptor.selector,
|
|
421
|
+
dependencyBumpedWorkspace.newVersion,
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
if (
|
|
425
|
+
dependencyDescriptor.selector === newRange &&
|
|
426
|
+
newRange !== "workspace:*" &&
|
|
427
|
+
newRange !== "workspace:^" &&
|
|
428
|
+
newRange !== "workspace:~"
|
|
429
|
+
) {
|
|
430
|
+
continue;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
dependenciesToBump.push([
|
|
434
|
+
dependencyType,
|
|
435
|
+
dependencyDescriptor,
|
|
436
|
+
newRange,
|
|
437
|
+
]);
|
|
438
|
+
|
|
439
|
+
bumpType = getHighestBumpType([
|
|
440
|
+
bumpType ?? "patch",
|
|
441
|
+
calcBumpType(
|
|
442
|
+
dependencyBumpedWorkspace.bumpType,
|
|
443
|
+
options.bumpDependentsHighestAs,
|
|
444
|
+
),
|
|
445
|
+
]);
|
|
446
|
+
|
|
447
|
+
bumpReasons.push(
|
|
448
|
+
`Version bump for dependency: ${PackageDescriptorNameUtils.stringify(dependencyDescriptor.name)}`,
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
const workspaceName = getWorkspaceName(workspace);
|
|
454
|
+
if (!currentVersion) {
|
|
455
|
+
logger.info(`${workspaceName}: skipped (no version)`);
|
|
456
|
+
if (workspace !== rootWorkspace) {
|
|
457
|
+
noVersionToUpdateWorkspaces.set(workspace, {
|
|
458
|
+
dependenciesToBump,
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
} else if (!bumpType) {
|
|
462
|
+
logger.info(
|
|
463
|
+
`${workspaceName}: skipped (${
|
|
464
|
+
changedWorkspace
|
|
465
|
+
? `no bump recommended by ${options.preset}`
|
|
466
|
+
: "no changes"
|
|
467
|
+
})`,
|
|
468
|
+
);
|
|
469
|
+
} else {
|
|
470
|
+
const newVersion = incrementVersion(
|
|
471
|
+
workspace,
|
|
472
|
+
currentVersion,
|
|
473
|
+
bumpType,
|
|
474
|
+
);
|
|
475
|
+
|
|
476
|
+
const tagName = buildTagName(workspace, newVersion);
|
|
477
|
+
|
|
478
|
+
if (workspace === rootWorkspace) {
|
|
479
|
+
rootNewVersion = newVersion;
|
|
480
|
+
rootNewTag = tagName;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (workspace !== rootWorkspace || !isMonorepo) {
|
|
484
|
+
const bumpReason = bumpReasons.join("\n");
|
|
485
|
+
bumpedWorkspaces.set(workspace, {
|
|
486
|
+
currentVersion,
|
|
487
|
+
bumpType,
|
|
488
|
+
bumpReason,
|
|
489
|
+
bumpForDependenciesReasons: changedWorkspace
|
|
490
|
+
? bumpReasons.slice(1)
|
|
491
|
+
: bumpReasons,
|
|
492
|
+
newVersion,
|
|
493
|
+
newTag: tagName,
|
|
494
|
+
hasChanged: changedWorkspace !== undefined,
|
|
495
|
+
dependenciesToBump,
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
logger.info(
|
|
499
|
+
`${workspaceName}: ${currentVersion} -> ${
|
|
500
|
+
!isMonorepo || isMonorepoVersionIndependent
|
|
501
|
+
? newVersion
|
|
502
|
+
: "bump"
|
|
503
|
+
} (${bumpReason.replaceAll("\n", " ; ")})`,
|
|
504
|
+
);
|
|
505
|
+
// TODO Json only:
|
|
506
|
+
// logger.info({
|
|
507
|
+
// cwd: npath.fromPortablePath(workspace.cwd),
|
|
508
|
+
// ident: workspaceName,
|
|
509
|
+
// oldVersion: currentVersion,
|
|
510
|
+
// ...(isMonorepoVersionIndependent ? { newVersion } : {}),
|
|
511
|
+
// bumpType,
|
|
512
|
+
// bumpReasons,
|
|
513
|
+
// });
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
// TODO ask for confirmation
|
|
521
|
+
// if (!this.yes) {
|
|
522
|
+
// }
|
|
523
|
+
|
|
524
|
+
// TODO do this entire phase here, not override for not independent only
|
|
525
|
+
if (isMonorepo && !isMonorepoVersionIndependent) {
|
|
526
|
+
const currentVersion = rootWorkspace.pkg.version!;
|
|
527
|
+
const highestBumpType = getHighestBumpType(
|
|
528
|
+
[...bumpedWorkspaces.values()].map(({ bumpType }) => bumpType),
|
|
529
|
+
);
|
|
530
|
+
const newVersion = incrementVersion(
|
|
531
|
+
rootWorkspace,
|
|
532
|
+
currentVersion,
|
|
533
|
+
highestBumpType,
|
|
534
|
+
);
|
|
535
|
+
rootNewVersion = newVersion;
|
|
536
|
+
rootNewTag = buildTagName(rootWorkspace, newVersion);
|
|
537
|
+
|
|
538
|
+
[...bumpedWorkspaces.entries()].forEach(([workspace, bumpedWorkspace]) => {
|
|
539
|
+
const isRoot = workspace === rootWorkspace;
|
|
540
|
+
if (isRoot) {
|
|
541
|
+
throw new Error("Unexpected root found in bumped workspaces");
|
|
542
|
+
}
|
|
543
|
+
bumpedWorkspace.bumpType = highestBumpType;
|
|
544
|
+
bumpedWorkspace.newVersion = newVersion;
|
|
545
|
+
bumpedWorkspace.newTag = null;
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
[
|
|
549
|
+
...bumpedWorkspaces.entries(),
|
|
550
|
+
...noVersionToUpdateWorkspaces.entries(),
|
|
551
|
+
].forEach(([workspace, { dependenciesToBump }]) => {
|
|
552
|
+
dependenciesToBump.forEach((dependencyToBump) => {
|
|
553
|
+
dependencyToBump[2] = calcBumpRange(
|
|
554
|
+
workspace,
|
|
555
|
+
dependencyToBump[1].selector,
|
|
556
|
+
newVersion,
|
|
557
|
+
);
|
|
558
|
+
});
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
bumpedWorkspaces.set(rootWorkspace, {
|
|
562
|
+
currentVersion,
|
|
563
|
+
bumpType: highestBumpType,
|
|
564
|
+
hasChanged: true,
|
|
565
|
+
newVersion: rootNewVersion,
|
|
566
|
+
newTag: rootNewTag,
|
|
567
|
+
dependenciesToBump: [],
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
logger.info(
|
|
571
|
+
`${currentVersion} -> ${newVersion}`,
|
|
572
|
+
// TODO Json only:
|
|
573
|
+
// {
|
|
574
|
+
// oldVersion: currentVersion,
|
|
575
|
+
// newVersion, },
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
await logger.group("Applying changes", async () => {
|
|
580
|
+
// Update lockfile ; must be done to make sure preversion script can be ran
|
|
581
|
+
|
|
582
|
+
if (!options.dryRun) {
|
|
583
|
+
if (packageManager.installOnPackageContentChange) {
|
|
584
|
+
logger.info(`${getWorkspaceName(rootWorkspace)}: Running install`);
|
|
585
|
+
await packageManager.installOnPackageContentChange(rootWorkspace);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
logger.info("Lifecycle script: preversion");
|
|
589
|
+
|
|
590
|
+
if (
|
|
591
|
+
isMonorepoVersionIndependent &&
|
|
592
|
+
rootWorkspace.pkg.scripts?.preversion
|
|
593
|
+
) {
|
|
594
|
+
await packageManager.runScript(rootWorkspace, "preversion");
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// lifecycle: preversion
|
|
598
|
+
for (const workspace of bumpedWorkspaces.keys()) {
|
|
599
|
+
if (workspace.pkg.scripts?.preversion) {
|
|
600
|
+
await packageManager.runScript(workspace, "preversion");
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
logger.info("Modifying versions in package.json");
|
|
605
|
+
// update versions
|
|
606
|
+
|
|
607
|
+
await Promise.all(
|
|
608
|
+
[...bumpedWorkspaces.entries()].map(
|
|
609
|
+
([workspace, { newVersion, dependenciesToBump }]) => {
|
|
610
|
+
workspace.pkg.version = newVersion;
|
|
611
|
+
|
|
612
|
+
for (const [
|
|
613
|
+
dependencyType,
|
|
614
|
+
dependencyDescriptor,
|
|
615
|
+
dependencyNewRange,
|
|
616
|
+
] of dependenciesToBump) {
|
|
617
|
+
const newDescriptor = PackageDependencyDescriptorUtils.make(
|
|
618
|
+
dependencyDescriptor,
|
|
619
|
+
dependencyNewRange,
|
|
620
|
+
);
|
|
621
|
+
const [key, newValue] =
|
|
622
|
+
PackageDependencyDescriptorUtils.stringify(newDescriptor);
|
|
623
|
+
workspace.pkg[dependencyType]![key] = newValue;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
return writePkg(workspace);
|
|
627
|
+
},
|
|
628
|
+
),
|
|
629
|
+
);
|
|
630
|
+
|
|
631
|
+
if (packageManager.installOnPackageContentChange) {
|
|
632
|
+
// Update lockfile ; must be done before running again lifecycle scripts
|
|
633
|
+
logger.info(`${getWorkspaceName(rootWorkspace)}: Running install`);
|
|
634
|
+
await packageManager.installOnPackageContentChange(rootWorkspace);
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// lifecycle: version
|
|
638
|
+
logger.info("Lifecycle script: version");
|
|
639
|
+
for (const workspace of bumpedWorkspaces.keys()) {
|
|
640
|
+
if (workspace.pkg.scripts?.version) {
|
|
641
|
+
await packageManager.runScript(workspace, "version");
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (isMonorepoVersionIndependent && rootWorkspace.pkg.scripts?.version) {
|
|
647
|
+
await packageManager.runScript(rootWorkspace, "version");
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
const changelogs = new Map<Workspace, string>();
|
|
652
|
+
|
|
653
|
+
await Promise.all(
|
|
654
|
+
[...bumpedWorkspaces.entries()].map(
|
|
655
|
+
async ([
|
|
656
|
+
workspace,
|
|
657
|
+
{ newTag, hasChanged, bumpReason, bumpForDependenciesReasons },
|
|
658
|
+
]) => {
|
|
659
|
+
// const workspaceRelativePath =
|
|
660
|
+
// rootWorkspace === workspace
|
|
661
|
+
// ? undefined
|
|
662
|
+
// : path.relative(rootWorkspace.cwd, workspace.cwd);
|
|
663
|
+
|
|
664
|
+
const commits = commitsByWorkspace?.get(workspace);
|
|
665
|
+
|
|
666
|
+
let changelog = await generateChangelog(
|
|
667
|
+
rootWorkspace,
|
|
668
|
+
workspace.pkg,
|
|
669
|
+
conventionalCommitConfig,
|
|
670
|
+
previousTagVersionByWorkspace.get(workspace)?.tag || null,
|
|
671
|
+
isMonorepoVersionIndependent ? newTag : rootNewTag,
|
|
672
|
+
commits,
|
|
673
|
+
todayInYYYYMMDD(),
|
|
674
|
+
// {
|
|
675
|
+
// path: workspaceRelativePath,
|
|
676
|
+
// previousTag: previousTagByWorkspace.get(workspace) || undefined,
|
|
677
|
+
// verbose: options.verbose,
|
|
678
|
+
// tagPrefix: options.tagVersionPrefix,
|
|
679
|
+
// lernaPackage:
|
|
680
|
+
// rootWorkspace === workspace
|
|
681
|
+
// ? undefined
|
|
682
|
+
// : getWorkspaceName(workspace),
|
|
683
|
+
// },
|
|
684
|
+
);
|
|
685
|
+
|
|
686
|
+
if (bumpForDependenciesReasons && workspace !== rootWorkspace) {
|
|
687
|
+
if (bumpForDependenciesReasons.length > 0) {
|
|
688
|
+
changelog += `${!changelog.endsWith("\n\n") ? "\n" : ""}${bumpForDependenciesReasons.join("\n")}\n\n`;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
if (changelog.slice(changelog.indexOf("\n")).trim().length === 0) {
|
|
693
|
+
changelog += `${!changelog.endsWith("\n\n") ? "\n" : ""}Note: no notable changes\n\n`;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
if (!changelog && rootWorkspace === workspace) {
|
|
697
|
+
throw new Error("No changelog found for root workspace");
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
changelogs.set(workspace, changelog);
|
|
701
|
+
|
|
702
|
+
if (options.changelog) {
|
|
703
|
+
if (options.dryRun) {
|
|
704
|
+
logger.info(
|
|
705
|
+
`${getWorkspaceName(workspace)}: ${options.changelog}\n${changelog}`,
|
|
706
|
+
);
|
|
707
|
+
} else {
|
|
708
|
+
await updateChangelogFile(
|
|
709
|
+
changelog,
|
|
710
|
+
options.tagVersionPrefix,
|
|
711
|
+
`${workspace.cwd}/${options.changelog}`,
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
},
|
|
716
|
+
),
|
|
717
|
+
);
|
|
718
|
+
|
|
719
|
+
if (!options.dryRun) {
|
|
720
|
+
logger.separator();
|
|
721
|
+
|
|
722
|
+
if (packageManager.installOnPackageContentChange) {
|
|
723
|
+
// install to update versions in lock file
|
|
724
|
+
logger.info(`${getWorkspaceName(rootWorkspace)}: Running install`);
|
|
725
|
+
await packageManager.installOnPackageContentChange(rootWorkspace);
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
logger.separator();
|
|
729
|
+
|
|
730
|
+
const changedFiles = await getDirtyFiles(project.root);
|
|
731
|
+
|
|
732
|
+
if (changedFiles) {
|
|
733
|
+
logger.info("Commit, tag and push", {
|
|
734
|
+
changedFiles,
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
const tagsSet = new Set<string>(
|
|
738
|
+
[...bumpedWorkspaces.values()]
|
|
739
|
+
.map(({ newTag }) => newTag)
|
|
740
|
+
.filter((newTag) => newTag !== null),
|
|
741
|
+
);
|
|
742
|
+
|
|
743
|
+
const tagsInCommitMessage = [...tagsSet]
|
|
744
|
+
.map((tag) => `- ${tag}`)
|
|
745
|
+
.join("\n");
|
|
746
|
+
const message = options.commitMessage
|
|
747
|
+
.replace(/\\n/g, "\n")
|
|
748
|
+
.replace(
|
|
749
|
+
/%a/g,
|
|
750
|
+
isMonorepoVersionIndependent
|
|
751
|
+
? `\n\n${tagsInCommitMessage}`
|
|
752
|
+
: rootNewVersion,
|
|
753
|
+
)
|
|
754
|
+
.replace(/%s/g, rootNewTag)
|
|
755
|
+
.replace(/%v/g, rootNewVersion)
|
|
756
|
+
.replace(/%t/g, tagsInCommitMessage);
|
|
757
|
+
|
|
758
|
+
await createGitCommit(rootWorkspace, message);
|
|
759
|
+
|
|
760
|
+
for (const [workspace, { newTag }] of bumpedWorkspaces.entries()) {
|
|
761
|
+
if (newTag === null) continue;
|
|
762
|
+
await createGitTag(workspace, newTag);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
if (
|
|
766
|
+
await isBehindRemote(rootWorkspace, options.gitRemote, gitCurrentBranch)
|
|
767
|
+
) {
|
|
768
|
+
logger.error("Remote is ahead, aborting");
|
|
769
|
+
// eslint-disable-next-line unicorn/no-process-exit
|
|
770
|
+
process.exit(1);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
await pushCommitsAndTags(
|
|
774
|
+
rootWorkspace,
|
|
775
|
+
options.gitRemote,
|
|
776
|
+
gitCurrentBranch,
|
|
777
|
+
);
|
|
778
|
+
|
|
779
|
+
// run postversion
|
|
780
|
+
if (rootWorkspace.pkg.scripts?.postversion) {
|
|
781
|
+
logger.info("Lifecycle script: postversion");
|
|
782
|
+
await packageManager.runScript(rootWorkspace, "postversion");
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
// TODO open github PR
|
|
786
|
+
|
|
787
|
+
if (options.createRelease && parsedRepoUrl) {
|
|
788
|
+
logger.info("Create git release");
|
|
789
|
+
|
|
790
|
+
await Promise.all(
|
|
791
|
+
[...bumpedWorkspaces.entries()].map(([workspace, { newTag }]) => {
|
|
792
|
+
if (newTag === null) return Promise.resolve(undefined);
|
|
793
|
+
const changelog = changelogs.get(workspace);
|
|
794
|
+
if (!changelog) {
|
|
795
|
+
logger.warn(
|
|
796
|
+
`No changelog found for workspace: ${getWorkspaceName(workspace)}`,
|
|
797
|
+
);
|
|
798
|
+
return Promise.resolve(undefined);
|
|
799
|
+
}
|
|
800
|
+
return createGhRelease(workspace, {
|
|
801
|
+
parsedRepoUrl,
|
|
802
|
+
title: newTag,
|
|
803
|
+
tag: newTag,
|
|
804
|
+
body: changelog,
|
|
805
|
+
prerelease: !!options.prerelease,
|
|
806
|
+
});
|
|
807
|
+
}),
|
|
808
|
+
);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
if (!options.publish) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
await logger.group("Publishing packages", async () => {
|
|
815
|
+
if (packageManager.publishWorkspaces) {
|
|
816
|
+
await packageManager.publishWorkspaces(rootWorkspace, {
|
|
817
|
+
provenance: options.publishProvenance,
|
|
818
|
+
});
|
|
819
|
+
} else {
|
|
820
|
+
for (const [workspace] of bumpedWorkspaces.entries()) {
|
|
821
|
+
if (workspace.pkg.private) {
|
|
822
|
+
logger.info(
|
|
823
|
+
`Skipping private workspace ${getWorkspaceName(workspace)}`,
|
|
824
|
+
);
|
|
825
|
+
continue;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
logger.info(`Publishing ${getWorkspaceName(workspace)}`);
|
|
829
|
+
await packageManager.publish(workspace, {
|
|
830
|
+
provenance: options.publishProvenance,
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
});
|
|
835
|
+
} else {
|
|
836
|
+
logger.warn("No changes made. Nothing to commit.");
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
export const Defaults: VersionCommandOptions = {
|
|
842
|
+
cwd: process.cwd(),
|
|
843
|
+
includesRoot: false,
|
|
844
|
+
dryRun: false,
|
|
845
|
+
json: false,
|
|
846
|
+
preset: "conventional-changelog-conventionalcommits",
|
|
847
|
+
tagVersionPrefix: "v",
|
|
848
|
+
changelog: "CHANGELOG.md",
|
|
849
|
+
commitMessage: "chore: release %a",
|
|
850
|
+
createRelease: false,
|
|
851
|
+
bumpDependentsHighestAs: "major",
|
|
852
|
+
alwaysBumpPeerDependencies: false,
|
|
853
|
+
gitRemote: "origin",
|
|
854
|
+
verbose: false,
|
|
855
|
+
publish: false,
|
|
856
|
+
publishProvenance: false,
|
|
857
|
+
};
|
|
858
|
+
|
|
859
|
+
export default program
|
|
860
|
+
.command("version", { isDefault: true })
|
|
861
|
+
.usage("Bump package version using conventional commit")
|
|
862
|
+
.addOption(
|
|
863
|
+
new Option("--includes-root", "Release root workspace [untested]").default(
|
|
864
|
+
Defaults.includesRoot,
|
|
865
|
+
),
|
|
866
|
+
)
|
|
867
|
+
.addOption(new Option("--cwd", "working directory").default(process.cwd()))
|
|
868
|
+
.addOption(
|
|
869
|
+
new Option(
|
|
870
|
+
"--dry-run",
|
|
871
|
+
"Print the versions without actually generating the package archive",
|
|
872
|
+
).default(Defaults.dryRun),
|
|
873
|
+
)
|
|
874
|
+
.addOption(new Option("-v,--verbose").default(Defaults.verbose))
|
|
875
|
+
.addOption(
|
|
876
|
+
new Option("--force <type>", "Specify the release type").choices([
|
|
877
|
+
"major",
|
|
878
|
+
"minor",
|
|
879
|
+
"patch",
|
|
880
|
+
]),
|
|
881
|
+
)
|
|
882
|
+
.addOption(
|
|
883
|
+
new Option(
|
|
884
|
+
"--prerelease [releaseType]",
|
|
885
|
+
"Add a prerelease identifier to new versions",
|
|
886
|
+
),
|
|
887
|
+
)
|
|
888
|
+
.addOption(
|
|
889
|
+
new Option(
|
|
890
|
+
"--preset <presetName>",
|
|
891
|
+
"Conventional Changelog preset to require. Defaults to conventional-changelog-conventionalcommits.",
|
|
892
|
+
).default("conventional-changelog-conventionalcommits"),
|
|
893
|
+
)
|
|
894
|
+
.addOption(
|
|
895
|
+
new Option("--tag-version-prefix <prefix>", "Tag version prefix").default(
|
|
896
|
+
Defaults.tagVersionPrefix,
|
|
897
|
+
),
|
|
898
|
+
)
|
|
899
|
+
.addOption(
|
|
900
|
+
new Option(
|
|
901
|
+
"--changelog <path>",
|
|
902
|
+
"Changelog path. Default to CHANGELOG.md.",
|
|
903
|
+
).default(Defaults.changelog),
|
|
904
|
+
)
|
|
905
|
+
.addOption(
|
|
906
|
+
new Option(
|
|
907
|
+
"-m,--commit-message <message>",
|
|
908
|
+
'Commit message. Default to "chore: release %a". You can use %v for the version, %s for the version with prefix, %t to list tags, %a for auto best display.',
|
|
909
|
+
).default(Defaults.commitMessage),
|
|
910
|
+
)
|
|
911
|
+
.addOption(
|
|
912
|
+
new Option("--create-release <type>", "Create a release").choices([
|
|
913
|
+
"github",
|
|
914
|
+
]),
|
|
915
|
+
)
|
|
916
|
+
.addOption(
|
|
917
|
+
new Option(
|
|
918
|
+
"--bump-dependents-highest-as <type>",
|
|
919
|
+
"Bump dependents highest version as major, minor or patch",
|
|
920
|
+
)
|
|
921
|
+
.choices(["major", "minor", "patch"])
|
|
922
|
+
.default(Defaults.bumpDependentsHighestAs),
|
|
923
|
+
)
|
|
924
|
+
.addOption(
|
|
925
|
+
new Option(
|
|
926
|
+
"--always-bump-peer-dependencies",
|
|
927
|
+
"Always bump peer dependencies. Default to bumping only if the version doesn't satisfies the peer dependency range.",
|
|
928
|
+
).default(Defaults.alwaysBumpPeerDependencies),
|
|
929
|
+
)
|
|
930
|
+
.addOption(
|
|
931
|
+
new Option(
|
|
932
|
+
"--git-remote <remote-name>",
|
|
933
|
+
"Git remote to push commits and tags to",
|
|
934
|
+
).default(Defaults.gitRemote),
|
|
935
|
+
)
|
|
936
|
+
.addOption(
|
|
937
|
+
new Option(
|
|
938
|
+
"--ignore-changes <glob>",
|
|
939
|
+
'Ignore changes in files matching the glob. Example: "**/*.test.js"',
|
|
940
|
+
),
|
|
941
|
+
)
|
|
942
|
+
.addOption(new Option("--json", "Logger json"))
|
|
943
|
+
.addOption(
|
|
944
|
+
new Option(
|
|
945
|
+
"--package-manager <manager>",
|
|
946
|
+
"Specify the package manager to use (bun or yarn). Autodetected if not specified.",
|
|
947
|
+
).choices(["bun", "yarn"]),
|
|
948
|
+
)
|
|
949
|
+
.addOption(new Option("--publish", "Publish after versioning").default(false))
|
|
950
|
+
.addOption(
|
|
951
|
+
new Option(
|
|
952
|
+
"--publish-provenance",
|
|
953
|
+
"Generate provenance attestation when publishing (if supported by package manager)",
|
|
954
|
+
).default(false),
|
|
955
|
+
)
|
|
956
|
+
.action((options) => versionCommandAction(options));
|