# Gitea Actions CI/CD 配置 # Duoqi API - 双分支工作流(develop → main) # # 工作流: # develop push → quality → test → 构建并自动部署测试环境 # main push → quality → test → 构建并手动确认部署生产环境 # # 注意:单服务器架构,构建后直接部署,无需 artifact 传递 name: CI/CD Pipeline on: push: branches: [main, develop] env: DEPLOY_DIR: /opt/duoqi-api jobs: # ==================== 代码质量检查 ==================== quality: name: Code Quality runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Install dependencies run: bun install --frozen-lockfile - name: Type check run: bun run typecheck # ==================== 运行测试 ==================== test: name: Unit Tests runs-on: ubuntu-latest needs: quality steps: - name: Checkout code uses: actions/checkout@v4 - name: Install dependencies run: bun install --frozen-lockfile - name: Run tests run: bun run test # ==================== 构建并部署测试环境(develop 自动触发)==================== build-and-deploy-test: name: Build & Deploy Test runs-on: ubuntu-latest needs: [quality, test] if: github.ref == 'refs/heads/develop' environment: name: test url: http://test-api.duoqi.me steps: - name: Checkout code uses: actions/checkout@v4 - name: Build test image run: docker build --build-arg NODE_ENV=test -t duoqi-api:test . - name: Deploy test environment run: docker compose -f /opt/duoqi-api/docker-compose.yml --profile test up -d --no-build api-test - name: Health check run: | sleep 10 for i in {1..5}; do if bun -e "try{const r=await fetch('http://localhost:3001/v1/health');process.exit(r.ok?0:1)}catch{process.exit(1)}"; then echo "Test environment is healthy!" exit 0 fi echo "Health check attempt $i failed, retrying..." sleep 5 done echo "Test environment health check failed" exit 1 # ==================== 构建并部署生产环境(main 手动确认)==================== build-and-deploy-prod: name: Build & Deploy Production runs-on: ubuntu-latest needs: [quality, test] if: github.ref == 'refs/heads/main' environment: name: production url: https://api.duoqi.me steps: - name: Checkout code uses: actions/checkout@v4 - name: Backup current image run: docker tag duoqi-api:prod duoqi-api:rollback 2>/dev/null || true - name: Build production image run: docker build -t duoqi-api:prod . - name: Deploy production run: docker compose -f /opt/duoqi-api/docker-compose.yml up -d --no-build api-prod - name: Health check run: | sleep 15 for i in {1..5}; do if bun -e "try{const r=await fetch('http://localhost:3000/v1/health');process.exit(r.ok?0:1)}catch{process.exit(1)}"; then echo "Production deployment successful!" exit 0 fi echo "Health check attempt $i failed, retrying..." sleep 5 done # 健康检查失败,自动回滚 echo "Health check failed! Rolling back..." docker tag duoqi-api:rollback duoqi-api:prod docker compose -f /opt/duoqi-api/docker-compose.yml up -d --force-recreate --no-build api-prod exit 1 - name: Cleanup if: always() run: docker image prune -f