relizy 1.5.0-beta.2 → 1.5.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +5 -3
- package/dist/index.d.mts +81 -1
- package/dist/index.d.ts +81 -1
- package/dist/index.mjs +1 -1
- package/dist/shared/{relizy.B0MWtDvR.mjs → relizy.CdiXgxMk.mjs} +229 -61
- package/package.json +15 -15
package/dist/cli.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import process from 'node:process';
|
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { printBanner, logger } from '@maz-ui/node';
|
|
7
7
|
import { Command } from 'commander';
|
|
8
|
-
import {
|
|
8
|
+
import { as as isInCI, S as getCIName, f as bump, h as changelog, aJ as publish, aH as providerRelease, a$ as social, aG as prComment, aS as release } from './shared/relizy.CdiXgxMk.mjs';
|
|
9
9
|
import 'node:child_process';
|
|
10
10
|
import '@maz-ui/utils/helpers/formatJson';
|
|
11
11
|
import 'c12';
|
|
@@ -109,7 +109,7 @@ program.command("changelog").description("Generate changelogs for all packages")
|
|
|
109
109
|
process.exit(1);
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
|
-
program.command("publish").description("Publish packages to registry").option("--registry <url>", "Custom registry URL").option("--tag <tag>", "Publish with specific tag (default: latest for stable, next for prerelease)").option("--access <type>", "Package access level (public or restricted)").option("--otp <code>", "One-time password for 2FA").option("--build-cmd <cmd>", 'Command to build packages before publish (e.g. "pnpm build")').option("--publish-token <token>", 'NPM token (e.g. "123456") - only supported for pnpm and npm').action(async (options) => {
|
|
112
|
+
program.command("publish").description("Publish packages to registry").option("--registry <url>", "Custom registry URL").option("--tag <tag>", "Publish with specific tag (default: latest for stable, next for prerelease)").option("--access <type>", "Package access level (public or restricted)").option("--otp <code>", "One-time password for 2FA").option("--build-cmd <cmd>", 'Command to build packages before publish (e.g. "pnpm build")').option("--publish-token <token>", 'NPM token (e.g. "123456") - only supported for pnpm and npm').option("--skip-existing-versions", "Skip packages whose version already exists on the registry instead of failing").action(async (options) => {
|
|
113
113
|
try {
|
|
114
114
|
await publish({
|
|
115
115
|
registry: options.registry,
|
|
@@ -118,6 +118,7 @@ program.command("publish").description("Publish packages to registry").option("-
|
|
|
118
118
|
otp: options.otp,
|
|
119
119
|
buildCmd: options.buildCmd,
|
|
120
120
|
token: options.publishToken,
|
|
121
|
+
skipExistingVersions: options.skipExistingVersions,
|
|
121
122
|
dryRun: program.opts().dryRun,
|
|
122
123
|
logLevel: program.opts().logLevel,
|
|
123
124
|
configName: program.opts().config
|
|
@@ -173,7 +174,7 @@ program.command("pr-comment").description("Post or re-post a PR comment with rel
|
|
|
173
174
|
process.exit(1);
|
|
174
175
|
}
|
|
175
176
|
});
|
|
176
|
-
program.command("release").description("Complete release workflow (bump + changelog + commit + tag + push to remote + publish release)").option("--major", "Bump major version").option("--minor", "Bump minor version").option("--patch", "Bump patch version").option("--prerelease", "Bump prerelease version").option("--premajor", "Bump premajor version").option("--preminor", "Bump preminor version").option("--prepatch", "Bump prepatch version").option("--preid <id>", "Prerelease identifier (alpha, beta, rc, etc.)").option("--suffix <suffix>", "Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix)").option("--from <ref>", "Start commit reference").option("--to <ref>", "End commit reference").option("--no-push", "Skip push changes and tags to remote").option("--no-provider-release", "Skip release creation (GitHub/GitLab)").option("--no-publish", "Skip npm publish").option("--registry <url>", "Custom npm registry URL").option("--tag <tag>", "Publish with specific tag (default: latest for stable, next for prerelease)").option("--access <type>", "Package access level (public or restricted)").option("--otp <code>", "One-time password for 2FA").option("--no-verify", "Skip git hooks during commit").option("--format-cmd <cmd>", 'Command to format CHANGELOG files after generation (e.g. "pnpm lint")').option("--build-cmd <cmd>", 'Command to build packages before publish (e.g. "pnpm build")').option("--no-root-changelog", "Skip generation of root changelog file").option("--token <token>", "Git token (github or gitlab)").option("--force", "Bump even if there are no commits").option("--no-clean", "Skip check if the working directory is clean").option("--no-commit", "Skip commit and tag").option("--no-git-tag", "Skip tag creation").option("--no-changelog", "Skip changelog generation files").option("--provider <provider>", "Git provider (github or gitlab)").option("--no-social", "Skip social media posting").option("--no-pr-comment", "Skip PR comment posting").option("--yes", "Skip confirmation prompt about bumping packages").option("--publish-token <token>", 'NPM token (e.g. "123456") - only supported for pnpm and npm').option("--canary", "Publish a canary release from the current commit").option("--include-private", "Include private packages in bump and changelog phases").option("--ai", "Force-enable AI for release notes and social posts").option("--no-ai", "Force-disable AI for release notes and social posts").action(async (options) => {
|
|
177
|
+
program.command("release").description("Complete release workflow (bump + changelog + commit + tag + push to remote + publish release)").option("--major", "Bump major version").option("--minor", "Bump minor version").option("--patch", "Bump patch version").option("--prerelease", "Bump prerelease version").option("--premajor", "Bump premajor version").option("--preminor", "Bump preminor version").option("--prepatch", "Bump prepatch version").option("--preid <id>", "Prerelease identifier (alpha, beta, rc, etc.)").option("--suffix <suffix>", "Custom suffix for prerelease versions - replace the last .X with .suffix (e.g. 1.0.0-beta.0 -> 1.0.0-beta.suffix)").option("--from <ref>", "Start commit reference").option("--to <ref>", "End commit reference").option("--no-push", "Skip push changes and tags to remote").option("--no-provider-release", "Skip release creation (GitHub/GitLab)").option("--no-publish", "Skip npm publish").option("--registry <url>", "Custom npm registry URL").option("--tag <tag>", "Publish with specific tag (default: latest for stable, next for prerelease)").option("--access <type>", "Package access level (public or restricted)").option("--otp <code>", "One-time password for 2FA").option("--no-verify", "Skip git hooks during commit").option("--format-cmd <cmd>", 'Command to format CHANGELOG files after generation (e.g. "pnpm lint")').option("--build-cmd <cmd>", 'Command to build packages before publish (e.g. "pnpm build")').option("--no-root-changelog", "Skip generation of root changelog file").option("--token <token>", "Git token (github or gitlab)").option("--force", "Bump even if there are no commits").option("--no-clean", "Skip check if the working directory is clean").option("--no-commit", "Skip commit and tag").option("--no-git-tag", "Skip tag creation").option("--no-changelog", "Skip changelog generation files").option("--provider <provider>", "Git provider (github or gitlab)").option("--no-social", "Skip social media posting").option("--no-pr-comment", "Skip PR comment posting").option("--yes", "Skip confirmation prompt about bumping packages").option("--publish-token <token>", 'NPM token (e.g. "123456") - only supported for pnpm and npm').option("--skip-existing-versions", "Skip packages whose version already exists on the registry instead of failing").option("--canary", "Publish a canary release from the current commit").option("--include-private", "Include private packages in bump and changelog phases").option("--ai", "Force-enable AI for release notes and social posts").option("--no-ai", "Force-disable AI for release notes and social posts").action(async (options) => {
|
|
177
178
|
try {
|
|
178
179
|
await release({
|
|
179
180
|
type: getReleaseType(options),
|
|
@@ -201,6 +202,7 @@ program.command("release").description("Complete release workflow (bump + change
|
|
|
201
202
|
rootChangelog: hasCliFlag("--no-root-changelog") ? false : void 0,
|
|
202
203
|
token: options.token,
|
|
203
204
|
publishToken: options.publishToken,
|
|
205
|
+
skipExistingVersions: options.skipExistingVersions,
|
|
204
206
|
logLevel: program.opts().logLevel,
|
|
205
207
|
force: options.force,
|
|
206
208
|
yes: options.yes,
|
package/dist/index.d.mts
CHANGED
|
@@ -29,6 +29,7 @@ declare function getDefaultConfig(): {
|
|
|
29
29
|
token: string | undefined;
|
|
30
30
|
safetyCheck: true;
|
|
31
31
|
safetyCheckTimeout: number;
|
|
32
|
+
skipExistingVersions: boolean;
|
|
32
33
|
packageManager: PackageManager;
|
|
33
34
|
};
|
|
34
35
|
tokens: {
|
|
@@ -401,6 +402,45 @@ declare function withRegistryNpmrc<T>({ config, registryTarget, packageName, pac
|
|
|
401
402
|
packageManager: PackageManager;
|
|
402
403
|
fn: () => Promise<T>;
|
|
403
404
|
}): Promise<T>;
|
|
405
|
+
/**
|
|
406
|
+
* Detect whether a failed publish is caused by the version already existing on
|
|
407
|
+
* the registry (the registry refusing to overwrite an immutable asset), as
|
|
408
|
+
* opposed to any other publish failure. This is what makes a retry safe: the
|
|
409
|
+
* artifact is already there, so the failure is really a "nothing to do".
|
|
410
|
+
*
|
|
411
|
+
* Registries phrase this differently, so we match the known variants:
|
|
412
|
+
* - npm public registry / verdaccio: `EPUBLISHCONFLICT`, `cannot publish over
|
|
413
|
+
* the previously published versions`, `you cannot publish over ...`;
|
|
414
|
+
* - Nexus: `Repository does not allow updating assets` (HTTP 400);
|
|
415
|
+
* - Artifactory/JFrog and others: `already exists` / `version already exists`;
|
|
416
|
+
* - a bare HTTP 409 Conflict from a registry that returns no message body.
|
|
417
|
+
*/
|
|
418
|
+
declare function isVersionAlreadyPublishedError(error: unknown): boolean;
|
|
419
|
+
/**
|
|
420
|
+
* Ask the registry whether `pkg@version` already exists. This is the primary,
|
|
421
|
+
* robust idempotency check: it relies on the standard registry metadata
|
|
422
|
+
* endpoint that every npm-compatible registry (npm, Nexus, JFrog, Verdaccio,
|
|
423
|
+
* GitHub/GitLab Packages) implements to serve `install`, rather than on the
|
|
424
|
+
* wording of a publish error - which varies per registry.
|
|
425
|
+
*
|
|
426
|
+
* Strategy: for npm/pnpm, use the `view` command first (it inherits the full
|
|
427
|
+
* `.npmrc` environment - proxy, CA, scoped auth). If that is inconclusive, or
|
|
428
|
+
* for yarn/bun (no usable `view`), fall back to a direct HTTP request to the
|
|
429
|
+
* packument endpoint so every package manager is covered.
|
|
430
|
+
*
|
|
431
|
+
* Returns:
|
|
432
|
+
* - `true` - the version is already published;
|
|
433
|
+
* - `false` - the package, or that specific version, is not on the registry;
|
|
434
|
+
* - `null` - the check was inconclusive (auth/network/registry error), so the
|
|
435
|
+
* caller should fall back to attempting the publish rather than skipping.
|
|
436
|
+
*/
|
|
437
|
+
declare function isVersionPublished({ pkg, version, config, packageManager, registryTarget, }: {
|
|
438
|
+
pkg: PackageBase;
|
|
439
|
+
version: string;
|
|
440
|
+
config: ResolvedRelizyConfig;
|
|
441
|
+
packageManager: PackageManager;
|
|
442
|
+
registryTarget: RegistryTarget;
|
|
443
|
+
}): Promise<boolean | null>;
|
|
404
444
|
declare function getAuthCommand({ packageManager, config, otp, registryTarget, }: {
|
|
405
445
|
packageManager: PackageManager;
|
|
406
446
|
config: ResolvedRelizyConfig;
|
|
@@ -1367,6 +1407,17 @@ type PublishConfig = ChangelogConfig$1['publish'] & {
|
|
|
1367
1407
|
* single-registry behavior.
|
|
1368
1408
|
*/
|
|
1369
1409
|
registries?: RegistryTarget[];
|
|
1410
|
+
/**
|
|
1411
|
+
* Skip a package (per registry) instead of failing when its version already
|
|
1412
|
+
* exists on the registry. Makes re-running a release idempotent: a retried
|
|
1413
|
+
* job whose version is already published (e.g. a canary rerun on the same
|
|
1414
|
+
* commit, or a partially completed publish) succeeds and only publishes what
|
|
1415
|
+
* is missing, rather than crashing on the registry's "cannot overwrite"
|
|
1416
|
+
* error. When disabled (the default), that situation still fails, but with a
|
|
1417
|
+
* clear error message instead of the raw registry error.
|
|
1418
|
+
* @default false
|
|
1419
|
+
*/
|
|
1420
|
+
skipExistingVersions?: boolean;
|
|
1370
1421
|
};
|
|
1371
1422
|
interface PublishOptions extends PublishConfig {
|
|
1372
1423
|
/**
|
|
@@ -2104,6 +2155,19 @@ interface CommentBodyParams {
|
|
|
2104
2155
|
}
|
|
2105
2156
|
declare function buildCommentBody(params: CommentBodyParams): string;
|
|
2106
2157
|
declare function prComment(options?: PrCommentOptions): Promise<boolean>;
|
|
2158
|
+
/**
|
|
2159
|
+
* Best-effort wrapper around {@link prComment} for the release flow: honours the
|
|
2160
|
+
* `--no-pr-comment` gate and swallows errors so a failed PR comment never aborts
|
|
2161
|
+
* an otherwise successful release.
|
|
2162
|
+
*/
|
|
2163
|
+
declare function tryPostPrComment({ config, releaseContext, prNumber, dryRun, logLevel, configName, }: {
|
|
2164
|
+
config: ResolvedRelizyConfig;
|
|
2165
|
+
releaseContext: ReleaseContext;
|
|
2166
|
+
prNumber?: number;
|
|
2167
|
+
dryRun: boolean;
|
|
2168
|
+
logLevel?: string;
|
|
2169
|
+
configName?: string;
|
|
2170
|
+
}): Promise<boolean>;
|
|
2107
2171
|
|
|
2108
2172
|
declare function providerReleaseSafetyCheck({ config, provider }: {
|
|
2109
2173
|
config: ResolvedRelizyConfig;
|
|
@@ -2119,6 +2183,22 @@ declare function publish(options?: Partial<PublishOptions>): Promise<{
|
|
|
2119
2183
|
publishedPackages: PackageBase[];
|
|
2120
2184
|
} | undefined>;
|
|
2121
2185
|
|
|
2186
|
+
/**
|
|
2187
|
+
* Build the final "Release workflow completed!" summary box from the outcome of
|
|
2188
|
+
* each release step. Pure formatting - no side effects - so it stays easy to read
|
|
2189
|
+
* and to test in isolation, and keeps the `release()` orchestration lean.
|
|
2190
|
+
*/
|
|
2191
|
+
declare function buildReleaseSummary({ config, bumpResult, publishResponse, createdTags, provider, postedReleases, providerError, socialResults, prCommentPosted, }: {
|
|
2192
|
+
config: ResolvedRelizyConfig;
|
|
2193
|
+
bumpResult: BumpResultTruthy;
|
|
2194
|
+
publishResponse?: PublishResponse;
|
|
2195
|
+
createdTags: string[];
|
|
2196
|
+
provider?: GitProvider;
|
|
2197
|
+
postedReleases: PostedRelease[];
|
|
2198
|
+
providerError?: string;
|
|
2199
|
+
socialResults?: SocialResult;
|
|
2200
|
+
prCommentPosted: boolean;
|
|
2201
|
+
}): string;
|
|
2122
2202
|
declare function release(options?: Partial<ReleaseOptions>): Promise<void>;
|
|
2123
2203
|
|
|
2124
2204
|
declare function socialSafetyCheck({ config }: {
|
|
@@ -2126,5 +2206,5 @@ declare function socialSafetyCheck({ config }: {
|
|
|
2126
2206
|
}): Promise<void>;
|
|
2127
2207
|
declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
|
|
2128
2208
|
|
|
2129
|
-
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, collectPackageBumps, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, findReachableCommitBySubject, formatChangelogForSlack, formatPackagesForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCommitSubject, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getNpmRegistry, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isAncestor, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, pushTagForce, readPackageJson, readPackages, reconcileFromTag, redactSecrets, release, resetRewrittenTagCache, resolveAllConfiguredRegistryTargets, resolveRegistryTargetsForPackage, resolveRegistryTargetsForPackages, resolveTags, retagAnnotatedLocal, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, tagExists, topologicalSort, updateLernaVersion, withRegistryNpmrc, writeChangelogToFile, writeVersion };
|
|
2209
|
+
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, buildReleaseSummary, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, collectPackageBumps, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, findReachableCommitBySubject, formatChangelogForSlack, formatPackagesForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCommitSubject, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getNpmRegistry, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isAncestor, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, isVersionAlreadyPublishedError, isVersionPublished, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, pushTagForce, readPackageJson, readPackages, reconcileFromTag, redactSecrets, release, resetRewrittenTagCache, resolveAllConfiguredRegistryTargets, resolveRegistryTargetsForPackage, resolveRegistryTargetsForPackages, resolveTags, retagAnnotatedLocal, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, tagExists, topologicalSort, tryPostPrComment, updateLernaVersion, withRegistryNpmrc, writeChangelogToFile, writeVersion };
|
|
2130
2210
|
export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogInclude, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, OnRewrittenTag, PackageBase, PackageBumpEntry, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, RegistryTarget, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackPackageEntry, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
|
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ declare function getDefaultConfig(): {
|
|
|
29
29
|
token: string | undefined;
|
|
30
30
|
safetyCheck: true;
|
|
31
31
|
safetyCheckTimeout: number;
|
|
32
|
+
skipExistingVersions: boolean;
|
|
32
33
|
packageManager: PackageManager;
|
|
33
34
|
};
|
|
34
35
|
tokens: {
|
|
@@ -401,6 +402,45 @@ declare function withRegistryNpmrc<T>({ config, registryTarget, packageName, pac
|
|
|
401
402
|
packageManager: PackageManager;
|
|
402
403
|
fn: () => Promise<T>;
|
|
403
404
|
}): Promise<T>;
|
|
405
|
+
/**
|
|
406
|
+
* Detect whether a failed publish is caused by the version already existing on
|
|
407
|
+
* the registry (the registry refusing to overwrite an immutable asset), as
|
|
408
|
+
* opposed to any other publish failure. This is what makes a retry safe: the
|
|
409
|
+
* artifact is already there, so the failure is really a "nothing to do".
|
|
410
|
+
*
|
|
411
|
+
* Registries phrase this differently, so we match the known variants:
|
|
412
|
+
* - npm public registry / verdaccio: `EPUBLISHCONFLICT`, `cannot publish over
|
|
413
|
+
* the previously published versions`, `you cannot publish over ...`;
|
|
414
|
+
* - Nexus: `Repository does not allow updating assets` (HTTP 400);
|
|
415
|
+
* - Artifactory/JFrog and others: `already exists` / `version already exists`;
|
|
416
|
+
* - a bare HTTP 409 Conflict from a registry that returns no message body.
|
|
417
|
+
*/
|
|
418
|
+
declare function isVersionAlreadyPublishedError(error: unknown): boolean;
|
|
419
|
+
/**
|
|
420
|
+
* Ask the registry whether `pkg@version` already exists. This is the primary,
|
|
421
|
+
* robust idempotency check: it relies on the standard registry metadata
|
|
422
|
+
* endpoint that every npm-compatible registry (npm, Nexus, JFrog, Verdaccio,
|
|
423
|
+
* GitHub/GitLab Packages) implements to serve `install`, rather than on the
|
|
424
|
+
* wording of a publish error - which varies per registry.
|
|
425
|
+
*
|
|
426
|
+
* Strategy: for npm/pnpm, use the `view` command first (it inherits the full
|
|
427
|
+
* `.npmrc` environment - proxy, CA, scoped auth). If that is inconclusive, or
|
|
428
|
+
* for yarn/bun (no usable `view`), fall back to a direct HTTP request to the
|
|
429
|
+
* packument endpoint so every package manager is covered.
|
|
430
|
+
*
|
|
431
|
+
* Returns:
|
|
432
|
+
* - `true` - the version is already published;
|
|
433
|
+
* - `false` - the package, or that specific version, is not on the registry;
|
|
434
|
+
* - `null` - the check was inconclusive (auth/network/registry error), so the
|
|
435
|
+
* caller should fall back to attempting the publish rather than skipping.
|
|
436
|
+
*/
|
|
437
|
+
declare function isVersionPublished({ pkg, version, config, packageManager, registryTarget, }: {
|
|
438
|
+
pkg: PackageBase;
|
|
439
|
+
version: string;
|
|
440
|
+
config: ResolvedRelizyConfig;
|
|
441
|
+
packageManager: PackageManager;
|
|
442
|
+
registryTarget: RegistryTarget;
|
|
443
|
+
}): Promise<boolean | null>;
|
|
404
444
|
declare function getAuthCommand({ packageManager, config, otp, registryTarget, }: {
|
|
405
445
|
packageManager: PackageManager;
|
|
406
446
|
config: ResolvedRelizyConfig;
|
|
@@ -1367,6 +1407,17 @@ type PublishConfig = ChangelogConfig$1['publish'] & {
|
|
|
1367
1407
|
* single-registry behavior.
|
|
1368
1408
|
*/
|
|
1369
1409
|
registries?: RegistryTarget[];
|
|
1410
|
+
/**
|
|
1411
|
+
* Skip a package (per registry) instead of failing when its version already
|
|
1412
|
+
* exists on the registry. Makes re-running a release idempotent: a retried
|
|
1413
|
+
* job whose version is already published (e.g. a canary rerun on the same
|
|
1414
|
+
* commit, or a partially completed publish) succeeds and only publishes what
|
|
1415
|
+
* is missing, rather than crashing on the registry's "cannot overwrite"
|
|
1416
|
+
* error. When disabled (the default), that situation still fails, but with a
|
|
1417
|
+
* clear error message instead of the raw registry error.
|
|
1418
|
+
* @default false
|
|
1419
|
+
*/
|
|
1420
|
+
skipExistingVersions?: boolean;
|
|
1370
1421
|
};
|
|
1371
1422
|
interface PublishOptions extends PublishConfig {
|
|
1372
1423
|
/**
|
|
@@ -2104,6 +2155,19 @@ interface CommentBodyParams {
|
|
|
2104
2155
|
}
|
|
2105
2156
|
declare function buildCommentBody(params: CommentBodyParams): string;
|
|
2106
2157
|
declare function prComment(options?: PrCommentOptions): Promise<boolean>;
|
|
2158
|
+
/**
|
|
2159
|
+
* Best-effort wrapper around {@link prComment} for the release flow: honours the
|
|
2160
|
+
* `--no-pr-comment` gate and swallows errors so a failed PR comment never aborts
|
|
2161
|
+
* an otherwise successful release.
|
|
2162
|
+
*/
|
|
2163
|
+
declare function tryPostPrComment({ config, releaseContext, prNumber, dryRun, logLevel, configName, }: {
|
|
2164
|
+
config: ResolvedRelizyConfig;
|
|
2165
|
+
releaseContext: ReleaseContext;
|
|
2166
|
+
prNumber?: number;
|
|
2167
|
+
dryRun: boolean;
|
|
2168
|
+
logLevel?: string;
|
|
2169
|
+
configName?: string;
|
|
2170
|
+
}): Promise<boolean>;
|
|
2107
2171
|
|
|
2108
2172
|
declare function providerReleaseSafetyCheck({ config, provider }: {
|
|
2109
2173
|
config: ResolvedRelizyConfig;
|
|
@@ -2119,6 +2183,22 @@ declare function publish(options?: Partial<PublishOptions>): Promise<{
|
|
|
2119
2183
|
publishedPackages: PackageBase[];
|
|
2120
2184
|
} | undefined>;
|
|
2121
2185
|
|
|
2186
|
+
/**
|
|
2187
|
+
* Build the final "Release workflow completed!" summary box from the outcome of
|
|
2188
|
+
* each release step. Pure formatting - no side effects - so it stays easy to read
|
|
2189
|
+
* and to test in isolation, and keeps the `release()` orchestration lean.
|
|
2190
|
+
*/
|
|
2191
|
+
declare function buildReleaseSummary({ config, bumpResult, publishResponse, createdTags, provider, postedReleases, providerError, socialResults, prCommentPosted, }: {
|
|
2192
|
+
config: ResolvedRelizyConfig;
|
|
2193
|
+
bumpResult: BumpResultTruthy;
|
|
2194
|
+
publishResponse?: PublishResponse;
|
|
2195
|
+
createdTags: string[];
|
|
2196
|
+
provider?: GitProvider;
|
|
2197
|
+
postedReleases: PostedRelease[];
|
|
2198
|
+
providerError?: string;
|
|
2199
|
+
socialResults?: SocialResult;
|
|
2200
|
+
prCommentPosted: boolean;
|
|
2201
|
+
}): string;
|
|
2122
2202
|
declare function release(options?: Partial<ReleaseOptions>): Promise<void>;
|
|
2123
2203
|
|
|
2124
2204
|
declare function socialSafetyCheck({ config }: {
|
|
@@ -2126,5 +2206,5 @@ declare function socialSafetyCheck({ config }: {
|
|
|
2126
2206
|
}): Promise<void>;
|
|
2127
2207
|
declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
|
|
2128
2208
|
|
|
2129
|
-
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, collectPackageBumps, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, findReachableCommitBySubject, formatChangelogForSlack, formatPackagesForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCommitSubject, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getNpmRegistry, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isAncestor, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, pushTagForce, readPackageJson, readPackages, reconcileFromTag, redactSecrets, release, resetRewrittenTagCache, resolveAllConfiguredRegistryTargets, resolveRegistryTargetsForPackage, resolveRegistryTargetsForPackages, resolveTags, retagAnnotatedLocal, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, tagExists, topologicalSort, updateLernaVersion, withRegistryNpmrc, writeChangelogToFile, writeVersion };
|
|
2209
|
+
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, buildReleaseSummary, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, collectPackageBumps, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, findReachableCommitBySubject, formatChangelogForSlack, formatPackagesForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCommitSubject, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getNpmRegistry, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isAncestor, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, isVersionAlreadyPublishedError, isVersionPublished, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, pushTagForce, readPackageJson, readPackages, reconcileFromTag, redactSecrets, release, resetRewrittenTagCache, resolveAllConfiguredRegistryTargets, resolveRegistryTargetsForPackage, resolveRegistryTargetsForPackages, resolveTags, retagAnnotatedLocal, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, tagExists, topologicalSort, tryPostPrComment, updateLernaVersion, withRegistryNpmrc, writeChangelogToFile, writeVersion };
|
|
2130
2210
|
export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogInclude, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, OnRewrittenTag, PackageBase, PackageBumpEntry, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, RegistryTarget, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackPackageEntry, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { N as NEW_PACKAGE_MARKER, P as PR_COMMENT_MARKER, b as buildChangelogBody, a as buildCommentBody, c as buildCompareLink, d as buildContributors, e as
|
|
1
|
+
export { N as NEW_PACKAGE_MARKER, P as PR_COMMENT_MARKER, b as buildChangelogBody, a as buildCommentBody, c as buildCompareLink, d as buildContributors, e as buildReleaseSummary, f as bump, g as capReleaseTypeForZeroMajor, h as changelog, i as checkGitStatusIfDirty, j as collectContributorNames, k as collectPackageBumps, l as confirmBump, m as createCommitAndTags, n as createGitlabRelease, o as defineConfig, p as detectGitProvider, q as detectPackageManager, r as detectPullRequest, s as determinePublishTag, t as determineReleaseType, u as determineSemverChange, v as executeBuildCmd, w as executeFormatCmd, x as executeHook, y as expandPackagesToBumpWithDependents, z as extractChangelogSummary, A as extractVersionFromPackageTag, B as extractVersionFromTag, C as fetchGitTags, D as filterOutPrivatePackages, E as findGitHubPR, F as findGitLabMR, G as findReachableCommitBySubject, H as formatChangelogForSlack, I as formatPackagesForSlack, J as formatSlackMessage, K as formatTweetMessage, L as generateChangelog, M as generateMarkDown, O as getAuthCommand, Q as getBumpedIndependentPackages, R as getBumpedPackageIndependently, S as getCIName, T as getCanaryVersion, U as getCommitSubject, V as getCurrentGitBranch, W as getCurrentGitRef, X as getDefaultConfig, Y as getDependentsOf, Z as getFirstCommit, _ as getGitStatus, $ as getIndependentTag, a0 as getLastPackageTag, a1 as getLastRepoTag, a2 as getLastStableTag, a3 as getLastTag, a4 as getModifiedReleaseFilePatterns, a5 as getNpmRegistry, a6 as getPackageCommits, a7 as getPackageDependencies, a8 as getPackageNewVersion, a9 as getPackages, aa as getPackagesOrBumpedPackages, ab as getPackagesToPublishInIndependentMode, ac as getPackagesToPublishInSelectiveMode, ad as getPreid, ae as getReleaseUrl, af as getRootPackage, ag as getShortCommitSha, ah as getSlackToken, ai as getSlackWebhookUrl, aj as getTwitterCredentials, ak as github, al as gitlab, am as hasLernaJson, an as isAncestor, ao as isBumpedPackage, ap as isChangedPreid, aq as isGraduating, ar as isGraduatingToStableBetweenVersion, as as isInCI, at as isPrerelease, au as isPrereleaseReleaseType, av as isStableReleaseType, aw as isTagVersionCompatibleWithCurrent, ax as isVersionAlreadyPublishedError, ay as isVersionPublished, az as loadRelizyConfig, aA as mergeTypes, aB as parseChangelogMarkdown, aC as parseGitRemoteUrl, aD as postPrComment, aE as postReleaseToSlack, aF as postReleaseToTwitter, aG as prComment, aH as providerRelease, aI as providerReleaseSafetyCheck, aJ as publish, aK as publishPackage, aL as publishSafetyCheck, aM as pushCommitAndTags, aN as pushTagForce, aO as readPackageJson, aP as readPackages, aQ as reconcileFromTag, aR as redactSecrets, aS as release, aT as resetRewrittenTagCache, aU as resolveAllConfiguredRegistryTargets, aV as resolveRegistryTargetsForPackage, aW as resolveRegistryTargetsForPackages, aX as resolveTags, aY as retagAnnotatedLocal, aZ as rollbackModifiedFiles, a_ as shouldFilterPrereleaseTags, a$ as social, b0 as socialSafetyCheck, b1 as tagExists, b2 as topologicalSort, b3 as tryPostPrComment, b4 as updateLernaVersion, b5 as withRegistryNpmrc, b6 as writeChangelogToFile, b7 as writeVersion } from './shared/relizy.CdiXgxMk.mjs';
|
|
2
2
|
import '@maz-ui/node';
|
|
3
3
|
import 'node:child_process';
|
|
4
4
|
import 'node:process';
|
|
@@ -2079,6 +2079,127 @@ function isOtpError(error) {
|
|
|
2079
2079
|
];
|
|
2080
2080
|
return otpPatterns.some((pattern) => searchText.includes(pattern));
|
|
2081
2081
|
}
|
|
2082
|
+
function isVersionAlreadyPublishedError(error) {
|
|
2083
|
+
if (typeof error !== "object" || error === null) {
|
|
2084
|
+
return false;
|
|
2085
|
+
}
|
|
2086
|
+
const errorMessage = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
|
|
2087
|
+
const searchText = `${errorMessage} ${String(error).toLowerCase()}`;
|
|
2088
|
+
const patterns = [
|
|
2089
|
+
"epublishconflict",
|
|
2090
|
+
"cannot publish over",
|
|
2091
|
+
"does not allow updating assets",
|
|
2092
|
+
"version already exists",
|
|
2093
|
+
"already exists in the repository",
|
|
2094
|
+
"status 409",
|
|
2095
|
+
"409 conflict"
|
|
2096
|
+
];
|
|
2097
|
+
return patterns.some((pattern) => searchText.includes(pattern));
|
|
2098
|
+
}
|
|
2099
|
+
function canQueryVersionViaView(packageManager) {
|
|
2100
|
+
return packageManager === "npm" || packageManager === "pnpm";
|
|
2101
|
+
}
|
|
2102
|
+
function isPackageNotFoundError(error) {
|
|
2103
|
+
if (typeof error !== "object" || error === null) {
|
|
2104
|
+
return false;
|
|
2105
|
+
}
|
|
2106
|
+
const errorMessage = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
|
|
2107
|
+
const searchText = `${errorMessage} ${String(error).toLowerCase()}`;
|
|
2108
|
+
return searchText.includes("e404") || searchText.includes("404 not found") || searchText.includes("is not in this registry") || searchText.includes("no match found");
|
|
2109
|
+
}
|
|
2110
|
+
async function queryVersionViaView({
|
|
2111
|
+
pkg,
|
|
2112
|
+
version,
|
|
2113
|
+
config,
|
|
2114
|
+
packageManager,
|
|
2115
|
+
registryTarget
|
|
2116
|
+
}) {
|
|
2117
|
+
const args = ["view", `${pkg.name}@${version}`, "version", "--json"];
|
|
2118
|
+
if (registryTarget.registry) {
|
|
2119
|
+
args.push("--registry", registryTarget.registry);
|
|
2120
|
+
}
|
|
2121
|
+
const command = `${packageManager} ${args.join(" ")}`;
|
|
2122
|
+
try {
|
|
2123
|
+
const { stdout } = await withRegistryNpmrc({
|
|
2124
|
+
config,
|
|
2125
|
+
registryTarget,
|
|
2126
|
+
packageName: pkg.name,
|
|
2127
|
+
packageManager,
|
|
2128
|
+
fn: () => execPromise(command, {
|
|
2129
|
+
cwd: pkg.path,
|
|
2130
|
+
noStdout: true,
|
|
2131
|
+
noStderr: true,
|
|
2132
|
+
noSuccess: true,
|
|
2133
|
+
noError: true,
|
|
2134
|
+
logLevel: config.logLevel
|
|
2135
|
+
})
|
|
2136
|
+
});
|
|
2137
|
+
const output = (stdout || "").trim();
|
|
2138
|
+
return output.length > 0 && output !== "undefined" && output !== "[]";
|
|
2139
|
+
} catch (error) {
|
|
2140
|
+
if (isPackageNotFoundError(error)) {
|
|
2141
|
+
return false;
|
|
2142
|
+
}
|
|
2143
|
+
logger.debug(`\`view\` check was inconclusive for ${pkg.name}@${version}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2144
|
+
return null;
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
function buildPackumentUrl(registry, packageName) {
|
|
2148
|
+
const base = registry.endsWith("/") ? registry : `${registry}/`;
|
|
2149
|
+
const encodedName = packageName.replace("/", "%2F");
|
|
2150
|
+
return `${base}${encodedName}`;
|
|
2151
|
+
}
|
|
2152
|
+
async function queryVersionViaHttp({
|
|
2153
|
+
pkg,
|
|
2154
|
+
version,
|
|
2155
|
+
config,
|
|
2156
|
+
registryTarget
|
|
2157
|
+
}) {
|
|
2158
|
+
const registry = registryTarget.registry || getNpmRegistry(config.cwd);
|
|
2159
|
+
if (!registry) {
|
|
2160
|
+
return null;
|
|
2161
|
+
}
|
|
2162
|
+
const token = registryTarget.token || config.publish.token || config.tokens.registry;
|
|
2163
|
+
const headers = { accept: "application/json" };
|
|
2164
|
+
if (token) {
|
|
2165
|
+
headers.authorization = `Bearer ${token}`;
|
|
2166
|
+
}
|
|
2167
|
+
const timeoutMs = config.publish.safetyCheckTimeout ?? 15e3;
|
|
2168
|
+
try {
|
|
2169
|
+
const response = await fetch(buildPackumentUrl(registry, pkg.name), {
|
|
2170
|
+
headers,
|
|
2171
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
2172
|
+
});
|
|
2173
|
+
if (response.status === 404) {
|
|
2174
|
+
return false;
|
|
2175
|
+
}
|
|
2176
|
+
if (!response.ok) {
|
|
2177
|
+
logger.debug(`Packument request for ${pkg.name} returned HTTP ${response.status} - treating as inconclusive`);
|
|
2178
|
+
return null;
|
|
2179
|
+
}
|
|
2180
|
+
const packument = await response.json();
|
|
2181
|
+
return Boolean(packument.versions && Object.hasOwn(packument.versions, version));
|
|
2182
|
+
} catch (error) {
|
|
2183
|
+
logger.debug(`Packument request for ${pkg.name} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
2184
|
+
return null;
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
async function isVersionPublished({
|
|
2188
|
+
pkg,
|
|
2189
|
+
version,
|
|
2190
|
+
config,
|
|
2191
|
+
packageManager,
|
|
2192
|
+
registryTarget
|
|
2193
|
+
}) {
|
|
2194
|
+
if (canQueryVersionViaView(packageManager)) {
|
|
2195
|
+
const viaView = await queryVersionViaView({ pkg, version, config, packageManager, registryTarget });
|
|
2196
|
+
if (viaView !== null) {
|
|
2197
|
+
return viaView;
|
|
2198
|
+
}
|
|
2199
|
+
logger.debug(`Falling back to a direct registry request for ${pkg.name}@${version}`);
|
|
2200
|
+
}
|
|
2201
|
+
return queryVersionViaHttp({ pkg, version, config, registryTarget });
|
|
2202
|
+
}
|
|
2082
2203
|
function promptOtpWithTimeout(timeout = 9e4) {
|
|
2083
2204
|
return new Promise((resolve, reject) => {
|
|
2084
2205
|
const timer = setTimeout(() => {
|
|
@@ -2178,6 +2299,14 @@ async function publishToRegistryTarget({
|
|
|
2178
2299
|
registryLabel
|
|
2179
2300
|
}) {
|
|
2180
2301
|
const tag = determinePublishTag(pkg.newVersion || pkg.version, registryTarget.tag ?? config.publish.tag);
|
|
2302
|
+
if (config.publish.skipExistingVersions && !dryRun) {
|
|
2303
|
+
const version = pkg.newVersion || pkg.version;
|
|
2304
|
+
const alreadyPublished = await isVersionPublished({ pkg, version, config, packageManager, registryTarget });
|
|
2305
|
+
if (alreadyPublished) {
|
|
2306
|
+
logger.warn(`Skipping ${packageNameAndVersion}${registryLabel}: version already exists on the registry (publish.skipExistingVersions enabled)`);
|
|
2307
|
+
return;
|
|
2308
|
+
}
|
|
2309
|
+
}
|
|
2181
2310
|
let dynamicOtp;
|
|
2182
2311
|
const maxAttempts = 2;
|
|
2183
2312
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
@@ -2215,6 +2344,15 @@ async function publishToRegistryTarget({
|
|
|
2215
2344
|
} catch (error) {
|
|
2216
2345
|
if (isOtpError(error) && attempt < maxAttempts - 1) {
|
|
2217
2346
|
dynamicOtp = await handleOtpError();
|
|
2347
|
+
} else if (isVersionAlreadyPublishedError(error)) {
|
|
2348
|
+
if (config.publish.skipExistingVersions) {
|
|
2349
|
+
logger.warn(`Skipping ${packageNameAndVersion}${registryLabel}: version already exists on the registry (publish.skipExistingVersions enabled)`);
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
throw new Error(
|
|
2353
|
+
`Version ${packageNameAndVersion} already exists on the registry${registryLabel} and cannot be overwritten. This usually happens when re-running a release on the same commit (e.g. a canary rerun). Enable publish.skipExistingVersions (or pass --skip-existing-versions) to skip already-published versions instead of failing.`,
|
|
2354
|
+
{ cause: error }
|
|
2355
|
+
);
|
|
2218
2356
|
} else {
|
|
2219
2357
|
logger.error(`Failed to publish ${packageNameAndVersion}:`, error);
|
|
2220
2358
|
throw error;
|
|
@@ -2372,6 +2510,9 @@ function getDefaultConfig() {
|
|
|
2372
2510
|
// (e.g. a corporate proxy) is honored instead of forcing the public one.
|
|
2373
2511
|
safetyCheck: true,
|
|
2374
2512
|
safetyCheckTimeout: 15e3,
|
|
2513
|
+
// Annotated as `boolean` (not the inferred `false` literal) so the resolved
|
|
2514
|
+
// config type stays assignable to true when overridden by config/CLI.
|
|
2515
|
+
skipExistingVersions: false,
|
|
2375
2516
|
packageManager: detectPackageManager(process$1.cwd())
|
|
2376
2517
|
},
|
|
2377
2518
|
tokens: {
|
|
@@ -3910,10 +4051,11 @@ function collectPackageBumps({
|
|
|
3910
4051
|
}) {
|
|
3911
4052
|
if (bumpedPackages && bumpedPackages.length > 0) {
|
|
3912
4053
|
return bumpedPackages.map((pkg) => {
|
|
3913
|
-
const
|
|
4054
|
+
const displayOldVersion = extractVersionFromTag(pkg.fromTag, pkg.name) || pkg.oldVersion;
|
|
4055
|
+
const hasTransition = Boolean(pkg.newVersion && displayOldVersion !== pkg.newVersion);
|
|
3914
4056
|
return {
|
|
3915
4057
|
name: pkg.name,
|
|
3916
|
-
oldVersion:
|
|
4058
|
+
oldVersion: displayOldVersion,
|
|
3917
4059
|
newVersion: pkg.newVersion,
|
|
3918
4060
|
version: pkg.newVersion || pkg.version,
|
|
3919
4061
|
hasTransition
|
|
@@ -5500,9 +5642,10 @@ function buildSuccessComment({
|
|
|
5500
5642
|
const distTag = config.publish?.tag;
|
|
5501
5643
|
const installCmd = getInstallCommand(config.publish?.packageManager);
|
|
5502
5644
|
const lines = [PR_COMMENT_MARKER, "", "## \u{1F680} Release published", ""];
|
|
5645
|
+
const previousVersion = extractVersionFromTag(bumpResult?.fromTag ?? "") || bumpResult?.oldVersion;
|
|
5503
5646
|
lines.push(...buildMetadataLines({
|
|
5504
5647
|
version,
|
|
5505
|
-
oldVersion:
|
|
5648
|
+
oldVersion: previousVersion,
|
|
5506
5649
|
tags,
|
|
5507
5650
|
distTag,
|
|
5508
5651
|
date,
|
|
@@ -5617,6 +5760,32 @@ ${body}`
|
|
|
5617
5760
|
}
|
|
5618
5761
|
return await postPrComment({ config, pr, body });
|
|
5619
5762
|
}
|
|
5763
|
+
async function tryPostPrComment({
|
|
5764
|
+
config,
|
|
5765
|
+
releaseContext,
|
|
5766
|
+
prNumber,
|
|
5767
|
+
dryRun,
|
|
5768
|
+
logLevel,
|
|
5769
|
+
configName
|
|
5770
|
+
}) {
|
|
5771
|
+
if (!config.release.prComment) {
|
|
5772
|
+
logger.info("Skipping PR comment (--no-pr-comment)");
|
|
5773
|
+
return false;
|
|
5774
|
+
}
|
|
5775
|
+
try {
|
|
5776
|
+
return await prComment({
|
|
5777
|
+
prNumber,
|
|
5778
|
+
dryRun,
|
|
5779
|
+
logLevel,
|
|
5780
|
+
configName,
|
|
5781
|
+
config,
|
|
5782
|
+
releaseContext
|
|
5783
|
+
});
|
|
5784
|
+
} catch (error) {
|
|
5785
|
+
logger.warn("PR comment posting failed:", error);
|
|
5786
|
+
return false;
|
|
5787
|
+
}
|
|
5788
|
+
}
|
|
5620
5789
|
|
|
5621
5790
|
async function providerReleaseSafetyCheck({ config, provider }) {
|
|
5622
5791
|
if (!config.safetyCheck || !config.release.providerRelease) {
|
|
@@ -5801,7 +5970,8 @@ async function publish(options = {}) {
|
|
|
5801
5970
|
registries: options.registries,
|
|
5802
5971
|
tag: options.tag,
|
|
5803
5972
|
buildCmd: options.buildCmd,
|
|
5804
|
-
token: options.token
|
|
5973
|
+
token: options.token,
|
|
5974
|
+
skipExistingVersions: options.skipExistingVersions
|
|
5805
5975
|
},
|
|
5806
5976
|
logLevel: options.logLevel,
|
|
5807
5977
|
safetyCheck: options.safetyCheck
|
|
@@ -6388,7 +6558,8 @@ function getReleaseConfig(options = {}) {
|
|
|
6388
6558
|
registries: options.registries,
|
|
6389
6559
|
tag: options.tag,
|
|
6390
6560
|
buildCmd: options.buildCmd,
|
|
6391
|
-
token: options.publishToken
|
|
6561
|
+
token: options.publishToken,
|
|
6562
|
+
skipExistingVersions: options.skipExistingVersions
|
|
6392
6563
|
},
|
|
6393
6564
|
release: {
|
|
6394
6565
|
commit: options.commit,
|
|
@@ -6428,31 +6599,51 @@ async function releaseSafetyCheck({
|
|
|
6428
6599
|
throw error;
|
|
6429
6600
|
}
|
|
6430
6601
|
}
|
|
6431
|
-
|
|
6602
|
+
function buildReleaseSummary({
|
|
6432
6603
|
config,
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6604
|
+
bumpResult,
|
|
6605
|
+
publishResponse,
|
|
6606
|
+
createdTags,
|
|
6607
|
+
provider,
|
|
6608
|
+
postedReleases,
|
|
6609
|
+
providerError,
|
|
6610
|
+
socialResults,
|
|
6611
|
+
prCommentPosted
|
|
6438
6612
|
}) {
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6613
|
+
const publishedPackageCount = publishResponse?.publishedPackages.length ?? 0;
|
|
6614
|
+
const versionDisplay = config.monorepo?.versionMode === "independent" ? `${bumpResult.bumpedPackages.length} packages bumped independently` : bumpResult.newVersion || readPackageJson(config.cwd)?.version;
|
|
6615
|
+
let providerDisplay = "Disabled";
|
|
6616
|
+
if (config.release.providerRelease) {
|
|
6617
|
+
if (providerError) {
|
|
6618
|
+
providerDisplay = `Failed: ${providerError}`;
|
|
6619
|
+
} else {
|
|
6620
|
+
providerDisplay = `${postedReleases.length} release${postedReleases.length !== 1 ? "s" : ""}`;
|
|
6621
|
+
}
|
|
6442
6622
|
}
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
}
|
|
6452
|
-
} catch (error) {
|
|
6453
|
-
logger.warn("PR comment posting failed:", error);
|
|
6454
|
-
return false;
|
|
6623
|
+
let socialDisplay = "Disabled";
|
|
6624
|
+
if (config.release.social && socialResults) {
|
|
6625
|
+
if (socialResults.hasErrors) {
|
|
6626
|
+
const failed = socialResults.results.filter((r) => !r.success).map((r) => r.platform);
|
|
6627
|
+
const succeeded = socialResults.results.filter((r) => r.success).map((r) => r.platform);
|
|
6628
|
+
socialDisplay = `${succeeded.length} succeeded, ${failed.length} failed (${failed.join(", ")})`;
|
|
6629
|
+
} else {
|
|
6630
|
+
socialDisplay = `${socialResults.results.length} succeeded`;
|
|
6631
|
+
}
|
|
6455
6632
|
}
|
|
6633
|
+
let prCommentDisplay = "Disabled";
|
|
6634
|
+
if (config.release.prComment) {
|
|
6635
|
+
prCommentDisplay = prCommentPosted ? "Posted" : "Failed";
|
|
6636
|
+
}
|
|
6637
|
+
return `Release workflow completed!
|
|
6638
|
+
|
|
6639
|
+
Version: ${versionDisplay ?? "Unknown"}
|
|
6640
|
+
Tag(s): ${createdTags?.length ? createdTags.join(", ") : "None"}
|
|
6641
|
+
Pushed: ${config.release.push ? "Yes" : "Disabled"}
|
|
6642
|
+
Published packages: ${config.release.publish ? publishedPackageCount : "Disabled"}
|
|
6643
|
+
Provider release: ${providerDisplay}
|
|
6644
|
+
Social media: ${socialDisplay}
|
|
6645
|
+
PR comment: ${prCommentDisplay}
|
|
6646
|
+
Git provider: ${provider}`;
|
|
6456
6647
|
}
|
|
6457
6648
|
async function release(options = {}) {
|
|
6458
6649
|
const isCanary = options.canary ?? false;
|
|
@@ -6641,40 +6832,17 @@ async function release(options = {}) {
|
|
|
6641
6832
|
logLevel: config.logLevel,
|
|
6642
6833
|
configName: options.configName
|
|
6643
6834
|
});
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
if (config.release.social && socialResults) {
|
|
6656
|
-
if (socialResults.hasErrors) {
|
|
6657
|
-
const failed = socialResults.results.filter((r) => !r.success).map((r) => r.platform);
|
|
6658
|
-
const succeeded = socialResults.results.filter((r) => r.success).map((r) => r.platform);
|
|
6659
|
-
socialDisplay = `${succeeded.length} succeeded, ${failed.length} failed (${failed.join(", ")})`;
|
|
6660
|
-
} else {
|
|
6661
|
-
socialDisplay = `${socialResults.results.length} succeeded`;
|
|
6662
|
-
}
|
|
6663
|
-
}
|
|
6664
|
-
let prCommentDisplay = "Disabled";
|
|
6665
|
-
if (config.release.prComment) {
|
|
6666
|
-
prCommentDisplay = prCommentPosted ? "Posted" : "Failed";
|
|
6667
|
-
}
|
|
6668
|
-
logger.box(`Release workflow completed!
|
|
6669
|
-
|
|
6670
|
-
Version: ${versionDisplay ?? "Unknown"}
|
|
6671
|
-
Tag(s): ${createdTags?.length ? createdTags.join(", ") : "None"}
|
|
6672
|
-
Pushed: ${config.release.push ? "Yes" : "Disabled"}
|
|
6673
|
-
Published packages: ${config.release.publish ? publishedPackageCount : "Disabled"}
|
|
6674
|
-
Provider release: ${providerDisplay}
|
|
6675
|
-
Social media: ${socialDisplay}
|
|
6676
|
-
PR comment: ${prCommentDisplay}
|
|
6677
|
-
Git provider: ${provider}`);
|
|
6835
|
+
logger.box(buildReleaseSummary({
|
|
6836
|
+
config,
|
|
6837
|
+
bumpResult,
|
|
6838
|
+
publishResponse,
|
|
6839
|
+
createdTags,
|
|
6840
|
+
provider,
|
|
6841
|
+
postedReleases,
|
|
6842
|
+
providerError,
|
|
6843
|
+
socialResults,
|
|
6844
|
+
prCommentPosted
|
|
6845
|
+
}));
|
|
6678
6846
|
await executeHook("success:release", config, dryRun);
|
|
6679
6847
|
} catch (error) {
|
|
6680
6848
|
logger.error("Error during release workflow!\n\n", error);
|
|
@@ -6695,4 +6863,4 @@ Git provider: ${provider}`);
|
|
|
6695
6863
|
}
|
|
6696
6864
|
}
|
|
6697
6865
|
|
|
6698
|
-
export {
|
|
6866
|
+
export { getIndependentTag as $, extractVersionFromPackageTag as A, extractVersionFromTag as B, fetchGitTags as C, filterOutPrivatePackages as D, findGitHubPR as E, findGitLabMR as F, findReachableCommitBySubject as G, formatChangelogForSlack as H, formatPackagesForSlack as I, formatSlackMessage as J, formatTweetMessage as K, generateChangelog as L, generateMarkDown as M, NEW_PACKAGE_MARKER as N, getAuthCommand as O, PR_COMMENT_MARKER as P, getBumpedIndependentPackages as Q, getBumpedPackageIndependently as R, getCIName as S, getCanaryVersion as T, getCommitSubject as U, getCurrentGitBranch as V, getCurrentGitRef as W, getDefaultConfig as X, getDependentsOf as Y, getFirstCommit as Z, getGitStatus as _, buildCommentBody as a, social as a$, getLastPackageTag as a0, getLastRepoTag as a1, getLastStableTag as a2, getLastTag as a3, getModifiedReleaseFilePatterns as a4, getNpmRegistry as a5, getPackageCommits as a6, getPackageDependencies as a7, getPackageNewVersion as a8, getPackages as a9, mergeTypes as aA, parseChangelogMarkdown as aB, parseGitRemoteUrl as aC, postPrComment as aD, postReleaseToSlack as aE, postReleaseToTwitter as aF, prComment as aG, providerRelease as aH, providerReleaseSafetyCheck as aI, publish as aJ, publishPackage as aK, publishSafetyCheck as aL, pushCommitAndTags as aM, pushTagForce as aN, readPackageJson as aO, readPackages as aP, reconcileFromTag as aQ, redactSecrets as aR, release as aS, resetRewrittenTagCache as aT, resolveAllConfiguredRegistryTargets as aU, resolveRegistryTargetsForPackage as aV, resolveRegistryTargetsForPackages as aW, resolveTags as aX, retagAnnotatedLocal as aY, rollbackModifiedFiles as aZ, shouldFilterPrereleaseTags as a_, getPackagesOrBumpedPackages as aa, getPackagesToPublishInIndependentMode as ab, getPackagesToPublishInSelectiveMode as ac, getPreid as ad, getReleaseUrl as ae, getRootPackage as af, getShortCommitSha as ag, getSlackToken as ah, getSlackWebhookUrl as ai, getTwitterCredentials as aj, github as ak, gitlab as al, hasLernaJson as am, isAncestor as an, isBumpedPackage as ao, isChangedPreid as ap, isGraduating as aq, isGraduatingToStableBetweenVersion as ar, isInCI as as, isPrerelease as at, isPrereleaseReleaseType as au, isStableReleaseType as av, isTagVersionCompatibleWithCurrent as aw, isVersionAlreadyPublishedError as ax, isVersionPublished as ay, loadRelizyConfig as az, buildChangelogBody as b, socialSafetyCheck as b0, tagExists as b1, topologicalSort as b2, tryPostPrComment as b3, updateLernaVersion as b4, withRegistryNpmrc as b5, writeChangelogToFile as b6, writeVersion as b7, buildCompareLink as c, buildContributors as d, buildReleaseSummary as e, bump as f, capReleaseTypeForZeroMajor as g, changelog as h, checkGitStatusIfDirty as i, collectContributorNames as j, collectPackageBumps as k, confirmBump as l, createCommitAndTags as m, createGitlabRelease as n, defineConfig as o, detectGitProvider as p, detectPackageManager as q, detectPullRequest as r, determinePublishTag as s, determineReleaseType as t, determineSemverChange as u, executeBuildCmd as v, executeFormatCmd as w, executeHook as x, expandPackagesToBumpWithDependents as y, extractChangelogSummary as z };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "relizy",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.5.0-beta.
|
|
4
|
+
"version": "1.5.0-beta.3",
|
|
5
5
|
"description": "Changelogen adapter for monorepo management with unified and independent versioning",
|
|
6
6
|
"author": "Louis Mazel <me@loicmazuel.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"node": ">=20.0.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@slack/web-api": "^7.0.0",
|
|
58
|
+
"@slack/web-api": "^7.0.0 || ^8.0.0",
|
|
59
59
|
"@yoloship/claude-sdk": "^0.2.0-beta.6",
|
|
60
60
|
"twitter-api-v2": "^1.20.0"
|
|
61
61
|
},
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@inquirer/prompts": "^8.7.2",
|
|
75
75
|
"@maz-ui/node": "5.0.0-beta.26",
|
|
76
|
-
"@maz-ui/utils": "5.0.0-beta.
|
|
76
|
+
"@maz-ui/utils": "5.0.0-beta.39",
|
|
77
77
|
"c12": "^3.3.3",
|
|
78
78
|
"changelogen": "^0.6.2",
|
|
79
79
|
"commander": "^15.0.0",
|
|
@@ -85,28 +85,28 @@
|
|
|
85
85
|
"semver": "^7.8.5"
|
|
86
86
|
},
|
|
87
87
|
"devDependencies": {
|
|
88
|
-
"@commitlint/cli": "^21.2.
|
|
89
|
-
"@commitlint/config-conventional": "21.2.
|
|
90
|
-
"@commitlint/cz-commitlint": "^21.2.
|
|
91
|
-
"@commitlint/types": "^21.2.
|
|
88
|
+
"@commitlint/cli": "^21.2.3",
|
|
89
|
+
"@commitlint/config-conventional": "21.2.3",
|
|
90
|
+
"@commitlint/cz-commitlint": "^21.2.3",
|
|
91
|
+
"@commitlint/types": "^21.2.3",
|
|
92
92
|
"@maz-ui/eslint-config": "5.0.0-beta.43",
|
|
93
|
-
"@slack/web-api": "
|
|
93
|
+
"@slack/web-api": "8.1.1",
|
|
94
94
|
"@types/micromatch": "^4.0.10",
|
|
95
|
-
"@types/node": "^
|
|
95
|
+
"@types/node": "^26.6.2",
|
|
96
96
|
"@types/semver": "^7.8.0",
|
|
97
|
-
"@vitest/coverage-v8": "^5.0.
|
|
97
|
+
"@vitest/coverage-v8": "^5.0.1",
|
|
98
98
|
"@yoloship/claude-sdk": "0.2.0-beta.6",
|
|
99
99
|
"cross-env": "10.1.0",
|
|
100
|
-
"eslint": "^10.
|
|
100
|
+
"eslint": "^10.11.0",
|
|
101
101
|
"husky": "9.1.7",
|
|
102
102
|
"jiti": "2.7.0",
|
|
103
103
|
"lint-staged": "^17.5.1",
|
|
104
|
-
"memfs": "^4.78.
|
|
105
|
-
"tsx": "^4.23.
|
|
104
|
+
"memfs": "^4.78.1",
|
|
105
|
+
"tsx": "^4.23.15",
|
|
106
106
|
"twitter-api-v2": "^1.29.1",
|
|
107
|
-
"typescript": "^6.0.
|
|
107
|
+
"typescript": "^6.0.0",
|
|
108
108
|
"unbuild": "^3.6.1",
|
|
109
|
-
"vitest": "^5.0.
|
|
109
|
+
"vitest": "^5.0.1"
|
|
110
110
|
},
|
|
111
111
|
"lint-staged": {
|
|
112
112
|
"*.{js,jsx,ts,tsx,mjs,mts,cjs,md,yml,json}": [
|