relizy 1.3.2 → 1.4.0-beta.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/dist/cli.mjs +1 -1
- package/dist/index.d.mts +74 -13
- package/dist/index.d.ts +74 -13
- package/dist/index.mjs +1 -1
- package/dist/shared/{relizy.ubFyghBI.mjs → relizy.CxbwJj6k.mjs} +177 -77
- package/package.json +8 -8
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 { ao as isInCI, ap as getCIName, b as bump, c as changelog, g as publish, e as providerRelease, h as social, p as prComment, r as release } from './shared/relizy.CxbwJj6k.mjs';
|
|
9
9
|
import 'node:child_process';
|
|
10
10
|
import '@maz-ui/utils';
|
|
11
11
|
import 'c12';
|
package/dist/index.d.mts
CHANGED
|
@@ -60,6 +60,8 @@ declare function getDefaultConfig(): {
|
|
|
60
60
|
slack: {
|
|
61
61
|
enabled: boolean;
|
|
62
62
|
onlyStable: boolean;
|
|
63
|
+
postMaxLength: number;
|
|
64
|
+
noAuthors: boolean;
|
|
63
65
|
};
|
|
64
66
|
};
|
|
65
67
|
prComment: Required<PrCommentConfig>;
|
|
@@ -233,6 +235,16 @@ declare function buildChangelogBody({ commits, config, minify }: {
|
|
|
233
235
|
config: ResolvedRelizyConfig;
|
|
234
236
|
minify?: boolean;
|
|
235
237
|
}): string;
|
|
238
|
+
/**
|
|
239
|
+
* Collect unique contributor names from a set of commits.
|
|
240
|
+
* Respects `config.noAuthors`, filters `[bot]` authors, and applies `config.excludeAuthors`.
|
|
241
|
+
* Returns plain formatted names (no emails, no GitHub handles) — useful for lightweight
|
|
242
|
+
* rendering contexts like Slack messages.
|
|
243
|
+
*/
|
|
244
|
+
declare function collectContributorNames({ commits, config }: {
|
|
245
|
+
commits: GitCommit[];
|
|
246
|
+
config: ResolvedRelizyConfig;
|
|
247
|
+
}): string[];
|
|
236
248
|
declare function buildContributors({ commits, config }: {
|
|
237
249
|
commits: GitCommit[];
|
|
238
250
|
config: ResolvedRelizyConfig;
|
|
@@ -347,6 +359,13 @@ declare function getSlackToken(options: {
|
|
|
347
359
|
socialCredentials?: SlackCredentials;
|
|
348
360
|
tokenCredential?: string;
|
|
349
361
|
}): string | null;
|
|
362
|
+
/**
|
|
363
|
+
* Get Slack Incoming Webhook URL from config or environment variables.
|
|
364
|
+
* Priority: social.slack.webhookUrl > RELIZY_SLACK_WEBHOOK_URL > SLACK_WEBHOOK_URL.
|
|
365
|
+
*/
|
|
366
|
+
declare function getSlackWebhookUrl(options: {
|
|
367
|
+
socialWebhookUrl?: string;
|
|
368
|
+
}): string | null;
|
|
350
369
|
/**
|
|
351
370
|
* Format changelog for Slack (convert markdown to Slack's mrkdwn format)
|
|
352
371
|
*/
|
|
@@ -354,18 +373,25 @@ declare function formatChangelogForSlack(changelog: string, maxLength?: number):
|
|
|
354
373
|
/**
|
|
355
374
|
* Format the Slack message using blocks
|
|
356
375
|
*/
|
|
357
|
-
declare function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template }: {
|
|
376
|
+
declare function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template, contributors, postMaxLength }: {
|
|
358
377
|
template?: string;
|
|
359
378
|
projectName: string;
|
|
360
379
|
version: string;
|
|
361
380
|
changelog: string;
|
|
362
381
|
releaseUrl?: string;
|
|
363
382
|
changelogUrl?: string;
|
|
383
|
+
contributors?: string[];
|
|
384
|
+
postMaxLength?: number;
|
|
364
385
|
}): any[];
|
|
365
386
|
/**
|
|
366
|
-
* Post a release announcement to Slack
|
|
387
|
+
* Post a release announcement to Slack.
|
|
388
|
+
* Dispatches to Incoming Webhook (if `webhookUrl` is set) or Web API (`token` + `channel`).
|
|
389
|
+
* When both are provided, the webhook takes priority.
|
|
367
390
|
*/
|
|
368
|
-
declare function postReleaseToSlack({ version, projectName, changelog, releaseUrl, changelogUrl, channel, token, template, dryRun, }: SlackOptions): Promise<
|
|
391
|
+
declare function postReleaseToSlack({ version, projectName, changelog, releaseUrl, changelogUrl, channel, token, webhookUrl, template, contributors, postMaxLength, dryRun, }: SlackOptions): Promise<{
|
|
392
|
+
ok: true;
|
|
393
|
+
transport: "webhook";
|
|
394
|
+
} | _slack_web_api.ChatPostMessageResponse | undefined>;
|
|
369
395
|
|
|
370
396
|
/**
|
|
371
397
|
* Extract a summary from changelog content
|
|
@@ -1269,8 +1295,10 @@ interface TwitterSocialConfig {
|
|
|
1269
1295
|
}
|
|
1270
1296
|
interface SlackCredentials {
|
|
1271
1297
|
/**
|
|
1272
|
-
* Slack Bot Token or User OAuth Token
|
|
1273
|
-
* Required scopes: chat:write
|
|
1298
|
+
* Slack Bot Token or User OAuth Token (starts with `xoxb-`).
|
|
1299
|
+
* Required scopes: chat:write (and chat:write.public for public channels without bot invite).
|
|
1300
|
+
* Env fallback: SLACK_TOKEN, RELIZY_SLACK_TOKEN.
|
|
1301
|
+
* Ignored when social.slack.webhookUrl is set (webhook takes priority).
|
|
1274
1302
|
*/
|
|
1275
1303
|
token?: string;
|
|
1276
1304
|
}
|
|
@@ -1287,18 +1315,38 @@ interface SlackSocialConfig {
|
|
|
1287
1315
|
*/
|
|
1288
1316
|
onlyStable?: boolean;
|
|
1289
1317
|
/**
|
|
1290
|
-
* Slack channel ID or name (e.g., "#releases" or "C1234567890")
|
|
1318
|
+
* Slack channel ID or name (e.g., "#releases" or "C1234567890").
|
|
1319
|
+
* Required when using token-based authentication.
|
|
1320
|
+
* Ignored (with warning) when webhookUrl is set — the channel is baked into the webhook URL.
|
|
1291
1321
|
*/
|
|
1292
|
-
channel
|
|
1322
|
+
channel?: string;
|
|
1323
|
+
/**
|
|
1324
|
+
* Slack Incoming Webhook URL. When set, takes priority over token-based auth.
|
|
1325
|
+
* Env fallback: SLACK_WEBHOOK_URL, RELIZY_SLACK_WEBHOOK_URL.
|
|
1326
|
+
* See: https://api.slack.com/messaging/webhooks
|
|
1327
|
+
*/
|
|
1328
|
+
webhookUrl?: string;
|
|
1293
1329
|
/**
|
|
1294
1330
|
* Custom message template
|
|
1295
|
-
* Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}
|
|
1331
|
+
* Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}, {{contributors}}
|
|
1296
1332
|
*/
|
|
1297
1333
|
template?: string;
|
|
1298
1334
|
/**
|
|
1299
1335
|
* Slack credentials (optional - falls back to environment variables)
|
|
1300
1336
|
*/
|
|
1301
1337
|
credentials?: SlackCredentials;
|
|
1338
|
+
/**
|
|
1339
|
+
* Maximum length (in characters) of the changelog rendered inside the Slack message.
|
|
1340
|
+
* Slack's per-section-block limit is 3000; default 2500 leaves margin for emoji/formatting.
|
|
1341
|
+
* @default 2500
|
|
1342
|
+
*/
|
|
1343
|
+
postMaxLength?: number;
|
|
1344
|
+
/**
|
|
1345
|
+
* Hide the contributors block in Slack messages.
|
|
1346
|
+
* If config.noAuthors is true globally, contributors are always hidden regardless of this setting.
|
|
1347
|
+
* @default false
|
|
1348
|
+
*/
|
|
1349
|
+
noAuthors?: boolean;
|
|
1302
1350
|
}
|
|
1303
1351
|
type AIProviderName = 'claude-code';
|
|
1304
1352
|
interface ClaudeCodeProviderOptions {
|
|
@@ -1462,17 +1510,30 @@ interface SlackOptions {
|
|
|
1462
1510
|
*/
|
|
1463
1511
|
changelogUrl?: string;
|
|
1464
1512
|
/**
|
|
1465
|
-
* Slack channel ID or name
|
|
1513
|
+
* Slack channel ID or name. Required when using token-based auth.
|
|
1466
1514
|
*/
|
|
1467
|
-
channel
|
|
1515
|
+
channel?: string;
|
|
1468
1516
|
/**
|
|
1469
|
-
* Slack
|
|
1517
|
+
* Slack Bot Token. Ignored if webhookUrl is set.
|
|
1470
1518
|
*/
|
|
1471
|
-
token
|
|
1519
|
+
token?: string;
|
|
1520
|
+
/**
|
|
1521
|
+
* Slack Incoming Webhook URL. Takes priority over token.
|
|
1522
|
+
*/
|
|
1523
|
+
webhookUrl?: string;
|
|
1472
1524
|
/**
|
|
1473
1525
|
* Custom message template
|
|
1474
1526
|
*/
|
|
1475
1527
|
template?: string;
|
|
1528
|
+
/**
|
|
1529
|
+
* Maximum chars of the changelog rendered in the message.
|
|
1530
|
+
* @default 2500
|
|
1531
|
+
*/
|
|
1532
|
+
postMaxLength?: number;
|
|
1533
|
+
/**
|
|
1534
|
+
* Contributor names (plain strings, no email/handle). Empty array or undefined → no contributors block.
|
|
1535
|
+
*/
|
|
1536
|
+
contributors?: string[];
|
|
1476
1537
|
/**
|
|
1477
1538
|
* Run without side effects
|
|
1478
1539
|
* @default false
|
|
@@ -1754,5 +1815,5 @@ declare function socialSafetyCheck({ config }: {
|
|
|
1754
1815
|
}): Promise<void>;
|
|
1755
1816
|
declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
|
|
1756
1817
|
|
|
1757
|
-
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
|
|
1818
|
+
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
|
|
1758
1819
|
export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
|
package/dist/index.d.ts
CHANGED
|
@@ -60,6 +60,8 @@ declare function getDefaultConfig(): {
|
|
|
60
60
|
slack: {
|
|
61
61
|
enabled: boolean;
|
|
62
62
|
onlyStable: boolean;
|
|
63
|
+
postMaxLength: number;
|
|
64
|
+
noAuthors: boolean;
|
|
63
65
|
};
|
|
64
66
|
};
|
|
65
67
|
prComment: Required<PrCommentConfig>;
|
|
@@ -233,6 +235,16 @@ declare function buildChangelogBody({ commits, config, minify }: {
|
|
|
233
235
|
config: ResolvedRelizyConfig;
|
|
234
236
|
minify?: boolean;
|
|
235
237
|
}): string;
|
|
238
|
+
/**
|
|
239
|
+
* Collect unique contributor names from a set of commits.
|
|
240
|
+
* Respects `config.noAuthors`, filters `[bot]` authors, and applies `config.excludeAuthors`.
|
|
241
|
+
* Returns plain formatted names (no emails, no GitHub handles) — useful for lightweight
|
|
242
|
+
* rendering contexts like Slack messages.
|
|
243
|
+
*/
|
|
244
|
+
declare function collectContributorNames({ commits, config }: {
|
|
245
|
+
commits: GitCommit[];
|
|
246
|
+
config: ResolvedRelizyConfig;
|
|
247
|
+
}): string[];
|
|
236
248
|
declare function buildContributors({ commits, config }: {
|
|
237
249
|
commits: GitCommit[];
|
|
238
250
|
config: ResolvedRelizyConfig;
|
|
@@ -347,6 +359,13 @@ declare function getSlackToken(options: {
|
|
|
347
359
|
socialCredentials?: SlackCredentials;
|
|
348
360
|
tokenCredential?: string;
|
|
349
361
|
}): string | null;
|
|
362
|
+
/**
|
|
363
|
+
* Get Slack Incoming Webhook URL from config or environment variables.
|
|
364
|
+
* Priority: social.slack.webhookUrl > RELIZY_SLACK_WEBHOOK_URL > SLACK_WEBHOOK_URL.
|
|
365
|
+
*/
|
|
366
|
+
declare function getSlackWebhookUrl(options: {
|
|
367
|
+
socialWebhookUrl?: string;
|
|
368
|
+
}): string | null;
|
|
350
369
|
/**
|
|
351
370
|
* Format changelog for Slack (convert markdown to Slack's mrkdwn format)
|
|
352
371
|
*/
|
|
@@ -354,18 +373,25 @@ declare function formatChangelogForSlack(changelog: string, maxLength?: number):
|
|
|
354
373
|
/**
|
|
355
374
|
* Format the Slack message using blocks
|
|
356
375
|
*/
|
|
357
|
-
declare function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template }: {
|
|
376
|
+
declare function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template, contributors, postMaxLength }: {
|
|
358
377
|
template?: string;
|
|
359
378
|
projectName: string;
|
|
360
379
|
version: string;
|
|
361
380
|
changelog: string;
|
|
362
381
|
releaseUrl?: string;
|
|
363
382
|
changelogUrl?: string;
|
|
383
|
+
contributors?: string[];
|
|
384
|
+
postMaxLength?: number;
|
|
364
385
|
}): any[];
|
|
365
386
|
/**
|
|
366
|
-
* Post a release announcement to Slack
|
|
387
|
+
* Post a release announcement to Slack.
|
|
388
|
+
* Dispatches to Incoming Webhook (if `webhookUrl` is set) or Web API (`token` + `channel`).
|
|
389
|
+
* When both are provided, the webhook takes priority.
|
|
367
390
|
*/
|
|
368
|
-
declare function postReleaseToSlack({ version, projectName, changelog, releaseUrl, changelogUrl, channel, token, template, dryRun, }: SlackOptions): Promise<
|
|
391
|
+
declare function postReleaseToSlack({ version, projectName, changelog, releaseUrl, changelogUrl, channel, token, webhookUrl, template, contributors, postMaxLength, dryRun, }: SlackOptions): Promise<{
|
|
392
|
+
ok: true;
|
|
393
|
+
transport: "webhook";
|
|
394
|
+
} | _slack_web_api.ChatPostMessageResponse | undefined>;
|
|
369
395
|
|
|
370
396
|
/**
|
|
371
397
|
* Extract a summary from changelog content
|
|
@@ -1269,8 +1295,10 @@ interface TwitterSocialConfig {
|
|
|
1269
1295
|
}
|
|
1270
1296
|
interface SlackCredentials {
|
|
1271
1297
|
/**
|
|
1272
|
-
* Slack Bot Token or User OAuth Token
|
|
1273
|
-
* Required scopes: chat:write
|
|
1298
|
+
* Slack Bot Token or User OAuth Token (starts with `xoxb-`).
|
|
1299
|
+
* Required scopes: chat:write (and chat:write.public for public channels without bot invite).
|
|
1300
|
+
* Env fallback: SLACK_TOKEN, RELIZY_SLACK_TOKEN.
|
|
1301
|
+
* Ignored when social.slack.webhookUrl is set (webhook takes priority).
|
|
1274
1302
|
*/
|
|
1275
1303
|
token?: string;
|
|
1276
1304
|
}
|
|
@@ -1287,18 +1315,38 @@ interface SlackSocialConfig {
|
|
|
1287
1315
|
*/
|
|
1288
1316
|
onlyStable?: boolean;
|
|
1289
1317
|
/**
|
|
1290
|
-
* Slack channel ID or name (e.g., "#releases" or "C1234567890")
|
|
1318
|
+
* Slack channel ID or name (e.g., "#releases" or "C1234567890").
|
|
1319
|
+
* Required when using token-based authentication.
|
|
1320
|
+
* Ignored (with warning) when webhookUrl is set — the channel is baked into the webhook URL.
|
|
1291
1321
|
*/
|
|
1292
|
-
channel
|
|
1322
|
+
channel?: string;
|
|
1323
|
+
/**
|
|
1324
|
+
* Slack Incoming Webhook URL. When set, takes priority over token-based auth.
|
|
1325
|
+
* Env fallback: SLACK_WEBHOOK_URL, RELIZY_SLACK_WEBHOOK_URL.
|
|
1326
|
+
* See: https://api.slack.com/messaging/webhooks
|
|
1327
|
+
*/
|
|
1328
|
+
webhookUrl?: string;
|
|
1293
1329
|
/**
|
|
1294
1330
|
* Custom message template
|
|
1295
|
-
* Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}
|
|
1331
|
+
* Available variables: {{projectName}}, {{newVersion}}, {{changelog}}, {{releaseUrl}}, {{changelogUrl}}, {{contributors}}
|
|
1296
1332
|
*/
|
|
1297
1333
|
template?: string;
|
|
1298
1334
|
/**
|
|
1299
1335
|
* Slack credentials (optional - falls back to environment variables)
|
|
1300
1336
|
*/
|
|
1301
1337
|
credentials?: SlackCredentials;
|
|
1338
|
+
/**
|
|
1339
|
+
* Maximum length (in characters) of the changelog rendered inside the Slack message.
|
|
1340
|
+
* Slack's per-section-block limit is 3000; default 2500 leaves margin for emoji/formatting.
|
|
1341
|
+
* @default 2500
|
|
1342
|
+
*/
|
|
1343
|
+
postMaxLength?: number;
|
|
1344
|
+
/**
|
|
1345
|
+
* Hide the contributors block in Slack messages.
|
|
1346
|
+
* If config.noAuthors is true globally, contributors are always hidden regardless of this setting.
|
|
1347
|
+
* @default false
|
|
1348
|
+
*/
|
|
1349
|
+
noAuthors?: boolean;
|
|
1302
1350
|
}
|
|
1303
1351
|
type AIProviderName = 'claude-code';
|
|
1304
1352
|
interface ClaudeCodeProviderOptions {
|
|
@@ -1462,17 +1510,30 @@ interface SlackOptions {
|
|
|
1462
1510
|
*/
|
|
1463
1511
|
changelogUrl?: string;
|
|
1464
1512
|
/**
|
|
1465
|
-
* Slack channel ID or name
|
|
1513
|
+
* Slack channel ID or name. Required when using token-based auth.
|
|
1466
1514
|
*/
|
|
1467
|
-
channel
|
|
1515
|
+
channel?: string;
|
|
1468
1516
|
/**
|
|
1469
|
-
* Slack
|
|
1517
|
+
* Slack Bot Token. Ignored if webhookUrl is set.
|
|
1470
1518
|
*/
|
|
1471
|
-
token
|
|
1519
|
+
token?: string;
|
|
1520
|
+
/**
|
|
1521
|
+
* Slack Incoming Webhook URL. Takes priority over token.
|
|
1522
|
+
*/
|
|
1523
|
+
webhookUrl?: string;
|
|
1472
1524
|
/**
|
|
1473
1525
|
* Custom message template
|
|
1474
1526
|
*/
|
|
1475
1527
|
template?: string;
|
|
1528
|
+
/**
|
|
1529
|
+
* Maximum chars of the changelog rendered in the message.
|
|
1530
|
+
* @default 2500
|
|
1531
|
+
*/
|
|
1532
|
+
postMaxLength?: number;
|
|
1533
|
+
/**
|
|
1534
|
+
* Contributor names (plain strings, no email/handle). Empty array or undefined → no contributors block.
|
|
1535
|
+
*/
|
|
1536
|
+
contributors?: string[];
|
|
1476
1537
|
/**
|
|
1477
1538
|
* Run without side effects
|
|
1478
1539
|
* @default false
|
|
@@ -1754,5 +1815,5 @@ declare function socialSafetyCheck({ config }: {
|
|
|
1754
1815
|
}): Promise<void>;
|
|
1755
1816
|
declare function social(options?: Partial<SocialOptions>): Promise<SocialResult>;
|
|
1756
1817
|
|
|
1757
|
-
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
|
|
1818
|
+
export { NEW_PACKAGE_MARKER, PR_COMMENT_MARKER, buildChangelogBody, buildCommentBody, buildCompareLink, buildContributors, bump, capReleaseTypeForZeroMajor, changelog, checkGitStatusIfDirty, collectContributorNames, confirmBump, createCommitAndTags, createGitlabRelease, defineConfig, detectGitProvider, detectPackageManager, detectPullRequest, determinePublishTag, determineReleaseType, determineSemverChange, executeBuildCmd, executeFormatCmd, executeHook, expandPackagesToBumpWithDependents, extractChangelogSummary, extractVersionFromPackageTag, extractVersionFromTag, fetchGitTags, filterOutPrivatePackages, findGitHubPR, findGitLabMR, formatChangelogForSlack, formatSlackMessage, formatTweetMessage, generateChangelog, generateMarkDown, getAuthCommand, getBumpedIndependentPackages, getBumpedPackageIndependently, getCIName, getCanaryVersion, getCurrentGitBranch, getCurrentGitRef, getDefaultConfig, getDependentsOf, getFirstCommit, getGitStatus, getIndependentTag, getLastPackageTag, getLastRepoTag, getLastStableTag, getLastTag, getModifiedReleaseFilePatterns, getPackageCommits, getPackageDependencies, getPackageNewVersion, getPackages, getPackagesOrBumpedPackages, getPackagesToPublishInIndependentMode, getPackagesToPublishInSelectiveMode, getPreid, getReleaseUrl, getRootPackage, getShortCommitSha, getSlackToken, getSlackWebhookUrl, getTwitterCredentials, github, gitlab, hasLernaJson, isBumpedPackage, isChangedPreid, isGraduating, isGraduatingToStableBetweenVersion, isInCI, isPrerelease, isPrereleaseReleaseType, isStableReleaseType, isTagVersionCompatibleWithCurrent, loadRelizyConfig, mergeTypes, parseChangelogMarkdown, parseGitRemoteUrl, postPrComment, postReleaseToSlack, postReleaseToTwitter, prComment, providerRelease, providerReleaseSafetyCheck, publish, publishPackage, publishSafetyCheck, pushCommitAndTags, readPackageJson, readPackages, release, resolveTags, rollbackModifiedFiles, shouldFilterPrereleaseTags, social, socialSafetyCheck, topologicalSort, updateLernaVersion, writeChangelogToFile, writeVersion };
|
|
1758
1819
|
export type { AIConfig, AIPromptTarget, AIProviderName, AISocialConfig, AISystemPromptOverrides, AITargetConfig, BumpConfig, BumpOptions, BumpResult, BumpResultFalsy, BumpResultTruthy, ChangelogConfig, ChangelogOptions, ClaudeCodeProviderOptions, ConfigType, GitProvider, GitlabRelease, GitlabReleaseResponse, HookConfig, HookStep, HookType, MonorepoConfig, PackageBase, PackageManager, PostedRelease, PrCommentConfig, PrCommentMode, PrCommentOptions, PrCommentStatus, ProviderReleaseOptions, ProviderReleaseResult, PublishConfig, PublishOptions, PublishResponse, PullRequestInfo, ReadPackage, Reference, ReleaseConfig, ReleaseContext, ReleaseOptions, RelizyConfig, RepoConfig, ResolvedConfig, ResolvedRelizyConfig, ResolvedTags, ResolvedTwitterCredentials, RootPackage, SlackCredentials, SlackOptions, SlackSocialConfig, SocialConfig, SocialNetworkResult, SocialOptions, SocialResult, Step, TemplatesConfig, TokensConfig, TwitterCredentials, TwitterOptions, TwitterSocialConfig, VersionMode };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { ai as NEW_PACKAGE_MARKER, _ as PR_COMMENT_MARKER, M as buildChangelogBody, a as buildCommentBody, L as buildCompareLink, O as buildContributors, b as bump, aw as capReleaseTypeForZeroMajor, c as changelog, v as checkGitStatusIfDirty, N as collectContributorNames, aK as confirmBump, B as createCommitAndTags, J as createGitlabRelease, k as defineConfig, y as detectGitProvider, R as detectPackageManager, Z as detectPullRequest, S as determinePublishTag, ay as determineReleaseType, ax as determineSemverChange, ar as executeBuildCmd, aq as executeFormatCmd, an as executeHook, q as expandPackagesToBumpWithDependents, ab as extractChangelogSummary, aC as extractVersionFromPackageTag, aN as extractVersionFromTag, x as fetchGitTags, at as filterOutPrivatePackages, X as findGitHubPR, Y as findGitLabMR, a8 as formatChangelogForSlack, a9 as formatSlackMessage, al as formatTweetMessage, i as generateChangelog, P as generateMarkDown, V as getAuthCommand, aL as getBumpedIndependentPackages, aJ as getBumpedPackageIndependently, ap as getCIName, aO as getCanaryVersion, F as getCurrentGitBranch, G as getCurrentGitRef, j as getDefaultConfig, o as getDependentsOf, E as getFirstCommit, u as getGitStatus, ad as getIndependentTag, ah as getLastPackageTag, ag as getLastRepoTag, ae as getLastStableTag, af as getLastTag, A as getModifiedReleaseFilePatterns, a4 as getPackageCommits, n as getPackageDependencies, aA as getPackageNewVersion, a3 as getPackages, au as getPackagesOrBumpedPackages, U as getPackagesToPublishInIndependentMode, T as getPackagesToPublishInSelectiveMode, aH as getPreid, ac as getReleaseUrl, a1 as getRootPackage, H as getShortCommitSha, a6 as getSlackToken, a7 as getSlackWebhookUrl, ak as getTwitterCredentials, I as github, K as gitlab, a5 as hasLernaJson, as as isBumpedPackage, aI as isChangedPreid, aG as isGraduating, av as isGraduatingToStableBetweenVersion, ao as isInCI, aD as isPrerelease, aF as isPrereleaseReleaseType, aE as isStableReleaseType, aP as isTagVersionCompatibleWithCurrent, l as loadRelizyConfig, m as mergeTypes, Q as parseChangelogMarkdown, z as parseGitRemoteUrl, $ as postPrComment, aa as postReleaseToSlack, am as postReleaseToTwitter, p as prComment, e as providerRelease, d as providerReleaseSafetyCheck, g as publish, W as publishPackage, f as publishSafetyCheck, C as pushCommitAndTags, a0 as readPackageJson, a2 as readPackages, r as release, aj as resolveTags, D as rollbackModifiedFiles, aM as shouldFilterPrereleaseTags, h as social, s as socialSafetyCheck, t as topologicalSort, aB as updateLernaVersion, w as writeChangelogToFile, az as writeVersion } from './shared/relizy.CxbwJj6k.mjs';
|
|
2
2
|
import '@maz-ui/node';
|
|
3
3
|
import 'node:child_process';
|
|
4
4
|
import 'node:process';
|
|
@@ -1914,7 +1914,9 @@ function getDefaultConfig() {
|
|
|
1914
1914
|
},
|
|
1915
1915
|
slack: {
|
|
1916
1916
|
enabled: false,
|
|
1917
|
-
onlyStable: true
|
|
1917
|
+
onlyStable: true,
|
|
1918
|
+
postMaxLength: 2500,
|
|
1919
|
+
noAuthors: false
|
|
1918
1920
|
}
|
|
1919
1921
|
},
|
|
1920
1922
|
prComment: {
|
|
@@ -2382,11 +2384,11 @@ function buildChangelogBody({ commits, config, minify }) {
|
|
|
2382
2384
|
}
|
|
2383
2385
|
return convert(markdown.join("\n").trim(), true);
|
|
2384
2386
|
}
|
|
2385
|
-
|
|
2387
|
+
function collectContributorNames({ commits, config }) {
|
|
2386
2388
|
if (config.noAuthors) {
|
|
2387
|
-
return
|
|
2389
|
+
return [];
|
|
2388
2390
|
}
|
|
2389
|
-
const
|
|
2391
|
+
const names = /* @__PURE__ */ new Set();
|
|
2390
2392
|
for (const commit of commits) {
|
|
2391
2393
|
if (!commit.author) {
|
|
2392
2394
|
continue;
|
|
@@ -2400,11 +2402,26 @@ async function buildContributors({ commits, config }) {
|
|
|
2400
2402
|
)) {
|
|
2401
2403
|
continue;
|
|
2402
2404
|
}
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2405
|
+
names.add(name);
|
|
2406
|
+
}
|
|
2407
|
+
return Array.from(names);
|
|
2408
|
+
}
|
|
2409
|
+
async function buildContributors({ commits, config }) {
|
|
2410
|
+
const names = collectContributorNames({ commits, config });
|
|
2411
|
+
if (names.length === 0) {
|
|
2412
|
+
return "";
|
|
2413
|
+
}
|
|
2414
|
+
const _authors = /* @__PURE__ */ new Map();
|
|
2415
|
+
for (const name of names) {
|
|
2416
|
+
_authors.set(name, { email: /* @__PURE__ */ new Set(), name });
|
|
2417
|
+
}
|
|
2418
|
+
for (const commit of commits) {
|
|
2419
|
+
if (!commit.author)
|
|
2420
|
+
continue;
|
|
2421
|
+
const name = formatName(commit.author.name);
|
|
2422
|
+
const entry = _authors.get(name);
|
|
2423
|
+
if (entry && commit.author.email) {
|
|
2424
|
+
entry.email.add(commit.author.email);
|
|
2408
2425
|
}
|
|
2409
2426
|
}
|
|
2410
2427
|
if (config.repo?.provider === "github") {
|
|
@@ -2638,24 +2655,25 @@ The user message contains a markdown changelog built from conventional commits,
|
|
|
2638
2655
|
Never ask for clarification. Never reply with questions, greetings, or meta-commentary. Your only output is the rewritten changelog content.
|
|
2639
2656
|
Never invent changes that are not in the input \u2014 if something is not mentioned, it does not exist.
|
|
2640
2657
|
Never include compare links, contributor lists, or release metadata \u2014 only the content provided.
|
|
2641
|
-
Preserve exactly as given: PR and issue references like #123, commit hashes, commit scopes like **auth:**, and all markdown links.
|
|
2642
2658
|
Respond with the rewritten content only \u2014 no preamble, no explanation, no surrounding code fence, no <changelog> tag.
|
|
2643
2659
|
Output language: {{language}}.`;
|
|
2644
2660
|
const PROVIDER_RELEASE_PROMPT = `Format the output as markdown with "### <Type>" sections matching the input (Features, Bug Fixes, etc.).
|
|
2645
2661
|
Merge redundant items that describe the same change.
|
|
2646
|
-
Rewrite each bullet for end-user clarity \u2014
|
|
2647
|
-
Preserve
|
|
2662
|
+
Rewrite each bullet for end-user clarity \u2014 focus on what changed for the user, not internal details.
|
|
2663
|
+
Preserve exactly as given: PR and issue references like #123, commit hashes, commit scopes like **auth:**, and all markdown links.
|
|
2664
|
+
Preserve the \u26A0\uFE0F marker on breaking items and the "#### \u26A0\uFE0F Breaking Changes" section if present.
|
|
2648
2665
|
Purely internal commits (chore, refactor with no user-visible impact) may be dropped unless they carry meaningful information.
|
|
2649
2666
|
Tone: professional, concise, public-facing release notes.`;
|
|
2650
2667
|
const TWITTER_PROMPT = `Output plain text \u2014 no markdown. A leading "#" becomes a hashtag on Twitter, so avoid it.
|
|
2651
|
-
Hard maximum: {{maxLength}} characters
|
|
2668
|
+
Hard maximum: {{maxLength}} characters \u2014 never exceed it.
|
|
2669
|
+
Remove commit hashes (e.g. "aabf96b") and PR/issue references (e.g. "#123") \u2014 they are meaningless on Twitter.
|
|
2652
2670
|
If the input has one change, write one substantive sentence about it (ground it in the input, never invent).
|
|
2653
2671
|
If the input has multiple changes, surface 2 to 4 highlights.
|
|
2654
2672
|
You produce ONLY the changelog content \u2014 the outer template will add the project name, version, and URLs around it.
|
|
2655
2673
|
Tone: enthusiastic but not cringy. At most 1-2 emojis total.
|
|
2656
2674
|
Do not add hashtags unless the user explicitly supplies them.`;
|
|
2657
2675
|
const SLACK_PROMPT = `Format with Slack-compatible markdown: *bold*, _italic_, \`code\`, and "-" bullet lists.
|
|
2658
|
-
Keep it
|
|
2676
|
+
Keep it concise \u2014 3 to 8 bullets maximum.
|
|
2659
2677
|
If any breaking changes are present, lead with them.
|
|
2660
2678
|
Tone: factual, oriented toward an internal team audience.`;
|
|
2661
2679
|
|
|
@@ -3716,7 +3734,10 @@ function getSlackToken(options) {
|
|
|
3716
3734
|
}
|
|
3717
3735
|
return token;
|
|
3718
3736
|
}
|
|
3719
|
-
function
|
|
3737
|
+
function getSlackWebhookUrl(options) {
|
|
3738
|
+
return options.socialWebhookUrl || process.env.RELIZY_SLACK_WEBHOOK_URL || process.env.SLACK_WEBHOOK_URL || null;
|
|
3739
|
+
}
|
|
3740
|
+
function formatChangelogForSlack(changelog, maxLength = 2500) {
|
|
3720
3741
|
let formatted = changelog.replace(/^### (.+)$/gm, "*$1*").replace(/^## (.+)$/gm, "*$1*").replace(/^# (.+)$/gm, "*$1*").replace(/\*\*(.+?)\*\*/g, "*$1*");
|
|
3721
3742
|
const linkPattern = /\[([^\]]*)]\(([^)]*)\)/g;
|
|
3722
3743
|
formatted = formatted.replace(linkPattern, (_, text, url) => `<${url}|${text}>`);
|
|
@@ -3725,10 +3746,11 @@ function formatChangelogForSlack(changelog, maxLength = 500) {
|
|
|
3725
3746
|
}
|
|
3726
3747
|
return formatted;
|
|
3727
3748
|
}
|
|
3728
|
-
function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template }) {
|
|
3749
|
+
function formatSlackMessage({ projectName, version, changelog, releaseUrl, changelogUrl, template, contributors = [], postMaxLength = 2500 }) {
|
|
3750
|
+
const contributorsLine = contributors.length > 0 ? contributors.map((n) => `\u2022 ${n}`).join("\n") : "";
|
|
3729
3751
|
if (template) {
|
|
3730
|
-
const summary = extractChangelogSummary(changelog, { maxLength:
|
|
3731
|
-
let message = template.replace("{{projectName}}", projectName).replace("{{newVersion}}", version).replace("{{changelog}}", summary);
|
|
3752
|
+
const summary = extractChangelogSummary(changelog, { maxLength: postMaxLength });
|
|
3753
|
+
let message = template.replace("{{projectName}}", projectName).replace("{{newVersion}}", version).replace("{{changelog}}", summary).replace("{{contributors}}", contributorsLine);
|
|
3732
3754
|
if (releaseUrl) {
|
|
3733
3755
|
message = message.replace("{{releaseUrl}}", releaseUrl);
|
|
3734
3756
|
} else {
|
|
@@ -3759,7 +3781,7 @@ function formatSlackMessage({ projectName, version, changelog, releaseUrl, chang
|
|
|
3759
3781
|
}
|
|
3760
3782
|
}
|
|
3761
3783
|
];
|
|
3762
|
-
const formattedChangelog = formatChangelogForSlack(changelog,
|
|
3784
|
+
const formattedChangelog = formatChangelogForSlack(changelog, postMaxLength);
|
|
3763
3785
|
if (formattedChangelog) {
|
|
3764
3786
|
blocks.push({
|
|
3765
3787
|
type: "section",
|
|
@@ -3769,6 +3791,17 @@ function formatSlackMessage({ projectName, version, changelog, releaseUrl, chang
|
|
|
3769
3791
|
}
|
|
3770
3792
|
});
|
|
3771
3793
|
}
|
|
3794
|
+
if (contributors.length > 0) {
|
|
3795
|
+
blocks.push({
|
|
3796
|
+
type: "section",
|
|
3797
|
+
text: {
|
|
3798
|
+
type: "mrkdwn",
|
|
3799
|
+
text: `*\u2764\uFE0F Contributors*
|
|
3800
|
+
|
|
3801
|
+
${contributorsLine}`
|
|
3802
|
+
}
|
|
3803
|
+
});
|
|
3804
|
+
}
|
|
3772
3805
|
blocks.push({
|
|
3773
3806
|
type: "divider"
|
|
3774
3807
|
});
|
|
@@ -3805,44 +3838,44 @@ function formatSlackMessage({ projectName, version, changelog, releaseUrl, chang
|
|
|
3805
3838
|
}
|
|
3806
3839
|
return blocks;
|
|
3807
3840
|
}
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3841
|
+
function mapWebhookError(status, body) {
|
|
3842
|
+
if (status === 404 || body.includes("no_service")) {
|
|
3843
|
+
return "The webhook URL is invalid or has been deactivated. Regenerate it in your Slack app settings.";
|
|
3844
|
+
}
|
|
3845
|
+
if (body.includes("invalid_payload")) {
|
|
3846
|
+
return "The message payload was rejected by Slack (likely exceeds 3000 chars per block). Lower social.slack.postMaxLength.";
|
|
3847
|
+
}
|
|
3848
|
+
if (body.includes("channel_not_found")) {
|
|
3849
|
+
return "The channel bound to this webhook was archived or removed. Create a new webhook.";
|
|
3850
|
+
}
|
|
3851
|
+
if (body.includes("action_prohibited")) {
|
|
3852
|
+
return "Your workspace has blocked the webhook. Check workspace settings.";
|
|
3853
|
+
}
|
|
3854
|
+
return null;
|
|
3855
|
+
}
|
|
3856
|
+
async function postViaWebhook({ url, blocks, text }) {
|
|
3857
|
+
const response = await fetch(url, {
|
|
3858
|
+
method: "POST",
|
|
3859
|
+
headers: { "Content-Type": "application/json" },
|
|
3860
|
+
body: JSON.stringify({ blocks, text })
|
|
3827
3861
|
});
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
const
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
${
|
|
3834
|
-
|
|
3862
|
+
if (!response.ok) {
|
|
3863
|
+
const body = await response.text().catch(() => "");
|
|
3864
|
+
const hint = mapWebhookError(response.status, body);
|
|
3865
|
+
const detail = body ? ` - ${body}` : "";
|
|
3866
|
+
const hintLine = hint ? `
|
|
3867
|
+
\u2192 ${hint}` : "";
|
|
3868
|
+
throw new Error(`Slack webhook failed: ${response.status} ${response.statusText}${detail}${hintLine}`);
|
|
3835
3869
|
}
|
|
3870
|
+
logger.success("Message posted successfully via Slack webhook!");
|
|
3871
|
+
return { ok: true, transport: "webhook" };
|
|
3872
|
+
}
|
|
3873
|
+
async function postViaWebApi({ token, channel, blocks, text }) {
|
|
3836
3874
|
try {
|
|
3837
3875
|
const { WebClient } = await import('@slack/web-api');
|
|
3838
3876
|
const client = new WebClient(token);
|
|
3839
3877
|
logger.debug(`Posting message to Slack channel: ${channel}`);
|
|
3840
|
-
const result = await client.chat.postMessage({
|
|
3841
|
-
channel,
|
|
3842
|
-
blocks,
|
|
3843
|
-
text: `${projectName} ${version} is out!`
|
|
3844
|
-
// Fallback text for notifications
|
|
3845
|
-
});
|
|
3878
|
+
const result = await client.chat.postMessage({ channel, blocks, text });
|
|
3846
3879
|
logger.success(`Message posted successfully! Channel: ${result.channel}, Timestamp: ${result.ts}`);
|
|
3847
3880
|
return result;
|
|
3848
3881
|
} catch (error) {
|
|
@@ -3869,6 +3902,54 @@ ${preview}`);
|
|
|
3869
3902
|
throw error;
|
|
3870
3903
|
}
|
|
3871
3904
|
}
|
|
3905
|
+
async function postReleaseToSlack({
|
|
3906
|
+
version,
|
|
3907
|
+
projectName,
|
|
3908
|
+
changelog,
|
|
3909
|
+
releaseUrl,
|
|
3910
|
+
changelogUrl,
|
|
3911
|
+
channel,
|
|
3912
|
+
token,
|
|
3913
|
+
webhookUrl,
|
|
3914
|
+
template,
|
|
3915
|
+
contributors,
|
|
3916
|
+
postMaxLength,
|
|
3917
|
+
dryRun = false
|
|
3918
|
+
}) {
|
|
3919
|
+
const useWebhook = Boolean(webhookUrl);
|
|
3920
|
+
if (!useWebhook && !token) {
|
|
3921
|
+
throw new Error("Slack: either webhookUrl or token must be provided");
|
|
3922
|
+
}
|
|
3923
|
+
if (!useWebhook && !channel) {
|
|
3924
|
+
throw new Error("Slack: channel is required when using token-based authentication");
|
|
3925
|
+
}
|
|
3926
|
+
logger.debug(`Slack transport: ${useWebhook ? "webhook" : "web-api"}`);
|
|
3927
|
+
logger.debug("Preparing Slack post...");
|
|
3928
|
+
const blocks = formatSlackMessage({
|
|
3929
|
+
template,
|
|
3930
|
+
projectName,
|
|
3931
|
+
version,
|
|
3932
|
+
changelog,
|
|
3933
|
+
releaseUrl,
|
|
3934
|
+
changelogUrl,
|
|
3935
|
+
contributors,
|
|
3936
|
+
postMaxLength
|
|
3937
|
+
});
|
|
3938
|
+
const fallbackText = `${projectName} ${version} is out!`;
|
|
3939
|
+
logger.debug(`Message blocks (${blocks.length} blocks)`);
|
|
3940
|
+
if (dryRun) {
|
|
3941
|
+
const preview = blocks.filter((b) => b.type === "header" || b.type === "section").map((b) => b.text?.text ?? "").filter(Boolean).join("\n\n");
|
|
3942
|
+
const target = useWebhook ? "webhook" : `channel: ${channel}`;
|
|
3943
|
+
logger.box(`[dry-run] Slack Post Preview (${target})
|
|
3944
|
+
|
|
3945
|
+
${preview}`);
|
|
3946
|
+
return;
|
|
3947
|
+
}
|
|
3948
|
+
if (useWebhook) {
|
|
3949
|
+
return await postViaWebhook({ url: webhookUrl, blocks, text: fallbackText });
|
|
3950
|
+
}
|
|
3951
|
+
return await postViaWebApi({ token, channel, blocks, text: fallbackText });
|
|
3952
|
+
}
|
|
3872
3953
|
|
|
3873
3954
|
function getTwitterCredentials({ socialCredentials, tokenCredentials }) {
|
|
3874
3955
|
const apiKey = socialCredentials?.apiKey || tokenCredentials?.apiKey;
|
|
@@ -5179,27 +5260,37 @@ async function socialSafetyCheck({ config }) {
|
|
|
5179
5260
|
}
|
|
5180
5261
|
const slackConfig = config.social?.slack;
|
|
5181
5262
|
if (slackConfig?.enabled) {
|
|
5263
|
+
const webhookUrl = getSlackWebhookUrl({ socialWebhookUrl: slackConfig.webhookUrl });
|
|
5182
5264
|
const token = getSlackToken({
|
|
5183
5265
|
socialCredentials: slackConfig.credentials,
|
|
5184
5266
|
tokenCredential: config.tokens?.slack
|
|
5185
5267
|
});
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5268
|
+
if (webhookUrl) {
|
|
5269
|
+
if (slackConfig.channel) {
|
|
5270
|
+
logger.warn("social.slack.channel is ignored when webhookUrl is set (channel is baked into the webhook URL).");
|
|
5271
|
+
}
|
|
5272
|
+
if (token) {
|
|
5273
|
+
logger.warn("Slack token is ignored when webhookUrl is set (webhook takes priority).");
|
|
5274
|
+
}
|
|
5275
|
+
} else if (token) {
|
|
5276
|
+
try {
|
|
5277
|
+
await import('@slack/web-api');
|
|
5278
|
+
} catch {
|
|
5279
|
+
logger.fail("@slack/web-api is not installed, please install it");
|
|
5280
|
+
throw new Error("@slack/web-api is not installed");
|
|
5281
|
+
}
|
|
5282
|
+
if (!slackConfig.channel) {
|
|
5283
|
+
logger.fail("Slack is enabled but no channel is configured.");
|
|
5284
|
+
logger.log('Set the channel in social.slack.channel (e.g., "#releases" or "C1234567890") or switch to webhookUrl for a simpler setup.');
|
|
5285
|
+
throw new Error("Slack channel not found");
|
|
5286
|
+
}
|
|
5287
|
+
} else {
|
|
5288
|
+
logger.fail("Slack is enabled but no credentials are configured.");
|
|
5289
|
+
logger.log("Provide ONE of the following:");
|
|
5290
|
+
logger.log(" (a) social.slack.webhookUrl (or SLACK_WEBHOOK_URL / RELIZY_SLACK_WEBHOOK_URL env var) \u2014 simpler setup, channel baked in");
|
|
5291
|
+
logger.log(" (b) social.slack.credentials.token (or SLACK_TOKEN / RELIZY_SLACK_TOKEN env var) + social.slack.channel \u2014 requires bot invite");
|
|
5196
5292
|
throw new Error("Slack credentials not found");
|
|
5197
5293
|
}
|
|
5198
|
-
if (!slackConfig.channel) {
|
|
5199
|
-
logger.fail("Slack is enabled but no channel is configured.");
|
|
5200
|
-
logger.log('Set the channel in social.slack.channel (e.g., "#releases" or "C1234567890")');
|
|
5201
|
-
throw new Error("Slack channel not found");
|
|
5202
|
-
}
|
|
5203
5294
|
}
|
|
5204
5295
|
if (isAISocialEnabled(config, "twitter") || isAISocialEnabled(config, "slack")) {
|
|
5205
5296
|
await aiSafetyCheck({ config });
|
|
@@ -5280,7 +5371,8 @@ async function handleSlackPost({
|
|
|
5280
5371
|
changelog,
|
|
5281
5372
|
dryRun,
|
|
5282
5373
|
newVersion,
|
|
5283
|
-
tag
|
|
5374
|
+
tag,
|
|
5375
|
+
commits
|
|
5284
5376
|
}) {
|
|
5285
5377
|
const slackConfig = config.social?.slack;
|
|
5286
5378
|
if (!slackConfig?.enabled) {
|
|
@@ -5289,22 +5381,23 @@ async function handleSlackPost({
|
|
|
5289
5381
|
}
|
|
5290
5382
|
logger.debug("Slack posting is enabled");
|
|
5291
5383
|
try {
|
|
5384
|
+
const webhookUrl = getSlackWebhookUrl({ socialWebhookUrl: slackConfig.webhookUrl });
|
|
5292
5385
|
const token = getSlackToken({
|
|
5293
5386
|
socialCredentials: slackConfig.credentials,
|
|
5294
5387
|
tokenCredential: config.tokens?.slack
|
|
5295
5388
|
});
|
|
5296
|
-
if (!token) {
|
|
5297
|
-
logger.warn("Slack token
|
|
5389
|
+
if (!webhookUrl && !token) {
|
|
5390
|
+
logger.warn("Neither Slack webhookUrl nor token is configured. Set SLACK_WEBHOOK_URL / SLACK_TOKEN or configure social.slack.webhookUrl / credentials.token.");
|
|
5298
5391
|
logger.info("Skipping Slack post");
|
|
5299
|
-
return { success: false, error: "Slack
|
|
5392
|
+
return { success: false, error: "Slack credentials not found" };
|
|
5300
5393
|
}
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
logger.warn("Slack channel not configured. Set it in social.slack.channel.");
|
|
5394
|
+
if (!webhookUrl && !slackConfig.channel) {
|
|
5395
|
+
logger.warn("Slack channel not configured (required in token mode). Set it in social.slack.channel.");
|
|
5304
5396
|
logger.info("Skipping Slack post");
|
|
5305
5397
|
return { success: false, error: "Slack channel not configured" };
|
|
5306
5398
|
}
|
|
5307
|
-
|
|
5399
|
+
const slackMode = webhookUrl ? "webhook mode" : `token mode, channel: ${slackConfig.channel}`;
|
|
5400
|
+
logger.debug(`Slack: ${slackMode}`);
|
|
5308
5401
|
logger.debug(`Preparing Slack message for release: ${tag} (${newVersion})`);
|
|
5309
5402
|
const onlyStable = slackConfig.onlyStable ?? true;
|
|
5310
5403
|
if (onlyStable && isPrerelease(newVersion)) {
|
|
@@ -5324,6 +5417,9 @@ async function handleSlackPost({
|
|
|
5324
5417
|
logger.debug(`Changelog URL: ${changelogUrl || "none"}`);
|
|
5325
5418
|
logger.debug(`Changelog generated (${changelog.length} chars)`);
|
|
5326
5419
|
const template = slackConfig.template || config.templates.slackMessage;
|
|
5420
|
+
const shouldHideContributors = config.noAuthors === true || slackConfig.noAuthors === true;
|
|
5421
|
+
const contributors = shouldHideContributors ? [] : collectContributorNames({ commits, config });
|
|
5422
|
+
logger.debug(`Contributors: ${contributors.length}`);
|
|
5327
5423
|
const response = await postReleaseToSlack({
|
|
5328
5424
|
version: newVersion,
|
|
5329
5425
|
projectName: config.projectName || rootPackageBase.name,
|
|
@@ -5331,8 +5427,11 @@ async function handleSlackPost({
|
|
|
5331
5427
|
releaseUrl,
|
|
5332
5428
|
changelogUrl,
|
|
5333
5429
|
channel: slackConfig.channel,
|
|
5334
|
-
token,
|
|
5430
|
+
token: token ?? void 0,
|
|
5431
|
+
webhookUrl: webhookUrl ?? void 0,
|
|
5335
5432
|
template,
|
|
5433
|
+
contributors,
|
|
5434
|
+
postMaxLength: slackConfig.postMaxLength ?? 2500,
|
|
5336
5435
|
dryRun
|
|
5337
5436
|
});
|
|
5338
5437
|
await executeHook("success:slack", config, dryRun);
|
|
@@ -5447,7 +5546,8 @@ ${twitterChangelog}`);
|
|
|
5447
5546
|
changelog: slackChangelog,
|
|
5448
5547
|
dryRun,
|
|
5449
5548
|
newVersion,
|
|
5450
|
-
tag: to
|
|
5549
|
+
tag: to,
|
|
5550
|
+
commits: rootPackage.commits
|
|
5451
5551
|
});
|
|
5452
5552
|
const results = [];
|
|
5453
5553
|
if (config.social?.twitter?.enabled) {
|
|
@@ -5817,4 +5917,4 @@ Git provider: ${provider}`);
|
|
|
5817
5917
|
}
|
|
5818
5918
|
}
|
|
5819
5919
|
|
|
5820
|
-
export {
|
|
5920
|
+
export { postPrComment as $, getModifiedReleaseFilePatterns as A, createCommitAndTags as B, pushCommitAndTags as C, rollbackModifiedFiles as D, getFirstCommit as E, getCurrentGitBranch as F, getCurrentGitRef as G, getShortCommitSha as H, github as I, createGitlabRelease as J, gitlab as K, buildCompareLink as L, buildChangelogBody as M, collectContributorNames as N, buildContributors as O, generateMarkDown as P, parseChangelogMarkdown as Q, detectPackageManager as R, determinePublishTag as S, getPackagesToPublishInSelectiveMode as T, getPackagesToPublishInIndependentMode as U, getAuthCommand as V, publishPackage as W, findGitHubPR as X, findGitLabMR as Y, detectPullRequest as Z, PR_COMMENT_MARKER as _, buildCommentBody as a, readPackageJson as a0, getRootPackage as a1, readPackages as a2, getPackages as a3, getPackageCommits as a4, hasLernaJson as a5, getSlackToken as a6, getSlackWebhookUrl as a7, formatChangelogForSlack as a8, formatSlackMessage as a9, getPackageNewVersion as aA, updateLernaVersion as aB, extractVersionFromPackageTag as aC, isPrerelease as aD, isStableReleaseType as aE, isPrereleaseReleaseType as aF, isGraduating as aG, getPreid as aH, isChangedPreid as aI, getBumpedPackageIndependently as aJ, confirmBump as aK, getBumpedIndependentPackages as aL, shouldFilterPrereleaseTags as aM, extractVersionFromTag as aN, getCanaryVersion as aO, isTagVersionCompatibleWithCurrent as aP, postReleaseToSlack as aa, extractChangelogSummary as ab, getReleaseUrl as ac, getIndependentTag as ad, getLastStableTag as ae, getLastTag as af, getLastRepoTag as ag, getLastPackageTag as ah, NEW_PACKAGE_MARKER as ai, resolveTags as aj, getTwitterCredentials as ak, formatTweetMessage as al, postReleaseToTwitter as am, executeHook as an, isInCI as ao, getCIName as ap, executeFormatCmd as aq, executeBuildCmd as ar, isBumpedPackage as as, filterOutPrivatePackages as at, getPackagesOrBumpedPackages as au, isGraduatingToStableBetweenVersion as av, capReleaseTypeForZeroMajor as aw, determineSemverChange as ax, determineReleaseType as ay, writeVersion as az, bump as b, changelog as c, providerReleaseSafetyCheck as d, providerRelease as e, publishSafetyCheck as f, publish as g, social as h, generateChangelog as i, getDefaultConfig as j, defineConfig as k, loadRelizyConfig as l, mergeTypes as m, getPackageDependencies as n, getDependentsOf as o, prComment as p, expandPackagesToBumpWithDependents as q, release as r, socialSafetyCheck as s, topologicalSort as t, getGitStatus as u, checkGitStatusIfDirty as v, writeChangelogToFile as w, fetchGitTags as x, detectGitProvider as y, parseGitRemoteUrl as z };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "relizy",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0-beta.0",
|
|
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",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
|
-
"@inquirer/prompts": "^8.4.
|
|
74
|
+
"@inquirer/prompts": "^8.4.2",
|
|
75
75
|
"@maz-ui/node": "4.6.1",
|
|
76
76
|
"@maz-ui/utils": "^4.7.6",
|
|
77
77
|
"c12": "^3.3.3",
|
|
@@ -88,23 +88,23 @@
|
|
|
88
88
|
"@commitlint/config-conventional": "20.5.0",
|
|
89
89
|
"@commitlint/cz-commitlint": "^20.5.1",
|
|
90
90
|
"@commitlint/types": "^20.5.0",
|
|
91
|
-
"@maz-ui/eslint-config": "^4.
|
|
92
|
-
"@slack/web-api": "7.15.
|
|
91
|
+
"@maz-ui/eslint-config": "^4.9.1",
|
|
92
|
+
"@slack/web-api": "7.15.1",
|
|
93
93
|
"@types/node": "^25.6.0",
|
|
94
94
|
"@types/semver": "^7.7.1",
|
|
95
|
-
"@vitest/coverage-v8": "^4.1.
|
|
95
|
+
"@vitest/coverage-v8": "^4.1.5",
|
|
96
96
|
"@yoloship/claude-sdk": "0.1.0-beta.3",
|
|
97
97
|
"cross-env": "10.1.0",
|
|
98
|
-
"eslint": "^10.2.
|
|
98
|
+
"eslint": "^10.2.1",
|
|
99
99
|
"husky": "9.1.7",
|
|
100
100
|
"jiti": "2.6.1",
|
|
101
101
|
"lint-staged": "^16.4.0",
|
|
102
|
-
"memfs": "^4.57.
|
|
102
|
+
"memfs": "^4.57.2",
|
|
103
103
|
"tsx": "^4.21.0",
|
|
104
104
|
"twitter-api-v2": "^1.29.0",
|
|
105
105
|
"typescript": "^5.9.3",
|
|
106
106
|
"unbuild": "^3.6.1",
|
|
107
|
-
"vitest": "^4.1.
|
|
107
|
+
"vitest": "^4.1.5"
|
|
108
108
|
},
|
|
109
109
|
"lint-staged": {
|
|
110
110
|
"*.{js,jsx,ts,tsx,mjs,mts,cjs,md,yml,json}": [
|