修复AI游戏创作壳跨平台启动
修复 macOS 下 Unix 文件身份比较和临时目录测试兼容 隔离 AI 游戏创作本地数据库与发布身份并阻止旧 schema 降级启动 完善 Tauri 开发栈错误传播和 POSIX 子进程树清理 跳过 macOS 不支持的进程指标回调以消除周期告警 补充开发调度测试、技术方案和团队排障记忆
This commit is contained in:
+77
-9
@@ -1513,12 +1513,11 @@ class DevRunner {
|
||||
await this.publishSpacetimeModule();
|
||||
} catch (error) {
|
||||
if (isSpacetimePublishPermissionError(error)) {
|
||||
console.warn(
|
||||
`[dev:spacetime] 本地发布被当前 identity 拒绝,保留已启动的 standalone: ${error.message}`,
|
||||
throw new Error(
|
||||
`本地数据库不属于当前隔离 identity,已停止启动以避免 API 使用旧 schema 后持续重试订阅。请改用独立本地数据目录,或在确认无需保留旧开发数据后重建该目录。详情: ${error.message}`,
|
||||
);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1645,8 +1644,10 @@ class DevRunner {
|
||||
async publishSpacetimeModule() {
|
||||
const env = buildLocalRustProcessEnv(this.baseEnv);
|
||||
this.prepareMigrationBootstrapSecret(env);
|
||||
const cliConfigPath = await this.prepareLocalSpacetimeCliIdentity(env);
|
||||
|
||||
const args = buildSpacetimePublishArgs({
|
||||
cliConfigPath,
|
||||
database: this.options.database,
|
||||
preserveDatabase: this.options.preserveDatabase,
|
||||
server: this.state.spacetimeServer,
|
||||
@@ -1660,6 +1661,48 @@ class DevRunner {
|
||||
});
|
||||
}
|
||||
|
||||
async prepareLocalSpacetimeCliIdentity(env) {
|
||||
if (!isLoopbackSpacetimeServer(this.state.spacetimeServer)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
await this.ensureApiServerSpacetimeToken();
|
||||
const cliConfigPath = resolve(
|
||||
this.options.spacetimeDataDir,
|
||||
'dev-cli',
|
||||
'cli.toml',
|
||||
);
|
||||
ensureParentDir(cliConfigPath);
|
||||
if (
|
||||
existsSync(cliConfigPath) &&
|
||||
resolveCurrentSpacetimeCliToken(cliConfigPath) === this.spacetimeApiToken
|
||||
) {
|
||||
chmodSync(cliConfigPath, 0o600);
|
||||
console.log('[dev:spacetime] 已复用隔离的本地发布 identity');
|
||||
return cliConfigPath;
|
||||
}
|
||||
await runForeground(
|
||||
'spacetime',
|
||||
[
|
||||
'--config-path',
|
||||
cliConfigPath,
|
||||
'login',
|
||||
'--token',
|
||||
this.spacetimeApiToken,
|
||||
],
|
||||
{
|
||||
cwd: serverRsDir,
|
||||
env,
|
||||
label: 'spacetime-login',
|
||||
},
|
||||
);
|
||||
if (existsSync(cliConfigPath)) {
|
||||
chmodSync(cliConfigPath, 0o600);
|
||||
}
|
||||
console.log('[dev:spacetime] 已配置隔离的本地发布 identity');
|
||||
return cliConfigPath;
|
||||
}
|
||||
|
||||
prepareMigrationBootstrapSecret(env) {
|
||||
let runtimeServiceBootstrapSecret = '';
|
||||
switch (this.options.migrationBootstrapSecretMode) {
|
||||
@@ -2814,8 +2857,14 @@ function isLoopbackSpacetimeServer(serverUrl) {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveCurrentSpacetimeCliToken() {
|
||||
const result = spawnSync('spacetime', ['login', 'show', '--token'], {
|
||||
function resolveCurrentSpacetimeCliToken(cliConfigPath = '') {
|
||||
const args = [
|
||||
...(cliConfigPath ? ['--config-path', cliConfigPath] : []),
|
||||
'login',
|
||||
'show',
|
||||
'--token',
|
||||
];
|
||||
const result = spawnSync('spacetime', args, {
|
||||
cwd: repoRoot,
|
||||
encoding: 'utf8',
|
||||
shell: process.platform === 'win32',
|
||||
@@ -2839,13 +2888,21 @@ function trimPreview(text, maxLength = 300) {
|
||||
|
||||
function runForeground(command, args, { cwd, env, label }) {
|
||||
return new Promise((resolveRun, rejectRun) => {
|
||||
let capturedOutput = '';
|
||||
const capture = (chunk, target) => {
|
||||
target.write(chunk);
|
||||
capturedOutput = `${capturedOutput}${String(chunk)}`.slice(-32_768);
|
||||
};
|
||||
const child = spawn(command, args, {
|
||||
cwd,
|
||||
env,
|
||||
stdio: 'inherit',
|
||||
stdio: ['inherit', 'pipe', 'pipe'],
|
||||
shell: process.platform === 'win32',
|
||||
});
|
||||
|
||||
child.stdout?.on('data', (chunk) => capture(chunk, process.stdout));
|
||||
child.stderr?.on('data', (chunk) => capture(chunk, process.stderr));
|
||||
|
||||
child.on('error', rejectRun);
|
||||
child.on('exit', (code, signal) => {
|
||||
if (signal) {
|
||||
@@ -2854,7 +2911,12 @@ function runForeground(command, args, { cwd, env, label }) {
|
||||
}
|
||||
|
||||
if (code !== 0) {
|
||||
rejectRun(new Error(`[dev:${label}] 退出码: ${code}`));
|
||||
const detail = trimPreview(capturedOutput, 2_000);
|
||||
rejectRun(
|
||||
new Error(
|
||||
`[dev:${label}] 退出码: ${code}${detail ? `: ${detail}` : ''}`,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2914,8 +2976,14 @@ function isDirectModuleExecution(argv1, moduleUrl, resolvePath = safeRealpath) {
|
||||
}
|
||||
}
|
||||
|
||||
function buildSpacetimePublishArgs({ database, server, preserveDatabase }) {
|
||||
function buildSpacetimePublishArgs({
|
||||
cliConfigPath = '',
|
||||
database,
|
||||
server,
|
||||
preserveDatabase,
|
||||
}) {
|
||||
const args = [
|
||||
...(cliConfigPath ? ['--config-path', cliConfigPath] : []),
|
||||
'publish',
|
||||
database,
|
||||
'--server',
|
||||
|
||||
Reference in New Issue
Block a user