@coze-arch/rush-publish-plugin 0.0.5-alpha.0f1107 → 0.0.5-alpha.5049d2

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/command-line.json CHANGED
@@ -106,6 +106,22 @@
106
106
  "associatedCommands": ["pub"],
107
107
  "required": false
108
108
  },
109
+ {
110
+ "parameterKind": "string",
111
+ "longName": "--branch-prefix",
112
+ "description": "Git branch name prefix (default: 'release')",
113
+ "argumentName": "BRANCH_PREFIX",
114
+ "associatedCommands": ["pub"],
115
+ "required": false
116
+ },
117
+ {
118
+ "parameterKind": "flag",
119
+ "longName": "--release",
120
+ "shortName": "-l",
121
+ "description": "Directly publish packages (only for alpha/beta versions)",
122
+ "associatedCommands": ["pub"],
123
+ "required": false
124
+ },
109
125
  {
110
126
  "parameterKind": "flag",
111
127
  "longName": "--amend-commit",
@@ -141,8 +157,8 @@
141
157
  "argumentName": "REGISTRY",
142
158
  "longName": "--registry",
143
159
  "shortName": "-r",
144
- "description": "Registry",
145
- "associatedCommands": ["release"]
160
+ "description": "NPM registry URL (default: https://registry.npmjs.org)",
161
+ "associatedCommands": ["release", "pub"]
146
162
  }
147
163
  ]
148
164
  }
@@ -1,2 +1,6 @@
1
1
  import { type PublishManifest } from './types';
2
- export declare const confirmForPublish: (publishManifest: PublishManifest[], dryRun: boolean) => Promise<boolean>;
2
+ export interface ConfirmForPublishOptions {
3
+ isReleaseMode?: boolean;
4
+ registry?: string;
5
+ }
6
+ export declare const confirmForPublish: (publishManifest: PublishManifest[], dryRun: boolean, options?: ConfirmForPublishOptions) => Promise<boolean>;
@@ -8,6 +8,7 @@ interface PushToRemoteOptions {
8
8
  skipCommit: boolean;
9
9
  skipPush: boolean;
10
10
  repoUrl: string;
11
+ branchPrefix?: string;
11
12
  }
12
13
  export declare const pushToRemote: (options: PushToRemoteOptions) => Promise<void>;
13
14
  export {};
@@ -16,6 +16,9 @@ export interface PublishOptions {
16
16
  skipCommit?: boolean;
17
17
  skipPush?: boolean;
18
18
  repoUrl: string;
19
+ branchPrefix?: string;
20
+ release?: boolean;
21
+ registry?: string;
19
22
  }
