Files
awoooi/.gitea/workflows/cd.yaml
OG T 1cec655168 fix(security): P0 移除 sudo 密碼明文
2026-03-30 ogt: 首席架構師審查 P0 修復

問題: cd.yaml 含明文 sudo 密碼
修復: 改用 ${{ secrets.SUDO_PASSWORD }}

⚠️ 需要在 Gitea 設定 SUDO_PASSWORD secret!

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-30 01:30:49 +08:00

156 lines
6.6 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# =============================================================================
# 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 }}
SUDO_PASSWORD: ${{ secrets.SUDO_PASSWORD }}
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: P0 安全修復 - 使用 secret 而非明文密碼
echo "$SUDO_PASSWORD" | sudo -S kubectl set image deployment/awoooi-api \
api=192.168.0.110:5000/awoooi/api:${{ github.sha }} \
-n awoooi-prod
echo "$SUDO_PASSWORD" | sudo -S kubectl set image deployment/awoooi-web \
web=192.168.0.110:5000/awoooi/web:${{ github.sha }} \
-n awoooi-prod
echo "$SUDO_PASSWORD" | sudo -S kubectl set image deployment/awoooi-worker \
worker=192.168.0.110:5000/awoooi/api:${{ github.sha }} \
-n awoooi-prod
echo "$SUDO_PASSWORD" | sudo -S kubectl rollout status deployment/awoooi-api -n awoooi-prod --timeout=120s
echo "$SUDO_PASSWORD" | sudo -S kubectl rollout status deployment/awoooi-web -n awoooi-prod --timeout=120s
echo "$SUDO_PASSWORD" | sudo -S 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."