统一客户端渠道产品名称
Project CI / AI game creator shell Rust smoke (push) Successful in 1m28s
Project CI / AI game creator shell Rust crates (push) Successful in 59s
Project CI / Backend tests (push) Successful in 4m50s
Project CI / Native shell tests (push) Successful in 5m43s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 7m23s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m55s
Project CI / Frontend tests (push) Successful in 2m8s
Project CI / AI game creator shell web tests (push) Failing after 1m52s
Project CI / Repository checks (push) Successful in 2m29s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m28s
Project CI / AI game creator shell Rust crates (push) Successful in 59s
Project CI / Backend tests (push) Successful in 4m50s
Project CI / Native shell tests (push) Successful in 5m43s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 7m23s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 8m55s
Project CI / Frontend tests (push) Successful in 2m8s
Project CI / AI game creator shell web tests (push) Failing after 1m52s
Project CI / Repository checks (push) Successful in 2m29s
dev 渠道显示为陶泥儿开发版并保持既有 identifier 与升级链。 将产品名注入 Tauri、原生窗口、前端标题栏和关于页面,统一快捷方式与注册表展示来源。 补充渠道配置门禁、发布脚本测试和渠道身份文档。
This commit is contained in:
@@ -386,6 +386,9 @@ export function createChannelConfig(
|
||||
return {
|
||||
productName,
|
||||
identifier,
|
||||
app: {
|
||||
windows: [{ title: productName }],
|
||||
},
|
||||
plugins: {
|
||||
updater: {
|
||||
endpoints: [updateManifestUrl(channel, target)],
|
||||
@@ -452,6 +455,8 @@ export function runTauriBuild(
|
||||
// Vite embeds the platform API origin in the packaged renderer. The
|
||||
// release channel and updater channel therefore cannot drift apart.
|
||||
VITE_AGC_PLATFORM_CHANNEL: channel,
|
||||
VITE_AGC_PRODUCT_NAME:
|
||||
resolveChannelInstallIdentity(channel).productName,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -177,8 +177,11 @@ test('channel manifest URL and build-time endpoint follow the channel', () => {
|
||||
'https://agc-dev.oss-rg-china-mainland.aliyuncs.com/agc/dev-win/latest.json',
|
||||
);
|
||||
assert.deepEqual(createChannelConfig('dev', 'aarch64-apple-darwin'), {
|
||||
productName: AGC_PRODUCT_NAME,
|
||||
productName: `${AGC_PRODUCT_NAME}开发版`,
|
||||
identifier: AGC_APP_IDENTIFIER,
|
||||
app: {
|
||||
windows: [{ title: `${AGC_PRODUCT_NAME}开发版` }],
|
||||
},
|
||||
plugins: {
|
||||
updater: {
|
||||
endpoints: [
|
||||
@@ -202,7 +205,7 @@ test('channel manifest URL and build-time endpoint follow the channel', () => {
|
||||
test('channel install identity isolates co-installed builds and keeps the default channel stable', () => {
|
||||
// 默认渠道必须保持已发布客户端身份:改身份等于换一个 App,升级链会断。
|
||||
assert.deepEqual(resolveChannelInstallIdentity('dev'), {
|
||||
productName: AGC_PRODUCT_NAME,
|
||||
productName: `${AGC_PRODUCT_NAME}开发版`,
|
||||
identifier: AGC_APP_IDENTIFIER,
|
||||
});
|
||||
assert.deepEqual(resolveChannelInstallIdentity('release'), {
|
||||
@@ -277,6 +280,10 @@ test('packaged renderer receives the same channel as the updater manifest', () =
|
||||
},
|
||||
});
|
||||
assert.equal(spawnOptions?.env?.VITE_AGC_PLATFORM_CHANNEL, 'release');
|
||||
assert.equal(
|
||||
spawnOptions?.env?.VITE_AGC_PRODUCT_NAME,
|
||||
`${AGC_PRODUCT_NAME} Release`,
|
||||
);
|
||||
});
|
||||
|
||||
test('macOS manifests advertise exactly the architectures actually built', () => {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* 因此不同渠道的包体在同一台设备上并存时互不顶掉,也不会共享登录态、
|
||||
* 本地项目与运行锁。
|
||||
*
|
||||
* 默认渠道 `dev` 保持已发布客户端身份不变:升级链路与既有安装不能断。
|
||||
* 默认渠道 `dev` 保持已发布客户端标识不变:升级链路与既有安装不能断;展示名显式标记为开发版。
|
||||
*/
|
||||
|
||||
export const AGC_DEFAULT_CHANNEL = 'dev';
|
||||
@@ -46,8 +46,9 @@ export function resolveReleaseChannel(env = process.env) {
|
||||
return validateReleaseChannel(env.AGC_UPDATE_CHANNEL?.trim() ?? 'dev');
|
||||
}
|
||||
|
||||
/** 安装身份里的展示后缀:`release` → `Release`,`beta-2` → `Beta-2`。 */
|
||||
/** 安装身份里的展示后缀:`dev` → `开发版`,`release` → `Release`,`beta-2` → `Beta-2`。 */
|
||||
export function channelDisplaySuffix(channel) {
|
||||
if (channel === AGC_DEFAULT_CHANNEL) return '开发版';
|
||||
return validateReleaseChannel(channel)
|
||||
.split('-')
|
||||
.map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1))
|
||||
@@ -55,19 +56,19 @@ export function channelDisplaySuffix(channel) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 渠道对应的安装身份。默认渠道返回基线身份,其它渠道派生渠道后缀,
|
||||
* 保证同一台设备上不同渠道互不覆盖。
|
||||
* 渠道对应的安装身份。默认渠道保持既有 identifier 以兼容已安装客户端,
|
||||
* 但展示名明确标记为开发版;其它渠道派生独立 identifier,保证同一台设备上并存。
|
||||
*/
|
||||
export function resolveChannelInstallIdentity(channel = AGC_DEFAULT_CHANNEL) {
|
||||
validateReleaseChannel(channel);
|
||||
if (channel === AGC_DEFAULT_CHANNEL) {
|
||||
return Object.freeze({
|
||||
productName: AGC_PRODUCT_NAME,
|
||||
identifier: AGC_APP_IDENTIFIER,
|
||||
});
|
||||
}
|
||||
return Object.freeze({
|
||||
productName: `${AGC_PRODUCT_NAME} ${channelDisplaySuffix(channel)}`,
|
||||
identifier: `${AGC_APP_IDENTIFIER}.${channel}`,
|
||||
productName:
|
||||
channel === AGC_DEFAULT_CHANNEL
|
||||
? `${AGC_PRODUCT_NAME}开发版`
|
||||
: `${AGC_PRODUCT_NAME} ${channelDisplaySuffix(channel)}`,
|
||||
identifier:
|
||||
channel === AGC_DEFAULT_CHANNEL
|
||||
? AGC_APP_IDENTIFIER
|
||||
: `${AGC_APP_IDENTIFIER}.${channel}`,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ execFileSync(
|
||||
|
||||
import {
|
||||
AGC_APP_IDENTIFIER,
|
||||
AGC_PRODUCT_NAME,
|
||||
resolveChannelInstallIdentity,
|
||||
} from './channel-identity.mjs';
|
||||
import {
|
||||
@@ -1313,7 +1312,7 @@ if (
|
||||
// 基线配置必须等于默认渠道的安装身份:默认渠道不能改身份,否则已发布客户端
|
||||
// 的升级链路与既有安装目录都会断开。
|
||||
const defaultChannelIdentity = resolveChannelInstallIdentity('dev');
|
||||
if (tauriConfig.productName !== AGC_PRODUCT_NAME) {
|
||||
if (tauriConfig.productName !== defaultChannelIdentity.productName) {
|
||||
throw new Error('AI game creator shell productName drifted');
|
||||
}
|
||||
|
||||
@@ -1486,7 +1485,7 @@ if (
|
||||
!Array.isArray(tauriConfig.app?.windows) ||
|
||||
tauriConfig.app.windows.length !== 1 ||
|
||||
tauriConfig.app.windows[0]?.label !== 'client' ||
|
||||
tauriConfig.app.windows[0]?.title !== '陶泥儿' ||
|
||||
tauriConfig.app.windows[0]?.title !== defaultChannelIdentity.productName ||
|
||||
tauriConfig.app.windows[0]?.url !== 'index.html'
|
||||
) {
|
||||
throw new Error(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "陶泥儿",
|
||||
"productName": "陶泥儿开发版",
|
||||
"version": "0.1.67",
|
||||
"identifier": "world.genarrative.ai-game-creator",
|
||||
"build": {
|
||||
@@ -14,7 +14,7 @@
|
||||
"windows": [
|
||||
{
|
||||
"label": "client",
|
||||
"title": "陶泥儿",
|
||||
"title": "陶泥儿开发版",
|
||||
"url": "index.html",
|
||||
"width": 1280,
|
||||
"height": 800,
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
import appPackage from '../../package.json';
|
||||
|
||||
const DEFAULT_APP_NAME = '陶泥儿开发版';
|
||||
|
||||
/**
|
||||
* 产品名由构建期注入;本地 Vite 开发没有注入时沿用 dev 渠道产品名。
|
||||
*
|
||||
* 发布构建可通过 `VITE_AGC_PRODUCT_NAME` 注入渠道产品名,避免 UI 自己
|
||||
* 根据渠道推导名称,保证标题栏、关于页等前端展示与安装身份保持一致。
|
||||
*/
|
||||
const injectedAppName = import.meta.env.VITE_AGC_PRODUCT_NAME?.trim();
|
||||
|
||||
/** Product metadata shared by the client UI and release bundle. */
|
||||
export const APP_NAME = 'Genarrative AI Game Creator';
|
||||
export const APP_NAME = injectedAppName || DEFAULT_APP_NAME;
|
||||
export const APP_VERSION = appPackage.version;
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
} from 'react';
|
||||
|
||||
import brandIcon from '../../../../packages/shared/src/icons/taonier-product-ip.png';
|
||||
import { APP_NAME } from '../app/appMetadata';
|
||||
import { appUpdateCheckEnabled } from '../app/featureFlags';
|
||||
import { ActiveProjectRunsPanel } from '../features/app-shell/ActiveProjectRunsPanel';
|
||||
import { subscribeTauriEvent } from '../services/tauriEventSubscription';
|
||||
@@ -150,12 +151,15 @@ export function WindowChrome({ children }: WindowChromeProps) {
|
||||
{appUpdateCheckEnabled ? <AppUpdateNotice /> : null}
|
||||
<header className="window-chrome__bar" aria-label="窗口标题栏">
|
||||
<div className="window-chrome__leading">
|
||||
<div className="window-chrome__brand" aria-label="陶泥儿 GameAgent">
|
||||
<div
|
||||
className="window-chrome__brand"
|
||||
aria-label={`${APP_NAME} GameAgent`}
|
||||
>
|
||||
<span className="window-chrome__brand-mark">
|
||||
<img src={brandIcon} alt="" />
|
||||
</span>
|
||||
<span className="window-chrome__brand-copy">
|
||||
<strong>陶泥儿</strong>
|
||||
<strong>{APP_NAME}</strong>
|
||||
<span>GameAgent</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import fs from 'node:fs';
|
||||
|
||||
import { APP_VERSION } from '../../src/app/appMetadata';
|
||||
import { APP_NAME, APP_VERSION } from '../../src/app/appMetadata';
|
||||
import { repoPath } from '../repoPath';
|
||||
import {
|
||||
act,
|
||||
@@ -348,7 +348,7 @@ export function registerRuntimeSettingsTests() {
|
||||
|
||||
fireEvent.click(screen.getByRole('button', { name: /关于/ }));
|
||||
|
||||
expect(screen.getByText('Genarrative AI Game Creator')).not.toBeNull();
|
||||
expect(screen.getByText(APP_NAME)).not.toBeNull();
|
||||
expect(
|
||||
screen.getByTestId('runtime-settings-app-logo').getAttribute('src'),
|
||||
).toContain('taonier-product-ip.png');
|
||||
|
||||
@@ -47,3 +47,10 @@
|
||||
- 风险:非默认渠道首次以新身份安装,老 `dev` 用户不会自动迁移本地数据。回滚点:渠道身份只影响非默认渠道构建,撤销该渠道的构建产物即可,仓库侧无数据迁移。
|
||||
- 风险:窗口标题改为构建期产品名后,标题不再等于配置里的字面量。回滚点:去掉 `main.rs` 的标题覆盖调用,行为回到配置标题。
|
||||
- 风险:ACL managed 识别放宽到前缀族。回滚点:`is_game_creator_packaged_app_data_leaf` 收紧回单一直线值,但非默认渠道的提权修复会重新失败关闭。
|
||||
|
||||
## 2026-09-23 追加:dev 渠道展示名统一
|
||||
|
||||
- `dev` 渠道继续复用 `world.genarrative.ai-game-creator`,保证既有安装、升级链和 AppData 路径不变;展示名统一为 `陶泥儿开发版`。
|
||||
- `channel-identity.mjs` 是展示名单一来源。发布构建将同一 `productName` 同时注入 Tauri 安装配置、原生窗口标题和 `VITE_AGC_PRODUCT_NAME`;React 自绘标题栏及关于/运行时配置展示从该注入值读取。
|
||||
- 因此 Windows NSIS 默认生成的快捷方式、开始菜单/卸载注册表展示名随 Tauri `productName` 变为 `陶泥儿开发版`;未新增自定义注册表或快捷方式实现。
|
||||
- 静态 Tauri 基线配置同步为 `陶泥儿开发版`,本地壳与正式 `dev` 包的显示名保持一致。
|
||||
|
||||
Reference in New Issue
Block a user