20
23
  export interface PublishManifest {
21
24
  project: RushConfigurationProject;
@@ -1,8 +1,9 @@
1
1
  import { type RushConfigurationProject } from '@rushstack/rush-sdk';
2
2
  export interface ReleaseOptions {
3
- commit: string;
3
+ commit?: string;
4
4
  dryRun?: boolean;
5
5
  registry: string;
6
+ packages?: PackageToPublish[];
6
7
  }
7
8
  export interface PackageToPublish {
8
9
  packageName: string;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * 默认的 NPM registry 地址
3
+ */
4
+ export declare const DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org";
5
+ /**
6
+ * 默认的 Git 分支名前缀
7
+ */
8
+ export declare const DEFAULT_BRANCH_PREFIX = "bump";
package/lib/index.js CHANGED
@@ -148,6 +148,19 @@ const logger = {
148
148
  // Copyright (c) 2025 coze-dev
149
149
  // SPDX-License-Identifier: MIT
150
150
 
151
+ /**
152
+ * 默认的 NPM registry 地址
153
+ */
154
+ const DEFAULT_NPM_REGISTRY = 'https://registry.npmjs.org';
155
+
156
+ /**
157
+ * 默认的 Git 分支名前缀
158
+ */
159
+ const DEFAULT_BRANCH_PREFIX = 'bump';
160
+
161
+ // Copyright (c) 2025 coze-dev
162
+ // SPDX-License-Identifier: MIT
163
+
151
164
 
152
165
 
153
166
 
@@ -214,6 +227,15 @@ const getCurrentBranchName = async () => {
214
227
  return stdout.trim();
215
228
  };
216
229
 
230
+ /**
231
+ * 获取当前 commit hash
232
+ * @returns commit hash
233
+ */
234
+ const getCurrentCommitHash = async () => {
235
+ const { stdout } = await exec('git rev-parse HEAD');
236
+ return stdout.trim();
237
+ };
238
+
217
239
  const isMainBranch = async () => {
218
240
  const currentBranchName = await getCurrentBranchName();
219
241
  return currentBranchName === 'main';
@@ -369,7 +391,12 @@ const publishPackage = async (
369
391
  : version.includes('beta')
370
392
  ? 'beta'
371
393
  : 'latest';
372
- const args = [`NPM_AUTH_TOKEN=${token}`, 'npm', 'publish', `--tag ${tag}`];
394
+ const setToken = `npm config set //bnpm.byted.org/:_authToken ${token}`;
395
+ await exec(setToken, {
396
+ cwd: project.projectFolder,
397
+ });
398
+
399
+ const args = [`NODE_AUTH_TOKEN=${token}`, 'npm', 'publish', `--tag ${tag}`];
373
400
  if (dryRun) {
374
401
  args.push('--dry-run');
375
402
  }
@@ -519,10 +546,27 @@ const getPackagesToPublish = async (
519
546
 
520
547
 
521
548
  async function release(options) {
522
- const { commit, dryRun = false, registry } = options;
549
+ const { dryRun = false, registry, packages } = options;
550
+ let { commit } = options;
551
+ const hasPassedCommit = !!options.commit;
523
552
 
524
553
  // 1. 获取需要发布的包列表
525
- const packagesToPublish = await getPackagesToPublish(commit);
554
+ let packagesToPublish;
555
+ if (packages) {
556
+ // 直接使用传入的包列表
557
+ packagesToPublish = packages;
558
+ logger.info('Using provided package list');
559
+ } else {
560
+ // 从 git tags 获取包列表
561
+ if (!hasPassedCommit) {
562
+ commit = await getCurrentCommitHash();
563
+ logger.info('Using current commit');
564
+ }
565
+ // 此时 commit 必定有值(要么传入了,要么刚获取了)
566
+ const commitHash = commit ;
567
+ packagesToPublish = await getPackagesToPublish(commitHash);
568
+ }
569
+
526
570
  if (packagesToPublish.length === 0) {
527
571
  logger.warn('No packages to publish');
528
572
  return;
@@ -539,7 +583,15 @@ async function release(options) {
539
583
  );
540
584
  const branchName = await getCurrentBranchName();
541
585
  checkReleasePlan(releaseManifests, branchName);
542
- await exec(`git checkout ${commit}`);
586
+
587
+ // 只有在指定了 commit 且与当前 HEAD 不同时才切换
588
+ if (hasPassedCommit) {
589
+ const currentHead = await getCurrentCommitHash();
590
+ if (currentHead !== commit) {
591
+ logger.info(`Checking out commit: ${commit}`);
592
+ await exec(`git checkout ${commit}`);
593
+ }
594
+ }
543
595
 
544
596
  await releasePackages(releaseManifests, { dryRun, registry });
545
597
  logger.success('All packages published successfully!');
@@ -555,18 +607,15 @@ const installAction$2 = (program) => {
555
607
  program
556
608
  .command('release')
557
609
  .description('Release packages based on git tags.')
558
- .requiredOption('--commit <string>', '需要执行发布的 commit id')
610
+ .option('--commit <string>', '需要执行发布的 commit id (默认使用当前 HEAD)')
559
611
  .option('--dry-run', '是否只执行不真实发布', false)
560
612
  .option(
561
613
  '-r, --registry <string>',
562
- '发布到的 registry',
563
- 'https://registry.npmjs.org',
614
+ `发布到的 registry (默认: ${DEFAULT_NPM_REGISTRY})`,
615
+ DEFAULT_NPM_REGISTRY,
564
616
  )
565
617
  .action(async (options) => {
566
618
  try {
567
- if (!options.commit) {
568
- throw new Error('请提供需要发布的 commit id');
569
- }
570
619
  if (!process.env.NPM_AUTH_TOKEN) {
571
620
  throw new Error('请设置 NPM_AUTH_TOKEN 环境变量');
572
621
  }
@@ -859,6 +908,7 @@ async function push({ refs, cwd, repoUrl }) {
859
908
 
860
909
 
861
910
 
911
+
862
912
  const pushToRemote = async (options) => {
863
913
  const {
864
914
  sessionId,
@@ -869,6 +919,7 @@ const pushToRemote = async (options) => {
869
919
  skipCommit,
870
920
  skipPush,
871
921
  repoUrl,
922
+ branchPrefix = 'release',
872
923
  } = options;
873
924
  if (skipCommit) {
874
925
  return;
@@ -882,7 +933,7 @@ const pushToRemote = async (options) => {
882
933
  branchName = await getCurrentBranchName();
883
934
  } else {
884
935
  const date = dayjs().format('YYYYMMDD');
885
- branchName = `release/${date}-${sessionId}`;
936
+ branchName = `${branchPrefix}/${date}-${sessionId}`;
886
937
  await exec(`git checkout -b ${branchName}`, { cwd });
887
938
  }
888
939
  const isTestPublish = [BumpType.ALPHA, BumpType.BETA].includes(
@@ -1034,7 +1085,7 @@ const lookupOnly = (packageName) => {
1034
1085
  return projects[0];
1035
1086
  };
1036
1087
 
1037
- function _optionalChain$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
1088
+ function _optionalChain$2(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
1038
1089
 
1039
1090
 
1040
1091
 
@@ -1088,7 +1139,7 @@ const retrievePackages = (
1088
1139
 
1089
1140
  const validateAndGetPackages = (options) => {
1090
1141
  const retrievePatterns = Object.values(RetrievePattern);
1091
- if (retrievePatterns.every(pattern => (_optionalChain$1([options, 'access', _ => _[pattern], 'optionalAccess', _2 => _2.length]) || 0) <= 0)) {
1142
+ if (retrievePatterns.every(pattern => (_optionalChain$2([options, 'access', _ => _[pattern], 'optionalAccess', _2 => _2.length]) || 0) <= 0)) {
1092
1143
  throw new Error('No packages to publish');
1093
1144
  }
1094
1145
  const res = retrievePatterns.reduce((acc, pattern) => {
@@ -1114,8 +1165,11 @@ const validateAndGetPackages = (options) => {
1114
1165
  return result;
1115
1166
  };
1116
1167
 
1117
- // Copyright (c) 2025 coze-dev
1118
- // SPDX-License-Identifier: MIT
1168
+ function _optionalChain$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// Copyright (c) 2025 coze-dev
1169
+
1170
+
1171
+
1172
+
1119
1173
 
1120
1174
 
1121
1175
 
@@ -1123,20 +1177,33 @@ const validateAndGetPackages = (options) => {
1123
1177
  const confirmForPublish = async (
1124
1178
  publishManifest,
1125
1179
  dryRun,
1180
+ options,
1126
1181
  ) => {
1127
- console.log(chalk.gray('Will publish the following packages:'));
1182
+ logger.info(chalk.gray('Will publish the following packages:'), false);
1128
1183
  publishManifest.forEach(manifest => {
1129
- const msg = `${manifest.project.packageName}: ${chalk.bgGreen(`${manifest.currentVersion} -> ${chalk.bold(manifest.newVersion)}`)}`;
1130
- console.log(`- ${msg}`);
1184
+ const versionChange = `${manifest.currentVersion} -> ${chalk.bold(manifest.newVersion)}`;
1185
+ const msg = `${manifest.project.packageName}: ${chalk.bgGreen(versionChange)}`;
1186
+ logger.info(`- ${msg}`, false);
1131
1187
  });
1188
+
1189
+ // Release 模式的额外提示
1190
+ if (_optionalChain$1([options, 'optionalAccess', _ => _.isReleaseMode])) {
1191
+ logger.info('', false);
1192
+ logger.warn(chalk.yellow.bold('⚠️ Release Mode Enabled:'), false);
1193
+ const registryMsg = ` Packages will be published directly to: ${chalk.bold(options.registry || 'default registry')}`;
1194
+ logger.warn(chalk.yellow(registryMsg), false);
1195
+ }
1196
+
1132
1197
  if (dryRun) {
1133
1198
  return false;
1134
1199
  }
1135
1200
 
1136
- console.log('\n');
1201
+ logger.info('', false);
1137
1202
  try {
1138
1203
  const result = await prompts.confirm({
1139
- message: 'Are you sure to publish?',
1204
+ message: _optionalChain$1([options, 'optionalAccess', _2 => _2.isReleaseMode])
1205
+ ? 'Are you sure to publish directly?'
1206
+ : 'Are you sure to publish?',
1140
1207
  default: true,
1141
1208
  });
1142
1209
  return result;
@@ -1500,7 +1567,10 @@ const publish = async (options) => {
1500
1567
  const sessionId = randomHash(6);
1501
1568
  const rushConfiguration = getRushConfiguration$1();
1502
1569
  const rushFolder = rushConfiguration.rushJsonFolder;
1503
- if (process.env.SKIP_UNCOMMITTED_CHECK !== 'true') {
1570
+ if (
1571
+ process.env.SKIP_UNCOMMITTED_CHECK !== 'true' &&
1572
+ options.release !== true
1573
+ ) {
1504
1574
  await ensureNotUncommittedChanges();
1505
1575
  }
1506
1576
 
@@ -1536,6 +1606,10 @@ const publish = async (options) => {
1536
1606
  const continuePublish = await confirmForPublish(
1537
1607
  publishManifests,
1538
1608
  !!options.dryRun,
1609
+ {
1610
+ isReleaseMode: !!options.release,
1611
+ registry: options.registry || DEFAULT_NPM_REGISTRY,
1612
+ },
1539
1613
  );
1540
1614
 
1541
1615
  if (!continuePublish) {
@@ -1551,17 +1625,47 @@ const publish = async (options) => {
1551
1625
  await Promise.all(postHandles.map(handle => handle(publishManifests)))
1552
1626
  ).flat();
1553
1627
 
1554
- // 4. 创建并推送发布分支
1555
- await pushToRemote({
1556
- publishManifests,
1557
- bumpPolicy: bumpPolicy ,
1558
- sessionId,
1559
- changedFiles,
1560
- cwd: rushFolder,
1561
- skipCommit: !!options.skipCommit,
1562
- skipPush: !!options.skipPush,
1563
- repoUrl: options.repoUrl,
1564
- });
1628
+ // 4. 创建并推送发布分支 或 直接发布
1629
+ let shouldRelease = false;
1630
+ if (options.release) {
1631
+ // 验证 release 模式的前置条件
1632
+ if (isBetaPublish === false) {
1633
+ logger.error(
1634
+ 'Direct release (--release) is only allowed for alpha or beta versions.',
1635
+ );
1636
+ logger.error(`Current bump type is: ${bumpPolicy}`);
1637
+ logger.warn('Falling back to normal publish mode...');
1638
+ } else {
1639
+ shouldRelease = true;
1640
+ }
1641
+ }
1642
+
1643
+ if (shouldRelease) {
1644
+ // Release 模式:直接发布
1645
+ logger.info('Running in direct release mode...');
1646
+ logger.info('Starting package release...');
1647
+ const registry = options.registry || DEFAULT_NPM_REGISTRY;
1648
+ // 将 PublishManifest[] 转换为 PackageToPublish[]
1649
+ const packages = publishManifests.map(manifest => ({
1650
+ packageName: manifest.project.packageName,
1651
+ version: manifest.newVersion,
1652
+ }));
1653
+ await release({ dryRun: !!options.dryRun, registry, packages });
1654
+ } else {
1655
+ // 普通模式:创建并推送发布分支
1656
+ await pushToRemote({
1657
+ publishManifests,
1658
+ bumpPolicy: bumpPolicy ,
1659
+ sessionId,
1660
+ changedFiles,
1661
+ cwd: rushFolder,
1662
+ skipCommit: !!options.skipCommit,
1663
+ skipPush: !!options.skipPush,
1664
+ repoUrl: options.repoUrl,
1665
+ branchPrefix: options.branchPrefix,
1666
+ });
1667
+ }
1668
+
1565
1669
  logger.success('Publish success.');
1566
1670
  };
1567
1671
 
@@ -1592,6 +1696,21 @@ const installAction$1 = (program) => {
1592
1696
  'Git repository URL (e.g. git@github.com:coze-dev/coze-js.git)',
1593
1697
  undefined,
1594
1698
  )
1699
+ .option(
1700
+ '--branch-prefix <prefix>',
1701
+ `Git branch name prefix (default: ${DEFAULT_BRANCH_PREFIX})`,
1702
+ DEFAULT_BRANCH_PREFIX,
1703
+ )
1704
+ .option(
1705
+ '-l, --release',
1706
+ 'Directly publish packages (only for alpha/beta versions)',
1707
+ false,
1708
+ )
1709
+ .option(
1710
+ '--registry <url>',
1711
+ `NPM registry URL (default: ${DEFAULT_NPM_REGISTRY})`,
1712
+ DEFAULT_NPM_REGISTRY,
1713
+ )
1595
1714
  .action(async (options) => {
1596
1715
  try {
1597
1716
  const repoUrl = options.repoUrl || (await getCurrentOrigin());
@@ -1599,8 +1718,9 @@ const installAction$1 = (program) => {
1599
1718
  throw new Error('Git repository URL is required');
1600
1719
  }
1601
1720
  if (!GIT_REPO_URL_REGEX.test(repoUrl)) {
1721
+ const expectedFormat = 'git@github.com:${org}/${repo}.git';
1602
1722
  throw new Error(
1603
- `Invalid git repository URL: ${repoUrl}, it should be follow the format: git@github.com:\${org}/\${repo}.git`,
1723
+ `Invalid git repository URL: ${repoUrl}, it should follow the format: ${expectedFormat}`,
1604
1724
  );
1605
1725
  }
1606
1726
  const normalizeOptions = {
@@ -0,0 +1,8 @@
1
+ export interface IPublishPluginConfig {
2
+ branchPrefix?: string;
3
+ }
4
+ /**
5
+ * Read plugin configuration from common/config/rush-plugins/@coze-arch/rush-publish-plugin.json
6
+ * @returns Plugin configuration object
7
+ */
8
+ export declare function getPluginConfig(): IPublishPluginConfig;
@@ -4,6 +4,11 @@ export declare const getChangedFilesFromCached: () => Promise<string[]>;
4
4
  * @returns string
5
5
  */
6
6
  export declare const getCurrentBranchName: () => Promise<string>;
7
+ /**
8
+ * 获取当前 commit hash
9
+ * @returns commit hash
10
+ */
11
+ export declare const getCurrentCommitHash: () => Promise<string>;
7
12
  export declare const isMainBranch: () => Promise<boolean>;
8
13
  export declare const getChangedFiles: () => Promise<string[]>;
9
14
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coze-arch/rush-publish-plugin",
3
- "version": "0.0.5-alpha.0f1107",
3
+ "version": "0.0.5-alpha.5049d2",
4
4
  "description": "rush plugin to generate change log and publish packages",
5
5
  "keywords": [
6
6
  "rush",