# ============================================================================= # AWOOOI CD Pipeline (Gitea Actions - 方案 B) # ============================================================================= # 流程: Build → Push to Harbor → Deploy to K8s # 加速措施: # 1. Docker Layer Cache → Harbor registry cache # 2. 內部 Mirror → 192.168.0.110:5001 (Harbor Proxy Cache for DockerHub) # 2026-03-29 Claude Code (ADR-039) - Retry after creating Harbor project name: CD Pipeline on: push: branches: [main] workflow_dispatch: # 2026-03-30 ogt: 佇列模式 - 等待前一個 run 完成,不取消 concurrency: group: cd-deploy-${{ github.ref }} cancel-in-progress: false env: HARBOR: 192.168.0.110:5000 # Harbor Proxy Cache (指向 DockerHub 的內部 Mirror,避免拉取限額) HARBOR_MIRROR: 192.168.0.110:5001 jobs: build-and-deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Notify Pipeline Start run: | curl -fS -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ -d chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \ -d text="🚀 [AWOOOI CI/CD] Pipeline Started by ${{ github.actor }} (Commit: ${{ github.sha }})" - name: Login to Harbor uses: docker/login-action@v3 with: registry: ${{ env.HARBOR }} username: ${{ secrets.HARBOR_USERNAME }} password: ${{ secrets.HARBOR_PASSWORD }} # ── API 鏡像建置(含 Layer Cache 加速)────────────────────────────── - name: Build and Push API run: | docker build -f apps/api/Dockerfile \ --build-arg BUILDKIT_INLINE_CACHE=1 \ --cache-from ${{ env.HARBOR }}/awoooi/api:latest \ -t ${{ env.HARBOR }}/awoooi/api:${{ github.sha }} \ -t ${{ env.HARBOR }}/awoooi/api:latest \ . docker push ${{ env.HARBOR }}/awoooi/api:${{ github.sha }} docker push ${{ env.HARBOR }}/awoooi/api:latest - name: Notify API Build run: | curl -fS -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ -d chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \ -d text="📦 [AWOOOI CI/CD] API Image Built & Pushed" # ── Web 鏡像建置(含 Layer Cache 加速)────────────────────────────── # 2026-03-30 ogt: NEXT_PUBLIC_* 必須用公網域名 (build-time 寫死) # 內網 IP 會觸發瀏覽器「存取區域網路」權限對話框 - name: Build and Push Web run: | docker build -f apps/web/Dockerfile \ --build-arg NEXT_PUBLIC_API_URL=https://awoooi.wooo.work \ --build-arg BUILDKIT_INLINE_CACHE=1 \ --cache-from ${{ env.HARBOR }}/awoooi/web:latest \ -t ${{ env.HARBOR }}/awoooi/web:${{ github.sha }} \ -t ${{ env.HARBOR }}/awoooi/web:latest \ . docker push ${{ env.HARBOR }}/awoooi/web:${{ github.sha }} docker push ${{ env.HARBOR }}/awoooi/web:latest - name: Notify Web Build run: | curl -fS -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ -d chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \ -d text="📦 [AWOOOI CI/CD] Web Image Built & Pushed" - name: Deploy to K8s env: SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_KEY }} run: | mkdir -p ~/.ssh echo "$SSH_PRIVATE_KEY" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key ssh -o StrictHostKeyChecking=no -i ~/.ssh/deploy_key wooo@192.168.0.121 << 'DEPLOY' set -e export KUBECONFIG=/etc/rancher/k3s/k3s.yaml # 2026-03-30 ogt: sudoers NOPASSWD 已設定,無需密碼 sudo kubectl set image deployment/awoooi-api \ api=192.168.0.110:5000/awoooi/api:${{ github.sha }} \ -n awoooi-prod sudo kubectl set image deployment/awoooi-web \ web=192.168.0.110:5000/awoooi/web:${{ github.sha }} \ -n awoooi-prod sudo kubectl set image deployment/awoooi-worker \ worker=192.168.0.110:5000/awoooi/api:${{ github.sha }} \ -n awoooi-prod sudo kubectl rollout status deployment/awoooi-api -n awoooi-prod --timeout=120s sudo kubectl rollout status deployment/awoooi-web -n awoooi-prod --timeout=120s sudo kubectl rollout status deployment/awoooi-worker -n awoooi-prod --timeout=120s echo "✅ 部署完成" DEPLOY - name: Notify K8s Deploy run: | curl -fS -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ -d chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \ -d text="🚢 [AWOOOI CI/CD] K8s Deployment Triggered" # ── Health Check ───────────────────────────────────────────────────── - name: Health Check env: SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SSH_KEY }} run: | ssh -o StrictHostKeyChecking=no -i ~/.ssh/deploy_key wooo@192.168.0.121 << 'CHECK' sleep 10 for i in 1 2 3; do HTTP_CODE=$(curl -s -w "%{http_code}" -o /dev/null --connect-timeout 10 "http://localhost:32334/api/v1/health") if [ "$HTTP_CODE" = "200" ]; then echo "✅ API 健康檢查通過" exit 0 fi echo "⏳ 嘗試 #$i: HTTP $HTTP_CODE,等待 10s..." sleep 10 done echo "❌ API 健康檢查失敗" exit 1 CHECK - name: Notify Health Check Success run: | curl -fS -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ -d chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \ -d text="✅ [AWOOOI CI/CD] Health Check Passed! Pipeline Complete." - name: Notify Pipeline Failure if: failure() run: | curl -fS -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \ -d chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \ -d text="❌ [AWOOOI CI/CD] Pipeline Failed! Please check Gitea Actions logs."