增加钉钉通知
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
---
|
||||
name: cicd补充分级钉钉通知
|
||||
overview: 在 3 个 Gitea Actions 工作流中补充分级钉钉通知(成功/失败/危险操作警告),webhook 走 Secret,采用 markdown 富文本样式。
|
||||
todos:
|
||||
- id: notify-deploy-and-mysqlup
|
||||
content: 为 deploy.yaml 与 mysqlup.yaml 新增开始计时步骤及成功/失败钉钉通知步骤
|
||||
status: completed
|
||||
- id: notify-mysqldown
|
||||
content: 为 mysqldown.yaml 新增开始计时、危险操作警告(执行前)及成功/失败钉钉通知步骤
|
||||
status: completed
|
||||
- id: verify-workflows
|
||||
content: 校验三个工作流 YAML 合法、缩进正确、无明文 webhook、变量与条件引用无误
|
||||
status: completed
|
||||
dependencies:
|
||||
- notify-deploy-and-mysqlup
|
||||
- notify-mysqldown
|
||||
---
|
||||
|
||||
## 产品概述
|
||||
|
||||
为仓库现有的 3 条 Gitea Actions 流水线(构建部署、数据库迁移升级、数据库迁移回滚)补齐钉钉机器人通知能力。通知按事件级别分级呈现,采用钉钉 markdown 富文本卡片样式,让团队在钉钉群里一眼看清「哪条流水线、什么结果、涉及哪个版本/提交、耗时多久、从哪看日志」。
|
||||
|
||||
## 核心功能
|
||||
|
||||
- **分级通知(3 级)**:成功、失败、危险操作警告。成功与失败在流水线结束时发送;危险操作警告在「数据库回滚」实际执行前发送,结束后再补一条结果通知。
|
||||
- **覆盖范围**:全部 3 条流水线——部署、迁移升级、迁移回滚;失败通知不做任何 @(不 @所有人、不 @指定人)。
|
||||
- **富文本样式**:使用钉钉 markdown 消息,含三级标题、引用块、加粗、无序列表与可点击链接;不同级别使用不同图标与标题文案,视觉上可快速区分。
|
||||
- **信息摘要**:每条通知包含仓库、分支或标签、提交短哈希、触发者、镜像版本、耗时、发生时间,并附「查看运行详情/失败日志」链接;失败通知额外给出定位指引。
|
||||
- **安全存放**:webhook 地址(含 access_token)以 Gitea 仓库 Secret 形式引用,不出现在流水线文件中,也不打印到日志。
|
||||
- **不干扰主流程**:通知发送失败不会导致流水线失败。
|
||||
|
||||
## 技术选型
|
||||
|
||||
- 流水线引擎:Gitea Actions(GitHub Actions 兼容语法),工作流文件为 YAML。
|
||||
- 通知通道:钉钉自定义机器人 webhook,`msgtype: markdown`(原生支持标题、引用、加粗、列表、链接,是当前钉钉机器人中样式表达力最好的纯文本消息类型;`text` 无样式,`actionCard` 无法体现级别差异)。
|
||||
- 发送方式:`curl` 直连 webhook,纯 shell 构造 JSON。**不引入任何外部 action**——与「checkout 已替换为 Gitee 镜像、避免依赖 GitHub action」的既定方向保持一致,避免新增拉取依赖。
|
||||
- 无新增语言/框架/依赖:仅使用 runner 自带的 `bash`、`curl`、`date`、`cut`。
|
||||
|
||||
## 实现方式
|
||||
|
||||
在 3 个工作流中新增「通知类」步骤,不动任何既有业务步骤(docker 构建/推送、SSH 部署、迁移执行)及其语义。
|
||||
|
||||
**分级触发条件**
|
||||
|
||||
| 级别 | 触发条件 | 位置 |
|
||||
| --- | --- | --- |
|
||||
| 成功 | `if: success()` | 作业最后(结果步骤之后) |
|
||||
| 失败 | `if: failure()` | 作业最后(结果步骤之后) |
|
||||
| 危险警告 | `if: success()` | 仅 mysqldown:置于「校验确认词」通过之后、拉取代码之前 |
|
||||
|
||||
|
||||
**耗时统计**:在每条作业的**第一步**新增「记录开始时间」,把 epoch 秒写入 `$GITHUB_ENV` 的 `JOB_START`;通知步骤用 `date +%s` 求差并格式化为「X 分 Y 秒」。该步骤位于拉取代码之前,可保证即便后续 checkout 失败也能正确计时。
|
||||
|
||||
**关键决策与理由**
|
||||
|
||||
1. **内联步骤而非本地 composite action**:本地 action 需要仓库先 checkout 成功才能加载,而本仓库恰好存在 checkout 拉取的现实风险(用户刚做过 checkout 替换),一旦 checkout 失败则失败通知自身也无法发送。内联步骤只依赖 runner 与工作流文件,可在 checkout 失败时照常发出失败通知,可靠性更高。代价是 3 个文件存在少量重复,可接受。
|
||||
2. **纯 shell 构造 JSON,不依赖 jq**:Gitea act runner 镜像中 jq 不保证存在;改为 bash 变量拼接 + 字面量 `\n` 转义,再以 heredoc 写入临时文件用 `curl -d @file` 发送。正文刻意不使用双引号、反引号与 `,从根本上规避 JSON 破坏与 shell 命令替换。
|
||||
3. **Secret 而非变量**:access_token 属凭据,走 `secrets`;通知步骤禁用 `set -x`,且不 echo webhook,避免凭据进入构建日志。
|
||||
4. **`continue-on-error: true`**:通知是旁路能力,任何发送异常都不得影响部署/迁移结果。
|
||||
|
||||
## 实现注意
|
||||
|
||||
- **前置人工操作**:需在 Gitea 仓库 Settings → Actions → Secrets 中新建 Secret `DINGTALK_WEBHOOK`,值为完整 webhook URL(含 `access_token=`)。若未创建,通知步骤会因空 URL 而失败,但被 `continue-on-error` 吞掉,不影响流水线。
|
||||
- **钉钉机器人安全设置需匹配**:本方案按「自定义关键词」或「IP 白名单」模式发送;若机器人配置的是「加签」模式,需在 URL 后追加 `×tamp=...&sign=...`,当前未实现该签名逻辑(需另行补充)。消息正文已包含 `zt-closet-backend` 等关键词,可满足常见关键词配置。
|
||||
- **表达式兼容性**:优先使用既有文件已证实的 `gitea.*` 上下文(`gitea.repository/ref/sha/actor/run_id/server_url`)。其中 `gitea.server_url` 若在该 Gitea 版本不可用,回退为仓库已知主机 `https://git.lzcwy.cn`(与 `env.REGISTRY` 一致)。
|
||||
- **不影响既有行为**:`deploy.yaml` 的「部署结果」步骤(`if: always()`)保留;`mysqldown.yaml` 的确认词校验逻辑与失败退出保持不变。
|
||||
- **限流**:钉钉机器人限 20 条/分钟;本方案单次运行最多 3 条,无风险。
|
||||
- **日志**:仅打印钉钉返回体中的 `errcode`/`errmsg` 便于排障,绝不输出 URL。
|
||||
|
||||
## 架构设计
|
||||
|
||||
通知能力作为「旁路观测层」附加在各作业末尾,与业务步骤零耦合:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["记录开始时间<br/>写入 JOB_START"] --> B["拉取代码 / 业务步骤"]
|
||||
B --> C{"作业结果"}
|
||||
C -- success --> D["钉钉通知(成功)<br/>if: success()"]
|
||||
C -- failure --> E["钉钉通知(失败)<br/>if: failure()"]
|
||||
D --> F["钉钉 markdown 机器人"]
|
||||
E --> F
|
||||
G["危险操作警告<br/>仅 mysqldown,执行前"] --> F
|
||||
```
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
zt-closet-backend/
|
||||
└── .gitea/
|
||||
└── workflows/
|
||||
├── deploy.yaml # [MODIFY] 新增「记录开始时间」+「钉钉通知(成功)」「钉钉通知(失败)」三步
|
||||
├── mysqlup.yaml # [MODIFY] 新增「记录开始时间」+「钉钉通知(成功)」「钉钉通知(失败)」三步
|
||||
└── mysqldown.yaml # [MODIFY] 新增「记录开始时间」+「钉钉通知(危险操作警告)」+「钉钉通知(成功)」「钉钉通知(失败)」四步
|
||||
```
|
||||
|
||||
- **deploy.yaml**:在 `steps` 首部插入计时步骤;在「部署结果」之后追加成功/失败两个通知步骤,通知中携带镜像 `${{ env.IMAGE }}:${{ steps.meta.outputs.tag }}`。
|
||||
- **mysqlup.yaml**:结构同上,镜像字段使用 `${{ env.IMAGE }}:${{ env.MIGRATE_TAG }}`。
|
||||
- **mysqldown.yaml**:在「校验确认词」之后追加危险操作警告步骤(`if: success()`,正文强调「删除所有迁移创建的表及其数据,不可恢复」),末尾再追加成功/失败通知。
|
||||
|
||||
## 关键代码结构
|
||||
|
||||
通知步骤统一形态(以 deploy.yaml 成功通知为例,失败/警告仅替换图标、文案、条件与链接文案):
|
||||
|
||||
```
|
||||
- name: 记录开始时间
|
||||
run: echo "JOB_START=$(date +%s)" >> "$GITHUB_ENV"
|
||||
|
||||
# ... 既有业务步骤保持不变 ...
|
||||
|
||||
- name: 钉钉通知(成功)
|
||||
if: success()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK: ${{ secrets.DINGTALK_WEBHOOK }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
REF: ${{ gitea.ref }}
|
||||
SHA: ${{ gitea.sha }}
|
||||
ACTOR: ${{ gitea.actor }}
|
||||
RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_id }}
|
||||
IMAGE_REF: ${{ env.IMAGE }}:${{ steps.meta.outputs.tag }}
|
||||
run: |
|
||||
set -uo pipefail
|
||||
REF_NAME="${REF#refs/heads/}"; REF_NAME="${REF_NAME#refs/tags/}"
|
||||
SHORT_SHA="$(printf '%s' "$SHA" | cut -c1-7)"
|
||||
COST=$(( $(date +%s) - ${JOB_START:-$(date +%s)} ))
|
||||
TEXT="### <状态图标> 构建并部署成功\n\n"
|
||||
TEXT="${TEXT}> **zt-closet-backend** · 构建并部署\n\n"
|
||||
TEXT="${TEXT}- **仓库**:$REPO\n"
|
||||
TEXT="${TEXT}- **分支/标签**:$REF_NAME\n"
|
||||
TEXT="${TEXT}- **提交**:$SHORT_SHA\n"
|
||||
TEXT="${TEXT}- **触发者**:$ACTOR\n"
|
||||
TEXT="${TEXT}- **镜像**:$IMAGE_REF\n"
|
||||
TEXT="${TEXT}- **耗时**:$((COST/60)) 分 $((COST%60)) 秒\n"
|
||||
TEXT="${TEXT}- **时间**:$(date '+%Y-%m-%d %H:%M:%S')\n\n"
|
||||
TEXT="${TEXT}[查看运行详情]($RUN_URL)"
|
||||
printf '%s' "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"<状态图标> 构建并部署成功 · zt-closet-backend\",\"text\":\"$TEXT\"}}" > /tmp/dingtalk.json
|
||||
RESP="$(curl -sS -X POST "$WEBHOOK" -H 'Content-Type: application/json' -d @/tmp/dingtalk.json)"
|
||||
echo "钉钉响应: $RESP"
|
||||
```
|
||||
|
||||
其中 `<状态图标>` 分别取「对勾」「叉」「警示」三类图标 emoji(实现时填入对应字符),使三级通知在钉钉列表中可被颜色与图形同时区分。失败通知额外增加一行「- **失败定位**:请点击下方链接查看失败步骤与日志」,链接文案为「查看失败日志」。
|
||||
@@ -17,6 +17,9 @@ jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 记录开始时间
|
||||
run: echo "JOB_START=$(date +%s)" >> "$GITHUB_ENV"
|
||||
|
||||
- name: 拉取代码
|
||||
uses: https://gitee.com/liu_zhengchi/checkout@v4
|
||||
|
||||
@@ -120,3 +123,64 @@ jobs:
|
||||
- name: 部署结果
|
||||
if: always()
|
||||
run: echo "镜像 ${{ env.IMAGE }}:${{ steps.meta.outputs.tag }} 部署流程结束"
|
||||
|
||||
- name: 钉钉通知(成功)
|
||||
if: success()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK: ${{ secrets.ZT_CLOSET_DINGTALK_WEBHOOK }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
REF: ${{ gitea.ref }}
|
||||
SHA: ${{ gitea.sha }}
|
||||
ACTOR: ${{ gitea.actor }}
|
||||
RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_id }}
|
||||
IMAGE_REF: ${{ env.IMAGE }}:${{ steps.meta.outputs.tag }}
|
||||
run: |
|
||||
set -uo pipefail
|
||||
REF_NAME="${REF#refs/heads/}"; REF_NAME="${REF_NAME#refs/tags/}"
|
||||
SHORT_SHA="$(printf '%s' "$SHA" | cut -c1-7)"
|
||||
COST=$(( $(date +%s) - ${JOB_START:-$(date +%s)} ))
|
||||
TEXT="### ✅ 构建并部署成功\n\n"
|
||||
TEXT="${TEXT}> **zt-closet-backend** · 构建并部署\n\n"
|
||||
TEXT="${TEXT}- **📦 仓库**:$REPO\n"
|
||||
TEXT="${TEXT}- **🌿 分支/标签**:$REF_NAME\n"
|
||||
TEXT="${TEXT}- **🔖 提交**:$SHORT_SHA\n"
|
||||
TEXT="${TEXT}- **👤 触发者**:$ACTOR\n"
|
||||
TEXT="${TEXT}- **🐳 镜像**:$IMAGE_REF\n"
|
||||
TEXT="${TEXT}- **⏱️ 耗时**:$((COST/60)) 分 $((COST%60)) 秒\n"
|
||||
TEXT="${TEXT}- **🕐 时间**:$(date '+%Y-%m-%d %H:%M:%S')\n\n"
|
||||
TEXT="${TEXT}[查看运行详情]($RUN_URL)"
|
||||
printf '%s' "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"✅ 构建并部署成功 · zt-closet-backend\",\"text\":\"$TEXT\"}}" > /tmp/dingtalk.json
|
||||
RESP="$(curl -sS -X POST "$WEBHOOK" -H 'Content-Type: application/json' -d @/tmp/dingtalk.json)"
|
||||
echo "钉钉响应: $RESP"
|
||||
|
||||
- name: 钉钉通知(失败)
|
||||
if: failure()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK: ${{ secrets.ZT_CLOSET_DINGTALK_WEBHOOK }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
REF: ${{ gitea.ref }}
|
||||
SHA: ${{ gitea.sha }}
|
||||
ACTOR: ${{ gitea.actor }}
|
||||
RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_id }}
|
||||
IMAGE_REF: ${{ env.IMAGE }}:${{ steps.meta.outputs.tag }}
|
||||
run: |
|
||||
set -uo pipefail
|
||||
REF_NAME="${REF#refs/heads/}"; REF_NAME="${REF_NAME#refs/tags/}"
|
||||
SHORT_SHA="$(printf '%s' "$SHA" | cut -c1-7)"
|
||||
COST=$(( $(date +%s) - ${JOB_START:-$(date +%s)} ))
|
||||
TEXT="### ❌ 构建并部署失败\n\n"
|
||||
TEXT="${TEXT}> **zt-closet-backend** · 构建并部署\n\n"
|
||||
TEXT="${TEXT}- **📦 仓库**:$REPO\n"
|
||||
TEXT="${TEXT}- **🌿 分支/标签**:$REF_NAME\n"
|
||||
TEXT="${TEXT}- **🔖 提交**:$SHORT_SHA\n"
|
||||
TEXT="${TEXT}- **👤 触发者**:$ACTOR\n"
|
||||
TEXT="${TEXT}- **🐳 镜像**:$IMAGE_REF\n"
|
||||
TEXT="${TEXT}- **⏱️ 耗时**:$((COST/60)) 分 $((COST%60)) 秒\n"
|
||||
TEXT="${TEXT}- **🕐 时间**:$(date '+%Y-%m-%d %H:%M:%S')\n"
|
||||
TEXT="${TEXT}- **🧭 失败定位**:请点击下方链接查看失败步骤与日志\n\n"
|
||||
TEXT="${TEXT}[查看失败日志]($RUN_URL)"
|
||||
printf '%s' "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"❌ 构建并部署失败 · zt-closet-backend\",\"text\":\"$TEXT\"}}" > /tmp/dingtalk.json
|
||||
RESP="$(curl -sS -X POST "$WEBHOOK" -H 'Content-Type: application/json' -d @/tmp/dingtalk.json)"
|
||||
echo "钉钉响应: $RESP"
|
||||
|
||||
@@ -21,6 +21,9 @@ jobs:
|
||||
migrate-down:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 记录开始时间
|
||||
run: echo "JOB_START=$(date +%s)" >> "$GITHUB_ENV"
|
||||
|
||||
- name: 校验确认词
|
||||
env:
|
||||
IN_CONFIRM: ${{ gitea.event.inputs.confirm }}
|
||||
@@ -31,6 +34,33 @@ jobs:
|
||||
fi
|
||||
echo "确认通过"
|
||||
|
||||
- name: 钉钉通知(危险操作警告)
|
||||
if: success()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK: ${{ secrets.ZT_CLOSET_DINGTALK_WEBHOOK }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
REF: ${{ gitea.ref }}
|
||||
SHA: ${{ gitea.sha }}
|
||||
ACTOR: ${{ gitea.actor }}
|
||||
RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_id }}
|
||||
run: |
|
||||
set -uo pipefail
|
||||
REF_NAME="${REF#refs/heads/}"; REF_NAME="${REF_NAME#refs/tags/}"
|
||||
SHORT_SHA="$(printf '%s' "$SHA" | cut -c1-7)"
|
||||
TEXT="### ⚠️ 危险操作:数据库回滚\n\n"
|
||||
TEXT="${TEXT}> **zt-closet-backend** · 即将执行全量回滚,不可恢复\n\n"
|
||||
TEXT="${TEXT}- **📦 仓库**:$REPO\n"
|
||||
TEXT="${TEXT}- **🌿 分支/标签**:$REF_NAME\n"
|
||||
TEXT="${TEXT}- **🔖 提交**:$SHORT_SHA\n"
|
||||
TEXT="${TEXT}- **👤 操作人**:$ACTOR\n"
|
||||
TEXT="${TEXT}- **🕐 时间**:$(date '+%Y-%m-%d %H:%M:%S')\n"
|
||||
TEXT="${TEXT}- **❗ 影响**:将删除所有迁移创建的表及其数据\n\n"
|
||||
TEXT="${TEXT}[查看运行详情]($RUN_URL)"
|
||||
printf '%s' "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"⚠️ 危险操作:数据库回滚 · zt-closet-backend\",\"text\":\"$TEXT\"}}" > /tmp/dingtalk.json
|
||||
RESP="$(curl -sS -X POST "$WEBHOOK" -H 'Content-Type: application/json' -d @/tmp/dingtalk.json)"
|
||||
echo "钉钉响应: $RESP"
|
||||
|
||||
- name: 拉取代码
|
||||
uses: https://gitee.com/liu_zhengchi/checkout@v4
|
||||
|
||||
@@ -82,3 +112,64 @@ jobs:
|
||||
-e TZ=Asia/Shanghai \
|
||||
"$IMAGE" down
|
||||
REMOTE
|
||||
|
||||
- name: 钉钉通知(成功)
|
||||
if: success()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK: ${{ secrets.ZT_CLOSET_DINGTALK_WEBHOOK }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
REF: ${{ gitea.ref }}
|
||||
SHA: ${{ gitea.sha }}
|
||||
ACTOR: ${{ gitea.actor }}
|
||||
RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_id }}
|
||||
IMAGE_REF: ${{ env.IMAGE }}:${{ env.MIGRATE_TAG }}
|
||||
run: |
|
||||
set -uo pipefail
|
||||
REF_NAME="${REF#refs/heads/}"; REF_NAME="${REF_NAME#refs/tags/}"
|
||||
SHORT_SHA="$(printf '%s' "$SHA" | cut -c1-7)"
|
||||
COST=$(( $(date +%s) - ${JOB_START:-$(date +%s)} ))
|
||||
TEXT="### ✅ 数据库回滚完成\n\n"
|
||||
TEXT="${TEXT}> **zt-closet-backend** · 数据库迁移-回滚\n\n"
|
||||
TEXT="${TEXT}- **📦 仓库**:$REPO\n"
|
||||
TEXT="${TEXT}- **🌿 分支/标签**:$REF_NAME\n"
|
||||
TEXT="${TEXT}- **🔖 提交**:$SHORT_SHA\n"
|
||||
TEXT="${TEXT}- **👤 操作人**:$ACTOR\n"
|
||||
TEXT="${TEXT}- **🐳 镜像**:$IMAGE_REF\n"
|
||||
TEXT="${TEXT}- **⏱️ 耗时**:$((COST/60)) 分 $((COST%60)) 秒\n"
|
||||
TEXT="${TEXT}- **🕐 时间**:$(date '+%Y-%m-%d %H:%M:%S')\n\n"
|
||||
TEXT="${TEXT}[查看运行详情]($RUN_URL)"
|
||||
printf '%s' "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"✅ 数据库回滚完成 · zt-closet-backend\",\"text\":\"$TEXT\"}}" > /tmp/dingtalk.json
|
||||
RESP="$(curl -sS -X POST "$WEBHOOK" -H 'Content-Type: application/json' -d @/tmp/dingtalk.json)"
|
||||
echo "钉钉响应: $RESP"
|
||||
|
||||
- name: 钉钉通知(失败)
|
||||
if: failure()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK: ${{ secrets.ZT_CLOSET_DINGTALK_WEBHOOK }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
REF: ${{ gitea.ref }}
|
||||
SHA: ${{ gitea.sha }}
|
||||
ACTOR: ${{ gitea.actor }}
|
||||
RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_id }}
|
||||
IMAGE_REF: ${{ env.IMAGE }}:${{ env.MIGRATE_TAG }}
|
||||
run: |
|
||||
set -uo pipefail
|
||||
REF_NAME="${REF#refs/heads/}"; REF_NAME="${REF_NAME#refs/tags/}"
|
||||
SHORT_SHA="$(printf '%s' "$SHA" | cut -c1-7)"
|
||||
COST=$(( $(date +%s) - ${JOB_START:-$(date +%s)} ))
|
||||
TEXT="### ❌ 数据库迁移-回滚失败\n\n"
|
||||
TEXT="${TEXT}> **zt-closet-backend** · 数据库迁移-回滚\n\n"
|
||||
TEXT="${TEXT}- **📦 仓库**:$REPO\n"
|
||||
TEXT="${TEXT}- **🌿 分支/标签**:$REF_NAME\n"
|
||||
TEXT="${TEXT}- **🔖 提交**:$SHORT_SHA\n"
|
||||
TEXT="${TEXT}- **👤 操作人**:$ACTOR\n"
|
||||
TEXT="${TEXT}- **🐳 镜像**:$IMAGE_REF\n"
|
||||
TEXT="${TEXT}- **⏱️ 耗时**:$((COST/60)) 分 $((COST%60)) 秒\n"
|
||||
TEXT="${TEXT}- **🕐 时间**:$(date '+%Y-%m-%d %H:%M:%S')\n"
|
||||
TEXT="${TEXT}- **🧭 失败定位**:请点击下方链接查看失败步骤与日志\n\n"
|
||||
TEXT="${TEXT}[查看失败日志]($RUN_URL)"
|
||||
printf '%s' "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"❌ 数据库迁移-回滚失败 · zt-closet-backend\",\"text\":\"$TEXT\"}}" > /tmp/dingtalk.json
|
||||
RESP="$(curl -sS -X POST "$WEBHOOK" -H 'Content-Type: application/json' -d @/tmp/dingtalk.json)"
|
||||
echo "钉钉响应: $RESP"
|
||||
|
||||
@@ -22,6 +22,9 @@ jobs:
|
||||
migrate-up:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 记录开始时间
|
||||
run: echo "JOB_START=$(date +%s)" >> "$GITHUB_ENV"
|
||||
|
||||
- name: 拉取代码
|
||||
uses: https://gitee.com/liu_zhengchi/checkout@v4
|
||||
|
||||
@@ -88,3 +91,64 @@ jobs:
|
||||
-e TZ=Asia/Shanghai \
|
||||
"$IMAGE" "$ACTION"
|
||||
REMOTE
|
||||
|
||||
- name: 钉钉通知(成功)
|
||||
if: success()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK: ${{ secrets.ZT_CLOSET_DINGTALK_WEBHOOK }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
REF: ${{ gitea.ref }}
|
||||
SHA: ${{ gitea.sha }}
|
||||
ACTOR: ${{ gitea.actor }}
|
||||
RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_id }}
|
||||
IMAGE_REF: ${{ env.IMAGE }}:${{ env.MIGRATE_TAG }}
|
||||
run: |
|
||||
set -uo pipefail
|
||||
REF_NAME="${REF#refs/heads/}"; REF_NAME="${REF_NAME#refs/tags/}"
|
||||
SHORT_SHA="$(printf '%s' "$SHA" | cut -c1-7)"
|
||||
COST=$(( $(date +%s) - ${JOB_START:-$(date +%s)} ))
|
||||
TEXT="### ✅ 数据库迁移-升级成功\n\n"
|
||||
TEXT="${TEXT}> **zt-closet-backend** · 数据库迁移-升级\n\n"
|
||||
TEXT="${TEXT}- **📦 仓库**:$REPO\n"
|
||||
TEXT="${TEXT}- **🌿 分支/标签**:$REF_NAME\n"
|
||||
TEXT="${TEXT}- **🔖 提交**:$SHORT_SHA\n"
|
||||
TEXT="${TEXT}- **👤 触发者**:$ACTOR\n"
|
||||
TEXT="${TEXT}- **🐳 镜像**:$IMAGE_REF\n"
|
||||
TEXT="${TEXT}- **⏱️ 耗时**:$((COST/60)) 分 $((COST%60)) 秒\n"
|
||||
TEXT="${TEXT}- **🕐 时间**:$(date '+%Y-%m-%d %H:%M:%S')\n\n"
|
||||
TEXT="${TEXT}[查看运行详情]($RUN_URL)"
|
||||
printf '%s' "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"✅ 数据库迁移-升级成功 · zt-closet-backend\",\"text\":\"$TEXT\"}}" > /tmp/dingtalk.json
|
||||
RESP="$(curl -sS -X POST "$WEBHOOK" -H 'Content-Type: application/json' -d @/tmp/dingtalk.json)"
|
||||
echo "钉钉响应: $RESP"
|
||||
|
||||
- name: 钉钉通知(失败)
|
||||
if: failure()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK: ${{ secrets.ZT_CLOSET_DINGTALK_WEBHOOK }}
|
||||
REPO: ${{ gitea.repository }}
|
||||
REF: ${{ gitea.ref }}
|
||||
SHA: ${{ gitea.sha }}
|
||||
ACTOR: ${{ gitea.actor }}
|
||||
RUN_URL: ${{ gitea.server_url }}/${{ gitea.repository }}/actions/runs/${{ gitea.run_id }}
|
||||
IMAGE_REF: ${{ env.IMAGE }}:${{ env.MIGRATE_TAG }}
|
||||
run: |
|
||||
set -uo pipefail
|
||||
REF_NAME="${REF#refs/heads/}"; REF_NAME="${REF_NAME#refs/tags/}"
|
||||
SHORT_SHA="$(printf '%s' "$SHA" | cut -c1-7)"
|
||||
COST=$(( $(date +%s) - ${JOB_START:-$(date +%s)} ))
|
||||
TEXT="### ❌ 数据库迁移-升级失败\n\n"
|
||||
TEXT="${TEXT}> **zt-closet-backend** · 数据库迁移-升级\n\n"
|
||||
TEXT="${TEXT}- **📦 仓库**:$REPO\n"
|
||||
TEXT="${TEXT}- **🌿 分支/标签**:$REF_NAME\n"
|
||||
TEXT="${TEXT}- **🔖 提交**:$SHORT_SHA\n"
|
||||
TEXT="${TEXT}- **👤 触发者**:$ACTOR\n"
|
||||
TEXT="${TEXT}- **🐳 镜像**:$IMAGE_REF\n"
|
||||
TEXT="${TEXT}- **⏱️ 耗时**:$((COST/60)) 分 $((COST%60)) 秒\n"
|
||||
TEXT="${TEXT}- **🕐 时间**:$(date '+%Y-%m-%d %H:%M:%S')\n"
|
||||
TEXT="${TEXT}- **🧭 失败定位**:请点击下方链接查看失败步骤与日志\n\n"
|
||||
TEXT="${TEXT}[查看失败日志]($RUN_URL)"
|
||||
printf '%s' "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"❌ 数据库迁移-升级失败 · zt-closet-backend\",\"text\":\"$TEXT\"}}" > /tmp/dingtalk.json
|
||||
RESP="$(curl -sS -X POST "$WEBHOOK" -H 'Content-Type: application/json' -d @/tmp/dingtalk.json)"
|
||||
echo "钉钉响应: $RESP"
|
||||
|
||||
Reference in New Issue
Block a user