relizy 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -39
- package/dist/cli.mjs +17 -10
- package/dist/index.d.mts +320 -65
- package/dist/index.d.ts +320 -65
- package/dist/index.mjs +5 -5
- package/dist/shared/{relizy.Blp-ymeX.mjs → relizy.CBq0DAtR.mjs} +533 -306
- package/package.json +3 -3
|
@@ -2,14 +2,14 @@ import { logger, execPromise } from '@maz-ui/node';
|
|
|
2
2
|
import { execSync } from 'node:child_process';
|
|
3
3
|
import { existsSync, readFileSync, writeFileSync, statSync } from 'node:fs';
|
|
4
4
|
import path, { join } from 'node:path';
|
|
5
|
-
import { formatCompareChanges, formatReference, resolveRepoConfig, getRepoConfig, createGithubRelease, getGitDiff, parseCommits, determineSemverChange } from 'changelogen';
|
|
6
|
-
import fastGlob from 'fast-glob';
|
|
7
|
-
import { confirm } from '@inquirer/prompts';
|
|
8
|
-
import { upperFirst, formatJson } from '@maz-ui/utils';
|
|
9
|
-
import * as semver from 'semver';
|
|
10
5
|
import process$1 from 'node:process';
|
|
6
|
+
import { upperFirst, formatJson } from '@maz-ui/utils';
|
|
11
7
|
import { setupDotenv, loadConfig } from 'c12';
|
|
8
|
+
import { formatCompareChanges, formatReference, resolveRepoConfig, getRepoConfig, createGithubRelease, getGitDiff, parseCommits, determineSemverChange } from 'changelogen';
|
|
12
9
|
import { defu } from 'defu';
|
|
10
|
+
import fastGlob from 'fast-glob';
|
|
11
|
+
import { confirm, input } from '@inquirer/prompts';
|
|
12
|
+
import * as semver from 'semver';
|
|
13
13
|
import { convert } from 'convert-gitmoji';
|
|
14
14
|
import { fetch as fetch$1 } from 'node-fetch-native';
|
|
15
15
|
|
|
@@ -110,7 +110,8 @@ function getCommitBody(commit) {
|
|
|
110
110
|
return false;
|
|
111
111
|
}
|
|
112
112
|
const isFileLine = /^[AMDRC]\s+/.test(trimmedLine);
|
|
113
|
-
|
|
113
|
+
const R100 = /R100\s+/.test(trimmedLine);
|
|
114
|
+
return !isFileLine && !R100;
|
|
114
115
|
});
|
|
115
116
|
if (contentLines.length === 0) {
|
|
116
117
|
return "";
|
|
@@ -148,6 +149,138 @@ function groupBy(items, key) {
|
|
|
148
149
|
return groups;
|
|
149
150
|
}
|
|
150
151
|
|
|
152
|
+
async function executeHook(hook, config, dryRun, params) {
|
|
153
|
+
const hookInput = config.hooks?.[hook];
|
|
154
|
+
if (!hookInput) {
|
|
155
|
+
logger.debug(`Hook ${hook} not found`);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (typeof hookInput === "function") {
|
|
159
|
+
logger.info(`Executing hook ${hook}`);
|
|
160
|
+
const result = await hookInput(config, dryRun, params);
|
|
161
|
+
if (result)
|
|
162
|
+
logger.debug(`Hook ${hook} returned: ${result}`);
|
|
163
|
+
logger.info(`Hook ${hook} executed`);
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
if (typeof hookInput === "string") {
|
|
167
|
+
logger.info(`Executing hook ${hook}`);
|
|
168
|
+
const result = await execPromise(hookInput, {
|
|
169
|
+
logLevel: config.logLevel,
|
|
170
|
+
cwd: config.cwd,
|
|
171
|
+
noStderr: true,
|
|
172
|
+
noStdout: true
|
|
173
|
+
});
|
|
174
|
+
if (result)
|
|
175
|
+
logger.debug(`Hook ${hook} returned: ${result}`);
|
|
176
|
+
logger.info(`Hook ${hook} executed`);
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function isInCI() {
|
|
181
|
+
return Boolean(
|
|
182
|
+
process.env.CI === "true" || process.env.CONTINUOUS_INTEGRATION === "true" || process.env.GITHUB_ACTIONS === "true" || process.env.GITHUB_WORKFLOW || process.env.GITLAB_CI === "true" || process.env.CIRCLECI === "true" || process.env.TRAVIS === "true" || process.env.JENKINS_HOME || process.env.JENKINS_URL || process.env.BUILD_ID || process.env.TF_BUILD === "True" || process.env.AZURE_PIPELINES === "true" || process.env.TEAMCITY_VERSION || process.env.BITBUCKET_BUILD_NUMBER || process.env.DRONE === "true" || process.env.APPVEYOR === "True" || process.env.APPVEYOR === "true" || process.env.BUILDKITE === "true" || process.env.CODEBUILD_BUILD_ID || process.env.NETLIFY === "true" || process.env.VERCEL === "1" || process.env.HEROKU_TEST_RUN_ID || process.env.BUDDY === "true" || process.env.SEMAPHORE === "true" || process.env.CF_BUILD_ID || process.env.bamboo_buildKey || process.env.BUILD_ID && process.env.PROJECT_ID || process.env.SCREWDRIVER === "true" || process.env.STRIDER === "true"
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
function getCIName() {
|
|
186
|
+
if (process.env.GITHUB_ACTIONS === "true")
|
|
187
|
+
return "GitHub Actions";
|
|
188
|
+
if (process.env.GITLAB_CI === "true")
|
|
189
|
+
return "GitLab CI";
|
|
190
|
+
if (process.env.CIRCLECI === "true")
|
|
191
|
+
return "CircleCI";
|
|
192
|
+
if (process.env.TRAVIS === "true")
|
|
193
|
+
return "Travis CI";
|
|
194
|
+
if (process.env.JENKINS_HOME || process.env.JENKINS_URL)
|
|
195
|
+
return "Jenkins";
|
|
196
|
+
if (process.env.TF_BUILD === "True")
|
|
197
|
+
return "Azure Pipelines";
|
|
198
|
+
if (process.env.TEAMCITY_VERSION)
|
|
199
|
+
return "TeamCity";
|
|
200
|
+
if (process.env.BITBUCKET_BUILD_NUMBER)
|
|
201
|
+
return "Bitbucket Pipelines";
|
|
202
|
+
if (process.env.DRONE === "true")
|
|
203
|
+
return "Drone";
|
|
204
|
+
if (process.env.APPVEYOR)
|
|
205
|
+
return "AppVeyor";
|
|
206
|
+
if (process.env.BUILDKITE === "true")
|
|
207
|
+
return "Buildkite";
|
|
208
|
+
if (process.env.CODEBUILD_BUILD_ID)
|
|
209
|
+
return "AWS CodeBuild";
|
|
210
|
+
if (process.env.NETLIFY === "true")
|
|
211
|
+
return "Netlify";
|
|
212
|
+
if (process.env.VERCEL === "1")
|
|
213
|
+
return "Vercel";
|
|
214
|
+
if (process.env.HEROKU_TEST_RUN_ID)
|
|
215
|
+
return "Heroku CI";
|
|
216
|
+
if (process.env.BUDDY === "true")
|
|
217
|
+
return "Buddy";
|
|
218
|
+
if (process.env.SEMAPHORE === "true")
|
|
219
|
+
return "Semaphore";
|
|
220
|
+
if (process.env.CF_BUILD_ID)
|
|
221
|
+
return "Codefresh";
|
|
222
|
+
if (process.env.bamboo_buildKey)
|
|
223
|
+
return "Bamboo";
|
|
224
|
+
if (process.env.BUILD_ID && process.env.PROJECT_ID)
|
|
225
|
+
return "Google Cloud Build";
|
|
226
|
+
if (process.env.SCREWDRIVER === "true")
|
|
227
|
+
return "Screwdriver";
|
|
228
|
+
if (process.env.STRIDER === "true")
|
|
229
|
+
return "Strider";
|
|
230
|
+
if (process.env.CI === "true")
|
|
231
|
+
return "Unknown CI";
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
async function executeFormatCmd({
|
|
235
|
+
config,
|
|
236
|
+
dryRun
|
|
237
|
+
}) {
|
|
238
|
+
if (config.changelog?.formatCmd) {
|
|
239
|
+
logger.info("Running format command");
|
|
240
|
+
logger.debug(`Running format command: ${config.changelog.formatCmd}`);
|
|
241
|
+
try {
|
|
242
|
+
if (!dryRun) {
|
|
243
|
+
await execPromise(config.changelog.formatCmd, {
|
|
244
|
+
noStderr: true,
|
|
245
|
+
noStdout: true,
|
|
246
|
+
logLevel: config.logLevel,
|
|
247
|
+
cwd: config.cwd
|
|
248
|
+
});
|
|
249
|
+
logger.info("Format completed");
|
|
250
|
+
} else {
|
|
251
|
+
logger.log("[dry-run] exec format command: ", config.changelog.formatCmd);
|
|
252
|
+
}
|
|
253
|
+
} catch (error) {
|
|
254
|
+
logger.error("Format command failed:", error);
|
|
255
|
+
process.exit(1);
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
logger.debug("No format command specified");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async function executeBuildCmd({
|
|
262
|
+
config,
|
|
263
|
+
dryRun
|
|
264
|
+
}) {
|
|
265
|
+
if (config.publish?.buildCmd) {
|
|
266
|
+
logger.info("Running build command");
|
|
267
|
+
logger.debug(`Running build command: ${config.publish.buildCmd}`);
|
|
268
|
+
if (!dryRun) {
|
|
269
|
+
await execPromise(config.publish.buildCmd, {
|
|
270
|
+
noStderr: true,
|
|
271
|
+
noStdout: true,
|
|
272
|
+
logLevel: config.logLevel,
|
|
273
|
+
cwd: config.cwd
|
|
274
|
+
});
|
|
275
|
+
logger.info("Build completed");
|
|
276
|
+
} else {
|
|
277
|
+
logger.log("[dry-run] exec build command: ", config.publish.buildCmd);
|
|
278
|
+
}
|
|
279
|
+
} else {
|
|
280
|
+
logger.debug("No build command specified");
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
151
284
|
function fromTagIsFirstCommit(fromTag, cwd) {
|
|
152
285
|
return fromTag === getFirstCommit(cwd);
|
|
153
286
|
}
|
|
@@ -164,21 +297,27 @@ async function generateChangelog({
|
|
|
164
297
|
fromTag = config.monorepo?.versionMode === "independent" ? `${pkg.name}@0.0.0` : config.templates.tagBody.replace("{{newVersion}}", "0.0.0");
|
|
165
298
|
}
|
|
166
299
|
const toTag = config.to || (config.monorepo?.versionMode === "independent" ? `${pkg.name}@${pkg.version}` : config.templates.tagBody.replace("{{newVersion}}", pkg.version));
|
|
300
|
+
logger.debug(`Generating changelog for ${pkg.name} - from ${fromTag} to ${toTag}`);
|
|
167
301
|
try {
|
|
168
|
-
logger.debug(`Generating changelog for ${pkg.name} - from ${fromTag} to ${toTag}`);
|
|
169
302
|
config = {
|
|
170
303
|
...config,
|
|
171
304
|
from: fromTag,
|
|
172
305
|
to: toTag
|
|
173
306
|
};
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
${changelog}`);
|
|
307
|
+
const generatedChangelog = await generateMarkDown(commits, config);
|
|
308
|
+
let changelog = generatedChangelog;
|
|
177
309
|
if (commits.length === 0) {
|
|
178
310
|
changelog = `${changelog}
|
|
179
311
|
|
|
180
312
|
${config.templates.emptyChangelogContent}`;
|
|
181
313
|
}
|
|
314
|
+
const changelogResult = await executeHook("generate:changelog", config, dryRun, {
|
|
315
|
+
commits,
|
|
316
|
+
changelog
|
|
317
|
+
});
|
|
318
|
+
changelog = changelogResult || changelog;
|
|
319
|
+
logger.verbose(`Output changelog for ${pkg.name}:
|
|
320
|
+
${changelog}`);
|
|
182
321
|
logger.debug(`Changelog generated for ${pkg.name} (${commits.length} commits)`);
|
|
183
322
|
logger.verbose(`Final changelog for ${pkg.name}:
|
|
184
323
|
|
|
@@ -224,55 +363,6 @@ ${existingChangelog}`;
|
|
|
224
363
|
logger.info(`Changelog updated for ${pkg.name}`);
|
|
225
364
|
}
|
|
226
365
|
}
|
|
227
|
-
async function executeFormatCmd({
|
|
228
|
-
config,
|
|
229
|
-
dryRun
|
|
230
|
-
}) {
|
|
231
|
-
if (config.changelog?.formatCmd) {
|
|
232
|
-
logger.info("Running format command");
|
|
233
|
-
logger.debug(`Running format command: ${config.changelog.formatCmd}`);
|
|
234
|
-
try {
|
|
235
|
-
if (!dryRun) {
|
|
236
|
-
await execPromise(config.changelog.formatCmd, {
|
|
237
|
-
noStderr: true,
|
|
238
|
-
noStdout: true,
|
|
239
|
-
logLevel: config.logLevel,
|
|
240
|
-
cwd: config.cwd
|
|
241
|
-
});
|
|
242
|
-
logger.info("Format completed");
|
|
243
|
-
} else {
|
|
244
|
-
logger.log("[dry-run] exec format command: ", config.changelog.formatCmd);
|
|
245
|
-
}
|
|
246
|
-
} catch (error) {
|
|
247
|
-
logger.error("Format command failed:", error);
|
|
248
|
-
process.exit(1);
|
|
249
|
-
}
|
|
250
|
-
} else {
|
|
251
|
-
logger.debug("No format command specified");
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
async function executeBuildCmd({
|
|
255
|
-
config,
|
|
256
|
-
dryRun
|
|
257
|
-
}) {
|
|
258
|
-
if (config.publish?.buildCmd) {
|
|
259
|
-
logger.info("Running build command");
|
|
260
|
-
logger.debug(`Running build command: ${config.publish.buildCmd}`);
|
|
261
|
-
if (!dryRun) {
|
|
262
|
-
await execPromise(config.publish.buildCmd, {
|
|
263
|
-
noStderr: true,
|
|
264
|
-
noStdout: true,
|
|
265
|
-
logLevel: config.logLevel,
|
|
266
|
-
cwd: config.cwd
|
|
267
|
-
});
|
|
268
|
-
logger.info("Build completed");
|
|
269
|
-
} else {
|
|
270
|
-
logger.log("[dry-run] exec build command: ", config.publish.buildCmd);
|
|
271
|
-
}
|
|
272
|
-
} else {
|
|
273
|
-
logger.debug("No build command specified");
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
366
|
|
|
277
367
|
function getDefaultConfig() {
|
|
278
368
|
return {
|
|
@@ -314,8 +404,8 @@ function getDefaultConfig() {
|
|
|
314
404
|
args: []
|
|
315
405
|
},
|
|
316
406
|
tokens: {
|
|
317
|
-
gitlab: process$1.env.
|
|
318
|
-
github: process$1.env.
|
|
407
|
+
gitlab: process$1.env.RELIZY_GITLAB_TOKEN || process$1.env.GITLAB_TOKEN || process$1.env.GITLAB_API_TOKEN || process$1.env.CI_JOB_TOKEN,
|
|
408
|
+
github: process$1.env.RELIZY_GITHUB_TOKEN || process$1.env.GITHUB_TOKEN || process$1.env.GH_TOKEN
|
|
319
409
|
},
|
|
320
410
|
scopeMap: {},
|
|
321
411
|
release: {
|
|
@@ -324,10 +414,11 @@ function getDefaultConfig() {
|
|
|
324
414
|
changelog: true,
|
|
325
415
|
push: true,
|
|
326
416
|
clean: true,
|
|
327
|
-
|
|
417
|
+
providerRelease: true,
|
|
328
418
|
noVerify: false
|
|
329
419
|
},
|
|
330
|
-
logLevel: "default"
|
|
420
|
+
logLevel: "default",
|
|
421
|
+
safetyCheck: true
|
|
331
422
|
};
|
|
332
423
|
}
|
|
333
424
|
function setupLogger(logLevel) {
|
|
@@ -353,12 +444,12 @@ async function resolveConfig(config, cwd) {
|
|
|
353
444
|
}
|
|
354
445
|
return config;
|
|
355
446
|
}
|
|
356
|
-
async function
|
|
357
|
-
const cwd = overrides?.cwd ?? process$1.cwd();
|
|
358
|
-
configName
|
|
447
|
+
async function loadRelizyConfig(options) {
|
|
448
|
+
const cwd = options?.overrides?.cwd ?? process$1.cwd();
|
|
449
|
+
const configName = options?.configName ?? "relizy";
|
|
359
450
|
await setupDotenv({ cwd });
|
|
360
451
|
const defaultConfig = getDefaultConfig();
|
|
361
|
-
const overridesConfig = defu(overrides, baseConfig);
|
|
452
|
+
const overridesConfig = defu(options?.overrides, options?.baseConfig);
|
|
362
453
|
const results = await loadConfig({
|
|
363
454
|
cwd,
|
|
364
455
|
name: configName,
|
|
@@ -367,10 +458,13 @@ async function loadMonorepoConfig({ baseConfig, overrides, configName = "relizy"
|
|
|
367
458
|
overrides: overridesConfig
|
|
368
459
|
});
|
|
369
460
|
if (!results._configFile) {
|
|
370
|
-
logger.
|
|
371
|
-
|
|
461
|
+
logger.debug(`No config file found with name "${configName}" - using standalone mode`);
|
|
462
|
+
if (options?.configName) {
|
|
463
|
+
logger.error(`No config file found with name "${configName}"`);
|
|
464
|
+
process$1.exit(1);
|
|
465
|
+
}
|
|
372
466
|
}
|
|
373
|
-
setupLogger(overrides?.logLevel || results.config.logLevel);
|
|
467
|
+
setupLogger(options?.overrides?.logLevel || results.config.logLevel);
|
|
374
468
|
logger.verbose("User config:", formatJson(results.config.changelog));
|
|
375
469
|
const resolvedConfig = await resolveConfig(results.config, cwd);
|
|
376
470
|
logger.debug("Resolved config:", formatJson(resolvedConfig));
|
|
@@ -499,7 +593,7 @@ function checkGitStatusIfDirty() {
|
|
|
499
593
|
if (dirty) {
|
|
500
594
|
logger.debug("git status:", `
|
|
501
595
|
${dirty.trim().split("\n").map((line) => line.trim()).join("\n")}`);
|
|
502
|
-
throw new Error(
|
|
596
|
+
throw new Error(dirty);
|
|
503
597
|
}
|
|
504
598
|
}
|
|
505
599
|
async function fetchGitTags(cwd) {
|
|
@@ -555,61 +649,88 @@ async function createCommitAndTags({
|
|
|
555
649
|
newVersion,
|
|
556
650
|
dryRun,
|
|
557
651
|
logLevel
|
|
558
|
-
}) {
|
|
559
|
-
const
|
|
560
|
-
|
|
561
|
-
"
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
652
|
+
} = {}) {
|
|
653
|
+
const internalConfig = config || await loadRelizyConfig();
|
|
654
|
+
try {
|
|
655
|
+
await executeHook("before:commit-and-tag", internalConfig, dryRun ?? false);
|
|
656
|
+
const filePatternsToAdd = [
|
|
657
|
+
"package.json",
|
|
658
|
+
"lerna.json",
|
|
659
|
+
"CHANGELOG.md",
|
|
660
|
+
"**/CHANGELOG.md",
|
|
661
|
+
"**/package.json"
|
|
662
|
+
];
|
|
663
|
+
logger.start("Start commit and tag");
|
|
664
|
+
logger.debug("Adding files to git staging area...");
|
|
665
|
+
for (const pattern of filePatternsToAdd) {
|
|
666
|
+
if (pattern === "lerna.json" && !hasLernaJson(internalConfig.cwd)) {
|
|
667
|
+
logger.verbose(`Skipping lerna.json as it doesn't exist`);
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
if ((pattern === "lerna.json" || pattern === "CHANGELOG.md") && !existsSync(join(internalConfig.cwd, pattern))) {
|
|
671
|
+
logger.verbose(`Skipping ${pattern} as it doesn't exist`);
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
if (dryRun) {
|
|
675
|
+
logger.info(`[dry-run] git add ${pattern}`);
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
try {
|
|
679
|
+
logger.debug(`git add ${pattern}`);
|
|
680
|
+
execSync(`git add ${pattern}`);
|
|
681
|
+
} catch {
|
|
682
|
+
}
|
|
576
683
|
}
|
|
684
|
+
const rootPackage = getRootPackage(internalConfig.cwd);
|
|
685
|
+
newVersion = newVersion || rootPackage.version;
|
|
686
|
+
const versionForMessage = internalConfig.monorepo?.versionMode === "independent" ? bumpedPackages?.map((pkg) => `${pkg.name}@${pkg.version}`).join(", ") || "unknown" : newVersion || "unknown";
|
|
687
|
+
const commitMessage = internalConfig.templates.commitMessage?.replaceAll("{{newVersion}}", versionForMessage) || `chore(release): bump version to ${versionForMessage}`;
|
|
688
|
+
const noVerifyFlag = noVerify ? "--no-verify " : "";
|
|
689
|
+
logger.debug(`No verify: ${noVerify}`);
|
|
577
690
|
if (dryRun) {
|
|
578
|
-
logger.info(`[dry-run] git
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
691
|
+
logger.info(`[dry-run] git commit ${noVerifyFlag}-m "${commitMessage}"`);
|
|
692
|
+
} else {
|
|
693
|
+
logger.debug(`Executing: git commit ${noVerifyFlag}-m "${commitMessage}"`);
|
|
694
|
+
await execPromise(`git commit ${noVerifyFlag}-m "${commitMessage}"`, {
|
|
695
|
+
logLevel,
|
|
696
|
+
noStderr: true,
|
|
697
|
+
noStdout: true,
|
|
698
|
+
cwd: internalConfig.cwd
|
|
699
|
+
});
|
|
700
|
+
logger.success(`Committed: ${commitMessage}${noVerify ? " (--no-verify)" : ""}`);
|
|
701
|
+
}
|
|
702
|
+
const signTags = internalConfig.signTags ? "-s" : "";
|
|
703
|
+
logger.debug(`Sign tags: ${internalConfig.signTags}`);
|
|
704
|
+
const createdTags = [];
|
|
705
|
+
if (internalConfig.monorepo?.versionMode === "independent" && bumpedPackages && bumpedPackages.length > 0) {
|
|
706
|
+
logger.debug(`Creating ${bumpedPackages.length} independent package tags`);
|
|
707
|
+
for (const pkg of bumpedPackages) {
|
|
708
|
+
const tagName = `${pkg.name}@${pkg.version}`;
|
|
709
|
+
const tagMessage = internalConfig.templates?.tagMessage?.replaceAll("{{newVersion}}", pkg.version || "") || tagName;
|
|
710
|
+
if (dryRun) {
|
|
711
|
+
logger.info(`[dry-run] git tag ${signTags} -a ${tagName} -m "${tagMessage}"`);
|
|
712
|
+
} else {
|
|
713
|
+
const cmd = `git tag ${signTags} -a ${tagName} -m "${tagMessage}"`;
|
|
714
|
+
logger.debug(`Executing: ${cmd}`);
|
|
715
|
+
try {
|
|
716
|
+
await execPromise(cmd, {
|
|
717
|
+
logLevel,
|
|
718
|
+
noStderr: true,
|
|
719
|
+
noStdout: true,
|
|
720
|
+
cwd: internalConfig.cwd
|
|
721
|
+
});
|
|
722
|
+
logger.debug(`Tag created: ${tagName}`);
|
|
723
|
+
} catch (error) {
|
|
724
|
+
logger.error(`Failed to create tag ${tagName}:`, error);
|
|
725
|
+
throw error;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
createdTags.push(tagName);
|
|
729
|
+
}
|
|
730
|
+
logger.success(`Created ${createdTags.length} tags for independent packages, ${createdTags.join(", ")}`);
|
|
731
|
+
} else {
|
|
732
|
+
const tagName = internalConfig.templates.tagBody?.replaceAll("{{newVersion}}", newVersion);
|
|
733
|
+
const tagMessage = internalConfig.templates?.tagMessage?.replaceAll("{{newVersion}}", newVersion) || tagName;
|
|
613
734
|
if (dryRun) {
|
|
614
735
|
logger.info(`[dry-run] git tag ${signTags} -a ${tagName} -m "${tagMessage}"`);
|
|
615
736
|
} else {
|
|
@@ -620,7 +741,7 @@ async function createCommitAndTags({
|
|
|
620
741
|
logLevel,
|
|
621
742
|
noStderr: true,
|
|
622
743
|
noStdout: true,
|
|
623
|
-
cwd:
|
|
744
|
+
cwd: internalConfig.cwd
|
|
624
745
|
});
|
|
625
746
|
logger.debug(`Tag created: ${tagName}`);
|
|
626
747
|
} catch (error) {
|
|
@@ -630,33 +751,15 @@ async function createCommitAndTags({
|
|
|
630
751
|
}
|
|
631
752
|
createdTags.push(tagName);
|
|
632
753
|
}
|
|
633
|
-
logger.
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
logger.debug(`Executing: ${cmd}`);
|
|
642
|
-
try {
|
|
643
|
-
await execPromise(cmd, {
|
|
644
|
-
logLevel,
|
|
645
|
-
noStderr: true,
|
|
646
|
-
noStdout: true,
|
|
647
|
-
cwd: config.cwd
|
|
648
|
-
});
|
|
649
|
-
logger.debug(`Tag created: ${tagName}`);
|
|
650
|
-
} catch (error) {
|
|
651
|
-
logger.error(`Failed to create tag ${tagName}:`, error);
|
|
652
|
-
throw error;
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
createdTags.push(tagName);
|
|
754
|
+
logger.debug("Created Tags:", createdTags.join(", "));
|
|
755
|
+
logger.success("Commit and tag completed!");
|
|
756
|
+
await executeHook("after:commit-and-tag", internalConfig, dryRun ?? false);
|
|
757
|
+
return createdTags;
|
|
758
|
+
} catch (error) {
|
|
759
|
+
logger.error("Error committing and tagging:", error);
|
|
760
|
+
await executeHook("error:commit-and-tag", internalConfig, dryRun ?? false);
|
|
761
|
+
throw error;
|
|
656
762
|
}
|
|
657
|
-
logger.debug("Created Tags:", createdTags.join(", "));
|
|
658
|
-
logger.success("Commit and tag completed!");
|
|
659
|
-
return createdTags;
|
|
660
763
|
}
|
|
661
764
|
async function pushCommitAndTags({ dryRun, logLevel, cwd }) {
|
|
662
765
|
logger.start("Start push changes and tags");
|
|
@@ -666,7 +769,7 @@ async function pushCommitAndTags({ dryRun, logLevel, cwd }) {
|
|
|
666
769
|
logger.debug("Executing: git push --follow-tags");
|
|
667
770
|
await execPromise("git push --follow-tags", { noStderr: true, noStdout: true, logLevel, cwd });
|
|
668
771
|
}
|
|
669
|
-
logger.success("
|
|
772
|
+
logger.success("Pushing changes and tags completed!");
|
|
670
773
|
}
|
|
671
774
|
function getFirstCommit(cwd) {
|
|
672
775
|
const result = execSync(
|
|
@@ -699,8 +802,8 @@ async function githubIndependentMode({
|
|
|
699
802
|
if (!repoConfig) {
|
|
700
803
|
throw new Error("No repository configuration found. Please check your changelog config.");
|
|
701
804
|
}
|
|
702
|
-
logger.debug(`GitHub token: ${config.tokens.github ? "\u2713 provided" : "\u2717 missing"}`);
|
|
703
|
-
if (!config.tokens.github) {
|
|
805
|
+
logger.debug(`GitHub token: ${config.tokens.github || config.repo?.token ? "\u2713 provided" : "\u2717 missing"}`);
|
|
806
|
+
if (!config.tokens.github && !config.repo?.token) {
|
|
704
807
|
throw new Error("No GitHub token specified. Set GITHUB_TOKEN or GH_TOKEN environment variable.");
|
|
705
808
|
}
|
|
706
809
|
const packages = bumpedPackages || getPackages({
|
|
@@ -783,8 +886,8 @@ async function githubUnified({
|
|
|
783
886
|
if (!repoConfig) {
|
|
784
887
|
throw new Error("No repository configuration found. Please check your changelog config.");
|
|
785
888
|
}
|
|
786
|
-
logger.debug(`GitHub token: ${config.tokens.github ? "\u2713 provided" : "\u2717 missing"}`);
|
|
787
|
-
if (!config.tokens.github) {
|
|
889
|
+
logger.debug(`GitHub token: ${config.tokens.github || config.repo?.token ? "\u2713 provided" : "\u2717 missing"}`);
|
|
890
|
+
if (!config.tokens.github && !config.repo?.token) {
|
|
788
891
|
throw new Error("No GitHub token specified. Set GITHUB_TOKEN or GH_TOKEN environment variable.");
|
|
789
892
|
}
|
|
790
893
|
const to = config.templates.tagBody.replace("{{newVersion}}", rootPackage.version);
|
|
@@ -838,10 +941,9 @@ async function githubUnified({
|
|
|
838
941
|
}
|
|
839
942
|
async function github(options = {}) {
|
|
840
943
|
try {
|
|
841
|
-
logger.start("Start publishing GitHub release");
|
|
842
944
|
const dryRun = options.dryRun ?? false;
|
|
843
945
|
logger.debug(`Dry run: ${dryRun}`);
|
|
844
|
-
const config = await
|
|
946
|
+
const config = await loadRelizyConfig({
|
|
845
947
|
configName: options.configName,
|
|
846
948
|
baseConfig: options.config,
|
|
847
949
|
overrides: {
|
|
@@ -849,7 +951,7 @@ async function github(options = {}) {
|
|
|
849
951
|
to: options.to,
|
|
850
952
|
logLevel: options.logLevel,
|
|
851
953
|
tokens: {
|
|
852
|
-
github: options.token
|
|
954
|
+
github: options.token
|
|
853
955
|
}
|
|
854
956
|
}
|
|
855
957
|
});
|
|
@@ -879,7 +981,7 @@ async function createGitlabRelease({
|
|
|
879
981
|
release,
|
|
880
982
|
dryRun
|
|
881
983
|
}) {
|
|
882
|
-
const token = config.tokens.gitlab ||
|
|
984
|
+
const token = config.tokens.gitlab || config.repo?.token;
|
|
883
985
|
if (!token && !dryRun) {
|
|
884
986
|
throw new Error(
|
|
885
987
|
"No GitLab token found. Set GITLAB_TOKEN or CI_JOB_TOKEN environment variable or configure tokens.gitlab"
|
|
@@ -940,7 +1042,7 @@ async function gitlabIndependentMode({
|
|
|
940
1042
|
dryRun,
|
|
941
1043
|
bumpedPackages
|
|
942
1044
|
}) {
|
|
943
|
-
logger.debug(`GitLab token: ${config.tokens.gitlab ? "\u2713 provided" : "\u2717 missing"}`);
|
|
1045
|
+
logger.debug(`GitLab token: ${config.tokens.gitlab || config.repo?.token ? "\u2713 provided" : "\u2717 missing"}`);
|
|
944
1046
|
const packages = bumpedPackages || getPackages({
|
|
945
1047
|
cwd: config.cwd,
|
|
946
1048
|
patterns: config.monorepo?.packages,
|
|
@@ -1020,7 +1122,7 @@ async function gitlabUnified({
|
|
|
1020
1122
|
fromTag,
|
|
1021
1123
|
oldVersion
|
|
1022
1124
|
}) {
|
|
1023
|
-
logger.debug(`GitLab token: ${config.tokens.gitlab ? "\u2713 provided" : "\u2717 missing"}`);
|
|
1125
|
+
logger.debug(`GitLab token: ${config.tokens.gitlab || config.repo?.token ? "\u2713 provided" : "\u2717 missing"}`);
|
|
1024
1126
|
const to = config.templates.tagBody.replace("{{newVersion}}", rootPackage.version);
|
|
1025
1127
|
const commits = await getPackageCommits({
|
|
1026
1128
|
pkg: rootPackage,
|
|
@@ -1077,10 +1179,9 @@ async function gitlabUnified({
|
|
|
1077
1179
|
}
|
|
1078
1180
|
async function gitlab(options = {}) {
|
|
1079
1181
|
try {
|
|
1080
|
-
logger.start("Start publishing GitLab release");
|
|
1081
1182
|
const dryRun = options.dryRun ?? false;
|
|
1082
1183
|
logger.debug(`Dry run: ${dryRun}`);
|
|
1083
|
-
const config = await
|
|
1184
|
+
const config = await loadRelizyConfig({
|
|
1084
1185
|
configName: options.configName,
|
|
1085
1186
|
baseConfig: options.config,
|
|
1086
1187
|
overrides: {
|
|
@@ -1088,7 +1189,7 @@ async function gitlab(options = {}) {
|
|
|
1088
1189
|
to: options.to,
|
|
1089
1190
|
logLevel: options.logLevel,
|
|
1090
1191
|
tokens: {
|
|
1091
|
-
gitlab: options.token
|
|
1192
|
+
gitlab: options.token
|
|
1092
1193
|
}
|
|
1093
1194
|
}
|
|
1094
1195
|
});
|
|
@@ -1976,6 +2077,7 @@ async function resolveTags({
|
|
|
1976
2077
|
return tags;
|
|
1977
2078
|
}
|
|
1978
2079
|
|
|
2080
|
+
let sessionOtp;
|
|
1979
2081
|
function detectPackageManager(cwd = process.cwd()) {
|
|
1980
2082
|
try {
|
|
1981
2083
|
const packageJsonPath = join(cwd, "package.json");
|
|
@@ -2078,7 +2180,8 @@ function isYarnBerry() {
|
|
|
2078
2180
|
function getCommandArgs({
|
|
2079
2181
|
packageManager,
|
|
2080
2182
|
tag,
|
|
2081
|
-
config
|
|
2183
|
+
config,
|
|
2184
|
+
otp
|
|
2082
2185
|
}) {
|
|
2083
2186
|
const args = ["publish", "--tag", tag];
|
|
2084
2187
|
if (packageManager === "pnpm") {
|
|
@@ -2098,12 +2201,72 @@ function getCommandArgs({
|
|
|
2098
2201
|
if (access) {
|
|
2099
2202
|
args.push("--access", access);
|
|
2100
2203
|
}
|
|
2101
|
-
const
|
|
2102
|
-
if (
|
|
2103
|
-
args.push("--otp",
|
|
2204
|
+
const finalOtp = otp ?? sessionOtp ?? config.publish.otp;
|
|
2205
|
+
if (finalOtp) {
|
|
2206
|
+
args.push("--otp", finalOtp);
|
|
2104
2207
|
}
|
|
2105
2208
|
return args;
|
|
2106
2209
|
}
|
|
2210
|
+
function isOtpError(error) {
|
|
2211
|
+
if (typeof error !== "object" || error === null)
|
|
2212
|
+
return false;
|
|
2213
|
+
const errorMessage = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
|
|
2214
|
+
return errorMessage.includes("otp") || errorMessage.includes("one-time password") || errorMessage.includes("eotp");
|
|
2215
|
+
}
|
|
2216
|
+
function promptOtpWithTimeout(timeout = 9e4) {
|
|
2217
|
+
return new Promise((resolve, reject) => {
|
|
2218
|
+
const timer = setTimeout(() => {
|
|
2219
|
+
reject(new Error("OTP input timeout"));
|
|
2220
|
+
}, timeout);
|
|
2221
|
+
input({
|
|
2222
|
+
message: "This operation requires a one-time password (OTP). Please enter your OTP:"
|
|
2223
|
+
}).then((otp) => {
|
|
2224
|
+
clearTimeout(timer);
|
|
2225
|
+
resolve(otp);
|
|
2226
|
+
}).catch((error) => {
|
|
2227
|
+
clearTimeout(timer);
|
|
2228
|
+
reject(error);
|
|
2229
|
+
});
|
|
2230
|
+
});
|
|
2231
|
+
}
|
|
2232
|
+
async function handleOtpError() {
|
|
2233
|
+
if (process.env.CI) {
|
|
2234
|
+
logger.error("OTP required but running in CI environment. Please provide OTP via config.");
|
|
2235
|
+
throw new Error("OTP required in CI environment");
|
|
2236
|
+
}
|
|
2237
|
+
logger.warn("Publish failed: OTP required");
|
|
2238
|
+
try {
|
|
2239
|
+
const otp = await promptOtpWithTimeout();
|
|
2240
|
+
logger.debug("OTP received, retrying publish...");
|
|
2241
|
+
return otp;
|
|
2242
|
+
} catch (promptError) {
|
|
2243
|
+
logger.error("Failed to get OTP:", promptError);
|
|
2244
|
+
throw promptError;
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
async function executePublishCommand({
|
|
2248
|
+
command,
|
|
2249
|
+
packageNameAndVersion,
|
|
2250
|
+
pkg,
|
|
2251
|
+
config,
|
|
2252
|
+
dryRun
|
|
2253
|
+
}) {
|
|
2254
|
+
logger.debug(`Executing publish command (${command}) in ${pkg.path}`);
|
|
2255
|
+
if (dryRun) {
|
|
2256
|
+
logger.info(`[dry-run] ${packageNameAndVersion}: Run ${command}`);
|
|
2257
|
+
return;
|
|
2258
|
+
}
|
|
2259
|
+
const { stdout } = await execPromise(command, {
|
|
2260
|
+
noStderr: true,
|
|
2261
|
+
noStdout: true,
|
|
2262
|
+
logLevel: config.logLevel,
|
|
2263
|
+
cwd: pkg.path
|
|
2264
|
+
});
|
|
2265
|
+
if (stdout) {
|
|
2266
|
+
logger.debug(stdout);
|
|
2267
|
+
}
|
|
2268
|
+
logger.info(`Published ${packageNameAndVersion}`);
|
|
2269
|
+
}
|
|
2107
2270
|
async function publishPackage({
|
|
2108
2271
|
pkg,
|
|
2109
2272
|
config,
|
|
@@ -2111,40 +2274,44 @@ async function publishPackage({
|
|
|
2111
2274
|
dryRun
|
|
2112
2275
|
}) {
|
|
2113
2276
|
const tag = determinePublishTag(pkg.version, config.publish.tag);
|
|
2114
|
-
logger.debug(`Building publish command for ${pkg.name}`);
|
|
2115
|
-
const args = getCommandArgs({
|
|
2116
|
-
packageManager,
|
|
2117
|
-
tag,
|
|
2118
|
-
config
|
|
2119
|
-
});
|
|
2120
|
-
const baseCommand = packageManager === "yarn" && isYarnBerry() ? "yarn npm" : packageManager;
|
|
2121
|
-
const command = `${baseCommand} ${args.join(" ")}`;
|
|
2122
2277
|
const packageNameAndVersion = `${pkg.name}@${pkg.version}`;
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2278
|
+
const baseCommand = packageManager === "yarn" && isYarnBerry() ? "yarn npm" : packageManager;
|
|
2279
|
+
logger.debug(`Building publish command for ${pkg.name}`);
|
|
2280
|
+
let dynamicOtp;
|
|
2281
|
+
const maxAttempts = 2;
|
|
2282
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
2283
|
+
try {
|
|
2284
|
+
const args = getCommandArgs({
|
|
2285
|
+
packageManager,
|
|
2286
|
+
tag,
|
|
2287
|
+
config,
|
|
2288
|
+
otp: dynamicOtp
|
|
2289
|
+
});
|
|
2290
|
+
const command = `${baseCommand} ${args.join(" ")}`;
|
|
2291
|
+
logger.debug(`Publishing ${packageNameAndVersion} with tag '${tag}' with command: ${command}`);
|
|
2292
|
+
process.chdir(pkg.path);
|
|
2293
|
+
await executePublishCommand({
|
|
2294
|
+
command,
|
|
2295
|
+
packageNameAndVersion,
|
|
2296
|
+
pkg,
|
|
2297
|
+
config,
|
|
2298
|
+
dryRun
|
|
2135
2299
|
});
|
|
2136
|
-
if (
|
|
2137
|
-
|
|
2300
|
+
if (dynamicOtp && !sessionOtp) {
|
|
2301
|
+
sessionOtp = dynamicOtp;
|
|
2302
|
+
logger.debug("OTP stored for session");
|
|
2138
2303
|
}
|
|
2304
|
+
return;
|
|
2305
|
+
} catch (error) {
|
|
2306
|
+
if (isOtpError(error) && attempt < maxAttempts - 1) {
|
|
2307
|
+
dynamicOtp = await handleOtpError();
|
|
2308
|
+
} else {
|
|
2309
|
+
logger.error(`Failed to publish ${packageNameAndVersion}:`, error);
|
|
2310
|
+
throw error;
|
|
2311
|
+
}
|
|
2312
|
+
} finally {
|
|
2313
|
+
process.chdir(config.cwd);
|
|
2139
2314
|
}
|
|
2140
|
-
if (!dryRun) {
|
|
2141
|
-
logger.info(`Published ${packageNameAndVersion}`);
|
|
2142
|
-
}
|
|
2143
|
-
} catch (error) {
|
|
2144
|
-
logger.error(`Failed to publish ${packageNameAndVersion}:`, error);
|
|
2145
|
-
throw error;
|
|
2146
|
-
} finally {
|
|
2147
|
-
process.chdir(config.cwd);
|
|
2148
2315
|
}
|
|
2149
2316
|
}
|
|
2150
2317
|
|
|
@@ -2393,30 +2560,31 @@ async function bumpSelectiveMode({
|
|
|
2393
2560
|
};
|
|
2394
2561
|
}
|
|
2395
2562
|
async function bump(options = {}) {
|
|
2563
|
+
const config = await loadRelizyConfig({
|
|
2564
|
+
configName: options.configName,
|
|
2565
|
+
baseConfig: options.config,
|
|
2566
|
+
overrides: {
|
|
2567
|
+
bump: {
|
|
2568
|
+
yes: options.yes,
|
|
2569
|
+
type: options.type,
|
|
2570
|
+
clean: options.clean,
|
|
2571
|
+
preid: options.preid
|
|
2572
|
+
},
|
|
2573
|
+
logLevel: options.logLevel
|
|
2574
|
+
}
|
|
2575
|
+
});
|
|
2576
|
+
const dryRun = options.dryRun ?? false;
|
|
2577
|
+
logger.debug(`Dry run: ${dryRun}`);
|
|
2578
|
+
const force = options.force ?? false;
|
|
2579
|
+
logger.debug(`Bump forced: ${force}`);
|
|
2396
2580
|
try {
|
|
2581
|
+
await executeHook("before:bump", config, dryRun);
|
|
2397
2582
|
logger.start("Start bumping versions");
|
|
2398
|
-
const dryRun = options.dryRun ?? false;
|
|
2399
|
-
logger.debug(`Dry run: ${dryRun}`);
|
|
2400
|
-
const force = options.force ?? false;
|
|
2401
|
-
logger.debug(`Bump forced: ${force}`);
|
|
2402
|
-
const config = await loadMonorepoConfig({
|
|
2403
|
-
configName: options.configName,
|
|
2404
|
-
baseConfig: options.config,
|
|
2405
|
-
overrides: {
|
|
2406
|
-
bump: {
|
|
2407
|
-
yes: options.yes,
|
|
2408
|
-
type: options.type,
|
|
2409
|
-
clean: options.clean,
|
|
2410
|
-
preid: options.preid
|
|
2411
|
-
},
|
|
2412
|
-
logLevel: options.logLevel
|
|
2413
|
-
}
|
|
2414
|
-
});
|
|
2415
2583
|
if (config.bump.clean && config.release.clean) {
|
|
2416
2584
|
try {
|
|
2417
2585
|
checkGitStatusIfDirty();
|
|
2418
|
-
} catch {
|
|
2419
|
-
logger.error("Git status is dirty, please commit or stash your changes before bumping or use --no-clean flag");
|
|
2586
|
+
} catch (error) {
|
|
2587
|
+
logger.error("Git status is dirty, please commit or stash your changes before bumping or use --no-clean flag", error);
|
|
2420
2588
|
process.exit(1);
|
|
2421
2589
|
}
|
|
2422
2590
|
}
|
|
@@ -2449,9 +2617,11 @@ async function bump(options = {}) {
|
|
|
2449
2617
|
} else {
|
|
2450
2618
|
logger.fail("No packages to bump, no commits found");
|
|
2451
2619
|
}
|
|
2620
|
+
await executeHook("after:bump", config, dryRun);
|
|
2452
2621
|
return result;
|
|
2453
2622
|
} catch (error) {
|
|
2454
2623
|
logger.error("Error bumping versions:", error);
|
|
2624
|
+
await executeHook("error:bump", config, dryRun);
|
|
2455
2625
|
throw error;
|
|
2456
2626
|
}
|
|
2457
2627
|
}
|
|
@@ -2577,24 +2747,25 @@ async function generateSimpleRootChangelog({
|
|
|
2577
2747
|
}
|
|
2578
2748
|
}
|
|
2579
2749
|
async function changelog(options = {}) {
|
|
2750
|
+
const config = await loadRelizyConfig({
|
|
2751
|
+
configName: options.configName,
|
|
2752
|
+
baseConfig: options.config,
|
|
2753
|
+
overrides: {
|
|
2754
|
+
from: options.from,
|
|
2755
|
+
to: options.to,
|
|
2756
|
+
logLevel: options.logLevel,
|
|
2757
|
+
changelog: {
|
|
2758
|
+
rootChangelog: options.rootChangelog,
|
|
2759
|
+
formatCmd: options.formatCmd
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
});
|
|
2763
|
+
const dryRun = options.dryRun ?? false;
|
|
2764
|
+
logger.debug(`Dry run: ${dryRun}`);
|
|
2765
|
+
logger.info(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
2580
2766
|
try {
|
|
2767
|
+
await executeHook("before:changelog", config, dryRun);
|
|
2581
2768
|
logger.start("Start generating changelogs");
|
|
2582
|
-
const dryRun = options.dryRun ?? false;
|
|
2583
|
-
logger.debug(`Dry run: ${dryRun}`);
|
|
2584
|
-
const config = await loadMonorepoConfig({
|
|
2585
|
-
configName: options.configName,
|
|
2586
|
-
baseConfig: options.config,
|
|
2587
|
-
overrides: {
|
|
2588
|
-
from: options.from,
|
|
2589
|
-
to: options.to,
|
|
2590
|
-
logLevel: options.logLevel,
|
|
2591
|
-
changelog: {
|
|
2592
|
-
rootChangelog: options.rootChangelog,
|
|
2593
|
-
formatCmd: options.formatCmd
|
|
2594
|
-
}
|
|
2595
|
-
}
|
|
2596
|
-
});
|
|
2597
|
-
logger.info(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
2598
2769
|
const packages = getPackagesToGenerateChangelogFor({
|
|
2599
2770
|
config,
|
|
2600
2771
|
bumpedPackages: options.bumpedPackages
|
|
@@ -2660,16 +2831,35 @@ async function changelog(options = {}) {
|
|
|
2660
2831
|
dryRun
|
|
2661
2832
|
});
|
|
2662
2833
|
logger.success(`${dryRun ? "[dry run] " : ""}Changelog generation completed!`);
|
|
2834
|
+
await executeHook("after:changelog", config, dryRun);
|
|
2663
2835
|
} catch (error) {
|
|
2664
2836
|
logger.error("Error generating changelogs:", error);
|
|
2837
|
+
await executeHook("error:changelog", config, dryRun);
|
|
2665
2838
|
throw error;
|
|
2666
2839
|
}
|
|
2667
2840
|
}
|
|
2668
2841
|
|
|
2842
|
+
function providerReleaseSafetyCheck({ config, provider }) {
|
|
2843
|
+
if (!config.safetyCheck || !config.release.providerRelease) {
|
|
2844
|
+
return;
|
|
2845
|
+
}
|
|
2846
|
+
const internalProvider = provider || config.repo?.provider || detectGitProvider();
|
|
2847
|
+
let token;
|
|
2848
|
+
if (internalProvider === "github") {
|
|
2849
|
+
token = config.tokens?.github || config.repo?.token;
|
|
2850
|
+
} else if (internalProvider === "gitlab") {
|
|
2851
|
+
token = config.tokens?.gitlab || config.repo?.token;
|
|
2852
|
+
} else {
|
|
2853
|
+
logger.error(`Unsupported Git provider: ${internalProvider || "unknown"}`);
|
|
2854
|
+
process.exit(1);
|
|
2855
|
+
}
|
|
2856
|
+
if (!token) {
|
|
2857
|
+
logger.error(`No token provided for ${internalProvider || "unknown"} - The release will not be published - Please refer to the documentation: https://louismazel.github.io/relizy/guide/installation#environment-setup`);
|
|
2858
|
+
process.exit(1);
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2669
2861
|
async function providerRelease(options = {}) {
|
|
2670
|
-
const
|
|
2671
|
-
logger.debug(`Dry run: ${dryRun}`);
|
|
2672
|
-
const config = await loadMonorepoConfig({
|
|
2862
|
+
const config = await loadRelizyConfig({
|
|
2673
2863
|
configName: options.configName,
|
|
2674
2864
|
baseConfig: options.config,
|
|
2675
2865
|
overrides: {
|
|
@@ -2679,68 +2869,82 @@ async function providerRelease(options = {}) {
|
|
|
2679
2869
|
github: options.token,
|
|
2680
2870
|
gitlab: options.token
|
|
2681
2871
|
},
|
|
2682
|
-
logLevel: options.logLevel
|
|
2872
|
+
logLevel: options.logLevel,
|
|
2873
|
+
safetyCheck: options.safetyCheck
|
|
2683
2874
|
}
|
|
2684
2875
|
});
|
|
2876
|
+
const dryRun = options.dryRun ?? false;
|
|
2877
|
+
logger.debug(`Dry run: ${dryRun}`);
|
|
2685
2878
|
logger.info(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2879
|
+
try {
|
|
2880
|
+
await executeHook("before:provider-release", config, dryRun);
|
|
2881
|
+
const detectedProvider = options.provider || detectGitProvider();
|
|
2882
|
+
providerReleaseSafetyCheck({ config, provider: detectedProvider });
|
|
2883
|
+
logger.start("Start provider release");
|
|
2884
|
+
if (!detectedProvider) {
|
|
2885
|
+
logger.warn("Unable to detect Git provider. Skipping release publication.");
|
|
2886
|
+
throw new Error("Unable to detect Git provider");
|
|
2887
|
+
} else {
|
|
2888
|
+
logger.info(
|
|
2889
|
+
options.provider ? `Using Git provider: ${options.provider}` : `Detected Git provider: ${detectedProvider}`
|
|
2890
|
+
);
|
|
2891
|
+
}
|
|
2892
|
+
let postedReleases = [];
|
|
2893
|
+
const payload = {
|
|
2894
|
+
from: config.from,
|
|
2895
|
+
dryRun,
|
|
2896
|
+
config,
|
|
2897
|
+
logLevel: config.logLevel,
|
|
2898
|
+
bumpResult: options.bumpResult
|
|
2899
|
+
};
|
|
2900
|
+
if (detectedProvider === "github") {
|
|
2901
|
+
postedReleases = await github(payload);
|
|
2902
|
+
} else if (detectedProvider === "gitlab") {
|
|
2903
|
+
postedReleases = await gitlab(payload);
|
|
2904
|
+
} else {
|
|
2905
|
+
logger.warn(`Unsupported Git provider: ${detectedProvider}`);
|
|
2906
|
+
}
|
|
2907
|
+
await executeHook("after:provider-release", config, dryRun);
|
|
2908
|
+
return {
|
|
2909
|
+
detectedProvider,
|
|
2910
|
+
postedReleases
|
|
2911
|
+
};
|
|
2912
|
+
} catch (error) {
|
|
2913
|
+
logger.error("Error publishing releases:", error);
|
|
2914
|
+
await executeHook("error:provider-release", config, dryRun);
|
|
2915
|
+
throw error;
|
|
2709
2916
|
}
|
|
2710
|
-
return {
|
|
2711
|
-
detectedProvider,
|
|
2712
|
-
postedReleases
|
|
2713
|
-
};
|
|
2714
2917
|
}
|
|
2715
2918
|
|
|
2716
2919
|
async function publish(options = {}) {
|
|
2920
|
+
const config = await loadRelizyConfig({
|
|
2921
|
+
configName: options.configName,
|
|
2922
|
+
baseConfig: options.config,
|
|
2923
|
+
overrides: {
|
|
2924
|
+
publish: {
|
|
2925
|
+
access: options.access,
|
|
2926
|
+
otp: options.otp,
|
|
2927
|
+
registry: options.registry,
|
|
2928
|
+
tag: options.tag,
|
|
2929
|
+
buildCmd: options.buildCmd
|
|
2930
|
+
},
|
|
2931
|
+
logLevel: options.logLevel
|
|
2932
|
+
}
|
|
2933
|
+
});
|
|
2934
|
+
const dryRun = options.dryRun ?? false;
|
|
2935
|
+
logger.debug(`Dry run: ${dryRun}`);
|
|
2936
|
+
const packageManager = detectPackageManager(process.cwd());
|
|
2937
|
+
logger.debug(`Package manager: ${packageManager}`);
|
|
2938
|
+
logger.info(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
2939
|
+
if (config.publish.registry) {
|
|
2940
|
+
logger.debug(`Registry: ${config.publish.registry}`);
|
|
2941
|
+
}
|
|
2942
|
+
if (config.publish.tag) {
|
|
2943
|
+
logger.debug(`Tag: ${config.publish.tag}`);
|
|
2944
|
+
}
|
|
2717
2945
|
try {
|
|
2946
|
+
await executeHook("before:publish", config, dryRun);
|
|
2718
2947
|
logger.start("Start publishing packages");
|
|
2719
|
-
const dryRun = options.dryRun ?? false;
|
|
2720
|
-
logger.debug(`Dry run: ${dryRun}`);
|
|
2721
|
-
const packageManager = detectPackageManager(process.cwd());
|
|
2722
|
-
logger.debug(`Package manager: ${packageManager}`);
|
|
2723
|
-
const config = await loadMonorepoConfig({
|
|
2724
|
-
configName: options.configName,
|
|
2725
|
-
baseConfig: options.config,
|
|
2726
|
-
overrides: {
|
|
2727
|
-
publish: {
|
|
2728
|
-
access: options.access,
|
|
2729
|
-
otp: options.otp,
|
|
2730
|
-
registry: options.registry,
|
|
2731
|
-
tag: options.tag,
|
|
2732
|
-
buildCmd: options.buildCmd
|
|
2733
|
-
},
|
|
2734
|
-
logLevel: options.logLevel
|
|
2735
|
-
}
|
|
2736
|
-
});
|
|
2737
|
-
logger.info(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
2738
|
-
if (config.publish.registry) {
|
|
2739
|
-
logger.debug(`Registry: ${config.publish.registry}`);
|
|
2740
|
-
}
|
|
2741
|
-
if (config.publish.tag) {
|
|
2742
|
-
logger.debug(`Tag: ${config.publish.tag}`);
|
|
2743
|
-
}
|
|
2744
2948
|
const packages = options.bumpedPackages || getPackages({
|
|
2745
2949
|
cwd: config.cwd,
|
|
2746
2950
|
patterns: config.publish.packages ?? config.monorepo?.packages,
|
|
@@ -2788,18 +2992,20 @@ async function publish(options = {}) {
|
|
|
2788
2992
|
if (!dryRun) {
|
|
2789
2993
|
logger.info("Package(s) have been published to npm registry");
|
|
2790
2994
|
}
|
|
2791
|
-
logger.success("Publishing completed!");
|
|
2995
|
+
logger.success("Publishing packages completed!");
|
|
2996
|
+
await executeHook("after:publish", config, dryRun);
|
|
2792
2997
|
return {
|
|
2793
2998
|
publishedPackages
|
|
2794
2999
|
};
|
|
2795
3000
|
} catch (error) {
|
|
2796
3001
|
logger.error("Error publishing packages:", error);
|
|
3002
|
+
await executeHook("error:publish", config, dryRun);
|
|
2797
3003
|
throw error;
|
|
2798
3004
|
}
|
|
2799
3005
|
}
|
|
2800
3006
|
|
|
2801
3007
|
function getReleaseConfig(options = {}) {
|
|
2802
|
-
return
|
|
3008
|
+
return loadRelizyConfig({
|
|
2803
3009
|
configName: options.configName,
|
|
2804
3010
|
overrides: {
|
|
2805
3011
|
logLevel: options.logLevel,
|
|
@@ -2832,21 +3038,33 @@ function getReleaseConfig(options = {}) {
|
|
|
2832
3038
|
push: options.push,
|
|
2833
3039
|
publish: options.publish,
|
|
2834
3040
|
noVerify: options.noVerify,
|
|
2835
|
-
|
|
3041
|
+
providerRelease: options.providerRelease,
|
|
2836
3042
|
clean: options.clean
|
|
2837
|
-
}
|
|
3043
|
+
},
|
|
3044
|
+
safetyCheck: options.safetyCheck
|
|
2838
3045
|
}
|
|
2839
3046
|
});
|
|
2840
3047
|
}
|
|
3048
|
+
function releaseSafetyCheck({
|
|
3049
|
+
config,
|
|
3050
|
+
provider
|
|
3051
|
+
}) {
|
|
3052
|
+
if (!config.safetyCheck) {
|
|
3053
|
+
return;
|
|
3054
|
+
}
|
|
3055
|
+
providerReleaseSafetyCheck({ config, provider });
|
|
3056
|
+
}
|
|
2841
3057
|
async function release(options = {}) {
|
|
3058
|
+
const dryRun = options.dryRun ?? false;
|
|
3059
|
+
logger.debug(`Dry run: ${dryRun}`);
|
|
3060
|
+
const force = options.force ?? false;
|
|
3061
|
+
logger.debug(`Force bump: ${force}`);
|
|
3062
|
+
const config = await getReleaseConfig(options);
|
|
3063
|
+
logger.debug(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
3064
|
+
logger.debug(`Push: ${config.release.push}, Publish: ${config.release.publish}, Provider Release: ${config.release.providerRelease}`);
|
|
3065
|
+
releaseSafetyCheck({ config, provider: options.provider });
|
|
2842
3066
|
try {
|
|
2843
|
-
|
|
2844
|
-
logger.debug(`Dry run: ${dryRun}`);
|
|
2845
|
-
const force = options.force ?? false;
|
|
2846
|
-
logger.debug(`Force bump: ${force}`);
|
|
2847
|
-
const config = await getReleaseConfig(options);
|
|
2848
|
-
logger.debug(`Version mode: ${config.monorepo?.versionMode || "standalone"}`);
|
|
2849
|
-
logger.debug(`Push: ${config.release.push}, Publish: ${config.release.publish}, Release: ${config.release.release}`);
|
|
3067
|
+
await executeHook("before:release", config, dryRun);
|
|
2850
3068
|
logger.box("Step 1/6: Bump versions");
|
|
2851
3069
|
const bumpResult = await bump({
|
|
2852
3070
|
type: config.bump.type,
|
|
@@ -2893,7 +3111,14 @@ async function release(options = {}) {
|
|
|
2893
3111
|
}
|
|
2894
3112
|
logger.box("Step 4/6: Push changes and tags");
|
|
2895
3113
|
if (config.release.push && config.release.commit) {
|
|
2896
|
-
await
|
|
3114
|
+
await executeHook("before:push", config, dryRun);
|
|
3115
|
+
try {
|
|
3116
|
+
await pushCommitAndTags({ dryRun, logLevel: config.logLevel, cwd: config.cwd });
|
|
3117
|
+
await executeHook("after:push", config, dryRun);
|
|
3118
|
+
} catch (error) {
|
|
3119
|
+
await executeHook("error:push", config, dryRun);
|
|
3120
|
+
throw error;
|
|
3121
|
+
}
|
|
2897
3122
|
} else {
|
|
2898
3123
|
logger.info("Skipping push (--no-push or --no-commit)");
|
|
2899
3124
|
}
|
|
@@ -2916,7 +3141,7 @@ async function release(options = {}) {
|
|
|
2916
3141
|
let provider = config.repo?.provider;
|
|
2917
3142
|
let postedReleases = [];
|
|
2918
3143
|
logger.box("Step 6/6: Publish Git release");
|
|
2919
|
-
if (config.release.
|
|
3144
|
+
if (config.release.providerRelease) {
|
|
2920
3145
|
logger.debug(`Provider from config: ${provider}`);
|
|
2921
3146
|
try {
|
|
2922
3147
|
const response = await providerRelease({
|
|
@@ -2933,7 +3158,7 @@ async function release(options = {}) {
|
|
|
2933
3158
|
logger.error("Error during release publication:", error);
|
|
2934
3159
|
}
|
|
2935
3160
|
} else {
|
|
2936
|
-
logger.info("Skipping release (--no-release)");
|
|
3161
|
+
logger.info("Skipping release (--no-provider-release)");
|
|
2937
3162
|
}
|
|
2938
3163
|
const publishedPackageCount = publishResponse?.publishedPackages.length ?? 0;
|
|
2939
3164
|
const versionDisplay = config.monorepo?.versionMode === "independent" ? `${bumpResult.bumpedPackages.length} packages bumped independently` : bumpResult.newVersion || getRootPackage(config.cwd).version;
|
|
@@ -2943,12 +3168,14 @@ Version: ${versionDisplay}
|
|
|
2943
3168
|
Tag(s): ${createdTags.length ? createdTags.join(", ") : "No"}
|
|
2944
3169
|
Pushed: ${config.release.push ? "Yes" : "Disabled"}
|
|
2945
3170
|
Published packages: ${config.release.publish ? publishedPackageCount : "Disabled"}
|
|
2946
|
-
Published release: ${config.release.
|
|
3171
|
+
Published release: ${config.release.providerRelease ? postedReleases.length : "Disabled"}
|
|
2947
3172
|
Git provider: ${provider}`);
|
|
3173
|
+
await executeHook("after:release", config, dryRun);
|
|
2948
3174
|
} catch (error) {
|
|
3175
|
+
await executeHook("error:release", config, dryRun);
|
|
2949
3176
|
logger.error("Error during release workflow:", error);
|
|
2950
3177
|
throw error;
|
|
2951
3178
|
}
|
|
2952
3179
|
}
|
|
2953
3180
|
|
|
2954
|
-
export {
|
|
3181
|
+
export { isStableReleaseType as $, github as A, createGitlabRelease as B, gitlab as C, getPackages as D, getPackageCommits as E, getRootPackage as F, hasLernaJson as G, getPackageToBump as H, detectPackageManager as I, determinePublishTag as J, getPackagesToPublishInSelectiveMode as K, getPackagesToPublishInIndependentMode as L, publishPackage as M, getLastRepoTag as N, getLastPackageTag as O, resolveTags as P, executeHook as Q, isInCI as R, getCIName as S, executeFormatCmd as T, executeBuildCmd as U, determineReleaseType as V, writeVersion as W, bumpPackageVersion as X, updateLernaVersion as Y, extractVersionFromPackageTag as Z, isPrerelease as _, providerRelease as a, isPrereleaseReleaseType as a0, isGraduating as a1, getPreid as a2, isChangedPreid as a3, bumpPackageIndependently as a4, confirmBump as a5, findPackagesWithCommitsAndCalculateVersions as a6, bumpIndependentPackages as a7, bump as b, changelog as c, publish as d, getDefaultConfig as e, defineConfig as f, generateChangelog as g, getPackageDependencies as h, getPackagesWithDependencies as i, getDependentsOf as j, expandPackagesToBumpWithDependents as k, loadRelizyConfig as l, getGitStatus as m, checkGitStatusIfDirty as n, fetchGitTags as o, providerReleaseSafetyCheck as p, detectGitProvider as q, release as r, parseGitRemoteUrl as s, topologicalSort as t, createCommitAndTags as u, pushCommitAndTags as v, writeChangelogToFile as w, getFirstCommit as x, getCurrentGitBranch as y, getCurrentGitRef as z };
|