1
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-04-30 00:27:07 +08:00
parent 7fd900543a
commit 3bfaa303cb
5 changed files with 76 additions and 12 deletions

View File

@@ -96,7 +96,7 @@ scripts/jenkins-deploy-release.sh \
脚本语义:
1. 若部署目录已有旧版本且存在 `stop.sh`,先执行旧版本 `stop.sh`
2. 覆盖前如果旧部署目录存在 `migration-bootstrap-secret.txt`,先复制到 `run/migration-bootstrap-secret.previous.txt`,供新版本 `start.sh` 在 schema 冲突自动迁移时授权导出旧库。
2. 覆盖前如果旧部署目录存在 `migration-bootstrap-secret.txt`,先复制到 `deploy-state/migration-bootstrap-secret.previous.txt`,供新版本 `start.sh` 在 schema 冲突自动迁移时授权导出旧库。该文件属于 Jenkins 部署状态,不放入 `run/`,避免 `sudo` 启停脚本生成的 root 私有运行目录阻断后续部署写入。
3. 只删除发布产物白名单中的旧文件,例如 `web/``api-server``spacetime_module.wasm``migration-bootstrap-secret.txt``scripts/``.env*``start.sh``stop.sh``web-server.mjs``README.md`
4. 将指定版本目录中的同名发布产物复制到部署目录;文件产物使用普通复制,`web/``scripts/` 等目录产物必须递归复制。
5.`WEB_PORT``MIGRATE_ON_CONFLICT``MIGRATION_DIRECTORY` 写入部署目录 `.env.local`,确保通过 sudo 执行 `start.sh` 时仍能读取 Jenkins 参数。
@@ -105,7 +105,7 @@ scripts/jenkins-deploy-release.sh \
如果 `RUN_DEPLOY_HOOKS_WITH_SUDO=true`,旧版本 `stop.sh` 和新版本 `start.sh` 会改为 `sudo -n` 调用;这要求 Jenkins 运行用户提前配置免密 sudo否则部署会直接失败不会进入交互式密码提示。
这样可以满足“发布文件直接覆盖”的要求,同时保留部署目录里像 `.spacetimedb/``logs/``run/``database-migrations/` 这类运行态目录,不会因为部署被整体删除。发布白名单内的 `.env``.env.local` 会先以构建产物中的文件为准;部署脚本会在启动 hook 前移除这些环境文件中的 UTF-8 BOM 与 CRLF并把 Jenkins 部署参数 `WEB_PORT` 写入 `.env.local``GENARRATIVE_WEB_PORT`,把 `MIGRATE_ON_CONFLICT` 写入 `GENARRATIVE_SPACETIME_MIGRATE_ON_CONFLICT`,把 `MIGRATION_DIRECTORY` 写入 `GENARRATIVE_SPACETIME_MIGRATION_DIR`,避免 `start.sh` 在 Bash 下把首行变量名误解析成命令,也避免端口和迁移配置只停留在上游构建阶段。`start.sh` 会先执行 Ubuntu 专用 `sync_ubuntu_spacetime_install`,优先从 `/usr/.local/share/spacetime/bin/<version>/spacetimedb-cli``$HOME/.local/share/spacetime/bin/<version>/spacetimedb-cli` 同步到部署目录 `.spacetimedb/bin/current/spacetimedb-cli`,后续启动、探活和 root-dir 占用判定都使用部署目录内 `.spacetimedb/`,且不再额外设置 `--data-dir`,避免 Jenkins 机器全局 `spacetime login` 变化影响本地库更新;如遇 `403 Forbidden`,按 `SPACETIMEDB_START_SH_PUBLISH_403_IDENTITY_FIX_2026-04-26.md` 排查数据库所有者与 CLI 身份。
这样可以满足“发布文件直接覆盖”的要求,同时保留部署目录里像 `.spacetimedb/``logs/``run/``deploy-state/``database-migrations/` 这类运行态目录,不会因为部署被整体删除。`run/` 只承载 pid 等启停运行状态;`deploy-state/` 承载 Jenkins 覆盖部署前保存的旧迁移引导密钥,必须由 Jenkins 用户保持可写。发布白名单内的 `.env``.env.local` 会先以构建产物中的文件为准;部署脚本会在启动 hook 前移除这些环境文件中的 UTF-8 BOM 与 CRLF并把 Jenkins 部署参数 `WEB_PORT` 写入 `.env.local``GENARRATIVE_WEB_PORT`,把 `MIGRATE_ON_CONFLICT` 写入 `GENARRATIVE_SPACETIME_MIGRATE_ON_CONFLICT`,把 `MIGRATION_DIRECTORY` 写入 `GENARRATIVE_SPACETIME_MIGRATION_DIR`,避免 `start.sh` 在 Bash 下把首行变量名误解析成命令,也避免端口和迁移配置只停留在上游构建阶段。`start.sh` 会先执行 Ubuntu 专用 `sync_ubuntu_spacetime_install`,优先从 `/usr/.local/share/spacetime/bin/<version>/spacetimedb-cli``$HOME/.local/share/spacetime/bin/<version>/spacetimedb-cli` 同步到部署目录 `.spacetimedb/bin/current/spacetimedb-cli`,后续启动、探活和 root-dir 占用判定都使用部署目录内 `.spacetimedb/`,且不再额外设置 `--data-dir`,避免 Jenkins 机器全局 `spacetime login` 变化影响本地库更新;如遇 `403 Forbidden`,按 `SPACETIMEDB_START_SH_PUBLISH_403_IDENTITY_FIX_2026-04-26.md` 排查数据库所有者与 CLI 身份。
### 4.3 构建并部署

