Compare commits
2 Commits
73d5ef40ed
...
39b1141287
| Author | SHA1 | Date | |
|---|---|---|---|
| 39b1141287 | |||
| ace13c7047 |
@@ -30,6 +30,7 @@
|
||||
- `jenkins/Jenkinsfile.production-server-provision`
|
||||
- `jenkins/Jenkinsfile.production-database-export`
|
||||
- `jenkins/Jenkinsfile.production-database-import`
|
||||
- `jenkins/Jenkinsfile.production-notify-email`
|
||||
- `npm run build:production-release`
|
||||
|
||||
旧 Jenkins 一体化发布链对应的 Jenkinsfile 已从仓库移除,生产构建和发布入口统一切到 `jenkins/Jenkinsfile.production-*`。`scripts/deploy-rust-remote.sh` 等旧发布包脚本暂保留为历史迁移参考,不再作为生产 Jenkins Job 的入口。
|
||||
@@ -237,6 +238,7 @@ Jenkins controller 与 Linux agent 看到的 Git 服务地址不同,必须拆
|
||||
8. `Genarrative-Database-Export`
|
||||
9. `Genarrative-Database-Import`
|
||||
10. `Genarrative-Full-Build-And-Deploy`
|
||||
11. `Genarrative-Notify-Email`
|
||||
|
||||
已落地的生产流水线脚本文件:
|
||||
|
||||
@@ -250,12 +252,17 @@ Jenkins controller 与 Linux agent 看到的 Git 服务地址不同,必须拆
|
||||
- `jenkins/Jenkinsfile.production-server-provision`
|
||||
- `jenkins/Jenkinsfile.production-database-export`
|
||||
- `jenkins/Jenkinsfile.production-database-import`
|
||||
- `jenkins/Jenkinsfile.production-notify-email`
|
||||
|
||||
`Genarrative-Database-Export`、`Genarrative-Database-Import` 的生产版 Jenkinsfile 已落地;旧的数据库导入导出 Jenkinsfile 已删除,避免继续沿用旧部署目录和旧一体化发布链假设。
|
||||
|
||||
构建流水线运行在当前 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 插件。数据库导入流水线的手动上传模式使用 `stashedFile` 文件参数,因此 Jenkins 还需要安装并启用 File Parameter 插件。所有生产 Pipeline 日志必须带时间戳以便审计,Jenkins 需要安装 Timestamper 插件,并在全局配置中启用 `Enabled for all Pipeline builds`。生产发布不能退回到读取构建 workspace 本地目录的旧模式。
|
||||
发布流水线通过 Jenkins `copyArtifacts(...)` 从对应构建 Job 获取归档产物,因此 Jenkins 需要安装并启用 Copy Artifact 插件。数据库导入流水线的手动上传模式使用 `stashedFile` 文件参数,因此 Jenkins 还需要安装并启用 File Parameter 插件。所有生产 Pipeline 日志必须带时间戳以便审计,Jenkins 需要安装 Timestamper 插件,并在全局配置中启用 `Enabled for all Pipeline builds`。邮件通知流水线使用 Jenkins Pipeline `mail` step,Jenkins 需要安装/启用 Mailer 能力,并在系统配置中配置 SMTP。生产发布不能退回到读取构建 workspace 本地目录的旧模式。
|
||||
|
||||
邮件通知的持久收件人不写入 Git,由 Jenkins 全局环境变量 `GENARRATIVE_NOTIFICATION_EMAILS` 保存,多个邮箱用逗号分隔。所有生产流水线仍提供 `NOTIFICATION_EMAILS` 参数作为本次运行的追加收件人;通知 Job 会把 `GENARRATIVE_NOTIFICATION_EMAILS` 与本次 `NOTIFICATION_EMAILS` 合并去重后发送,参数留空时只发送给全局持久收件人。流水线结束时在 `post { always { ... } }` 中异步触发 `Genarrative-Notify-Email`,把来源 Job、构建号、构建 URL、结果、源码分支、源码 commit、发布版本、部署目标和数据库名传给通知 Job。通知 Job 失败不能反向改变业务流水线结果,只在来源流水线日志中记录触发失败。
|
||||
|
||||
`GENARRATIVE_NOTIFICATION_EMAILS` 在 Jenkins controller 的 `Manage Jenkins` -> `System` -> `Global properties` -> `Environment variables` 中配置,例如 `ops@example.com,dev@example.com`。SMTP 服务器在同一页面的 `E-mail Notification` 区域配置。该全局变量属于 Jenkins 持久化配置,不作为仓库文件提交。
|
||||
|
||||
所有发布流水线必须提供 `DEPLOY_TARGET` 参数,用于选择逻辑部署目标:
|
||||
|
||||
@@ -323,6 +330,8 @@ Rust 构建流水线还必须在真正执行 `cargo` 前 source `scripts/jenkins
|
||||
|
||||
`server-rs/.cargo/config.toml` 只保留 Linux release 目标的 linker/rustflags 等仓库级构建配置,不在仓库级 `config.toml` 里重定义 agent 全局镜像源。不要把这些约束写到单个 crate 的 `Cargo.toml`,因为 Cargo 不会从 crate manifest 的 `[target.x86_64-unknown-linux-gnu]` 读取构建器配置。
|
||||
|
||||
由于 `server-rs/.cargo/config.toml` 使用 `clang` 与 `-fuse-ld=lld` 构建 Linux release 目标,构建 agent 必须安装 `clang` 和 `lld`。`Genarrative-Server-Provision` 负责通过 `apt-get`、`dnf` 或 `yum` 安装 `clang`、`lld`、`pkg-config/pkgconf-pkg-config`、OpenSSL headers 与 CA 证书;API/Stdb 构建流水线在执行 Cargo 前必须检查 `clang` 与 `lld`,缺失时直接失败并提示先运行 Server-Provision。
|
||||
|
||||
`scripts/build-production-release.sh` 必须尊重 `CARGO_TARGET_DIR`,不能硬编码从 `server-rs/target/` 拷贝 Rust 产物。脚本中的产物路径应按以下口径计算:
|
||||
|
||||
```bash
|
||||
@@ -379,13 +388,13 @@ WASM_SOURCE="${CARGO_TARGET_DIR}/wasm32-unknown-unknown/release/spacetime_module
|
||||
- 安装或更新 SpacetimeDB。
|
||||
- 安装 systemd unit。
|
||||
- 可选安装 Nginx 配置和维护模式 snippet。
|
||||
- 安装 Nginx 配置时执行 `nginx -t`。
|
||||
- 安装 Nginx 配置时执行 `nginx -t`,通过后必须执行 `nginx -s reload`,确保新配置对当前 Nginx master/worker 生效。
|
||||
- 启用并启动 `spacetimedb.service` 与 `genarrative-api.service`。
|
||||
|
||||
该流水线属于高风险操作,默认要求人工确认后执行。
|
||||
已落地的 Jenkinsfile 为 `jenkins/Jenkinsfile.production-server-provision`。该流水线默认 `DRY_RUN=true`,只打印将执行的初始化动作;真正写入系统用户、目录、systemd、环境文件并启动服务时,必须设置 `DRY_RUN=false` 且勾选 `CONFIRM_PROVISION`。当 `DEPLOY_TARGET=release` 时,还必须勾选 `CONFIRM_RELEASE_DEPLOY_AGENT`,并通过 `linux && genarrative-release-deploy` 调度到独立 release 部署 agent。
|
||||
|
||||
首次真实初始化默认保持 `NGINX_CONFIG_MODE=none`,先完成系统用户、目录、SpacetimeDB、systemd unit 与 `/etc/genarrative/api-server.env` 落盘。开发服没有域名时,使用 `DEPLOY_TARGET=development` + `NGINX_CONFIG_MODE=development-http` 安装 `deploy/nginx/genarrative-dev-http.conf`,并把 `SERVER_NAME` 填为开发机 IP 或临时主机名。等正式域名确定,并且目标机已经存在 `/etc/letsencrypt/live/<SERVER_NAME>/fullchain.pem` 与 `/etc/letsencrypt/live/<SERVER_NAME>/privkey.pem` 后,再把 `SERVER_NAME` 改成真实域名,并设置 `NGINX_CONFIG_MODE=production-https` 安装 Nginx HTTPS 配置。流水线会拒绝 release 目标安装 `development-http`,也会拒绝用占位域名或缺失证书安装 `production-https`。
|
||||
首次真实初始化默认保持 `NGINX_CONFIG_MODE=none`,先完成系统用户、目录、SpacetimeDB、systemd unit 与 `/etc/genarrative/api-server.env` 落盘。开发服没有域名时,使用 `DEPLOY_TARGET=development` + `NGINX_CONFIG_MODE=development-http` 安装 `deploy/nginx/genarrative-dev-http.conf`,并把 `SERVER_NAME` 填为开发机 IP 或临时主机名。等正式域名确定,并且目标机已经存在 `/etc/letsencrypt/live/<SERVER_NAME>/fullchain.pem` 与 `/etc/letsencrypt/live/<SERVER_NAME>/privkey.pem` 后,再把 `SERVER_NAME` 改成真实域名,并设置 `NGINX_CONFIG_MODE=production-https` 安装 Nginx HTTPS 配置。流水线会拒绝 release 目标安装 `development-http`,也会拒绝用占位域名或缺失证书安装 `production-https`。Nginx 配置写入后必须先 `nginx -t`,再 `nginx -s reload`,不能只验证配置而不重载当前进程。
|
||||
|
||||
若误用占位域名执行过真实初始化,失败通常发生在 `nginx -t`,错误表现为找不到 `/etc/letsencrypt/live/genarrative.example.com/fullchain.pem` 或 `privkey.pem`。新版初始化在 `NGINX_CONFIG_MODE=none` 时会检测并禁用上一轮留下的占位域名 Nginx 配置,避免它继续影响后续 `nginx -t`。
|
||||
|
||||
@@ -450,6 +459,7 @@ WASM_SOURCE="${CARGO_TARGET_DIR}/wasm32-unknown-unknown/release/spacetime_module
|
||||
|
||||
- 先解析一次最终 `SOURCE_COMMIT`,所有下游构建和发布都使用同一个分支与 commit。
|
||||
- 并行执行 Web / API / Stdb 三条构建流水线。
|
||||
- 并行构建阶段必须开启 fail-fast:任一构建流水线失败时,立即中断其他仍在执行的并行构建分支,本次全量编排不再继续进入发布阶段。
|
||||
- 构建全部成功后,按顺序执行 Stdb publish、API deploy、Web deploy,并把同一个 `DEPLOY_TARGET` 透传给三条发布流水线。
|
||||
- 每条下游构建都只消费自己的归档产物,不直接复用别的 workspace。
|
||||
- 生产 Web 发布只处理 `web.tar.gz` 与 checksum,API 发布只处理 `api-server` 与 checksum,Stdb 发布只处理 `spacetime_module.wasm` 与 checksum。
|
||||
@@ -497,7 +507,7 @@ WASM_SOURCE="${CARGO_TARGET_DIR}/wasm32-unknown-unknown/release/spacetime_module
|
||||
`Genarrative-Full-Build-And-Deploy` 编排:
|
||||
|
||||
1. 按 `SOURCE_BRANCH` / `COMMIT_HASH` 解析一次最终 `SOURCE_COMMIT`,默认 `origin/master` 最新 commit。
|
||||
2. 并行触发 `Genarrative-Web-Build`、`Genarrative-Api-Build`、`Genarrative-Stdb-Module-Build`,三条构建都必须使用同一个 `SOURCE_BRANCH` 和 `SOURCE_COMMIT`。
|
||||
2. 并行触发 `Genarrative-Web-Build`、`Genarrative-Api-Build`、`Genarrative-Stdb-Module-Build`,三条构建都必须使用同一个 `SOURCE_BRANCH` 和 `SOURCE_COMMIT`;并行阶段开启 fail-fast,任一构建失败就中断其他仍在执行的构建分支。
|
||||
3. 三条构建全部成功后,按顺序触发 `Genarrative-Stdb-Module-Publish`、`Genarrative-Api-Deploy`、`Genarrative-Web-Deploy`,同样继续透传同一个 `SOURCE_BRANCH`、`SOURCE_COMMIT` 和 `DEPLOY_TARGET`。
|
||||
4. 最后执行生产 smoke test。
|
||||
|
||||
@@ -544,6 +554,8 @@ WASM_SOURCE="${CARGO_TARGET_DIR}/wasm32-unknown-unknown/release/spacetime_module
|
||||
- [x] 更新旧部署文档,标记旧一体化脚本为废弃或迁移对象。
|
||||
- [x] `jenkins/Jenkinsfile.production-database-export`
|
||||
- [x] `jenkins/Jenkinsfile.production-database-import`
|
||||
- [x] `jenkins/Jenkinsfile.production-notify-email`
|
||||
- [x] 所有生产流水线通过 `NOTIFICATION_EMAILS` 参数在结束时触发 `Genarrative-Notify-Email`
|
||||
|
||||
## 参考
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '源码分支,默认 master 最新提交')
|
||||
string(name: 'COMMIT_HASH', defaultValue: '', description: '可选,指定属于 SOURCE_BRANCH 的 Git commit')
|
||||
string(name: 'BUILD_VERSION', defaultValue: '', description: '发布版本号,留空则使用 Jenkins BUILD_NUMBER')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
booleanParam(name: 'PUBLISH_AFTER_BUILD', defaultValue: false, description: '构建成功后是否触发 API 发布')
|
||||
string(name: 'DEPLOY_JOB_NAME', defaultValue: 'Genarrative-Api-Deploy', description: 'API 发布流水线作业名')
|
||||
choice(name: 'DEPLOY_TARGET', choices: ['development', 'release'], description: 'PUBLISH_AFTER_BUILD=true 时的逻辑部署目标;development 使用当前 Linux 开发/构建/开发部署 agent')
|
||||
@@ -64,6 +65,10 @@ pipeline {
|
||||
set -euo pipefail
|
||||
chmod +x scripts/jenkins-prepare-cargo-env.sh
|
||||
source scripts/jenkins-prepare-cargo-env.sh
|
||||
if ! command -v clang >/dev/null 2>&1 || ! command -v lld >/dev/null 2>&1; then
|
||||
echo "[api-build] 缺少 clang/lld。请先运行 Genarrative-Server-Provision 安装 Linux 构建依赖。" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v sccache >/dev/null 2>&1; then
|
||||
echo "[api-build] 未找到 sccache,改用 rustc 直接构建。"
|
||||
unset RUSTC_WRAPPER
|
||||
@@ -93,6 +98,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH),
|
||||
string(name: 'COMMIT_HASH', value: env.SOURCE_COMMIT),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET),
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', value: params.CONFIRM_RELEASE_DEPLOY_AGENT),
|
||||
string(name: 'BUILD_JOB_NAME', value: env.JOB_NAME),
|
||||
@@ -103,6 +109,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: 'API 构建流水线结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "API 构建完成: version=${env.EFFECTIVE_BUILD_VERSION}, commit=${env.SOURCE_COMMIT}"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ pipeline {
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', defaultValue: false, description: '确认 release 目标已有独立 release 部署 agent;当前 Linux 开发/构建/开发部署 agent 不可冒充 release 部署机')
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '部署脚本来源分支')
|
||||
string(name: 'COMMIT_HASH', defaultValue: '', description: '部署脚本来源 commit;上游触发时传实际构建 commit')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
string(name: 'BUILD_VERSION', defaultValue: '', description: '待发布版本号')
|
||||
string(name: 'BUILD_JOB_NAME', defaultValue: 'Genarrative-Api-Build', description: 'API 构建流水线作业名')
|
||||
string(name: 'BUILD_NUMBER_TO_DEPLOY', defaultValue: '', description: '要复制归档产物的上游构建号')
|
||||
@@ -112,6 +113,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: 'API 发布流水线结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "API 发布完成: version=${params.BUILD_VERSION}"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ pipeline {
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', defaultValue: false, description: '确认 release 目标已有独立 release 部署 agent;当前 Linux 开发/构建/开发部署 agent 不可冒充 release 部署机')
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '导出脚本来源分支')
|
||||
string(name: 'COMMIT_HASH', defaultValue: '', description: '导出脚本来源 commit')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
string(name: 'DATABASE', defaultValue: 'genarrative-prod', description: 'SpacetimeDB database')
|
||||
string(name: 'SPACETIME_SERVER', defaultValue: 'local', description: 'SpacetimeDB server alias')
|
||||
string(name: 'SPACETIME_SERVER_URL', defaultValue: '', description: '显式 SpacetimeDB server URL,填写后优先于 SPACETIME_SERVER')
|
||||
@@ -191,6 +192,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: '数据库导出流水线结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "数据库导出完成: target=${params.DEPLOY_TARGET}, database=${params.DATABASE}, file=${env.EFFECTIVE_EXPORT_NAME}"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ pipeline {
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', defaultValue: false, description: '确认 release 目标已有独立 release 部署 agent;当前 Linux 开发/构建/开发部署 agent 不可冒充 release 部署机')
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '导入脚本来源分支')
|
||||
string(name: 'COMMIT_HASH', defaultValue: '', description: '导入脚本来源 commit')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
string(name: 'DATABASE', defaultValue: 'genarrative-prod', description: 'SpacetimeDB database')
|
||||
string(name: 'SPACETIME_SERVER', defaultValue: 'local', description: 'SpacetimeDB server alias')
|
||||
string(name: 'SPACETIME_SERVER_URL', defaultValue: '', description: '显式 SpacetimeDB server URL,填写后优先于 SPACETIME_SERVER')
|
||||
@@ -308,6 +309,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: '数据库导入流水线结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "数据库导入流水线完成: target=${params.DEPLOY_TARGET}, database=${params.DATABASE}, dryRun=${params.DRY_RUN}"
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ pipeline {
|
||||
string(name: 'COMMIT_HASH', defaultValue: '', description: '可选,指定属于 SOURCE_BRANCH 的 Git commit')
|
||||
string(name: 'BUILD_VERSION', defaultValue: '', description: '发布版本号,留空则使用 Jenkins BUILD_NUMBER')
|
||||
booleanParam(name: 'RUN_NPM_CI', defaultValue: true, description: 'Web 构建前是否执行 npm ci')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
string(name: 'WEB_BUILD_JOB_NAME', defaultValue: 'Genarrative-Web-Build', description: 'Web 构建流水线作业名')
|
||||
string(name: 'API_BUILD_JOB_NAME', defaultValue: 'Genarrative-Api-Build', description: 'API 构建流水线作业名')
|
||||
string(name: 'STDB_BUILD_JOB_NAME', defaultValue: 'Genarrative-Stdb-Module-Build', description: 'Stdb 构建流水线作业名')
|
||||
@@ -66,6 +67,8 @@ pipeline {
|
||||
}
|
||||
|
||||
stage('Build Components') {
|
||||
// 任一构建分支失败时立即中断其他并行分支,避免失败后继续消耗构建资源。
|
||||
failFast true
|
||||
parallel {
|
||||
stage('Web') {
|
||||
steps {
|
||||
@@ -77,6 +80,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH),
|
||||
string(name: 'COMMIT_HASH', value: env.SOURCE_COMMIT),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
booleanParam(name: 'RUN_NPM_CI', value: params.RUN_NPM_CI),
|
||||
]
|
||||
env.WEB_BUILD_NUMBER = webRun.number.toString()
|
||||
@@ -93,6 +97,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH),
|
||||
string(name: 'COMMIT_HASH', value: env.SOURCE_COMMIT),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
]
|
||||
env.API_BUILD_NUMBER = apiRun.number.toString()
|
||||
}
|
||||
@@ -108,6 +113,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH),
|
||||
string(name: 'COMMIT_HASH', value: env.SOURCE_COMMIT),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE),
|
||||
]
|
||||
env.STDB_BUILD_NUMBER = stdbRun.number.toString()
|
||||
@@ -126,6 +132,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH),
|
||||
string(name: 'COMMIT_HASH', value: env.SOURCE_COMMIT),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET),
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', value: params.CONFIRM_RELEASE_DEPLOY_AGENT),
|
||||
@@ -144,6 +151,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH),
|
||||
string(name: 'COMMIT_HASH', value: env.SOURCE_COMMIT),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET),
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', value: params.CONFIRM_RELEASE_DEPLOY_AGENT),
|
||||
string(name: 'BUILD_JOB_NAME', value: params.API_BUILD_JOB_NAME),
|
||||
@@ -161,6 +169,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH),
|
||||
string(name: 'COMMIT_HASH', value: env.SOURCE_COMMIT),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET),
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', value: params.CONFIRM_RELEASE_DEPLOY_AGENT),
|
||||
string(name: 'BUILD_JOB_NAME', value: params.WEB_BUILD_JOB_NAME),
|
||||
@@ -171,6 +180,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: '全量构建发布编排结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "Full Build-And-Deploy 完成: version=${env.EFFECTIVE_BUILD_VERSION}, commit=${env.SOURCE_COMMIT}"
|
||||
}
|
||||
|
||||
69
jenkins/Jenkinsfile.production-notify-email
Normal file
69
jenkins/Jenkinsfile.production-notify-email
Normal file
@@ -0,0 +1,69 @@
|
||||
pipeline {
|
||||
agent {
|
||||
label 'linux && genarrative-build'
|
||||
}
|
||||
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
skipDefaultCheckout(true)
|
||||
buildDiscarder(logRotator(numToKeepStr: '50', artifactNumToKeepStr: '0'))
|
||||
}
|
||||
|
||||
parameters {
|
||||
string(name: 'EMAIL_RECIPIENTS', defaultValue: '', description: '本次运行追加邮件通知收件人;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
string(name: 'SOURCE_JOB_NAME', defaultValue: '', description: '来源流水线名称')
|
||||
string(name: 'SOURCE_BUILD_NUMBER', defaultValue: '', description: '来源构建号')
|
||||
string(name: 'SOURCE_BUILD_URL', defaultValue: '', description: '来源构建 URL')
|
||||
string(name: 'SOURCE_RESULT', defaultValue: 'UNKNOWN', description: '来源流水线结果')
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: '', description: '源码分支')
|
||||
string(name: 'SOURCE_COMMIT', defaultValue: '', description: '源码 commit')
|
||||
string(name: 'BUILD_VERSION', defaultValue: '', description: '发布版本号')
|
||||
string(name: 'DEPLOY_TARGET', defaultValue: '', description: '部署目标')
|
||||
string(name: 'DATABASE', defaultValue: '', description: 'SpacetimeDB database')
|
||||
string(name: 'SUMMARY', defaultValue: '', description: '补充摘要')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Send Email') {
|
||||
steps {
|
||||
script {
|
||||
def recipientList = []
|
||||
[env.GENARRATIVE_NOTIFICATION_EMAILS, params.EMAIL_RECIPIENTS].each { rawRecipients ->
|
||||
rawRecipients?.split(',')?.each { recipient ->
|
||||
def normalized = recipient.trim()
|
||||
if (normalized && !recipientList.contains(normalized)) {
|
||||
recipientList.add(normalized)
|
||||
}
|
||||
}
|
||||
}
|
||||
def recipients = recipientList.join(',')
|
||||
if (!recipients) {
|
||||
echo '[notify-email] EMAIL_RECIPIENTS 与 GENARRATIVE_NOTIFICATION_EMAILS 均未配置,跳过邮件发送。'
|
||||
return
|
||||
}
|
||||
|
||||
def result = params.SOURCE_RESULT?.trim() ?: 'UNKNOWN'
|
||||
def jobName = params.SOURCE_JOB_NAME?.trim() ?: 'unknown-job'
|
||||
def buildNumber = params.SOURCE_BUILD_NUMBER?.trim() ?: 'unknown-build'
|
||||
def subject = "[Genarrative][${result}] ${jobName} #${buildNumber}"
|
||||
def body = """Genarrative Jenkins 流水线执行结果
|
||||
|
||||
结果: ${result}
|
||||
流水线: ${jobName}
|
||||
构建号: ${buildNumber}
|
||||
构建 URL: ${params.SOURCE_BUILD_URL ?: ''}
|
||||
源码分支: ${params.SOURCE_BRANCH ?: ''}
|
||||
源码 commit: ${params.SOURCE_COMMIT ?: ''}
|
||||
发布版本: ${params.BUILD_VERSION ?: ''}
|
||||
部署目标: ${params.DEPLOY_TARGET ?: ''}
|
||||
数据库: ${params.DATABASE ?: ''}
|
||||
摘要: ${params.SUMMARY ?: ''}
|
||||
"""
|
||||
|
||||
mail to: recipients, subject: subject, body: body
|
||||
echo "[notify-email] 已发送邮件: recipients=${recipients}, source=${jobName} #${buildNumber}, result=${result}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ pipeline {
|
||||
parameters {
|
||||
choice(name: 'DEPLOY_TARGET', choices: ['development', 'release'], description: '逻辑部署目标;development 使用当前 Linux 开发/构建/开发部署 agent')
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', defaultValue: false, description: '确认 release 目标已有独立 release 部署 agent')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
booleanParam(name: 'CONFIRM_PROVISION', defaultValue: false, description: '确认执行服务器初始化;未勾选时只允许 dry-run')
|
||||
booleanParam(name: 'DRY_RUN', defaultValue: true, description: '只打印将执行的服务器初始化命令,不写入系统配置')
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '部署脚本来源分支')
|
||||
@@ -123,6 +124,21 @@ pipeline {
|
||||
fi
|
||||
}
|
||||
|
||||
install_build_dependencies() {
|
||||
echo "[server-provision] 安装 Linux 构建依赖: clang, lld, pkg-config, OpenSSL headers"
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
run_cmd apt-get update
|
||||
run_cmd apt-get install -y clang lld pkg-config libssl-dev ca-certificates
|
||||
elif command -v dnf >/dev/null 2>&1; then
|
||||
run_cmd dnf install -y clang lld pkgconf-pkg-config openssl-devel ca-certificates
|
||||
elif command -v yum >/dev/null 2>&1; then
|
||||
run_cmd yum install -y clang lld pkgconf-pkg-config openssl-devel ca-certificates
|
||||
else
|
||||
echo "[server-provision] 未找到 apt-get/dnf/yum,无法自动安装 clang/lld。请手动安装后重跑构建。" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
render_nginx_https_config() {
|
||||
sed "s/genarrative.example.com/${SERVER_NAME}/g" deploy/nginx/genarrative.conf
|
||||
}
|
||||
@@ -174,6 +190,7 @@ pipeline {
|
||||
|
||||
if [[ "${DRY_RUN}" == "true" ]]; then
|
||||
echo "+ nginx -t"
|
||||
echo "+ nginx -s reload"
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -216,6 +233,8 @@ pipeline {
|
||||
rm -f "${rendered_config}" "${rendered_snippet}" "${config_backup}" "${snippet_backup}"
|
||||
exit 1
|
||||
fi
|
||||
echo "+ nginx -s reload"
|
||||
nginx -s reload
|
||||
|
||||
rm -f "${rendered_config}" "${rendered_snippet}" "${config_backup}" "${snippet_backup}"
|
||||
}
|
||||
@@ -239,6 +258,9 @@ pipeline {
|
||||
if command -v nginx >/dev/null 2>&1; then
|
||||
if ! nginx -t; then
|
||||
echo "[server-provision] 占位配置已禁用,但 nginx -t 仍失败;请检查其他 Nginx 配置。" >&2
|
||||
else
|
||||
echo "+ nginx -s reload"
|
||||
nginx -s reload
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -279,6 +301,7 @@ pipeline {
|
||||
echo "[server-provision] target=${DEPLOY_TARGET}, dry_run=${DRY_RUN}, nginx_config_mode=${NGINX_CONFIG_MODE}, source_commit=$(cat .jenkins-source-commit)"
|
||||
|
||||
run_cmd id
|
||||
install_build_dependencies
|
||||
run_cmd mkdir -p "${SPACETIME_ROOT}" "${RELEASE_ROOT}" "$(dirname "${CURRENT_LINK}")" "$(dirname "${WEB_LINK}")" /etc/genarrative /var/lib/genarrative/maintenance /var/lib/genarrative/auth
|
||||
|
||||
if ! id spacetimedb >/dev/null 2>&1; then
|
||||
@@ -350,6 +373,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: '服务器初始化流水线结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "Server provision 完成: target=${params.DEPLOY_TARGET}, dryRun=${params.DRY_RUN}, nginxConfigMode=${params.NGINX_CONFIG_MODE}"
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '源码分支,默认 master 最新提交')
|
||||
string(name: 'COMMIT_HASH', defaultValue: '', description: '可选,指定属于 SOURCE_BRANCH 的 Git commit')
|
||||
string(name: 'BUILD_VERSION', defaultValue: '', description: '发布版本号,留空则使用 Jenkins BUILD_NUMBER')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
booleanParam(name: 'PUBLISH_AFTER_BUILD', defaultValue: false, description: '构建成功后是否触发 Stdb module 发布')
|
||||
string(name: 'DEPLOY_JOB_NAME', defaultValue: 'Genarrative-Stdb-Module-Publish', description: 'Stdb module 发布流水线作业名')
|
||||
choice(name: 'DEPLOY_TARGET', choices: ['development', 'release'], description: 'PUBLISH_AFTER_BUILD=true 时的逻辑部署目标;development 使用当前 Linux 开发/构建/开发部署 agent')
|
||||
@@ -65,6 +66,10 @@ pipeline {
|
||||
set -euo pipefail
|
||||
chmod +x scripts/jenkins-prepare-cargo-env.sh
|
||||
source scripts/jenkins-prepare-cargo-env.sh
|
||||
if ! command -v clang >/dev/null 2>&1 || ! command -v lld >/dev/null 2>&1; then
|
||||
echo "[stdb-build] 缺少 clang/lld。请先运行 Genarrative-Server-Provision 安装 Linux 构建依赖。" >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v sccache >/dev/null 2>&1; then
|
||||
echo "[stdb-build] 未找到 sccache,改用 rustc 直接构建。"
|
||||
unset RUSTC_WRAPPER
|
||||
@@ -94,6 +99,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH),
|
||||
string(name: 'COMMIT_HASH', value: env.SOURCE_COMMIT),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET),
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', value: params.CONFIRM_RELEASE_DEPLOY_AGENT),
|
||||
string(name: 'BUILD_JOB_NAME', value: env.JOB_NAME),
|
||||
@@ -105,6 +111,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: 'Stdb module 构建流水线结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "Stdb module 构建完成: version=${env.EFFECTIVE_BUILD_VERSION}, commit=${env.SOURCE_COMMIT}"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ pipeline {
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', defaultValue: false, description: '确认 release 目标已有独立 release 部署 agent;当前 Linux 开发/构建/开发部署 agent 不可冒充 release 部署机')
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '部署脚本来源分支')
|
||||
string(name: 'COMMIT_HASH', defaultValue: '', description: '部署脚本来源 commit;上游触发时传实际构建 commit')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
string(name: 'BUILD_VERSION', defaultValue: '', description: '待发布版本号')
|
||||
string(name: 'BUILD_JOB_NAME', defaultValue: 'Genarrative-Stdb-Module-Build', description: 'Stdb module 构建流水线作业名')
|
||||
string(name: 'BUILD_NUMBER_TO_DEPLOY', defaultValue: '', description: '要复制归档产物的上游构建号')
|
||||
@@ -115,6 +116,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: 'Stdb module 发布流水线结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "Stdb module 发布完成: version=${params.BUILD_VERSION}, database=${params.DATABASE}"
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '源码分支,默认 master 最新提交')
|
||||
string(name: 'COMMIT_HASH', defaultValue: '', description: '可选,指定属于 SOURCE_BRANCH 的 Git commit')
|
||||
string(name: 'BUILD_VERSION', defaultValue: '', description: '发布版本号,留空则使用 Jenkins BUILD_NUMBER')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
booleanParam(name: 'RUN_NPM_CI', defaultValue: true, description: '构建前是否执行 npm ci')
|
||||
booleanParam(name: 'PUBLISH_AFTER_BUILD', defaultValue: false, description: '构建成功后是否触发 Web 发布')
|
||||
string(name: 'DEPLOY_JOB_NAME', defaultValue: 'Genarrative-Web-Deploy', description: 'Web 发布流水线作业名')
|
||||
@@ -87,6 +88,7 @@ pipeline {
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH),
|
||||
string(name: 'COMMIT_HASH', value: env.SOURCE_COMMIT),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION),
|
||||
string(name: 'NOTIFICATION_EMAILS', value: params.NOTIFICATION_EMAILS ?: ''),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET),
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', value: params.CONFIRM_RELEASE_DEPLOY_AGENT),
|
||||
string(name: 'BUILD_JOB_NAME', value: env.JOB_NAME),
|
||||
@@ -97,6 +99,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: 'Web 构建流水线结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "Web 构建完成: version=${env.EFFECTIVE_BUILD_VERSION}, commit=${env.SOURCE_COMMIT}"
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ pipeline {
|
||||
booleanParam(name: 'CONFIRM_RELEASE_DEPLOY_AGENT', defaultValue: false, description: '确认 release 目标已有独立 release 部署 agent;当前 Linux 开发/构建/开发部署 agent 不可冒充 release 部署机')
|
||||
string(name: 'SOURCE_BRANCH', defaultValue: 'master', description: '部署脚本来源分支')
|
||||
string(name: 'COMMIT_HASH', defaultValue: '', description: '部署脚本来源 commit;上游触发时传实际构建 commit')
|
||||
string(name: 'NOTIFICATION_EMAILS', defaultValue: '', description: '本次运行追加通知邮箱;会与 Jenkins 全局环境变量 GENARRATIVE_NOTIFICATION_EMAILS 合并发送')
|
||||
string(name: 'BUILD_VERSION', defaultValue: '', description: '待发布版本号')
|
||||
string(name: 'BUILD_JOB_NAME', defaultValue: 'Genarrative-Web-Build', description: 'Web 构建流水线作业名')
|
||||
string(name: 'BUILD_NUMBER_TO_DEPLOY', defaultValue: '', description: '要复制归档产物的上游构建号')
|
||||
@@ -110,6 +111,34 @@ pipeline {
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
def notificationParameters = [
|
||||
string(name: 'SOURCE_JOB_NAME', value: env.JOB_NAME),
|
||||
string(name: 'SOURCE_BUILD_NUMBER', value: env.BUILD_NUMBER),
|
||||
string(name: 'SOURCE_BUILD_URL', value: env.BUILD_URL ?: ''),
|
||||
string(name: 'SOURCE_RESULT', value: currentBuild.currentResult ?: 'UNKNOWN'),
|
||||
string(name: 'SOURCE_BRANCH', value: params.SOURCE_BRANCH ?: ''),
|
||||
string(name: 'SOURCE_COMMIT', value: env.SOURCE_COMMIT ?: (params.COMMIT_HASH ?: '')),
|
||||
string(name: 'BUILD_VERSION', value: env.EFFECTIVE_BUILD_VERSION ?: (params.BUILD_VERSION ?: '')),
|
||||
string(name: 'DEPLOY_TARGET', value: params.DEPLOY_TARGET ?: ''),
|
||||
string(name: 'DATABASE', value: params.DATABASE ?: ''),
|
||||
string(name: 'SUMMARY', value: 'Web 发布流水线结束'),
|
||||
]
|
||||
def notificationRecipients = params.NOTIFICATION_EMAILS?.trim()
|
||||
if (notificationRecipients) {
|
||||
notificationParameters.add(string(name: 'EMAIL_RECIPIENTS', value: notificationRecipients))
|
||||
}
|
||||
try {
|
||||
build job: 'Genarrative-Notify-Email',
|
||||
wait: false,
|
||||
propagate: false,
|
||||
parameters: notificationParameters
|
||||
} catch (error) {
|
||||
echo "邮件通知触发失败: ${error.message}"
|
||||
}
|
||||
}
|
||||
}
|
||||
success {
|
||||
echo "Web 发布完成: version=${params.BUILD_VERSION}"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user