Merge branch 'master' of http://82.157.175.59:3000/GenarrativeAI/Genarrative
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
2026-05-09 18:24:41 +08:00
18 changed files with 1460 additions and 118 deletions

View File

@@ -18,6 +18,8 @@ usage() {
--skip-web-build 跳过主站与后台构建,仅复制已有 dist 产物
--skip-api-build 跳过 api-server 构建,仅复制已有 release 二进制
--skip-spacetime-build 跳过 spacetime-module 构建,仅复制已有 wasm
--no-migration-bootstrap-secret
构建不带迁移引导密钥的 spacetime-module wasm
EOF
}
@@ -73,6 +75,61 @@ write_sha256_file() {
) >"${checksum_path}"
}
generate_migration_bootstrap_secret() {
node -e 'const crypto = require("crypto"); process.stdout.write(crypto.randomBytes(32).toString("hex"));'
}
prepare_migration_bootstrap_secret() {
local secret_source="generated"
if [[ "${BUILD_SPACETIME}" -ne 1 || "${SKIP_SPACETIME_BUILD}" -eq 1 ]]; then
return
fi
if [[ "${MIGRATION_BOOTSTRAP_SECRET_MODE}" == "disabled" ]]; then
unset GENARRATIVE_SPACETIME_MIGRATION_BOOTSTRAP_SECRET
echo "[production-release] 未启用迁移引导密钥。"
return
fi
if [[ -n "${GENARRATIVE_SPACETIME_MIGRATION_BOOTSTRAP_SECRET:-}" ]]; then
MIGRATION_BOOTSTRAP_SECRET="${GENARRATIVE_SPACETIME_MIGRATION_BOOTSTRAP_SECRET}"
secret_source="environment"
else
MIGRATION_BOOTSTRAP_SECRET="$(generate_migration_bootstrap_secret)"
export GENARRATIVE_SPACETIME_MIGRATION_BOOTSTRAP_SECRET="${MIGRATION_BOOTSTRAP_SECRET}"
fi
if [[ "${#MIGRATION_BOOTSTRAP_SECRET}" -lt 16 ]]; then
echo "[production-release] 迁移引导密钥至少需要 16 个字符。" >&2
exit 1
fi
echo "[production-release] 已准备迁移引导密钥: source=${secret_source}, length=${#MIGRATION_BOOTSTRAP_SECRET}"
}
write_migration_bootstrap_secret_file() {
local target_path="${TARGET_DIR}/migration-bootstrap-secret.txt"
if [[ "${BUILD_SPACETIME}" -ne 1 || "${SKIP_SPACETIME_BUILD}" -eq 1 ]]; then
return
fi
if [[ "${MIGRATION_BOOTSTRAP_SECRET_MODE}" == "disabled" ]]; then
return
fi
if [[ -z "${MIGRATION_BOOTSTRAP_SECRET}" ]]; then
echo "[production-release] 迁移引导密钥为空,无法写入发布产物。" >&2
exit 1
fi
printf "%s\n" "${MIGRATION_BOOTSTRAP_SECRET}" >"${target_path}"
chmod 600 "${target_path}" 2>/dev/null || true
MIGRATION_BOOTSTRAP_SECRET_ARTIFACT=1
echo "[production-release] 已写入迁移引导密钥文件: ${target_path}"
}
write_release_manifest() {
RELEASE_MANIFEST_PATH="${TARGET_DIR}/release-manifest.json" \
RELEASE_VERSION="${BUILD_NAME}" \
@@ -83,6 +140,7 @@ write_release_manifest() {
RELEASE_INCLUDE_WEB="${BUILD_WEB}" \
RELEASE_INCLUDE_API="${BUILD_API}" \
RELEASE_INCLUDE_SPACETIME="${BUILD_SPACETIME}" \
RELEASE_INCLUDE_MIGRATION_BOOTSTRAP_SECRET="${MIGRATION_BOOTSTRAP_SECRET_ARTIFACT}" \
node <<'NODE'
const fs = require('fs');
@@ -108,6 +166,13 @@ if (process.env.RELEASE_INCLUDE_SPACETIME === '1') {
checksum_path: 'spacetime_module.wasm.sha256',
});
}
if (process.env.RELEASE_INCLUDE_MIGRATION_BOOTSTRAP_SECRET === '1') {
artifacts.push({
component: 'spacetime-module',
path: 'migration-bootstrap-secret.txt',
sensitive: true,
});
}
const manifest = {
version: process.env.RELEASE_VERSION,
@@ -131,6 +196,9 @@ COMPONENT="all"
SKIP_WEB_BUILD=0
SKIP_API_BUILD=0
SKIP_SPACETIME_BUILD=0
MIGRATION_BOOTSTRAP_SECRET=""
MIGRATION_BOOTSTRAP_SECRET_ARTIFACT=0
MIGRATION_BOOTSTRAP_SECRET_MODE="auto"
BUILD_COMPLETED=0
while [[ $# -gt 0 ]]; do
@@ -159,6 +227,11 @@ while [[ $# -gt 0 ]]; do
SKIP_SPACETIME_BUILD=1
shift
;;
--no-migration-bootstrap-secret)
MIGRATION_BOOTSTRAP_SECRET=""
MIGRATION_BOOTSTRAP_SECRET_MODE="disabled"
shift
;;
*)
echo "[production-release] 未知参数: $1" >&2
usage >&2
@@ -262,6 +335,7 @@ mkdir -p "${TARGET_DIR}"
echo "[production-release] 发布包目录: ${TARGET_DIR}"
echo "[production-release] 构建组件: ${COMPONENT}"
prepare_migration_bootstrap_secret
if [[ "${BUILD_WEB}" -eq 1 ]]; then
mkdir -p "${WEB_DIR}"
@@ -364,6 +438,7 @@ fi
if [[ "${BUILD_SPACETIME}" -eq 1 ]]; then
copy_required_file "${WASM_SOURCE}" "${TARGET_DIR}/spacetime_module.wasm" "spacetime-module wasm"
write_sha256_file "${TARGET_DIR}/spacetime_module.wasm"
write_migration_bootstrap_secret_file
fi
mkdir -p "${TARGET_DIR}/scripts" "${TARGET_DIR}/deploy"
@@ -402,6 +477,7 @@ cat >"${TARGET_DIR}/README.md" <<EOF
- \`web.tar.gz\` / \`web.tar.gz.sha256\`Web 发布流水线使用的静态资源压缩包与校验文件。
- \`api-server\`:生产 Linux release 可执行文件。
- \`spacetime_module.wasm\`SpacetimeDB 模块 wasm。
- \`migration-bootstrap-secret.txt\`:构建 \`spacetime_module.wasm\` 时注入的迁移引导密钥,仅用于创建首个迁移操作员;请作为敏感文件保存到 Jenkins Secret Text授权完成后不要长期留在公开归档中。
- \`*.sha256\`:发布产物 checksum用于部署前校验。
- \`release-manifest.json\`:发布版本、源码 commit 与产物清单。
- \`scripts/\`:维护模式脚本、数据库导入导出脚本、迁移授权脚本和 Jenkins inbound agent systemd 安装脚本。

View File

@@ -7,6 +7,10 @@ COMMIT_HASH="${COMMIT_HASH:-}"
GIT_REMOTE_URL="${GIT_REMOTE_URL:-}"
SOURCE_COMMIT_FILE="${SOURCE_COMMIT_FILE:-.jenkins-source-commit}"
# Windows PowerShell 5.1 的 UTF-8 输出可能带 BOM下游参数校验前先剥离不可见字节。
SOURCE_BRANCH="$(printf "%s" "${SOURCE_BRANCH}" | sed $'s/^\xef\xbb\xbf//' | tr -d '\r\n')"
COMMIT_HASH="$(printf "%s" "${COMMIT_HASH}" | sed $'s/^\xef\xbb\xbf//' | tr -d '\r\n')"
if [[ ! "${SOURCE_BRANCH}" =~ ^[0-9A-Za-z._/-]+$ ]]; then
echo "[jenkins-checkout-source] SOURCE_BRANCH 只能包含数字、字母、点、下划线、短横线和斜杠: ${SOURCE_BRANCH}" >&2
exit 1