Add release web artifact rsync fallback

This commit is contained in:
2026-05-13 21:20:11 +08:00
parent 57de9a8df6
commit bf4423e53b
3 changed files with 41 additions and 2 deletions

View File

@@ -438,6 +438,14 @@
- 验证:发布链路使用当前 `deploy/systemd``deploy/nginx``scripts/deploy``jenkins/Jenkinsfile.production-*`
- 关联:`docs/technical/PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md`
## Release Web 产物通过内网 rsync 拉取
- 现象:`Genarrative-Web-Deploy` 发布到 `release` 目标时release agent 本地没有 `/var/cache/genarrative-build/web-artifacts/<job>/<build>/<version>/web.tar.gz`,但 Jenkins controller 又只归档轻量元数据,导致发布阶段找不到 Web 大包。
- 原因Web 大包为了避免从 Linux 构建机拉回 Jenkins controller默认留在构建机稳定缓存目录development 目标与构建机同机可直接读取release 目标是独立机器,需要内网同步。
- 处理release 服务器的 Jenkins 运行用户配置 SSH Host `genarrative-build-internal` 指向构建机内网地址,`Genarrative-Web-Deploy``DEPLOY_TARGET=release` 且本地缺少大包时默认执行 `rsync` 拉取同一路径内容;真实内网 IP、用户和私钥路径只放在服务器本机 SSH config不写入 Jenkinsfile。
- 验证:在 release 服务器上先手工跑通 `rsync -av --progress "genarrative-build-internal:${SRC}/" "${DST}/"`,再运行 Web Deploy流水线会继续执行 `web.tar.gz.sha256` 校验。
- 关联:`jenkins/Jenkinsfile.production-web-deploy``docs/technical/PRODUCTION_DEPLOYMENT_PLAN_2026-05-02.md`
## Jenkins 生产流水线拉 Git 先本机再域名备用
- 现象:生产发布、数据库导入导出或服务器配置流水线在目标 Linux agent 上执行 `GitSCM checkout` 时,`http://127.0.0.1:3000/GenarrativeAI/Genarrative.git` 不可达,导致脚本还没拉下来就失败;若 fallback 到公网 Git 时没有限制 refspec、浅克隆和 tags还可能在约 10 分钟后出现 `git-remote-https died of signal 15``early EOF``invalid index-pack output`

View File