View File

@@ -181,7 +181,7 @@ cd build/<timestamp>
./stop.sh
```
如果后续通过 Jenkins 的部署脚本把发布包覆盖到固定部署目录,部署阶段默认只替换 `web/``api-server``spacetime_module.wasm``migration-bootstrap-secret.txt``scripts/``.env*``start.sh``stop.sh``web-server.mjs``README.md` 等发布产物;文件产物使用普通复制,`web/``scripts/` 等目录产物递归复制,不会删除部署目录中的 `.spacetimedb/``logs/``run/``database-migrations/` 这类运行态目录。
如果后续通过 Jenkins 的部署脚本把发布包覆盖到固定部署目录,部署阶段默认只替换 `web/``api-server``spacetime_module.wasm``migration-bootstrap-secret.txt``scripts/``.env*``start.sh``stop.sh``web-server.mjs``README.md` 等发布产物;文件产物使用普通复制,`web/``scripts/` 等目录产物递归复制,不会删除部署目录中的 `.spacetimedb/``logs/``run/``deploy-state/``database-migrations/` 这类运行态目录。
安全边界:
@@ -189,7 +189,7 @@ cd build/<timestamp>
2. 如果仓库根目录不存在 `.env``.env.local`,脚本会打印跳过日志,但不会因此失败;此时 `start.sh` 仅使用构建时写入的默认值与运行时显式传入的环境变量。
3. `start.sh` 只解析合法 `KEY=value` 环境行,支持不加引号、双引号和单引号;不执行复杂 shell 表达式,避免把环境文件变成脚本入口。
4. `start.sh` 默认不追加清理参数;普通发布如果遇到 SpacetimeDB schema 冲突,会调用发布包内的 `scripts/spacetime-export-migration-json.mjs` 导出旧库,再清库发布新 wasm并调用 `scripts/spacetime-import-migration-json.mjs --replace-existing` 回灌。可通过 `GENARRATIVE_SPACETIME_MIGRATE_ON_CONFLICT=false` 禁用该行为。
5. 自动迁移导出旧库时优先读取 `run/migration-bootstrap-secret.previous.txt`,导入新库时读取当前发布包 `migration-bootstrap-secret.txt`Jenkins 部署脚本会在覆盖发布包前保存旧密钥。手工覆盖发布包时,也应在覆盖前保留旧模块的引导密钥,否则旧库导出可能无法授权。
5. 自动迁移导出旧库时优先读取 `deploy-state/migration-bootstrap-secret.previous.txt`,导入新库时读取当前发布包 `migration-bootstrap-secret.txt`Jenkins 部署脚本会在覆盖发布包前保存旧密钥。该快照属于部署状态,不放入 `run/`,避免启停 hook 通过 `sudo` 运行后把部署阶段要写的文件变成 root 私有。手工覆盖发布包时,也应在覆盖前保留旧模块的引导密钥,否则旧库导出可能无法授权。
6. 自动迁移 JSON 默认写入发布目录下 `database-migrations/<database>/`;可通过 `GENARRATIVE_SPACETIME_MIGRATION_DIR` 改写。该目录属于运行态,不应被 Jenkins 覆盖部署删除。
7. 只有显式执行 `./start.sh --clear-database` 才追加 `-c=on-conflict`,该模式代表人工确认清库,不执行导出和回灌。
8. `start.sh` 会先复用已经按目标地址就绪的 SpacetimeDB如果同一个 `.spacetimedb/` root-dir 已被其他未就绪实例占用,则只输出命令名为 `spacetime``spacetimedb-cli` 且命令行包含当前 root-dir 的真实占用进程并失败,避免把排查用的 `grep` / `awk` 误判为 SpacetimeDB 实例。

View File

@@ -156,7 +156,7 @@ npm run spacetime:publish:maincloud -- --database xushi-p4wfr
Ubuntu 发布包的 `start.sh` 与 Jenkins `Genarrative-Deploy` 也采用同一套迁移 procedure但迁移触发点在部署目录内
1. Jenkins 覆盖部署前,如果旧部署目录存在 `migration-bootstrap-secret.txt`,先保存到 `run/migration-bootstrap-secret.previous.txt`
1. Jenkins 覆盖部署前,如果旧部署目录存在 `migration-bootstrap-secret.txt`,先保存到 `deploy-state/migration-bootstrap-secret.previous.txt`旧密钥快照属于部署状态,不再写入 `run/`,避免 `sudo` 启停脚本生成的 root 私有运行目录阻断后续覆盖部署。
2. Jenkins 复制新发布包,包含新 wasm、新 `migration-bootstrap-secret.txt``scripts/spacetime-*.mjs` 迁移脚本。
3.`start.sh` 先不清库发布当前包内 `spacetime_module.wasm`
4. 如果发布成功,流程结束。
@@ -172,7 +172,7 @@ Jenkins 参数 `CLEAR_DATABASE=true` 或手工执行 `./start.sh --clear-databas
自动迁移依赖两个引导密钥:
- 导出旧库:优先使用 `run/migration-bootstrap-secret.previous.txt`,也就是旧模块编译时注入的密钥。
- 导出旧库:优先使用 `deploy-state/migration-bootstrap-secret.previous.txt`,也就是旧模块编译时注入的密钥。
- 导入新库:使用当前发布包 `migration-bootstrap-secret.txt`,也就是新模块编译时注入的密钥。
如果不是通过 Jenkins 部署脚本覆盖发布包,而是手工替换文件,必须在覆盖前保留旧 `migration-bootstrap-secret.txt`;否则旧库迁移 procedure 可能无法授权导出。