添加jenkins配置脚本

This commit is contained in:
2026-04-23 02:19:23 +08:00
parent e071f03b3d
commit ad0ded5e58
6 changed files with 506 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
# Jenkins Rust 构建与部署流水线方案
日期:`2026-04-23`
## 1. 目标
本方案为当前仓库补齐 3 条 Jenkins 流水线:
1. `构建`:只负责在仓库根目录执行 `npm run deploy:rust:remote -- --skip-upload`,生成发布包。
2. `部署`:只负责把指定发布版本部署到 `/home/ubuntu/Genarrative-deploy/`,禁止人工直接点击执行。
3. `构建并部署`:先构建,再把构建出的版本号传给 `部署` 流水线并等待部署完成。
本次只补 Jenkins 编排与本地部署脚本,不改现有 Rust 发布包构建逻辑,不恢复旧 `server-node` 部署链。
## 2. 执行约束
1. 构建产物目录统一使用 `build/<版本号>/`
2. 默认使用 Jenkins `BUILD_NUMBER` 作为版本号,避免依赖时间戳;如有需要也允许显式传 `BUILD_VERSION`
3. `部署` 流水线必须校验当前构建原因包含 `UpstreamCause`,没有上游触发则直接失败。
4. `部署` 流水线额外校验上游作业名与传入的 `EXPECTED_UPSTREAM_JOB` 一致;如配置了环境变量 `GENARRATIVE_ALLOWED_UPSTREAM_JOB`,还必须与该值一致。
5. `构建并部署` 在触发 `部署` 前先释放自己的构建节点,避免单执行器节点出现死锁。
6. `部署` 不重新构建,不重新上传,不从 Jenkins 插件仓库复制产物,直接使用上游构建节点的本地 `build/<版本号>/` 目录。
## 3. 节点与工作区要求
这套方案依赖“本地目录发布”,因此有两个前提:
1. `构建并部署``部署` 必须落到同一台 Ubuntu Jenkins Agent或者落到同一块共享文件系统。
2. `构建并部署` 触发 `部署` 时,必须把 `SOURCE_NODE_NAME``SOURCE_WORKSPACE_ROOT` 一并传下去。
仓库中提供的 Jenkinsfile 已按这个约束实现:
1. `构建` / `构建并部署` 在指定源码目录内 `checkout scm` 并生成 `build/<版本号>/`
2. `构建并部署` 结束构建节点占用后,再触发 `部署`
3. `部署` 优先按 `SOURCE_NODE_NAME` 调度到同名节点,再读取 `SOURCE_WORKSPACE_ROOT/build/<版本号>/`
## 4. 三条流水线定义
### 4.1 构建
脚本路径:
```text
jenkins/Jenkinsfile.build
```
核心流程:
1. 可选执行 `npm ci`
2. 在源码根目录执行:
```bash
npm run deploy:rust:remote -- --skip-upload --name <BUILD_VERSION>
```
3. 校验 `build/<BUILD_VERSION>/` 存在。
4. 归档 `build/<BUILD_VERSION>/**` 作为 Jenkins 产物。
默认版本号:
```text
BUILD_VERSION = Jenkins BUILD_NUMBER
```
### 4.2 部署
脚本路径:
```text
jenkins/Jenkinsfile.deploy
```
核心流程:
1. 校验触发原因必须是上游流水线,而不是人工点击。
2. 校验 `BUILD_VERSION``SOURCE_WORKSPACE_ROOT``DEPLOY_DIRECTORY` 非空。
3. 执行:
```bash
scripts/jenkins-deploy-release.sh \
--source-dir <SOURCE_WORKSPACE_ROOT>/build/<BUILD_VERSION> \
--deploy-dir /home/ubuntu/Genarrative-deploy
```
脚本语义:
1. 若部署目录已有旧版本且存在 `stop.sh`,先执行旧版本 `stop.sh`
2. 直接清空部署目录中的全部旧文件。
3. 将指定版本目录中的内容移动到部署目录。
4. 执行新版本 `start.sh`
这样可以满足你要求的“直接覆盖部署目录中的所有文件”。同时这也意味着部署目录内原有的 `.env``.env.local`、日志和本地 SpacetimeDB 数据都会被清掉,最终以构建产物中的文件为准。
### 4.3 构建并部署
脚本路径:
```text
jenkins/Jenkinsfile.build-and-deploy
```
核心流程:
1. 复用与 `构建` 相同的构建命令生成 `build/<BUILD_VERSION>/`
2. 归档 `build/<BUILD_VERSION>/**`
3. 记录当前 `NODE_NAME`、源码根目录、版本号。
4. 触发 `部署` 流水线,并传递:
- `BUILD_VERSION`
- `SOURCE_WORKSPACE_ROOT`
- `SOURCE_NODE_NAME`
- `DEPLOY_DIRECTORY`
- `EXPECTED_UPSTREAM_JOB`
## 5. Jenkins 参数建议
三条流水线统一建议暴露以下参数:
1. `AGENT_LABEL`:默认执行节点标签。
2. `GENARRATIVE_WORKSPACE_ROOT`:源码根目录;为空时回退到 Jenkins 当前工作区。
3. `BUILD_VERSION`:发布版本号;为空时回退到 `BUILD_NUMBER`
4. `RUN_NPM_CI`:是否在构建前执行 `npm ci`
其中仅 `部署` 流水线还需要:
1. `SOURCE_WORKSPACE_ROOT`
2. `SOURCE_NODE_NAME`
3. `DEPLOY_DIRECTORY`
4. `EXPECTED_UPSTREAM_JOB`
其中仅 `构建并部署` 流水线还需要:
1. `DEPLOY_JOB_NAME`
## 6. 推荐 Job 命名
建议在 Jenkins 中创建以下 3 个 Pipeline Job并分别指向仓库中的脚本路径
1. `Genarrative-Build` -> `jenkins/Jenkinsfile.build`
2. `Genarrative-Deploy` -> `jenkins/Jenkinsfile.deploy`
3. `Genarrative-Build-And-Deploy` -> `jenkins/Jenkinsfile.build-and-deploy`
同时给 `Genarrative-Deploy` 配置环境变量:
```text
GENARRATIVE_ALLOWED_UPSTREAM_JOB=Genarrative-Build-And-Deploy
```
如果 Job 在 Jenkins Folder 下,值应填写完整上游作业名,例如:
```text
game/Genarrative-Build-And-Deploy
```
## 7. 文件清单
本方案对应的仓库文件:
```text
jenkins/Jenkinsfile.build
jenkins/Jenkinsfile.deploy
jenkins/Jenkinsfile.build-and-deploy
scripts/jenkins-deploy-release.sh
```
## 8. 风险与边界
1. 该方案依赖本地目录切换,不适用于“构建节点”和“部署节点”完全隔离且不共享文件系统的 Jenkins 架构。
2. 当前 `部署` 采取的是“覆盖固定部署目录”的方式,不包含版本回滚目录管理;如需保留完整历史版本,应在后续单独补一层 release/current 软链接结构。
3. 当前 `start.sh` / `stop.sh` 仍以发布包内脚本为准,不替代 `systemd``supervisor``nginx``tls` 与日志轮转治理。