Files
Genarrative/apps/ai-game-creator-shell/scripts/channel-identity.mjs
T
kdletters 13a15fed5c
Project CI / AI game creator shell Rust crates (push) Successful in 3m5s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 4m24s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 5m20s
Project CI / Backend tests (push) Successful in 6m42s
Project CI / Frontend tests (push) Successful in 3m2s
Project CI / Native shell tests (push) Successful in 7m16s
Project CI / AI game creator shell web tests (push) Successful in 3m17s
Project CI / Repository checks (push) Successful in 6m25s
修复 AGC 渠道更新互相终止与快捷方式迁移
为 release 与自定义渠道注入独立主程序名,隔离 Windows 更新进程。

新增 release 旧安装目录与快捷方式迁移钩子,保护 dev 历史目录清理。

同步渠道规范、共享决策与排障记录,补充发布脚本回归测试。
2026-10-04 11:45:20 +08:00

92 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* AGC 渠道 → 安装身份。
*
* 渠道同时决定两件事:
* - 更新端点:OSS 分区 `<channel>-win` / `<channel>-mac` 的清单地址;
* - 安装身份:`productName` 与 `identifier`。
*
* 安装身份决定 Windows 安装目录与卸载项、macOS `.app` 名字与 bundle id、
* Windows WebView2 数据目录以及 `%APPDATA%\<identifier>` 客户端数据目录。
* 因此不同渠道的包体在同一台设备上并存时互不顶掉,也不会共享登录态、
* 本地项目与运行锁。
*
* 默认渠道 `dev` 保持已发布客户端标识不变:升级链路与既有安装不能断;展示名显式标记为开发版。
*/
export const AGC_DEFAULT_CHANNEL = 'dev';
export const AGC_PRODUCT_NAME = '陶泥儿';
export const AGC_APP_IDENTIFIER = 'world.genarrative.ai-game-creator';
/**
* Tauri/NSIS 默认按主可执行文件名查找并结束进程。
* dev 保留历史文件名以维持既有更新链;其它渠道使用独立文件名,
* 这样更新一个渠道时不会把另一个渠道的进程一起结束。
*/
export const AGC_MAIN_BINARY_NAME = 'genarrative-ai-game-creator-shell';
const reservedChannelNames = new Set([
'win',
'mac',
'windows',
'macos',
'darwin',
'linux',
]);
/** 校验渠道名:小写字母开头,允许数字与连字符,系统名不属于渠道。 */
export function validateReleaseChannel(channel) {
if (
typeof channel !== 'string' ||
!/^[a-z][a-z0-9-]{0,31}$/u.test(channel) ||
channel.endsWith('-') ||
reservedChannelNames.has(channel) ||
/-(win|mac)$/u.test(channel)
) {
throw new Error(
'发布渠道无效:请使用 dev、release 或最多 32 位的小写字母、数字和连字符名称,系统名称不属于渠道',
);
}
return channel;
}
export function resolveReleaseChannel(env = process.env) {
return validateReleaseChannel(env.AGC_UPDATE_CHANNEL?.trim() ?? 'dev');
}
/** 安装身份里的展示后缀:`dev` → `开发版`,`beta-2` → `Beta-2`;release 复用正式产品名。 */
export function channelDisplaySuffix(channel) {
if (channel === AGC_DEFAULT_CHANNEL) return '开发版';
return validateReleaseChannel(channel)
.split('-')
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
.join('-');
}
/**
* 渠道对应的安装身份。默认渠道保持既有 identifier 以兼容已安装客户端,
* 但展示名明确标记为开发版;release 复用正式产品名,其它渠道带展示后缀;
* 所有非默认渠道都派生独立 identifier,保证同一台设备上并存。
*/
export function resolveChannelInstallIdentity(channel = AGC_DEFAULT_CHANNEL) {
validateReleaseChannel(channel);
return Object.freeze({
productName:
channel === AGC_DEFAULT_CHANNEL
? `${AGC_PRODUCT_NAME}开发版`
: channel === 'release'
? AGC_PRODUCT_NAME
: `${AGC_PRODUCT_NAME} ${channelDisplaySuffix(channel)}`,
identifier:
channel === AGC_DEFAULT_CHANNEL
? AGC_APP_IDENTIFIER
: `${AGC_APP_IDENTIFIER}.${channel}`,
});
}
/** 渠道对应的主可执行文件名(不含平台扩展名)。 */
export function resolveChannelMainBinaryName(channel = AGC_DEFAULT_CHANNEL) {
validateReleaseChannel(channel);
return channel === AGC_DEFAULT_CHANNEL
? AGC_MAIN_BINARY_NAME
: `${AGC_MAIN_BINARY_NAME}-${channel}`;
}