@@ -324,7 +324,7 @@ Jenkins controller 与 Linux agent 看到的 Git 服务地址不同,必须拆
构建流水线运行在当前 Linux agent 的脱敏 label expression `linux && genarrative-build`。发布、导入导出和服务器配置流水线通过 `DEPLOY_TARGET` 映射到 Linux-only 脱敏部署表达式;其中 `development` 映射到当前 Linux 开发/构建/开发部署 agent 的 `linux && genarrative-build``release` 映射到独立 Linux 生产部署 agent 的 `linux && genarrative-release-deploy`,不能复用当前开发/构建/开发部署 agent。真实机器名、IP 和带 IP 的 Jenkins label 只允许留在 Jenkins 节点连接配置中,不能暴露为 Job 参数默认值、调度标签或文档推荐值。
发布流水线通过 Jenkins `copyArtifacts(...)` 从对应构建 Job 获取归档产物,因此 Jenkins 需要安装并启用 Copy Artifact 插件。Web 大包例外:`Genarrative-Web-Build` 只把轻量元数据归档到 Jenkins controller`web.tar.gz` 保留在 Linux 构建机稳定目录 `/var/cache/genarrative-build/web-artifacts/``Genarrative-Web-Deploy` 在部署目标机器上按构建 Job、构建号和版本号读取该目录。development 目标天然共享当前 Linux 开发/构建/开发部署机release 目标若不是同一台机器,必须先把该目录通过共享存储、rsync 或其它内网同步方式提供给 release 部署 agent。数据库导入流水线的手动上传模式使用 `stashedFile` 文件参数,因此 Jenkins 还需要安装并启用 File Parameter 插件。所有生产 Pipeline 日志必须带时间戳以便审计Jenkins 需要安装 Timestamper 插件,并在全局配置中启用 `Enabled for all Pipeline builds`。邮件通知流水线使用 Jenkins Pipeline `mail` stepJenkins 需要安装/启用 Mailer 能力,并在系统配置中配置 SMTP。生产发布不能退回到读取构建 workspace 本地目录的旧模式。
发布流水线通过 Jenkins `copyArtifacts(...)` 从对应构建 Job 获取归档产物,因此 Jenkins 需要安装并启用 Copy Artifact 插件。Web 大包例外:`Genarrative-Web-Build` 只把轻量元数据归档到 Jenkins controller`web.tar.gz` 保留在 Linux 构建机稳定目录 `/var/cache/genarrative-build/web-artifacts/``Genarrative-Web-Deploy` 在部署目标机器上按构建 Job、构建号和版本号读取该目录。development 目标天然共享当前 Linux 开发/构建/开发部署机release 目标若不是同一台机器,发布流水线默认在本地缓存缺少 `web.tar.gz` 时通过 `rsync` 从 SSH Host `genarrative-build-internal` 拉取同一路径内容。该 Host 必须配置在 release 服务器上 Jenkins 运行用户的 SSH config 中,真实内网 IP、用户和私钥路径只保存在服务器本机如需改名或指定 config可通过 `WEB_ARTIFACT_SYNC_HOST` / `WEB_ARTIFACT_SYNC_SSH_CONFIG` 参数覆盖。也可以提前通过共享存储或其它内网同步方式提供该目录。数据库导入流水线的手动上传模式使用 `stashedFile` 文件参数,因此 Jenkins 还需要安装并启用 File Parameter 插件。所有生产 Pipeline 日志必须带时间戳以便审计Jenkins 需要安装 Timestamper 插件,并在全局配置中启用 `Enabled for all Pipeline builds`。邮件通知流水线使用 Jenkins Pipeline `mail` stepJenkins 需要安装/启用 Mailer 能力,并在系统配置中配置 SMTP。生产发布不能退回到读取构建 workspace 本地目录的旧模式。
邮件通知的持久收件人不写入 Git由 Jenkins `Secret text` 凭据 `genarrative-notification-emails` 保存,凭据内容为逗号分隔邮箱。所有生产流水线仍提供 `NOTIFICATION_EMAILS` 参数作为本次运行的追加收件人;通知 Job 会把持久收件人凭据与本次 `NOTIFICATION_EMAILS` 合并去重后发送,参数留空时只发送给持久收件人。流水线结束时在 `post { always { ... } }` 中异步触发 `Genarrative-Notify-Email`,把来源 Job、构建号、构建 URL、结果、源码分支、源码 commit、发布版本、部署目标和数据库名传给通知 Job。通知 Job 失败不能反向改变业务流水线结果,只在来源流水线日志中记录触发失败。
@@ -483,6 +483,7 @@ WASM_SOURCE="${CARGO_TARGET_DIR}/wasm32-unknown-unknown/release/spacetime_module
- 先按 `SOURCE_BRANCH` / `COMMIT_HASH` 解析并 checkout 部署脚本源码,默认使用 `origin/master` 最新 commit上游构建触发时使用上游传入的实际构建 commit。
- 通过 Jenkins 归档获取 `web.tar.gz.sha256``release-manifest.json``web-artifact-pointer.txt`,再从 `/var/cache/genarrative-build/web-artifacts/<job>/<build>/<version>/` 读取 `web.tar.gz`;先校验 checksum再解压到 `/opt/genarrative/releases/<version>/web`
-`DEPLOY_TARGET=release` 且 release 服务器本地缓存缺少 `web.tar.gz` 时,默认先执行 `rsync -av --progress <WEB_ARTIFACT_SYNC_HOST>:/var/cache/genarrative-build/web-artifacts/<job>/<build>/<version>/ /var/cache/genarrative-build/web-artifacts/<job>/<build>/<version>/`,再继续校验 checksum默认 Host 为 `genarrative-build-internal`,由 release 服务器本机 SSH config 解析。
- 更新 `/opt/genarrative/current``/srv/genarrative/web` 指向。
- 执行 Nginx 配置测试和静态页面 smoke test。
- 不进入维护模式。

