Test #1

Merged
admin merged 256 commits from test into main 2026-09-28 16:01:16 +08:00
Showing only changes of commit 004beefb17 - Show all commits
+98 -214
View File
@@ -1,275 +1,159 @@
# 测试环境 Jenkins 部署指南
# 开发/测试环境 Jenkins API 自动部署指南
> 最后核对:2026-08-25
>
> 本文供 Codex 对话和项目维护人员部署虫虫出海测试环境使用。只适用于测试环境,不适用于预发布或生产。
>
> 开发、测试环境内国内/海外服务同机共置,以及生产双区域 Nacos 和 Event Bridge 目标拓扑,统一见[双区域部署与 Nacos 规划](双区域部署与Nacos规划.md);本文只维护测试环境 Jenkins 操作步骤。
> 只适用于当前开发、测试阶段。生产环境启用后必须重新收紧权限、轮换并移除开发 Token。
## 1. 人工部署默认与 Codex 授权边界
## 1. 使用场景
测试环境默认由人工部署。读取本指南、完成代码、远端联调、测试环境回归、浏览器验收或“部署后才能继续验证”都不自动授权 Codex 触发 Jenkins。
本指南用于长时间全量测试或夜间任务。用户在当前对话明确要求“持续修复并部署”“自动部署并测试”或等价表述后,工具可以在本次授权范围内循环执行:
没有当前对话的明确部署授权时,Codex 工作到“可人工部署”即停止,并交付:目标仓库和分支、完整 commit SHA、受影响 Job/服务、已通过的本地门禁、必要环境前提、人工触发步骤和部署后验证清单。Codex 可以按任务需要只读检查 Jenkins 现状,但不得触发、重跑或停止构建,也不得重建远端容器。
`定位失败 → 修改代码 → 本地门禁 → 提交并推送 → API 部署 → 等待终态 → 健康/业务验收 → 继续修复`
只有用户在当前对话明确要求“由 Codex 部署”“自动部署并测试”“今晚持续部署验收”或等价表述时,Codex 才能执行。授权必须能确定环境、服务或 Job、目标提交和结束条件;只在该范围内有效,任务完成或用户叫停后自动失效。
同一轮任务不需要每次提交或重试都重新询问。以下情况仍必须停下确认:
用户明确安排夜间持续执行时,Codex 可以在授权范围内等待构建、重试同一提交的失败 Job、执行部署后健康检查和验收;不得借此新增服务、扩大到全量部署或执行数据库操作。不得根据当前时间、用户长时间未回复或用户可能已经休息自行推断夜间授权。
- 涉及预发布或生产环境。
- 需要执行 SQL、初始化数据库、修改真实数据或清理容器/数据。
- 需要跳过测试、停止他人构建或扩大到未授权服务。
- 缺少环境凭据,或连续三次遇到同一个外部阻断。
此授权不包含以下操作;遇到时必须单独取得用户明确确认:
## 2. 本机一次性配置
- 部署 `staging` 或 `production`。
- 执行任何数据库写入、迁移、初始化和测试数据修改。
- 勾选 `SKIP_TESTS`。
- 无法明确影响范围时执行后端 `ALL` 全量部署。
- 修改 Jenkins Job、Credentials、节点、插件、权限或系统配置。
- 删除构建、停止他人正在执行的构建、回滚环境或清理容器/数据。
Jenkins API 信息固定保存在以下未提交文件:
“请继续”“完成验收”“修复后验证”不单独构成部署授权;必须明确表达由 Codex 操作 Jenkins。人工已经部署后,用户要求 Codex 继续测试的,只授权测试和只读核对,不反向授权再次部署。
`C:/Users/BY-OY/.codex/jenkins-api.env`
## 2. 环境与认证
文件格式:
| 项目 | 地址或标识 |
|---|---|
| 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 用户在个人“安全”页面生成独立 API Token。Token 只保存到本机密钥管理或未提交环境文件,不得写入仓库、命令示例、聊天记录、构建参数、日志或 Jenkinsfile。旧版明文密码调用方式已停用;历史上曾写入文档的密码必须视为泄露并完成轮换。
只有当前对话已明确授权 Codex 部署时才可使用 API;未授权时不得通过浏览器或 API 触发构建。已获部署授权时优先使用 API Token 调用,不复用浏览器 Cookie。API 用户只授予读取目标 Job、触发构建和读取构建结果所需的最小权限,不授予 Job 配置、Credentials、节点、插件或系统管理权限。
Jenkins 页面会显示“系统管理”“新建任务”“配置”“删除 Pipeline”等管理入口。即使当前账号具有管理权限,也只能执行本任务所需的构建和只读检查。
## 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'
```dotenv
JENKINS_URL=https://jenkins.example.com
JENKINS_USER=admin
JENKINS_API_TOKEN=replace-with-current-development-token
DEV_GATEWAY_URL=https://dev-api.example.com
TEST_GATEWAY_URL=https://test-api.example.com
```
先做只读连通性检查:
工具直接读取该文件,不把 Token 输出到 commentary、最终回复、命令日志或仓库。使用 API Token 的 Jenkins 请求不需要 CSRF Crumb。
连通性检查:
```bash
curl --fail --silent --show-error \
--user "$JENKINS_USER:$JENKINS_API_TOKEN" \
curl -fsS --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. Job 对照
### 3.2 触发无参数前端 Job
| 环境 | 后端总控 | Admin | Client | 后端分支 | 下游前缀 |
|---|---|---|---|---|---|
| 开发 | `backend-java-dev` | `admin-web-dev` | `client-web-dev` | `dev` | `baiyue-firstleg-dev-` |
| 测试 | `backend-java` | `admin-web-test` | `client-web-test` | `test` | `baiyue-firstleg-` |
后端可部署服务:
`gateway`、`gateway-overseas`、`auth`、`iam`、`firstleg`、`finance`、`order`、`warehouse`、`file`、`print`、`integration-service`、`lastleg-service`、`warehouse-overseas-service`、`overseas-security-service`、`event-bridge-service`、`audit-service`。
正常从总控 Job 发起。只有重跑同一提交的单个失败服务时,才直接触发下游 Job。
## 4. API 触发
### 4.1 前端
```bash
curl --fail-with-body --silent --show-error \
--request POST \
curl -fsS -X POST \
--user "$JENKINS_USER:$JENKINS_API_TOKEN" \
--dump-header admin-web-test.headers \
--output /dev/null \
"${JENKINS_URL%/}/job/admin-web-test/build"
-D build.headers -o /dev/null \
"${JENKINS_URL%/}/job/admin-web-dev/build"
```
Client 将 Job 路径改为 `/job/client-web-test/build`。成功响应通常是 HTTP 201/302,并在 `Location` 响应头返回队列条目 URL。临时响应头文件使用后立即删除,不得提交。
按目标环境和应用替换 Job 名称。
### 3.3 触发参数化后端 Job
### 4.2 后端
以下示例只部署测试环境的 `gateway-overseas` 与 `lastleg-service`;实际调用必须按本次授权修改服务范围:
开发环境选择两个服务的示例:
```bash
curl --fail-with-body --silent --show-error \
--request POST \
curl -fsS -X POST \
--user "$JENKINS_USER:$JENKINS_API_TOKEN" \
--dump-header backend-java.headers \
--output /dev/null \
-D build.headers -o /dev/null \
--data-urlencode 'BUILD_MODE=SELECT' \
--data-urlencode 'SERVICE_GATEWAY_OVERSEAS=true' \
--data-urlencode 'SERVICE_LASTLEG=true' \
--data-urlencode 'ENVIRONMENT=test' \
--data-urlencode 'ENVIRONMENT=development' \
--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"
--data-urlencode 'DOWNSTREAM_JOB_PREFIX=baiyue-firstleg-dev-' \
"${JENKINS_URL%/}/job/backend-java-dev/buildWithParameters"
```
没有明确选择的 `SERVICE_*` 参数保持 Job 默认 `false`,不要为了省事传 `ALL`。调用前应从 `${JENKINS_URL%/}/job/backend-java/api/json` 核对当前 Job 参数定义;参数发生变化时先更新本文,禁止让调用脚本静默依赖过期默认值。
规则:
### 3.4 跟踪队列与构建结果
- 日常优先 `AUTO`;明确修复单个或少量服务时使用 `SELECT`。
- `SELECT` 只把目标 `SERVICE_*` 设为 `true`,其余保持 `false`。
- `ALL` 只用于用户明确授权的全量部署。
- 开发环境固定 `ENVIRONMENT=development`;测试固定 `ENVIRONMENT=test`。
- 开发/测试默认 `DEPLOY=true`、`SKIP_TESTS=false`。
- 事件桥默认 `BOTH`;单区故障重跑才使用 `CN` 或 `OVERSEAS`。
- 不在 API 参数中传密码、数据库凭据或服务 Token。
从触发响应的 `Location` 头取得 `QUEUE_URL`,轮询队列,直到出现 `executable.url`:
## 5. 自动等待终态
触发响应的 `Location` 是队列地址:
```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="$(awk 'BEGIN{IGNORECASE=1} /^Location:/{gsub("\r",""); print $2}' build.headers)"
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
"${QUEUE_URL%/}/api/json?tree=id,why,cancelled,executable[number,url]"
```
取得返回中的 `executable.url` 后,用它作为 `BUILD_URL` 查询终态和日志:
出现 `executable.url` 后,将其作为 `BUILD_URL`:
```bash
curl --fail --silent --show-error \
--user "$JENKINS_USER:$JENKINS_API_TOKEN" \
curl -fsS --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" \
每 5–10 秒轮询一次。只有 `building=false` 且 `result=SUCCESS` 才成功;进入队列、拿到构建号或 HTTP POST 成功都不算完成。后端总控还必须确认每个下游 Job 都是 `SUCCESS`。
失败时读取:
```bash
curl -fsS --user "$JENKINS_USER:$JENKINS_API_TOKEN" \
"${BUILD_URL%/}/consoleText"
```
只有 `building=false` 且 `result=SUCCESS` 才算 Job 成功。后端总控还必须核对每个下游 Job 结果;HTTP POST 成功、进入队列或拿到构建号均不代表部署成功。轮询建议每 5–10 秒一次,并设置调用方总超时;未经授权不得调用队列取消、构建停止或重跑接口。
删除本次产生的临时 `*.headers` 文件,不提交。
### 3.5 API 常见错误
## 6. 夜间自动闭环
- `401`:用户或 API Token 错误,或者反向代理未转发 `Authorization`。
- `403`:用户缺少 Job Read/Build 权限;使用 API Token 时不要通过关闭 CSRF 或改用密码规避。
- `404`:Job 名称、Folder 路径或反向代理 Jenkins Context Path 错误。
- `400`:参数名或 Choice 值与当前 Job 定义不一致。
- 队列长期没有 `executable`:读取 `why`,检查 Job 并发限制、节点标签、部署锁和执行器,不要重复 POST 制造重复部署。
1. 记录目标环境、服务和远端 commit。
2. 运行直接受影响的本地测试;签名变化必须编译测试源码。
3. 只提交当前修复文件并推送目标分支。
4. 用 API 触发对应 Job,保存队列 URL、构建 URL 和构建号。
5. 等待总控及全部下游进入终态。
6. 失败时读取第一个有效错误,修改后使用新 commit 再部署。
7. 网络抖动、镜像拉取等瞬时基础设施错误允许同一提交重试,最多两次。
8. 部署成功后检查 Gateway `/actuator/health`,再执行本轮真实 API/全量测试。
9. 全部通过后汇总 commit、构建号、服务结果和验收结果。
## 4. Job 与部署单元
不要因为某个服务失败就盲目重跑全量;优先修复并只重跑失败服务。部署脚本会在新容器不健康时自动回滚,任务仍视为失败。
| 部署单元 | Jenkins Job | 源码目录 | 流水线行为 |
|---|---|---|---|
| Admin Web | `admin-web-test` | `apps/admin-web/` | 拉取 `release/test`,构建镜像,重建容器,执行容器内 `/healthz` |
| Client Web | `client-web-test` | `apps/client-web/` | 拉取 `release/test`,构建镜像,重建容器,执行容器内 `/healthz` |
| 后端总控 | `backend-java` | `baiyue-firstleg/` | 选择变更服务并行调度下游 Job;测试环境使用 Jenkins 节点本机镜像 |
## 7. 快速故障判断
后端下游 Job:
| 现象 | 处理 |
|---|---|
| `401` | 检查本机 API Token 和反向代理 `Authorization` 头 |
| `403` | 检查 Job Read/Build 权限;不要关闭 CSRF |
| `400` | 参数名或 Choice 值与当前 Job 不一致 |
| 队列长期等待 | 查询队列 `why`,检查节点、执行器和部署锁 |
| Maven/测试失败 | 修复代码并产生新 commit,不跳过测试 |
| 容器不健康 | 读取 Job 自动采集的容器日志和回滚结果 |
| 镜像被其他任务覆盖 | 核对同服务部署锁和实际运行镜像标签 |
| 总控成功但下游失败 | 整体仍按失败处理,只重跑失败服务 |
- `baiyue-firstleg-gateway`
- `baiyue-firstleg-gateway-overseas`
- `baiyue-firstleg-auth`
- `baiyue-firstleg-iam`
- `baiyue-firstleg-firstleg`
- `baiyue-firstleg-finance`
- `baiyue-firstleg-order`
- `baiyue-firstleg-warehouse`
- `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`
## 8. 完成记录
正常部署后端时从 `backend-java` 总控 Job 发起。下游 Job 主要由总控调度;只有重跑同一提交的单个失败服务且已核对全部参数时,才直接操作下游 Job。
最终只需记录:环境、Job、服务、分支、commit、Jenkins 构建号、最终结果、健康检查、业务验收及剩余阻断。不得输出 Token、Cookie、Jenkins Credential 或环境文件内容。
## 5. 部署前强制检查
1. 阅读目标项目及目标模块的 `AGENTS.md`,确认任务允许修改和部署该单元。
2. 检查工作区状态,区分当前任务变更与用户已有变更。不得擅自提交或部署无关改动。
3. 运行目标项目声明的测试和构建门禁:
- Admin:至少运行受影响测试、`pnpm typecheck` 和 `pnpm build`;交付部署前优先运行 `pnpm test`。
- Client:至少运行 `pnpm typecheck`、受影响测试和 `pnpm build`;交付部署前优先运行 `pnpm test`。
- Backend:优先运行 `mvn -pl <module> -am test`;公共模块或跨服务变更按影响范围扩大验证。
4. 确认待部署代码已经提交并推送到 Jenkins 实际拉取的远端分支。Jenkins 无法部署本地未提交或未推送的文件。
5. 记录准备部署的仓库、分支、完整 commit SHA、Job 和后端服务列表。
6. 触发前核对当前对话是否存在符合第 1 节的明确部署授权,并通过 commentary 告知用户即将部署的 Job、commit 和范围。没有明确授权时停止在人工部署交接,不以通知替代授权。
7. 检查 Jenkins 构建队列和执行器。不得覆盖或中断他人构建;同一 Job 正在构建时等待其结束,再重新核对远端提交。
如果当前工作区包含其他人的未提交改动,只有在能够证明远端目标 commit 仅包含本任务变更时才可部署。无法隔离时停止并说明阻断。
## 6. 前端部署
Admin 和 Client Job 无部署参数,触发后会直接构建并重建对应测试容器。因此触发前必须确认远端 `release/test` HEAD 就是目标提交。
### Admin
1. 打开 `admin-web-test`。
2. 核对最近构建、当前队列和远端 `release/test` 目标提交。
3. 触发“立即构建”。
4. 等待构建进入终态,不得只看到进入队列就结束任务。
5. 成功后检查 `${TEST_ADMIN_WEB_URL}/healthz` 返回 HTTP 200 和 `ok`。
### Client
1. 打开 `client-web-test`。
2. 核对最近构建、当前队列和远端 `release/test` 目标提交。
3. 触发“立即构建”。
4. 等待构建进入终态。
5. 成功后检查 `${TEST_CLIENT_WEB_URL}/healthz` 返回 HTTP 200 和 `ok`。
前端 `/healthz` 只证明容器和 Nginx 正常。任务涉及登录、接口或业务页面时,还必须按当前任务执行对应 Gateway 请求或浏览器业务验收。
## 7. 后端部署
打开 `backend-java`,选择 “Build with Parameters”。测试环境常规部署使用以下参数:
| 参数 | 常规值 | 说明 |
|---|---|---|
| `BUILD_MODE` | `SELECT` 或已核对后的 `AUTO` | 优先显式选择受影响服务;确认提交差异完整时可用 `AUTO` |
| `SERVICE_*` | 仅勾选受影响服务 | `SELECT` 模式至少选择一个 |
| `ENVIRONMENT` | `test` | 本文禁止改为其他环境 |
| `DEPLOY` | `true` | 否则只构建镜像,不更新测试容器 |
| `SKIP_TESTS` | `false` | 未经单独确认不得跳过测试 |
| `EVENT_BRIDGE_REGION` | `BOTH` | 选择事件桥时默认一次部署国内和海外实例;`CN`/`OVERSEAS` 仅用于单区故障重跑 |
| `IMAGE_REPOSITORY` | 保持测试默认值 | `test` 会解析为 `baiyue-firstleg-test` |
| `DOCKER_BASE_IMAGE` | 保持 Job 默认值 | 除非任务明确要求变更基础镜像 |
| `DOWNSTREAM_JOB_PREFIX` | `baiyue-firstleg-` | 与现有 16 个下游 Job 对应 |
选择规则:
- 单服务业务代码:选择该服务,并检查内部客户端或契约消费者是否也需要部署。
- `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 路径不调用该同步校验。
- 跨服务 DTO/OpenAPI/内部客户端变化:同时选择生产者和消费者。
- 数据库结构变化:不能仅部署服务。先按数据库变更规则取得明确授权并完成迁移,再部署依赖该结构的服务。
- Finance 服务部署使用模块名 `finance`,Jenkins 下游 Job 必须命名为 `baiyue-firstleg-finance`;测试环境凭据 `firstleg-test-env` 必须包含非空 `FINANCE_DB_URL`、`FINANCE_DB_USERNAME`、`FINANCE_DB_PASSWORD`。
- File 服务部署依赖 Jenkins 文件凭据 `firstleg-test-env` 中有效的 `ROCKETMQ_NAME_SERVER`,且 `MQ_TOPIC_PREFIX` 必须为 `test-`。
总控 Job 成功不应只看主任务颜色。必须核对描述或日志中的每个下游结果均为 `SUCCESS`。出现任一 `FAILURE` 时,总控可能显示 `UNSTABLE`;这种情况视为部署失败。
## 8. 部署后验证
每次部署至少完成以下检查:
1. Jenkins Job 已进入终态,记录构建号、结果、commit 和耗时。
2. 后端总控部署记录全部下游 Job 名称、构建号和结果。
3. 前端健康检查:
- `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 成功就宣称业务验收通过,也不得让测试失败回退为模拟成功。
## 9. 失败处理
- 构建失败:读取失败阶段和控制台日志,定位第一个有效错误;修复并完成本地验证后,用新 commit 重新部署。
- 下游服务失败:记录失败的服务 Job 和构建号,检查 Maven 测试、镜像构建、环境凭据及 Docker Compose 输出。
- 部署成功但健康检查失败:检查对应 Job 的容器状态和末尾日志,不切换为本地后端。
- 健康检查成功但业务失败:记录请求证据,核对数据库迁移、Nacos 配置、服务注册和真实接口契约。
- 不得在未确认影响的情况下通过跳过测试、初始化数据库、清理工作区外数据或全量重启来“试一下”。
失败后不要自动回滚、删除容器或修改测试数据。需要这些动作时先向用户说明具体目标、影响和恢复方案并取得确认。
## 10. 交付记录
部署完成后,最终回复至少包含:
- 部署的环境、Job 和服务范围。
- 分支与 commit SHA。
- Jenkins 构建号及最终结果。
- 健康检查和直接业务验证结果。
- 任何失败、跳过项、残余风险及 `requestId`/`traceId`。
不要在回复中输出密码、Token、Cookie、Jenkins Credential 内容或环境文件内容。
参考:[Jenkins Remote Access API](https://www.jenkins.io/doc/book/using/remote-access-api/)、[Jenkins CSRF Protection](https://www.jenkins.io/doc/book/security/csrf-protection/)。