65d52571de
并发组 = workflow name + ref。同分支连续 push 时: - 新 run 入组发现已有 in-progress run → 立即取消旧的,新的开跑 - 最终只构建 + 部署最新代码,省 CI 时间 - 不同分支的 build/deploy 互不干扰(虽然当前只 custom 用) - build 与 deploy 是两个独立 workflow name,互不影响(build 跑时 deploy 不会被取消,反之亦然) CLAUDE.md 同步加"并发取消策略"段说明该行为。
74 lines
2.9 KiB
YAML
74 lines
2.9 KiB
YAML
name: Deploy Docker Image
|
||
|
||
on:
|
||
# 自动触发:build-image workflow 成功完成后跑
|
||
workflow_run:
|
||
workflows: ["Build Docker Image"]
|
||
types: [completed]
|
||
branches: [custom]
|
||
# 手动触发:保留作为应急通道(重新部署当前镜像 / 跑临时脚本)
|
||
workflow_dispatch:
|
||
|
||
# 并发控制:连续多次 build 完成时,最新那次的 deploy 会取消旧的 in-progress
|
||
# deploy。避免老镜像被 docker compose up -d 临时切换到、又立即被新镜像覆盖
|
||
# 的窗口期,保证 ezbookkeeping 容器最终运行的是最新代码
|
||
concurrency:
|
||
group: ${{ github.workflow }}-${{ github.ref }}
|
||
cancel-in-progress: true
|
||
|
||
jobs:
|
||
deploy:
|
||
runs-on: ubuntu-latest
|
||
# 只在 build 成功后跑;手动触发时 workflow_run 字段不存在,
|
||
# 第一个条件保证手动跑也能继续
|
||
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
|
||
steps:
|
||
- name: Pull and restart ezbookkeeping
|
||
# 部署逻辑直接内联在这。runner 容器挂了 host docker.sock,
|
||
# 所以这里 docker 命令直接操作的是宿主机 docker daemon,
|
||
# 容器层面相当于 "ssh 到 NAS 跑 docker compose"。
|
||
#
|
||
# NAS_INFRA_TOKEN secret 仅在 nas-infra 是私有仓库时需要;
|
||
# 公开仓库不设这个 secret 也能拉。
|
||
env:
|
||
NAS_INFRA_TOKEN: ${{ secrets.NAS_INFRA_TOKEN }}
|
||
run: |
|
||
set -e
|
||
|
||
TMPDIR=$(mktemp -d)
|
||
trap 'rm -rf "$TMPDIR"' EXIT
|
||
|
||
# 决定 clone URL:有 token 用 token(私有),没有用裸 URL(公开)
|
||
if [ -n "$NAS_INFRA_TOKEN" ]; then
|
||
CLONE_URL="https://x-access-token:${NAS_INFRA_TOKEN}@git.zhengchentao.win/dev/nas-infra.git"
|
||
else
|
||
CLONE_URL="https://git.zhengchentao.win/dev/nas-infra.git"
|
||
fi
|
||
|
||
git clone --depth 1 "$CLONE_URL" "$TMPDIR/nas-infra"
|
||
cd "$TMPDIR/nas-infra/ezbookkeeping"
|
||
|
||
docker compose pull
|
||
docker compose up -d
|
||
|
||
# 简单 health:列容器状态 + 输出最近日志
|
||
sleep 3
|
||
docker compose ps
|
||
docker compose logs --tail=30 ezbookkeeping
|
||
|
||
- name: Deploy summary
|
||
if: always()
|
||
run: |
|
||
{
|
||
echo "## Deploy Summary"
|
||
echo ""
|
||
echo "| 项 | 值 |"
|
||
echo "|---|---|"
|
||
echo "| 触发方式 | \`${{ github.event_name }}\` |"
|
||
if [ "${{ github.event_name }}" = "workflow_run" ]; then
|
||
echo "| 触发自 | \`${{ github.event.workflow_run.name }}\` run #${{ github.event.workflow_run.run_number }} |"
|
||
echo "| 上游 build 结果 | \`${{ github.event.workflow_run.conclusion }}\` |"
|
||
echo "| 上游 build commit | \`${{ github.event.workflow_run.head_sha }}\` |"
|
||
fi
|
||
} >> "$GITHUB_STEP_SUMMARY"
|