@coze-arch/rush-publish-plugin 0.0.5-alpha.8b5f6f → 0.0.5-alpha.a2c426
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/lib/action/release/release.d.ts +1 -1
- package/lib/action/release/types.d.ts +1 -1
- package/lib/const/index.d.ts +0 -4
- package/lib/index.js +322 -69
- package/lib/utils/git.d.ts +22 -0
- package/lib/utils/resolve-registry.d.ts +12 -0
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ReleaseManifest, type ReleaseOptions } from './types';
|
|
2
2
|
export declare const releasePackages: (releaseManifests: ReleaseManifest[], releaseOptions: ReleaseOptions) => Promise<void>;
|
package/lib/const/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -148,11 +148,6 @@ 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
151
|
/**
|
|
157
152
|
* 默认的 Git 分支名前缀
|
|
158
153
|
*/
|
|
@@ -282,6 +277,140 @@ const getCurrentOrigin = async (
|
|
|
282
277
|
}
|
|
283
278
|
};
|
|
284
279
|
|
|
280
|
+
/**
|
|
281
|
+
* 解析 Git 远程仓库 URL,提取主机和仓库路径
|
|
282
|
+
* 支持 HTTP/HTTPS 和 SSH 格式
|
|
283
|
+
* @param gitUrl Git 仓库 URL
|
|
284
|
+
* @returns 包含主机和仓库路径的对象,解析失败返回 null
|
|
285
|
+
*/
|
|
286
|
+
const parseGitRemoteUrl = (
|
|
287
|
+
gitUrl,
|
|
288
|
+
) => {
|
|
289
|
+
if (!gitUrl) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const trimmedUrl = gitUrl.trim().replace(/\.git$/, '');
|
|
294
|
+
|
|
295
|
+
// 匹配 SSH 格式: git@github.com:owner/repo.git
|
|
296
|
+
const sshMatch = trimmedUrl.match(/^git@([^:]+):(.+)$/);
|
|
297
|
+
if (sshMatch) {
|
|
298
|
+
const host = sshMatch[1];
|
|
299
|
+
const path = sshMatch[2];
|
|
300
|
+
return {
|
|
301
|
+
host,
|
|
302
|
+
path,
|
|
303
|
+
fullUrl: `https://${host}/${path}`,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// 匹配 HTTP/HTTPS 格式: https://github.com/owner/repo.git
|
|
308
|
+
const httpMatch = trimmedUrl.match(/^https?:\/\/([^/]+)\/(.+)$/);
|
|
309
|
+
if (httpMatch) {
|
|
310
|
+
const host = httpMatch[1];
|
|
311
|
+
const path = httpMatch[2];
|
|
312
|
+
return {
|
|
313
|
+
host,
|
|
314
|
+
path,
|
|
315
|
+
fullUrl: `https://${host}/${path}`,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return null;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* 根据仓库信息构建 MR/PR 创建链接
|
|
324
|
+
* @param repoInfo 仓库信息
|
|
325
|
+
* @param branchName 分支名称
|
|
326
|
+
* @returns MR/PR 创建链接,如果无法构建则返回 null
|
|
327
|
+
*/
|
|
328
|
+
const buildMergeRequestUrl = (
|
|
329
|
+
repoInfo,
|
|
330
|
+
branchName,
|
|
331
|
+
) => {
|
|
332
|
+
const { host, fullUrl } = repoInfo;
|
|
333
|
+
|
|
334
|
+
// GitHub
|
|
335
|
+
if (host.includes('github.com')) {
|
|
336
|
+
return `${fullUrl}/compare/${branchName}?expand=1`;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// GitLab
|
|
340
|
+
if (host.includes('gitlab')) {
|
|
341
|
+
return `${fullUrl}/-/merge_requests/new?merge_request[source_branch]=${branchName}`;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Gitee
|
|
345
|
+
if (host.includes('gitee.com')) {
|
|
346
|
+
return `${fullUrl}/compare/${branchName}...master`;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Bitbucket
|
|
350
|
+
if (host.includes('bitbucket')) {
|
|
351
|
+
return `${fullUrl}/pull-requests/new?source=${branchName}`;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// 无法识别的平台
|
|
355
|
+
return null;
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
function _optionalChain$3(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; }
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* package.json 的类型定义
|
|
362
|
+
*/
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* 解析发布 registry 的优先级:
|
|
373
|
+
* 1. 命令行参数 --registry (最高优先级)
|
|
374
|
+
* 2. package.json 中的 publishConfig.registry
|
|
375
|
+
* 3. 使用 npm 配置的默认 registry (不传 --registry 参数)
|
|
376
|
+
*
|
|
377
|
+
* @param project - Rush 项目配置
|
|
378
|
+
* @param registryFromCli - 命令行参数传入的 registry
|
|
379
|
+
* @returns 解析后的 registry URL,如果为 undefined 则使用 npm 默认配置
|
|
380
|
+
*/
|
|
381
|
+
function resolveRegistry(
|
|
382
|
+
project,
|
|
383
|
+
registryFromCli,
|
|
384
|
+
) {
|
|
385
|
+
// 1. 优先使用命令行参数
|
|
386
|
+
if (registryFromCli) {
|
|
387
|
+
logger.info(
|
|
388
|
+
`Using registry from CLI: ${registryFromCli} (${project.packageName})`,
|
|
389
|
+
false,
|
|
390
|
+
);
|
|
391
|
+
return registryFromCli;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// 2. 尝试读取 package.json 中的 publishConfig.registry
|
|
395
|
+
const packageJson = project.packageJson ;
|
|
396
|
+
const registryFromPackageJson = _optionalChain$3([packageJson, 'access', _ => _.publishConfig, 'optionalAccess', _2 => _2.registry]);
|
|
397
|
+
|
|
398
|
+
if (registryFromPackageJson) {
|
|
399
|
+
logger.info(
|
|
400
|
+
`Using registry from publishConfig: ${registryFromPackageJson} (${project.packageName})`,
|
|
401
|
+
false,
|
|
402
|
+
);
|
|
403
|
+
return registryFromPackageJson;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// 3. 返回 undefined,让 npm 使用自己配置的 registry
|
|
407
|
+
logger.info(
|
|
408
|
+
`Using npm configured registry (${project.packageName})`,
|
|
409
|
+
false,
|
|
410
|
+
);
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
413
|
+
|
|
285
414
|
// Copyright (c) 2025 coze-dev
|
|
286
415
|
// SPDX-License-Identifier: MIT
|
|
287
416
|
|
|
@@ -323,8 +452,7 @@ const getRushConfiguration$1 = (() => {
|
|
|
323
452
|
};
|
|
324
453
|
})();
|
|
325
454
|
|
|
326
|
-
// Copyright (c) 2025 coze-dev
|
|
327
|
-
// SPDX-License-Identifier: MIT
|
|
455
|
+
function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// Copyright (c) 2025 coze-dev
|
|
328
456
|
|
|
329
457
|
|
|
330
458
|
|
|
@@ -355,14 +483,21 @@ const updateDependencyVersions = async (
|
|
|
355
483
|
return Promise.resolve(packageJson);
|
|
356
484
|
};
|
|
357
485
|
|
|
358
|
-
|
|
486
|
+
/**
|
|
487
|
+
* 应用发布配置
|
|
488
|
+
* 优先使用 botPublishConfig,如果不存在则使用 cozePublishConfig
|
|
489
|
+
*/
|
|
490
|
+
const applyPublishConfigSettings = async (
|
|
359
491
|
packageJson,
|
|
360
492
|
) => {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
493
|
+
// 优先使用 botPublishConfig,如果不存在则回退到 cozePublishConfig
|
|
494
|
+
const publishConfig =
|
|
495
|
+
_nullishCoalesce(packageJson.botPublishConfig, () => ( packageJson.cozePublishConfig));
|
|
496
|
+
|
|
497
|
+
if (publishConfig) {
|
|
498
|
+
const keys = Object.keys(publishConfig);
|
|
364
499
|
for (const key of keys) {
|
|
365
|
-
packageJson[key] =
|
|
500
|
+
packageJson[key] = publishConfig[key];
|
|
366
501
|
}
|
|
367
502
|
}
|
|
368
503
|
return Promise.resolve(packageJson);
|
|
@@ -371,7 +506,7 @@ const applyCozePublishConfig = async (
|
|
|
371
506
|
const applyPublishConfig = async (project) => {
|
|
372
507
|
const jobs = [
|
|
373
508
|
updateDependencyVersions,
|
|
374
|
-
|
|
509
|
+
applyPublishConfigSettings,
|
|
375
510
|
];
|
|
376
511
|
const packageJsonPath = path.join(project.projectFolder, 'package.json');
|
|
377
512
|
let packageJson = await readJsonFile(packageJsonPath);
|
|
@@ -388,7 +523,7 @@ const publishPackage = async (
|
|
|
388
523
|
project,
|
|
389
524
|
releaseOptions,
|
|
390
525
|
) => {
|
|
391
|
-
const { dryRun
|
|
526
|
+
const { dryRun } = releaseOptions;
|
|
392
527
|
const token = process.env.NPM_AUTH_TOKEN;
|
|
393
528
|
const { version } = project.packageJson;
|
|
394
529
|
const tag = version.includes('alpha')
|
|
@@ -396,15 +531,16 @@ const publishPackage = async (
|
|
|
396
531
|
: version.includes('beta')
|
|
397
532
|
? 'beta'
|
|
398
533
|
: 'latest';
|
|
399
|
-
const setToken = `npm config set //bnpm.byted.org/:_authToken ${token}`;
|
|
400
|
-
await exec(setToken, {
|
|
401
|
-
cwd: project.projectFolder,
|
|
402
|
-
});
|
|
403
534
|
|
|
535
|
+
// 解析 registry:CLI 参数 > package.json publishConfig > npm 配置
|
|
536
|
+
const registry = resolveRegistry(project, releaseOptions.registry);
|
|
537
|
+
|
|
538
|
+
// 使用环境变量传递 authToken,npm 会自动应用到任何 registry
|
|
404
539
|
const args = [`NODE_AUTH_TOKEN=${token}`, 'npm', 'publish', `--tag ${tag}`];
|
|
405
540
|
if (dryRun) {
|
|
406
541
|
args.push('--dry-run');
|
|
407
542
|
}
|
|
543
|
+
// 只有明确指定了 registry 才传递参数,否则使用 npm 配置的默认值
|
|
408
544
|
if (registry) {
|
|
409
545
|
args.push(`--registry=${registry}`);
|
|
410
546
|
}
|
|
@@ -484,7 +620,7 @@ const checkReleasePlan = (
|
|
|
484
620
|
!allowBranches.includes(branchName)
|
|
485
621
|
) {
|
|
486
622
|
throw new Error(
|
|
487
|
-
`For LATEST release, should be on one of these branches: ${allowBranches.join(', ')}
|
|
623
|
+
`For LATEST release, should be on one of these branches: ${allowBranches.join(', ')}. Current Branch: ${branchName}`,
|
|
488
624
|
);
|
|
489
625
|
}
|
|
490
626
|
return true;
|
|
@@ -624,8 +760,7 @@ const installAction$2 = (program) => {
|
|
|
624
760
|
.option('--dry-run', '是否只执行不真实发布', false)
|
|
625
761
|
.option(
|
|
626
762
|
'-r, --registry <string>',
|
|
627
|
-
|
|
628
|
-
DEFAULT_NPM_REGISTRY,
|
|
763
|
+
'发布到的 registry (优先级: CLI参数 > package.json publishConfig.registry > npm config)',
|
|
629
764
|
)
|
|
630
765
|
.option(
|
|
631
766
|
'--allow-branches <branches...>',
|
|
@@ -910,6 +1045,144 @@ async function push({ refs, cwd, repoUrl }) {
|
|
|
910
1045
|
|
|
911
1046
|
|
|
912
1047
|
|
|
1048
|
+
/**
|
|
1049
|
+
* 获取或创建发布分支
|
|
1050
|
+
*/
|
|
1051
|
+
const getOrCreateBranch = async (params
|
|
1052
|
+
|
|
1053
|
+
|
|
1054
|
+
|
|
1055
|
+
|
|
1056
|
+
) => {
|
|
1057
|
+
const { bumpPolicy, sessionId, branchPrefix, cwd } = params;
|
|
1058
|
+
|
|
1059
|
+
if (bumpPolicy === BumpType.BETA) {
|
|
1060
|
+
return await getCurrentBranchName();
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
const date = dayjs().format('YYYYMMDD');
|
|
1064
|
+
const branchName = `${branchPrefix}/${date}-${sessionId}`;
|
|
1065
|
+
await exec(`git checkout -b ${branchName}`, { cwd });
|
|
1066
|
+
return branchName;
|
|
1067
|
+
};
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* 处理 Beta 发布流程:询问并执行 git push
|
|
1071
|
+
*/
|
|
1072
|
+
const handleBetaPublish = async (
|
|
1073
|
+
branchName,
|
|
1074
|
+
cwd,
|
|
1075
|
+
) => {
|
|
1076
|
+
logger.success(`Changes have been committed to branch "${branchName}".`);
|
|
1077
|
+
|
|
1078
|
+
const shouldPush = await prompts.confirm({
|
|
1079
|
+
message: 'Do you want to push the changes now?',
|
|
1080
|
+
default: true,
|
|
1081
|
+
});
|
|
1082
|
+
|
|
1083
|
+
if (shouldPush) {
|
|
1084
|
+
logger.info('Pushing changes to remote...');
|
|
1085
|
+
await exec('git push', { cwd });
|
|
1086
|
+
logger.success('Changes pushed successfully!');
|
|
1087
|
+
} else {
|
|
1088
|
+
logger.info('Please run "git push" manually when you are ready.');
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
/**
|
|
1093
|
+
* 显示手动创建 MR 的提示消息
|
|
1094
|
+
*/
|
|
1095
|
+
const showManualMrMessage = (
|
|
1096
|
+
branchName,
|
|
1097
|
+
repositoryUrl,
|
|
1098
|
+
) => {
|
|
1099
|
+
const baseMessage = `Please create a merge request from branch "${branchName}" to the main branch`;
|
|
1100
|
+
const suffix =
|
|
1101
|
+
'The release will be triggered after the merge request is merged.';
|
|
1102
|
+
|
|
1103
|
+
if (repositoryUrl) {
|
|
1104
|
+
logger.success(
|
|
1105
|
+
`Repository: ${repositoryUrl}\n${baseMessage}.\n${suffix}`,
|
|
1106
|
+
false,
|
|
1107
|
+
);
|
|
1108
|
+
} else {
|
|
1109
|
+
logger.success(`${baseMessage} in your repository.\n${suffix}`);
|
|
1110
|
+
}
|
|
1111
|
+
};
|
|
1112
|
+
|
|
1113
|
+
/**
|
|
1114
|
+
* 显示 MR/PR 创建链接并打开浏览器
|
|
1115
|
+
*/
|
|
1116
|
+
const showMrLinkAndOpenBrowser = async (mrUrl) => {
|
|
1117
|
+
const log = [
|
|
1118
|
+
'************************************************',
|
|
1119
|
+
'*',
|
|
1120
|
+
`* Please create MR/PR: ${mrUrl}`,
|
|
1121
|
+
'*',
|
|
1122
|
+
'* The release will be triggered after the MR is merged.',
|
|
1123
|
+
'*',
|
|
1124
|
+
'************************************************',
|
|
1125
|
+
];
|
|
1126
|
+
logger.success(log.join('\n'), false);
|
|
1127
|
+
|
|
1128
|
+
const open = await import('open');
|
|
1129
|
+
await open.default(mrUrl);
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
/**
|
|
1133
|
+
* 处理正式版本发布流程:提示创建 MR/PR
|
|
1134
|
+
*/
|
|
1135
|
+
const handleProductionPublish = async (
|
|
1136
|
+
branchName,
|
|
1137
|
+
cwd,
|
|
1138
|
+
) => {
|
|
1139
|
+
const originUrl = await getCurrentOrigin(cwd);
|
|
1140
|
+
if (!originUrl) {
|
|
1141
|
+
showManualMrMessage(branchName);
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
const repoInfo = parseGitRemoteUrl(originUrl);
|
|
1146
|
+
if (!repoInfo) {
|
|
1147
|
+
showManualMrMessage(branchName);
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
const mrUrl = buildMergeRequestUrl(repoInfo, branchName);
|
|
1152
|
+
if (!mrUrl) {
|
|
1153
|
+
showManualMrMessage(branchName, repoInfo.fullUrl);
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
await showMrLinkAndOpenBrowser(mrUrl);
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1160
|
+
/**
|
|
1161
|
+
* 根据发布类型处理后续提示
|
|
1162
|
+
*/
|
|
1163
|
+
const handlePostPushPrompts = async (
|
|
1164
|
+
bumpPolicy,
|
|
1165
|
+
branchName,
|
|
1166
|
+
cwd,
|
|
1167
|
+
) => {
|
|
1168
|
+
const isAlphaPublish = bumpPolicy === BumpType.ALPHA;
|
|
1169
|
+
const isBetaPublish = bumpPolicy === BumpType.BETA;
|
|
1170
|
+
|
|
1171
|
+
// Alpha 发布:不需要提示(会自动触发 CI 发布)
|
|
1172
|
+
if (isAlphaPublish) {
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
// Beta 发布:询问用户是否立即执行 git push
|
|
1177
|
+
if (isBetaPublish) {
|
|
1178
|
+
await handleBetaPublish(branchName, cwd);
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
// 正式版本发布:提示创建 MR/PR
|
|
1183
|
+
await handleProductionPublish(branchName, cwd);
|
|
1184
|
+
};
|
|
1185
|
+
|
|
913
1186
|
const pushToRemote = async (options) => {
|
|
914
1187
|
const {
|
|
915
1188
|
sessionId,
|
|
@@ -921,65 +1194,39 @@ const pushToRemote = async (options) => {
|
|
|
921
1194
|
repoUrl,
|
|
922
1195
|
branchPrefix = 'release',
|
|
923
1196
|
} = options;
|
|
1197
|
+
|
|
924
1198
|
if (skipCommit) {
|
|
925
1199
|
return;
|
|
926
1200
|
}
|
|
927
1201
|
|
|
928
|
-
//
|
|
929
|
-
const
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
}
|
|
935
|
-
const date = dayjs().format('YYYYMMDD');
|
|
936
|
-
branchName = `${branchPrefix}/${date}-${sessionId}`;
|
|
937
|
-
await exec(`git checkout -b ${branchName}`, { cwd });
|
|
938
|
-
}
|
|
939
|
-
const isTestPublish = [BumpType.ALPHA, BumpType.BETA].includes(
|
|
940
|
-
bumpPolicy ,
|
|
941
|
-
);
|
|
1202
|
+
// 1. 获取或创建发布分支
|
|
1203
|
+
const branchName = await getOrCreateBranch({
|
|
1204
|
+
bumpPolicy,
|
|
1205
|
+
sessionId,
|
|
1206
|
+
branchPrefix,
|
|
1207
|
+
cwd,
|
|
1208
|
+
});
|
|
942
1209
|
|
|
943
|
-
//
|
|
1210
|
+
// 2. 提交变更
|
|
944
1211
|
const { effects } = await commitChanges({
|
|
945
1212
|
files: changedFiles,
|
|
946
1213
|
cwd,
|
|
947
1214
|
branchName,
|
|
948
1215
|
});
|
|
1216
|
+
|
|
949
1217
|
if (skipPush) {
|
|
950
1218
|
return;
|
|
951
1219
|
}
|
|
1220
|
+
|
|
1221
|
+
// 3. 推送变更
|
|
952
1222
|
await push({
|
|
953
1223
|
refs: effects,
|
|
954
1224
|
cwd,
|
|
955
|
-
repoUrl
|
|
1225
|
+
repoUrl,
|
|
956
1226
|
});
|
|
957
1227
|
|
|
958
|
-
//
|
|
959
|
-
|
|
960
|
-
if (!repoInfoMatch) {
|
|
961
|
-
throw new Error('Invalid git repository URL');
|
|
962
|
-
}
|
|
963
|
-
const repoOwner = repoInfoMatch[1];
|
|
964
|
-
const repoName = repoInfoMatch[2];
|
|
965
|
-
|
|
966
|
-
if (isTestPublish) {
|
|
967
|
-
logger.success(
|
|
968
|
-
`Please refer to https://github.com/${repoOwner}/${repoName}/actions/workflows/release.yml for the release progress.`,
|
|
969
|
-
);
|
|
970
|
-
} else {
|
|
971
|
-
const prUrl = `https://github.com/${repoOwner}/${repoName}/compare/${branchName}?expand=1`;
|
|
972
|
-
const log = [
|
|
973
|
-
'************************************************',
|
|
974
|
-
'*',
|
|
975
|
-
`* Please create PR: ${prUrl}`,
|
|
976
|
-
'*',
|
|
977
|
-
'************************************************',
|
|
978
|
-
];
|
|
979
|
-
logger.success(log.join('\n'), false);
|
|
980
|
-
const open = await import('open');
|
|
981
|
-
await open.default(prUrl);
|
|
982
|
-
}
|
|
1228
|
+
// 4. 根据发布类型显示不同提示
|
|
1229
|
+
await handlePostPushPrompts(bumpPolicy, branchName, cwd);
|
|
983
1230
|
};
|
|
984
1231
|
|
|
985
1232
|
// Copyright (c) 2025 coze-dev
|
|
@@ -1186,7 +1433,7 @@ const confirmForPublish = async (
|
|
|
1186
1433
|
if (_optionalChain$1([options, 'optionalAccess', _ => _.isReleaseMode])) {
|
|
1187
1434
|
logger.info('', false);
|
|
1188
1435
|
logger.warn(chalk.yellow.bold('⚠️ Release Mode Enabled:'), false);
|
|
1189
|
-
const registryMsg = ` Packages will be published directly to: ${chalk.bold(options.registry || '
|
|
1436
|
+
const registryMsg = ` Packages will be published directly to: ${chalk.bold(options.registry || 'npm configured registry')}`;
|
|
1190
1437
|
logger.warn(chalk.yellow(registryMsg), false);
|
|
1191
1438
|
}
|
|
1192
1439
|
|
|
@@ -1591,7 +1838,11 @@ const publish = async (options) => {
|
|
|
1591
1838
|
const isBetaPublish = [BumpType.BETA, BumpType.ALPHA].includes(
|
|
1592
1839
|
bumpPolicy ,
|
|
1593
1840
|
);
|
|
1594
|
-
if (
|
|
1841
|
+
if (
|
|
1842
|
+
process.env.SKIP_BRANCH_CHECK !== 'true' &&
|
|
1843
|
+
isBetaPublish === false &&
|
|
1844
|
+
(await isMainBranch()) === false
|
|
1845
|
+
) {
|
|
1595
1846
|
// 只允许在主分支发布
|
|
1596
1847
|
logger.error(
|
|
1597
1848
|
'You are not in main branch, please switch to main branch and try again.',
|
|
@@ -1604,7 +1855,7 @@ const publish = async (options) => {
|
|
|
1604
1855
|
!!options.dryRun,
|
|
1605
1856
|
{
|
|
1606
1857
|
isReleaseMode: !!options.release,
|
|
1607
|
-
registry: options.registry
|
|
1858
|
+
registry: options.registry,
|
|
1608
1859
|
},
|
|
1609
1860
|
);
|
|
1610
1861
|
|
|
@@ -1640,13 +1891,16 @@ const publish = async (options) => {
|
|
|
1640
1891
|
// Release 模式:直接发布
|
|
1641
1892
|
logger.info('Running in direct release mode...');
|
|
1642
1893
|
logger.info('Starting package release...');
|
|
1643
|
-
const registry = options.registry || DEFAULT_NPM_REGISTRY;
|
|
1644
1894
|
// 将 PublishManifest[] 转换为 PackageToPublish[]
|
|
1645
1895
|
const packages = publishManifests.map(manifest => ({
|
|
1646
1896
|
packageName: manifest.project.packageName,
|
|
1647
1897
|
version: manifest.newVersion,
|
|
1648
1898
|
}));
|
|
1649
|
-
await release({
|
|
1899
|
+
await release({
|
|
1900
|
+
dryRun: !!options.dryRun,
|
|
1901
|
+
registry: options.registry,
|
|
1902
|
+
packages,
|
|
1903
|
+
});
|
|
1650
1904
|
} else {
|
|
1651
1905
|
// 普通模式:创建并推送发布分支
|
|
1652
1906
|
await pushToRemote({
|
|
@@ -1703,8 +1957,7 @@ const installAction$1 = (program) => {
|
|
|
1703
1957
|
)
|
|
1704
1958
|
.option(
|
|
1705
1959
|
'--registry <url>',
|
|
1706
|
-
|
|
1707
|
-
DEFAULT_NPM_REGISTRY,
|
|
1960
|
+
'NPM registry URL (优先级: CLI参数 > package.json publishConfig.registry > npm config)',
|
|
1708
1961
|
)
|
|
1709
1962
|
.action(async (options) => {
|
|
1710
1963
|
try {
|
package/lib/utils/git.d.ts
CHANGED
|
@@ -22,3 +22,25 @@ export declare const ensureNotUncommittedChanges: () => Promise<boolean>;
|
|
|
22
22
|
*/
|
|
23
23
|
export declare const getCurrentOrigin: (cwd?: string) => Promise<string | undefined>;
|
|
24
24
|
export declare const convertGitSchemaToHttp: (gitUrl: string) => string;
|
|
25
|
+
/**
|
|
26
|
+
* 解析 Git 远程仓库 URL,提取主机和仓库路径
|
|
27
|
+
* 支持 HTTP/HTTPS 和 SSH 格式
|
|
28
|
+
* @param gitUrl Git 仓库 URL
|
|
29
|
+
* @returns 包含主机和仓库路径的对象,解析失败返回 null
|
|
30
|
+
*/
|
|
31
|
+
export declare const parseGitRemoteUrl: (gitUrl: string) => {
|
|
32
|
+
host: string;
|
|
33
|
+
path: string;
|
|
34
|
+
fullUrl: string;
|
|
35
|
+
} | null;
|
|
36
|
+
/**
|
|
37
|
+
* 根据仓库信息构建 MR/PR 创建链接
|
|
38
|
+
* @param repoInfo 仓库信息
|
|
39
|
+
* @param branchName 分支名称
|
|
40
|
+
* @returns MR/PR 创建链接,如果无法构建则返回 null
|
|
41
|
+
*/
|
|
42
|
+
export declare const buildMergeRequestUrl: (repoInfo: {
|
|
43
|
+
host: string;
|
|
44
|
+
path: string;
|
|
45
|
+
fullUrl: string;
|
|
46
|
+
}, branchName: string) => string | null;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type RushConfigurationProject } from '@rushstack/rush-sdk';
|
|
2
|
+
/**
|
|
3
|
+
* 解析发布 registry 的优先级:
|
|
4
|
+
* 1. 命令行参数 --registry (最高优先级)
|
|
5
|
+
* 2. package.json 中的 publishConfig.registry
|
|
6
|
+
* 3. 使用 npm 配置的默认 registry (不传 --registry 参数)
|
|
7
|
+
*
|
|
8
|
+
* @param project - Rush 项目配置
|
|
9
|
+
* @param registryFromCli - 命令行参数传入的 registry
|
|
10
|
+
* @returns 解析后的 registry URL,如果为 undefined 则使用 npm 默认配置
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveRegistry(project: RushConfigurationProject, registryFromCli?: string): string | undefined;
|