name: CI/CD Pipeline on: push: branches: [main, master] jobs: # ========== 测试阶段 ========== test: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies run: | pip install -r requirements.txt pip install pytest - name: Run tests run: pytest tests/ -v || echo "No tests yet" # ========== 构建阶段 ========== build: needs: test runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build Docker image run: | docker build -t app01:${{ github.sha }} . docker tag app01:${{ github.sha }} app01:latest - name: Save Docker image run: | docker save app01:latest > /tmp/app01.tar - name: Upload artifact uses: actions/upload-artifact@v4 with: name: docker-image path: /tmp/app01.tar # ========== 部署阶段 ========== deploy: needs: build runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Download Docker image uses: actions/download-artifact@v4 with: name: docker-image path: /tmp - name: Deploy to server env: SSH_KEY: ${{ secrets.SSH_KEY }} HOST: ${{ secrets.DEPLOY_HOST }} PORT: ${{ secrets.DEPLOY_PORT }} USER: ${{ secrets.DEPLOY_USER }} run: | # 设置 SSH mkdir -p ~/.ssh echo "$SSH_KEY" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa # 传输镜像到服务器 docker load -i /tmp/app01.tar docker save app01:latest | ssh -o StrictHostKeyChecking=no -p "$PORT" -i ~/.ssh/id_rsa "$USER@$HOST" "docker load" # 执行部署 ssh -o StrictHostKeyChecking=no -p "$PORT" -i ~/.ssh/id_rsa "$USER@$HOST" << 'EOF' cd ~/app01 # 停止旧容器 docker stop app01-blue 2>/dev/null || true docker rm app01-blue 2>/dev/null || true # 启动新容器 docker run -d \ --name app01-blue \ --restart unless-stopped \ -p 127.0.0.1:8001:8000 \ -e PORT=8000 \ app01:latest # 等待健康检查 sleep 5 if curl -sf http://localhost:8001/health > /dev/null; then echo "✓ 健康检查通过" # 更新 Nginx 上游 echo "upstream app_backend { server 127.0.0.1:8001; }" | sudo tee /etc/nginx/conf.d/upstream.conf sudo nginx -s reload echo "✓ 部署完成" else echo "✗ 健康检查失败,执行回滚" docker stop app01-blue && docker rm app01-blue exit 1 fi EOF - name: Verify deployment run: | sleep 10 curl -f https://app.gch3n.online/health || exit 1 echo "✓ 部署验证成功"