name: Deploy to Production # 触发条件:推送到主干分支 或 手动触发 on: push: branches: [main, master] workflow_dispatch: env: DEPLOY_DIR: /opt/agentkit REPO_DIR: /opt/agentkit/repo COMPOSE_FILE: docker-compose.deploy.yaml jobs: deploy: # 使用自托管 runner(同机部署,host 模式) runs-on: self-hosted timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Prepare deploy directory run: | sudo mkdir -p "$DEPLOY_DIR" "$REPO_DIR" sudo chown -R "$(id -u):$(id -g)" "$DEPLOY_DIR" - name: Sync code to deploy directory run: | rsync -a --delete \ --exclude='.git' \ --exclude='node_modules' \ --exclude='__pycache__' \ --exclude='.pytest_cache' \ --exclude='*.pyc' \ --exclude='.venv' \ --exclude='venv' \ --exclude='build/' \ --exclude='dist/' \ --exclude='test-results/' \ ./ "$REPO_DIR/" - name: Write .env from Gitea Secrets # 仅写入基础设施密码;LLM key 由用户部署后通过 Web UI onboarding 配置 # (PUT /api/v1/settings/llm 会写入 agentkit.yaml 和 .env) run: | umask 077 cat > "$REPO_DIR/.env" < /dev/null 2>&1; then echo "[OK] 服务健康检查通过" curl -s http://localhost:8001/api/v1/health exit 0 fi echo "尝试 $i/30: 服务未就绪,等待 5 秒..." sleep 5 done echo "[FAIL] 健康检查失败" docker compose -f "$REPO_DIR/$COMPOSE_FILE" logs --tail=100 exit 1 - name: Cleanup old images if: always() run: | docker image prune -f --filter "until=24h" || true