155 lines
6.2 KiB
YAML
155 lines
6.2 KiB
YAML
name: 数据库迁移 - 升级
|
||
|
||
on:
|
||
workflow_dispatch:
|
||
inputs:
|
||
check_only:
|
||
description: '只查看当前版本和脏库状态(执行 version,不改动数据库)'
|
||
required: false
|
||
default: false
|
||
type: boolean
|
||
|
||
concurrency:
|
||
group: migrate
|
||
cancel-in-progress: false
|
||
|
||
env:
|
||
REGISTRY: git.lzcwy.cn
|
||
IMAGE: git.lzcwy.cn/zhengchiliu/zt-closet-backend
|
||
MIGRATE_TAG: migrate
|
||
|
||
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
|
||
|
||
- name: 确认 docker 可用
|
||
run: |
|
||
docker version --format 'Server: {{.Server.Version}}'
|
||
|
||
- name: 决定动作
|
||
id: args
|
||
env:
|
||
IN_CHECK: ${{ gitea.event.inputs.check_only }}
|
||
run: |
|
||
if [ "${IN_CHECK:-false}" = "true" ]; then
|
||
echo "action=version" >> "$GITHUB_OUTPUT"
|
||
echo "动作: version(只读)"
|
||
else
|
||
echo "action=up" >> "$GITHUB_OUTPUT"
|
||
echo "动作: up"
|
||
fi
|
||
|
||
- name: 登录 Gitea 镜像仓库
|
||
env:
|
||
REGISTRY_USER: ${{ secrets.ZT_CLOSET_REGISTRY_USER }}
|
||
REGISTRY_TOKEN: ${{ secrets.ZT_CLOSET_REGISTRY_TOKEN }}
|
||
run: |
|
||
echo "$REGISTRY_TOKEN" | docker login "$REGISTRY" -u "$REGISTRY_USER" --password-stdin
|
||
|
||
- name: 构建并推送迁移镜像
|
||
run: |
|
||
docker build \
|
||
--build-arg GOPROXY=https://goproxy.cn,direct \
|
||
-f scripts/dockerfile/Dockerfile.migrate \
|
||
-t "$IMAGE:$MIGRATE_TAG" \
|
||
.
|
||
docker push "$IMAGE:$MIGRATE_TAG"
|
||
|
||
- name: 生产机执行(结束即删容器)
|
||
env:
|
||
SSH_KEY: ${{ secrets.ZT_CLOSET_PROD_SSH_KEY }}
|
||
SSH_HOST: ${{ vars.ZT_CLOSET_PROD_SSH_HOST }}
|
||
SSH_USER: ${{ vars.ZT_CLOSET_PROD_SSH_USER }}
|
||
ACTION: ${{ steps.args.outputs.action }}
|
||
run: |
|
||
mkdir -p ~/.ssh && chmod 700 ~/.ssh
|
||
printf '%s\n' "$SSH_KEY" > ~/.ssh/deploy_key
|
||
chmod 600 ~/.ssh/deploy_key
|
||
SSHOPT="-i ~/.ssh/deploy_key -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
|
||
|
||
ssh $SSHOPT "$SSH_USER@$SSH_HOST" "bash -s -- '$ACTION'" <<'REMOTE'
|
||
set -e
|
||
ACTION="$1"
|
||
DIR=/opt/zt-closet
|
||
IMAGE=git.lzcwy.cn/zhengchiliu/zt-closet-backend:migrate
|
||
|
||
cd "$DIR" || { echo "目录不存在: $DIR"; exit 1; }
|
||
[ -f configs/config.yaml ] || { echo "缺 configs/config.yaml"; exit 1; }
|
||
|
||
docker pull "$IMAGE"
|
||
|
||
docker run --rm \
|
||
--network host \
|
||
-v "$DIR/configs:/app/configs:ro" \
|
||
-v zt-go-build-cache:/root/.cache/go-build \
|
||
-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"
|