Files
sundynix-pets/.gitea/workflows/deploy.yml
T
Blizzard e102f5c610
ci / verify (push) Successful in 2m6s
ci: fetch source archive from Gitea
2026-10-01 13:30:13 +08:00

99 lines
4.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: deploy
# 只认 main(含 PR 合并入 main)。
# runner 上构建单个应用镜像 → docker save 打包 → scp 镜像包 + compose 到服务器
# → 服务器 docker load + docker compose up -d(用预构建镜像,不在服务器上 build)。
# 服务器上只有 compose + .env(+ 临时镜像包),没有源码。
on:
push:
branches: [main]
workflow_dispatch:
env:
REMOTE_DIR: /home/workspace/sundynix-pet
IMAGE: sundynix/pets-be:latest
jobs:
deploy:
runs-on: ubuntu-latest # 须匹配已注册 runner 的标签
steps:
# Gitea 的 Git HTTP pack 当前不可用,改用带 job token 的归档接口检出当前提交。
- name: 检出代码(内网 Gitea)
env:
GITEA_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
curl -fLsS -H "Authorization: token ${GITEA_TOKEN}" \
"https://git.sundynix.cn/${{ github.repository }}/archive/${{ github.sha }}.tar.gz" \
| tar -xz --strip-components=1
# 单镜像:内部先用 node 构建管理后台前端,再 Go 编译内嵌进二进制。
# 构建上下文是 pets-be/(go.mod 和 web/admin 都在里面)。
- name: 构建应用镜像
run: docker build -f pets-be/Dockerfile -t "$IMAGE" pets-be
- name: 导出镜像为压缩包
run: docker save "$IMAGE" | gzip > image.tar.gz
# 每次 job 都是全新容器,装过的东西不会留下。这里做两件事提速:
# 1) 已经有就直接跳过;2) 换阿里云镜像源,避免连境外源拖到几分钟。
- name: 安装 ssh 工具
run: |
if command -v sshpass >/dev/null && command -v ssh >/dev/null; then
echo "sshpass/ssh 已存在,跳过安装"; exit 0
fi
if command -v apk >/dev/null; then
sed -i 's#dl-cdn.alpinelinux.org#mirrors.aliyun.com#g' /etc/apk/repositories
apk add --no-cache sshpass openssh-client
elif command -v apt-get >/dev/null; then
sed -i -e 's#deb.debian.org#mirrors.aliyun.com#g' \
-e 's#security.debian.org#mirrors.aliyun.com#g' \
-e 's#archive.ubuntu.com#mirrors.aliyun.com#g' \
-e 's#security.ubuntu.com#mirrors.aliyun.com#g' \
/etc/apt/sources.list 2>/dev/null || true
sed -i -e 's#deb.debian.org#mirrors.aliyun.com#g' \
-e 's#archive.ubuntu.com#mirrors.aliyun.com#g' \
/etc/apt/sources.list.d/*.sources /etc/apt/sources.list.d/*.list 2>/dev/null || true
apt-get update -qq && apt-get install -y -qq --no-install-recommends sshpass openssh-client
fi
- name: 传镜像包与 compose 到服务器
env:
SSHPASS: ${{ secrets.DEPLOY_PASSWORD }}
run: |
H="${{ secrets.DEPLOY_HOST }}"
U="${{ secrets.DEPLOY_USER }}"
# 只送两样:镜像包 + compose。服务器上的 .env 由人工预放,绝不覆盖。
sshpass -e ssh -o StrictHostKeyChecking=no "$U@$H" "mkdir -p $REMOTE_DIR"
sshpass -e scp -o StrictHostKeyChecking=no image.tar.gz "$U@$H:$REMOTE_DIR/"
sshpass -e scp -o StrictHostKeyChecking=no \
deploy/docker-compose.yml "$U@$H:$REMOTE_DIR/docker-compose.yml"
- name: 服务器加载镜像并起服务
env:
SSHPASS: ${{ secrets.DEPLOY_PASSWORD }}
run: |
H="${{ secrets.DEPLOY_HOST }}"
U="${{ secrets.DEPLOY_USER }}"
sshpass -e ssh -o StrictHostKeyChecking=no "$U@$H" "\
cd $REMOTE_DIR && \
test -f .env || { echo '❌ 缺少 .env,请先按 deploy/.env.example 创建'; exit 1; } && \
gunzip -c image.tar.gz | docker load && \
rm -f image.tar.gz && \
docker compose up -d --no-build && \
docker image prune -f"
- name: 健康检查(宿主机 :4000/api/ping)
env:
SSHPASS: ${{ secrets.DEPLOY_PASSWORD }}
run: |
H="${{ secrets.DEPLOY_HOST }}"
U="${{ secrets.DEPLOY_USER }}"
sshpass -e ssh -o StrictHostKeyChecking=no "$U@$H" "\
for i in \$(seq 1 20); do \
curl -sf http://127.0.0.1:4000/api/ping && echo ' ✅ 健康' && exit 0; \
sleep 3; \
done; \
echo '❌ 健康检查失败'; \
cd $REMOTE_DIR && docker compose logs --tail 50 app; exit 1"