diff --git a/测试环境Jenkins部署指南.md b/测试环境Jenkins部署指南.md index 54c44ff..f42cfb1 100644 --- a/测试环境Jenkins部署指南.md +++ b/测试环境Jenkins部署指南.md @@ -1,6 +1,6 @@ # 测试环境 Jenkins 部署指南 -> 最后核对:2026-08-11 +> 最后核对:2026-08-25 > > 本文供 Codex 对话和项目维护人员部署虫虫出海测试环境使用。只适用于测试环境,不适用于预发布或生产。 > @@ -19,7 +19,7 @@ 此授权不包含以下操作;遇到时必须单独取得用户明确确认: - 部署 `staging` 或 `production`。 -- 勾选 `INITIALIZE_TEST_DATABASE`,或执行任何数据库写入、迁移、初始化和测试数据修改。 +- 执行任何数据库写入、迁移、初始化和测试数据修改。 - 勾选 `SKIP_TESTS`。 - 无法明确影响范围时执行后端 `ALL` 全量部署。 - 修改 Jenkins Job、Credentials、节点、插件、权限或系统配置。 @@ -31,20 +31,117 @@ | 项目 | 地址或标识 | |---|---| -| Jenkins | `http://8.163.30.128:14808/` | -| Jenkins 用户 | `admin` | -| Jenkins 密码 | `DR22R71Nym7Smse1` | -| 测试 Gateway | `http://8.163.30.128:9000` | -| Admin Web | `http://8.163.30.128:9001` | -| Client Web | `http://8.163.30.128:9002` | +| Jenkins | 本机未提交环境变量 `JENKINS_URL`;使用已配置的 HTTPS 反向代理地址 | +| Jenkins 用户 | 本机未提交环境变量 `JENKINS_USER` | +| Jenkins API Token | 本机未提交环境变量 `JENKINS_API_TOKEN`;禁止使用账号密码代替 | +| 测试 Gateway | 本机未提交环境变量 `TEST_GATEWAY_URL` | +| Admin Web | 本机未提交环境变量 `TEST_ADMIN_WEB_URL` | +| Client Web | 本机未提交环境变量 `TEST_CLIENT_WEB_URL` | | 后端 Git 分支 | `test` | | Admin/Client Git 分支 | `release/test` | -上述 Jenkins 账号和密码是当前开发阶段临时记录的测试环境凭据。只有当前对话已明确授权 Codex 部署时才可使用;未授权时不得登录后触发构建。测试账号调整或正式交付前必须从本文删除并轮换密码;不得继续复制到源码、脚本、命令行历史、日志或交付说明。已获部署授权时优先复用已登录的受控浏览器会话,没有登录会话时才使用本文凭据。 +Jenkins 用户在个人“安全”页面生成独立 API Token。Token 只保存到本机密钥管理或未提交环境文件,不得写入仓库、命令示例、聊天记录、构建参数、日志或 Jenkinsfile。旧版明文密码调用方式已停用;历史上曾写入文档的密码必须视为泄露并完成轮换。 + +只有当前对话已明确授权 Codex 部署时才可使用 API;未授权时不得通过浏览器或 API 触发构建。已获部署授权时优先使用 API Token 调用,不复用浏览器 Cookie。API 用户只授予读取目标 Job、触发构建和读取构建结果所需的最小权限,不授予 Job 配置、Credentials、节点、插件或系统管理权限。 Jenkins 页面会显示“系统管理”“新建任务”“配置”“删除 Pipeline”等管理入口。即使当前账号具有管理权限,也只能执行本任务所需的构建和只读检查。 -## 3. Job 与部署单元 +## 3. Jenkins HTTP API 调用 + +Jenkins Remote Access API 可以触发构建、读取队列、查询构建状态和获取控制台日志。API 只是人工点击的等价入口,不扩大第 1 节的授权范围,也不允许绕过部署前检查、参数门禁或部署后验收。 + +实现依据以 Jenkins 官方 [Remote Access API](https://www.jenkins.io/doc/book/using/remote-access-api/) 和 [CSRF Protection](https://www.jenkins.io/doc/book/security/csrf-protection/) 文档为准。 + +### 3.1 本机认证准备 + +以下变量只在当前受控终端设置,示例值必须替换为实际反向代理地址、用户和 API Token,不写入任何受版本控制文件: + +```bash +export JENKINS_URL='https://jenkins.example.com' +export JENKINS_USER='jenkins-api-user' +export JENKINS_API_TOKEN='replace-with-local-secret' +``` + +先做只读连通性检查: + +```bash +curl --fail --silent --show-error \ + --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ + "${JENKINS_URL%/}/api/json?tree=nodeName,mode" +``` + +使用 API Token 的认证请求不需要 CSRF Crumb;不得关闭 Jenkins CSRF 防护。若仍返回 401/403,先检查 Token、用户权限和反向代理是否保留 `Authorization` 头,不要改用明文密码。只有遗留的用户名/密码脚本才需要同时维护 Cookie 与 `/crumbIssuer/api/json` 返回的 Crumb,本项目不再采用该方式。 + +### 3.2 触发无参数前端 Job + +```bash +curl --fail-with-body --silent --show-error \ + --request POST \ + --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ + --dump-header admin-web-test.headers \ + --output /dev/null \ + "${JENKINS_URL%/}/job/admin-web-test/build" +``` + +Client 将 Job 路径改为 `/job/client-web-test/build`。成功响应通常是 HTTP 201/302,并在 `Location` 响应头返回队列条目 URL。临时响应头文件使用后立即删除,不得提交。 + +### 3.3 触发参数化后端 Job + +以下示例只部署测试环境的 `gateway-overseas` 与 `lastleg-service`;实际调用必须按本次授权修改服务范围: + +```bash +curl --fail-with-body --silent --show-error \ + --request POST \ + --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ + --dump-header backend-java.headers \ + --output /dev/null \ + --data-urlencode 'BUILD_MODE=SELECT' \ + --data-urlencode 'SERVICE_GATEWAY_OVERSEAS=true' \ + --data-urlencode 'SERVICE_LASTLEG=true' \ + --data-urlencode 'ENVIRONMENT=test' \ + --data-urlencode 'DEPLOY=true' \ + --data-urlencode 'SKIP_TESTS=false' \ + --data-urlencode 'EVENT_BRIDGE_REGION=BOTH' \ + --data-urlencode 'DOWNSTREAM_JOB_PREFIX=baiyue-firstleg-' \ + "${JENKINS_URL%/}/job/backend-java/buildWithParameters" +``` + +没有明确选择的 `SERVICE_*` 参数保持 Job 默认 `false`,不要为了省事传 `ALL`。调用前应从 `${JENKINS_URL%/}/job/backend-java/api/json` 核对当前 Job 参数定义;参数发生变化时先更新本文,禁止让调用脚本静默依赖过期默认值。 + +### 3.4 跟踪队列与构建结果 + +从触发响应的 `Location` 头取得 `QUEUE_URL`,轮询队列,直到出现 `executable.url`: + +```bash +QUEUE_URL="$(awk 'BEGIN{IGNORECASE=1} /^Location:/{gsub("\\r",""); print $2}' backend-java.headers)" +curl --fail --silent --show-error \ + --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ + "${QUEUE_URL%/}/api/json?tree=id,why,cancelled,executable[number,url]" +``` + +取得返回中的 `executable.url` 后,用它作为 `BUILD_URL` 查询终态和日志: + +```bash +curl --fail --silent --show-error \ + --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ + "${BUILD_URL%/}/api/json?tree=number,building,result,url,duration,estimatedDuration" + +curl --fail --silent --show-error \ + --user "$JENKINS_USER:$JENKINS_API_TOKEN" \ + "${BUILD_URL%/}/consoleText" +``` + +只有 `building=false` 且 `result=SUCCESS` 才算 Job 成功。后端总控还必须核对每个下游 Job 结果;HTTP POST 成功、进入队列或拿到构建号均不代表部署成功。轮询建议每 5–10 秒一次,并设置调用方总超时;未经授权不得调用队列取消、构建停止或重跑接口。 + +### 3.5 API 常见错误 + +- `401`:用户或 API Token 错误,或者反向代理未转发 `Authorization`。 +- `403`:用户缺少 Job Read/Build 权限;使用 API Token 时不要通过关闭 CSRF 或改用密码规避。 +- `404`:Job 名称、Folder 路径或反向代理 Jenkins Context Path 错误。 +- `400`:参数名或 Choice 值与当前 Job 定义不一致。 +- 队列长期没有 `executable`:读取 `why`,检查 Job 并发限制、节点标签、部署锁和执行器,不要重复 POST 制造重复部署。 + +## 4. Job 与部署单元 | 部署单元 | Jenkins Job | 源码目录 | 流水线行为 | |---|---|---|---| @@ -55,6 +152,7 @@ Jenkins 页面会显示“系统管理”“新建任务”“配置”“删除 后端下游 Job: - `baiyue-firstleg-gateway` +- `baiyue-firstleg-gateway-overseas` - `baiyue-firstleg-auth` - `baiyue-firstleg-iam` - `baiyue-firstleg-firstleg` @@ -64,12 +162,15 @@ Jenkins 页面会显示“系统管理”“新建任务”“配置”“删除 - `baiyue-firstleg-file` - `baiyue-firstleg-print` - `baiyue-firstleg-integration-service` +- `baiyue-firstleg-lastleg-service` +- `baiyue-firstleg-warehouse-overseas-service` +- `baiyue-firstleg-overseas-security-service` - `baiyue-firstleg-event-bridge-service` - `baiyue-firstleg-audit-service` 正常部署后端时从 `backend-java` 总控 Job 发起。下游 Job 主要由总控调度;只有重跑同一提交的单个失败服务且已核对全部参数时,才直接操作下游 Job。 -## 4. 部署前强制检查 +## 5. 部署前强制检查 1. 阅读目标项目及目标模块的 `AGENTS.md`,确认任务允许修改和部署该单元。 2. 检查工作区状态,区分当前任务变更与用户已有变更。不得擅自提交或部署无关改动。 @@ -84,7 +185,7 @@ Jenkins 页面会显示“系统管理”“新建任务”“配置”“删除 如果当前工作区包含其他人的未提交改动,只有在能够证明远端目标 commit 仅包含本任务变更时才可部署。无法隔离时停止并说明阻断。 -## 5. 前端部署 +## 6. 前端部署 Admin 和 Client Job 无部署参数,触发后会直接构建并重建对应测试容器。因此触发前必须确认远端 `release/test` HEAD 就是目标提交。 @@ -94,7 +195,7 @@ Admin 和 Client Job 无部署参数,触发后会直接构建并重建对应 2. 核对最近构建、当前队列和远端 `release/test` 目标提交。 3. 触发“立即构建”。 4. 等待构建进入终态,不得只看到进入队列就结束任务。 -5. 成功后检查 `http://8.163.30.128:9001/healthz` 返回 HTTP 200 和 `ok`。 +5. 成功后检查 `${TEST_ADMIN_WEB_URL}/healthz` 返回 HTTP 200 和 `ok`。 ### Client @@ -102,11 +203,11 @@ Admin 和 Client Job 无部署参数,触发后会直接构建并重建对应 2. 核对最近构建、当前队列和远端 `release/test` 目标提交。 3. 触发“立即构建”。 4. 等待构建进入终态。 -5. 成功后检查 `http://8.163.30.128:9002/healthz` 返回 HTTP 200 和 `ok`。 +5. 成功后检查 `${TEST_CLIENT_WEB_URL}/healthz` 返回 HTTP 200 和 `ok`。 前端 `/healthz` 只证明容器和 Nginx 正常。任务涉及登录、接口或业务页面时,还必须按当前任务执行对应 Gateway 请求或浏览器业务验收。 -## 6. 后端部署 +## 7. 后端部署 打开 `backend-java`,选择 “Build with Parameters”。测试环境常规部署使用以下参数: @@ -116,17 +217,16 @@ Admin 和 Client Job 无部署参数,触发后会直接构建并重建对应 | `SERVICE_*` | 仅勾选受影响服务 | `SELECT` 模式至少选择一个 | | `ENVIRONMENT` | `test` | 本文禁止改为其他环境 | | `DEPLOY` | `true` | 否则只构建镜像,不更新测试容器 | -| `INITIALIZE_TEST_DATABASE` | `false` | 修改数据库,未经单独确认不得开启 | | `SKIP_TESTS` | `false` | 未经单独确认不得跳过测试 | | `EVENT_BRIDGE_REGION` | `BOTH` | 选择事件桥时默认一次部署国内和海外实例;`CN`/`OVERSEAS` 仅用于单区故障重跑 | | `IMAGE_REPOSITORY` | 保持测试默认值 | `test` 会解析为 `baiyue-firstleg-test` | | `DOCKER_BASE_IMAGE` | 保持 Job 默认值 | 除非任务明确要求变更基础镜像 | -| `DOWNSTREAM_JOB_PREFIX` | `baiyue-firstleg-` | 与现有 12 个下游 Job 对应 | +| `DOWNSTREAM_JOB_PREFIX` | `baiyue-firstleg-` | 与现有 16 个下游 Job 对应 | 选择规则: - 单服务业务代码:选择该服务,并检查内部客户端或契约消费者是否也需要部署。 -- `common-*`、父 `pom.xml`、`platform-bom/`、`Jenkinsfile*` 或 `deploy/` 中非 `deploy/sql/` 的部署设施变化:`AUTO` 会选择全部 12 个服务。能够证明公共变更影响全部服务时可直接部署;无法证明范围时按第 1 节取得确认。 +- `common-*`、父 `pom.xml`、`platform-bom/`、`Jenkinsfile*` 或 `deploy/` 中非 `deploy/sql/` 的部署设施变化:`AUTO` 会选择全部 16 个服务。能够证明公共变更影响全部服务时可直接部署;无法证明范围时按第 1 节取得确认。 - `deploy/sql/` 变化:`AUTO` 只标记存在待执行的数据库迁移,不据此扩大服务范围;同一提交中的服务目录变化仍按目录选择对应服务。若提交只有 SQL 变化,则不调度服务 Job。数据库迁移必须独立审核、取得明确授权并执行,不能由普通服务部署隐式触发。 - Gateway 路由、CORS 或访问域变化:选择 `gateway`,并检查受影响业务服务。 - 海外 PDA 换仓即时失效链变化:同时选择 `gateway-overseas`、`auth`、`iam`;Jenkins 环境文件必须提供非空 `AUTH_SESSION_VALIDATION_URL`,并复用既有 `INTERNAL_SERVICE_TOKEN`,不得把 URL、服务令牌或 raw 用户 Token 写入源码/Nacos 明文。普通海外 Admin/Client 路径不调用该同步校验。 @@ -137,22 +237,22 @@ Admin 和 Client Job 无部署参数,触发后会直接构建并重建对应 总控 Job 成功不应只看主任务颜色。必须核对描述或日志中的每个下游结果均为 `SUCCESS`。出现任一 `FAILURE` 时,总控可能显示 `UNSTABLE`;这种情况视为部署失败。 -## 7. 部署后验证 +## 8. 部署后验证 每次部署至少完成以下检查: 1. Jenkins Job 已进入终态,记录构建号、结果、commit 和耗时。 2. 后端总控部署记录全部下游 Job 名称、构建号和结果。 3. 前端健康检查: - - `GET http://8.163.30.128:9001/healthz` - - `GET http://8.163.30.128:9002/healthz` -4. 后端入口检查:`GET http://8.163.30.128:9000/actuator/health` 返回 HTTP 200。 + - `GET ${TEST_ADMIN_WEB_URL}/healthz` + - `GET ${TEST_CLIENT_WEB_URL}/healthz` +4. 后端入口检查:`GET ${TEST_GATEWAY_URL}/actuator/health` 返回 HTTP 200。 5. 执行与变更直接相关的真实 API 或浏览器流程。健康检查不能代替业务验收。 6. 失败响应记录 HTTP 状态、业务错误码、`requestId`、`traceId` 和阻断原因。 不得因为 Jenkins 成功就宣称业务验收通过,也不得让测试失败回退为模拟成功。 -## 8. 失败处理 +## 9. 失败处理 - 构建失败:读取失败阶段和控制台日志,定位第一个有效错误;修复并完成本地验证后,用新 commit 重新部署。 - 下游服务失败:记录失败的服务 Job 和构建号,检查 Maven 测试、镜像构建、环境凭据及 Docker Compose 输出。 @@ -162,7 +262,7 @@ Admin 和 Client Job 无部署参数,触发后会直接构建并重建对应 失败后不要自动回滚、删除容器或修改测试数据。需要这些动作时先向用户说明具体目标、影响和恢复方案并取得确认。 -## 9. 交付记录 +## 10. 交付记录 部署完成后,最终回复至少包含: