name: deploy-132 # 只认 main(含 PR 合并入 main)。照 sundynix-site 的模式: # runner(128) 构建 4 个应用镜像 → docker save 打包 → scp 镜像包 + compose 到 132 # → 132 docker load + docker compose up -d(用预构建镜像,不在 132 上 build)。 # 于是 132 上只有 compose + .env(+ 临时镜像包),没有源码。 on: push: branches: [main] workflow_dispatch: env: REMOTE_DIR: /home/workspace/sundynix-agentix jobs: deploy: runs-on: ubuntu-latest # 须匹配 128 上已注册 runner 的标签;不符请改成你的标签 steps: # 不用 actions/checkout(它要去 github.com 下载 action,内网 runner 连不上会 EOF); # 直接从内网 Gitea 用工作流自带 token 拉本仓库当前分支。init+fetch 不怕工作目录非空。 - name: 检出代码(内网 Gitea) run: | git init -q . git remote add origin "https://token:${{ github.token }}@git.sundynix.cn/${{ github.repository }}.git" git fetch -q --depth 1 origin "${{ github.ref_name }}" git checkout -q FETCH_HEAD - name: 构建 4 个应用镜像(在 runner 上) run: | # gateway/dispatcher/mcp-go 的构建上下文是仓库根(Go replace ../sundynix-shared, # 且 gateway 还要 COPY sundynix-admin/ 构建内嵌前端);mcp-py 上下文是自己的目录。 docker build -f sundynix-gateway/Dockerfile -t sundynix/gateway:latest . docker build -f sundynix-dispatcher/Dockerfile -t sundynix/dispatcher:latest . docker build -f sundynix-mcp-go/Dockerfile -t sundynix/mcp-go:latest . docker build -f sundynix-mcp-py/Dockerfile -t sundynix/mcp-py:latest sundynix-mcp-py - name: 导出镜像为压缩包 run: | docker save \ sundynix/gateway:latest sundynix/dispatcher:latest \ sundynix/mcp-go:latest sundynix/mcp-py:latest \ | gzip > images.tar.gz - name: 安装 ssh 工具 run: | if command -v apt-get >/dev/null; then apt-get update && apt-get install -y sshpass openssh-client elif command -v apk >/dev/null; then apk add --no-cache sshpass openssh-client fi - name: 传镜像包与 compose 到 132 env: SSHPASS: ${{ secrets.DEPLOY_PASSWORD }} run: | H="${{ secrets.DEPLOY_HOST }}" U="${{ secrets.DEPLOY_USER }}" # 只送两样:镜像包 + compose 文件。132 上的 .env 由你手工预放,绝不覆盖。 sshpass -e ssh -o StrictHostKeyChecking=no "$U@$H" "mkdir -p $REMOTE_DIR/deploy/132-app" sshpass -e scp -o StrictHostKeyChecking=no images.tar.gz "$U@$H:$REMOTE_DIR/" sshpass -e scp -o StrictHostKeyChecking=no \ deploy/132-app/docker-compose.yml "$U@$H:$REMOTE_DIR/deploy/132-app/" - name: 132 加载镜像并起服务 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 && \ gunzip -c images.tar.gz | docker load && \ rm -f images.tar.gz && \ cd deploy/132-app && \ docker compose up -d --no-build && \ docker image prune -f" - name: 健康检查(gateway :3000/healthz) 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:3000/healthz && echo ' ✅ 健康' && exit 0; \ sleep 3; \ done; \ echo '❌ 健康检查失败'; \ cd $REMOTE_DIR/deploy/132-app && docker compose logs --tail 50 gateway; exit 1"