Merge pull request 'fix(jenkins): preflight node toolchain for database import/export' (#24) from master into release

Reviewed-on: #24
This commit was merged in pull request #24.
This commit is contained in:
2026-05-15 17:21:29 +08:00
5 changed files with 135 additions and 0 deletions

View File

@@ -855,3 +855,11 @@
- 处理:前端标题和选中标签从 `imageSrc` 路径末尾推导,例如 `image.png`;时间解析兼容 ISO 与 `1713686400.000000Z`;创作页主图、历史列表图和结果页参考图继续用 `ResolvedAssetImage`,提交给后端时仍保留原始 `imageSrc` - 处理:前端标题和选中标签从 `imageSrc` 路径末尾推导,例如 `image.png`;时间解析兼容 ISO 与 `1713686400.000000Z`;创作页主图、历史列表图和结果页参考图继续用 `ResolvedAssetImage`,提交给后端时仍保留原始 `imageSrc`
- 验证:`npm run test -- src/components/puzzle-agent/PuzzleAgentWorkspace.interaction.test.tsx src/components/puzzle-result/PuzzleResultView.test.tsx`,并执行 `npm run check:encoding` - 验证:`npm run test -- src/components/puzzle-agent/PuzzleAgentWorkspace.interaction.test.tsx src/components/puzzle-result/PuzzleResultView.test.tsx`,并执行 `npm run check:encoding`
- 关联:`src/services/puzzle-works/puzzleHistoryAsset.ts``src/components/puzzle-agent/PuzzleHistoryAssetPickerDialog.tsx``docs/technical/ASSET_HISTORY_PUZZLE_COVER_KIND_FIX_2026-04-27.md` - 关联:`src/services/puzzle-works/puzzleHistoryAsset.ts``src/components/puzzle-agent/PuzzleHistoryAssetPickerDialog.tsx``docs/technical/ASSET_HISTORY_PUZZLE_COVER_KIND_FIX_2026-04-27.md`
## Jenkins 数据库导入导出脚本先补 Node 工具链 PATH
- 现象:`Genarrative-Database-Import``Genarrative-Database-Export` 运行到迁移脚本时,`bash``node: command not found`,常见在日志里表现为某个 `sh` 块内第 61 行直接调用 `node` 失败。
- 原因Jenkins 的非交互 shell 没有自动加载用户的 nvm/profile数据库导入导出脚本又在 shell 里直接执行 `node scripts/spacetime-*.mjs`,因此只要 Jenkins agent 没把 Node 的 bin 目录放进 PATH就会在迁移开始前失败。
- 处理:导入 / 导出流水线在调用迁移脚本前先 `source scripts/jenkins-prepare-toolchain-env.sh`;该脚本会把 `GENARRATIVE_JENKINS_TOOL_PATHS``/var/lib/jenkins/.nvm/versions/node/v22.22.2/bin``/var/lib/jenkins/.cargo/bin``/var/lib/jenkins/.local/bin` 和系统 PATH 前缀统一补齐,并在缺少 `node` 时尽早报错。
- 验证:重新跑 `Genarrative-Database-Import``Genarrative-Database-Export`,日志应先打印 `jenkins-toolchain``node=...` 解析结果,而不是在迁移中途报 `node: command not found`
- 关联:`scripts/jenkins-prepare-toolchain-env.sh``jenkins/Jenkinsfile.production-database-import``jenkins/Jenkinsfile.production-database-export``docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`

View File

@@ -135,6 +135,7 @@ UI 相关修改要重点验证:
3. 发布目标必须显式 `--server` / `--server-url` 3. 发布目标必须显式 `--server` / `--server-url`
4. 身份问题先查 `spacetime login show``spacetime server list` 和目标库权限,不通过切回旧 Node / PostgreSQL 绕过。 4. 身份问题先查 `spacetime login show``spacetime server list` 和目标库权限,不通过切回旧 Node / PostgreSQL 绕过。
5. 旧库迁移或 private 表数据保留走 `migration.rs` 的 JSON 导入导出和分片导入思路。 5. 旧库迁移或 private 表数据保留走 `migration.rs` 的 JSON 导入导出和分片导入思路。
6. Jenkins 数据库导入 / 导出流水线会先加载 `scripts/jenkins-prepare-toolchain-env.sh`,显式补齐 Jenkins 用户的 Node、Cargo、SpacetimeDB 工具链目录;如果目标机器安装路径不同,用 `GENARRATIVE_JENKINS_TOOL_PATHS` 传入额外 `bin` 目录。
## 生产运维 ## 生产运维

View File

@@ -131,6 +131,9 @@ pipeline {
bash -lc ' bash -lc '
set -euo pipefail set -euo pipefail
chmod +x scripts/jenkins-prepare-toolchain-env.sh
source scripts/jenkins-prepare-toolchain-env.sh
chmod +x scripts/deploy/maintenance-on.sh scripts/deploy/maintenance-off.sh chmod +x scripts/deploy/maintenance-on.sh scripts/deploy/maintenance-off.sh
database="${DATABASE:?DATABASE 不能为空}" database="${DATABASE:?DATABASE 不能为空}"

View File

@@ -225,6 +225,9 @@ pipeline {
bash -lc ' bash -lc '
set -euo pipefail set -euo pipefail
chmod +x scripts/jenkins-prepare-toolchain-env.sh
source scripts/jenkins-prepare-toolchain-env.sh
chmod +x scripts/deploy/maintenance-on.sh scripts/deploy/maintenance-off.sh chmod +x scripts/deploy/maintenance-on.sh scripts/deploy/maintenance-off.sh
database="${DATABASE:?DATABASE 不能为空}" database="${DATABASE:?DATABASE 不能为空}"

View File

@@ -0,0 +1,120 @@
#!/usr/bin/env bash
set -euo pipefail
prepend_path_dir() {
local dir="$1"
if [[ -z "${dir}" || ! -d "${dir}" ]]; then
return
fi
if [[ ":${PATH}:" == *":${dir}:"* ]]; then
return
fi
export PATH="${dir}:${PATH}"
}
prepend_colon_path() {
local raw_paths="$1"
local old_ifs="${IFS}"
local -a dirs=()
local dir
IFS=':'
for dir in ${raw_paths}; do
dirs+=("${dir}")
done
IFS="${old_ifs}"
for ((index = ${#dirs[@]} - 1; index >= 0; index--)); do
prepend_path_dir "${dirs[index]}"
done
}
append_path_dir() {
local dir="$1"
if [[ -z "${dir}" || ! -d "${dir}" ]]; then
return
fi
if [[ ":${PATH}:" == *":${dir}:"* ]]; then
return
fi
export PATH="${PATH}:${dir}"
}
append_colon_path() {
local raw_paths="$1"
local old_ifs="${IFS}"
local dir
IFS=':'
for dir in ${raw_paths}; do
append_path_dir "${dir}"
done
IFS="${old_ifs}"
}
append_node_version_dirs() {
local root="$1"
local dir
if [[ ! -d "${root}" ]]; then
return
fi
for dir in "${root}"/*/bin; do
[[ -d "${dir}" ]] || continue
prepend_path_dir "${dir}"
done
}
# Jenkins 的非交互 shell 不一定加载 nvm/profile生产导入导出脚本需要显式补齐工具链目录。
append_node_version_dirs "/var/lib/jenkins/.nvm/versions/node"
append_node_version_dirs "${HOME:-}/.nvm/versions/node"
for tool_dir in \
"/var/lib/jenkins/.nvm/versions/node/v22.22.2/bin" \
"/var/lib/jenkins/.cargo/bin" \
"/var/lib/jenkins/.local/bin" \
"/var/lib/jenkins/bin" \
"${HOME:-}/.cargo/bin" \
"${HOME:-}/.local/bin" \
"/root/.cargo/bin" \
"/usr/local/cargo/bin" \
"/stdb/bin/current" \
"/usr/.local/share/spacetime/bin/current"; do
prepend_path_dir "${tool_dir}"
done
# 系统路径只做补位,避免压过 Jenkins 用户目录里的 Node/Cargo/SpacetimeDB 工具链。
append_colon_path "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
# 目标机器路径不同的时候,显式传入的路径应当拥有最高优先级。
prepend_colon_path "${GENARRATIVE_JENKINS_TOOL_PATHS:-}"
require_toolchain_command() {
local command_name="$1"
local install_hint="$2"
if command -v "${command_name}" >/dev/null 2>&1; then
echo "[jenkins-toolchain] ${command_name}=$(command -v "${command_name}")"
return
fi
echo "[jenkins-toolchain] 缺少 ${command_name}${install_hint}" >&2
echo "[jenkins-toolchain] 当前 PATH=${PATH}" >&2
exit 1
}
require_toolchain_command node "请确认 Node.js 已安装到 Jenkins 用户目录,或通过 GENARRATIVE_JENKINS_TOOL_PATHS 显式传入其 bin 目录。"
if [[ -z "${GENARRATIVE_SPACETIME_TOKEN:-}" ]]; then
require_toolchain_command spacetime "请确认 SpacetimeDB CLI 已安装到 Jenkins 用户目录,或通过 GENARRATIVE_JENKINS_TOOL_PATHS 显式传入其 bin 目录。"
else
echo "[jenkins-toolchain] 已提供 GENARRATIVE_SPACETIME_TOKEN跳过 spacetime CLI 预检"
fi