chore: checkpoint local workspace changes
This commit is contained in:
@@ -484,6 +484,10 @@ API_LOG="${GENARRATIVE_API_LOG:-info,tower_http=info}"
|
||||
WEB_HOST="${GENARRATIVE_WEB_HOST:-__GENARRATIVE_DEFAULT_WEB_HOST__}"
|
||||
WEB_PORT="${GENARRATIVE_WEB_PORT:-__GENARRATIVE_DEFAULT_WEB_PORT__}"
|
||||
|
||||
# 日志默认落文件,显式关闭 ANSI 颜色码,避免控制字符写入 *.log。
|
||||
export NO_COLOR="${NO_COLOR:-1}"
|
||||
export CARGO_TERM_COLOR="${CARGO_TERM_COLOR:-never}"
|
||||
|
||||
require_command() {
|
||||
local command_name="$1"
|
||||
|
||||
@@ -651,6 +655,7 @@ cat >"${TARGET_DIR}/README.md" <<EOF
|
||||
|
||||
- 启动时会先加载发布目录根部的 \`.env\` 与 \`.env.local\`,再回退到脚本内默认值。
|
||||
- 脚本内默认值来自构建时的 `--database`、`--api-port`、`--web-port`、`--spacetime-host`、`--spacetime-port` 参数。
|
||||
- 默认导出 \`NO_COLOR=1\` 与 \`CARGO_TERM_COLOR=never\`,避免 ANSI 颜色控制码写入日志文件;如确有需要可在启动前显式覆盖。
|
||||
- \`GENARRATIVE_WEB_HOST\` / \`GENARRATIVE_WEB_PORT\`
|
||||
- \`GENARRATIVE_API_HOST\` / \`GENARRATIVE_API_PORT\` / \`GENARRATIVE_API_LOG\`
|
||||
- \`GENARRATIVE_SPACETIME_HOST\` / \`GENARRATIVE_SPACETIME_PORT\`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {spawn} from 'node:child_process';
|
||||
import {spawn, spawnSync} from 'node:child_process';
|
||||
import {existsSync, readFileSync} from 'node:fs';
|
||||
import net from 'node:net';
|
||||
import path from 'node:path';
|
||||
@@ -33,6 +33,14 @@ const DEFAULT_RUST_API_PORT = '3100';
|
||||
const DEFAULT_SPACETIME_SERVER_URL = 'http://127.0.0.1:3001';
|
||||
const DEFAULT_SPACETIME_DATABASE = 'genarrative-dev';
|
||||
const DEFAULT_INTERNAL_API_SECRET = 'genarrative-dev-internal-bridge';
|
||||
const spacetimeModulePath = path.join(serverRsRoot, 'crates', 'spacetime-module');
|
||||
const spacetimeRustBindingsOutDir = path.join(
|
||||
serverRsRoot,
|
||||
'crates',
|
||||
'spacetime-client',
|
||||
'src',
|
||||
'module_bindings',
|
||||
);
|
||||
|
||||
function parseEnvContents(contents) {
|
||||
return contents
|
||||
@@ -195,6 +203,98 @@ function prependEnvPath(envMap, nextEntry) {
|
||||
envMap[pathKey] = [nextEntry, ...segments].join(path.delimiter);
|
||||
}
|
||||
|
||||
function resolveSpacetimeCommand() {
|
||||
const command = process.platform === 'win32' ? 'where' : 'which';
|
||||
const result = spawnSync(command, ['spacetime'], {
|
||||
cwd: repoRoot,
|
||||
env: mergedEnv,
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
});
|
||||
|
||||
if (result.status !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const firstLine = `${result.stdout || ''}`
|
||||
.split(/\r?\n/u)
|
||||
.map((line) => line.trim())
|
||||
.find(Boolean);
|
||||
|
||||
return firstLine || 'spacetime';
|
||||
}
|
||||
|
||||
function runRequiredCommand(command, args, label) {
|
||||
const result = spawnSync(command, args, {
|
||||
cwd: repoRoot,
|
||||
env: mergedEnv,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
if (result.status !== 0) {
|
||||
console.error(`[dev:node] ${label} failed with exit code ${result.status ?? 1}`);
|
||||
process.exit(result.status ?? 1);
|
||||
}
|
||||
}
|
||||
|
||||
function ensureSpacetimeSchemaReady() {
|
||||
const spacetimeCommand = resolveSpacetimeCommand();
|
||||
if (!spacetimeCommand) {
|
||||
console.error(
|
||||
'[dev:node] Missing `spacetime` CLI. Install or expose it in PATH before starting local dev.',
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const spacetimeServerUrl = `${mergedEnv.GENARRATIVE_SPACETIME_SERVER_URL || ''}`.trim();
|
||||
const spacetimeDatabase = `${mergedEnv.GENARRATIVE_SPACETIME_DATABASE || ''}`.trim();
|
||||
|
||||
if (!spacetimeServerUrl || !spacetimeDatabase) {
|
||||
console.error(
|
||||
'[dev:node] Missing GENARRATIVE_SPACETIME_SERVER_URL or GENARRATIVE_SPACETIME_DATABASE, cannot publish local schema.',
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[dev:node] Publishing spacetime-module to ${spacetimeDatabase} (${spacetimeServerUrl}) before Rust api-server starts...`,
|
||||
);
|
||||
runRequiredCommand(
|
||||
spacetimeCommand,
|
||||
[
|
||||
'publish',
|
||||
spacetimeDatabase,
|
||||
'--server',
|
||||
spacetimeServerUrl,
|
||||
'--module-path',
|
||||
spacetimeModulePath,
|
||||
'--yes',
|
||||
...(mergedEnv.GENARRATIVE_SPACETIME_DELETE_DATA_ON_CONFLICT === '1'
|
||||
? ['--delete-data=on-conflict']
|
||||
: []),
|
||||
],
|
||||
'spacetime publish',
|
||||
);
|
||||
|
||||
console.log('[dev:node] Generating Rust Spacetime bindings before Rust api-server starts...');
|
||||
runRequiredCommand(
|
||||
spacetimeCommand,
|
||||
[
|
||||
'generate',
|
||||
'--no-config',
|
||||
'--lang',
|
||||
'rust',
|
||||
'--out-dir',
|
||||
spacetimeRustBindingsOutDir,
|
||||
'--module-path',
|
||||
spacetimeModulePath,
|
||||
'--include-private',
|
||||
'--yes',
|
||||
],
|
||||
'spacetime generate (rust)',
|
||||
);
|
||||
}
|
||||
|
||||
const exampleEnv = readEnvFile(envExamplePath);
|
||||
const localEnv = readEnvFile(envLocalPath);
|
||||
const spacetimeConfig = readJsonFile(spacetimeConfigPath);
|
||||
@@ -292,6 +392,8 @@ console.log(`[dev:node] DATABASE_URL=${redactDatabaseUrl(mergedEnv.DATABASE_URL)
|
||||
console.log(`[dev:node] VITE_DEV_HOST=${mergedEnv.VITE_DEV_HOST}`);
|
||||
console.log(`[dev:node] NODE_RUNTIME=${runtimeNodePath}`);
|
||||
|
||||
ensureSpacetimeSchemaReady();
|
||||
|
||||
const children = new Set();
|
||||
let shuttingDown = false;
|
||||
let pendingExitCode = 0;
|
||||
|
||||
@@ -9,8 +9,8 @@ usage() {
|
||||
|
||||
说明:
|
||||
1. 如果部署目录已有旧版本且存在 stop.sh,则先执行旧版本 stop.sh。
|
||||
2. 直接清空部署目录中的全部旧文件。
|
||||
3. 把指定发布目录中的内容移动到部署目录。
|
||||
2. 仅删除并替换发布产物文件,保留部署目录中的运行数据目录。
|
||||
3. 把指定发布目录中的内容覆盖到部署目录。
|
||||
4. 最后执行新版本 start.sh。
|
||||
|
||||
参数:
|
||||
@@ -33,6 +33,17 @@ require_argument() {
|
||||
SOURCE_DIR=""
|
||||
DEPLOY_DIR=""
|
||||
HOOK_WITH_SUDO="0"
|
||||
DEPLOY_ITEMS=(
|
||||
".env"
|
||||
".env.local"
|
||||
"README.md"
|
||||
"api-server"
|
||||
"spacetime_module.wasm"
|
||||
"start.sh"
|
||||
"stop.sh"
|
||||
"web"
|
||||
"web-server.mjs"
|
||||
)
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
@@ -114,10 +125,20 @@ else
|
||||
fi
|
||||
|
||||
echo "[jenkins-deploy] 清空部署目录: ${DEPLOY_DIR}"
|
||||
find "${DEPLOY_DIR}" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
|
||||
for item in "${DEPLOY_ITEMS[@]}"; do
|
||||
if [[ -e "${DEPLOY_DIR}/${item}" ]]; then
|
||||
echo "[jenkins-deploy] 删除旧产物: ${DEPLOY_DIR}/${item}"
|
||||
rm -rf "${DEPLOY_DIR:?}/${item}"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "[jenkins-deploy] 移动发布内容: ${SOURCE_DIR} -> ${DEPLOY_DIR}"
|
||||
find "${SOURCE_DIR}" -mindepth 1 -maxdepth 1 -exec mv {} "${DEPLOY_DIR}/" \;
|
||||
for item in "${DEPLOY_ITEMS[@]}"; do
|
||||
if [[ -e "${SOURCE_DIR}/${item}" ]]; then
|
||||
echo "[jenkins-deploy] 覆盖产物: ${item}"
|
||||
mv "${SOURCE_DIR}/${item}" "${DEPLOY_DIR}/"
|
||||
fi
|
||||
done
|
||||
|
||||
chmod +x "${DEPLOY_DIR}/start.sh"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user