View File

@@ -25,6 +25,9 @@ pipeline {
string(name: 'RELEASE_ROOT', defaultValue: '/opt/genarrative/releases', description: '生产 release 根目录')
string(name: 'CURRENT_LINK', defaultValue: '/opt/genarrative/current', description: '当前版本软链接')
string(name: 'WEB_LINK', defaultValue: '/srv/genarrative/web', description: 'Nginx 静态站点软链接')
booleanParam(name: 'SYNC_WEB_ARTIFACT_FROM_BUILD_HOST', defaultValue: true, description: 'release 目标本地缺少 Web 大包时,是否通过 rsync 从构建机内网拉取')
string(name: 'WEB_ARTIFACT_SYNC_HOST', defaultValue: 'genarrative-build-internal', description: 'rsync 源 SSH Host通常来自 release 服务器上 Jenkins 运行用户的 ~/.ssh/config')
string(name: 'WEB_ARTIFACT_SYNC_SSH_CONFIG', defaultValue: '', description: '可选rsync 使用的 ssh config 绝对路径;留空使用当前用户默认 ~/.ssh/config')
}
stages {
@@ -109,9 +112,36 @@ pipeline {
set -euo pipefail
artifact_dir="${WEB_ARTIFACT_ROOT}/${BUILD_JOB_NAME}/${BUILD_NUMBER_TO_DEPLOY}/${BUILD_VERSION}"
if [[ ! -f "${artifact_dir}/web.tar.gz" ]]; then
sync_enabled="${SYNC_WEB_ARTIFACT_FROM_BUILD_HOST:-true}"
sync_host="${WEB_ARTIFACT_SYNC_HOST:-genarrative-build-internal}"
sync_ssh_config="${WEB_ARTIFACT_SYNC_SSH_CONFIG:-}"
if [[ "${DEPLOY_TARGET:-development}" == "release" && "${sync_enabled}" == "true" ]]; then
if [[ -z "${sync_host}" ]]; then
echo "[web-deploy] release 目标需要同步 Web 大包,但 WEB_ARTIFACT_SYNC_HOST 为空。" >&2
exit 1
fi
echo "[web-deploy] release 目标本地缓存缺少 Web 大包,尝试从 ${sync_host} 同步: ${artifact_dir}"
if ! command -v rsync >/dev/null 2>&1; then
echo "[web-deploy] 当前 release agent 缺少 rsync请先安装 rsync 或预先挂载 Web 产物目录。" >&2
exit 1
fi
mkdir -p "${artifact_dir}"
rsync_args=(-av --progress)
if [[ -n "${sync_ssh_config}" ]]; then
rsync_args+=(-e "ssh -F ${sync_ssh_config}")
fi
rsync "${rsync_args[@]}" "${sync_host}:${artifact_dir}/" "${artifact_dir}/"
fi
fi
if [[ ! -f "${artifact_dir}/web.tar.gz" ]]; then
echo "[web-deploy] 未找到构建机本地 Web 大包: ${artifact_dir}/web.tar.gz" >&2
echo "[web-deploy] development 目标要求 Web 构建与发布共享同一 Linux 构建/开发部署机release 目标需要预先同步或挂载 ${WEB_ARTIFACT_ROOT}。" >&2
echo "[web-deploy] development 目标要求 Web 构建与发布共享同一 Linux 构建/开发部署机release 目标会默认通过 rsync 从 WEB_ARTIFACT_SYNC_HOST 拉取,也可预先同步或挂载 ${WEB_ARTIFACT_ROOT}。" >&2
exit 1
fi