lty/.gitea/workflows/deploy.yaml
pmc 94f31ad699
All checks were successful
Build and Deploy LTY / build-and-deploy (push) Successful in 8m36s
chore(infra): k8s yaml 与 deploy.yaml sed 源串同步为火山 Redis
- k8s/backend-deployment-prod.yaml L44/L46 字面值直接写火山 URL+密码
- deploy.yaml L131/L132 sed 源串同步更新(功能变为同值替换,保留 sed 以备 env 差异化注入)
- 静态读 yaml 即真实部署状态,消除 yaml 与线上不一致的认知陷阱
- 代价:未来再切 Redis 需同步改 4 处;详见 qy_lty/docs/修改记录.md 2026-05-18 第三条

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 14:36:48 +08:00

229 lines
10 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.

name: Build and Deploy LTY
on:
push:
branches:
- main
- master
- dev
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
run: |
git clone --depth=1 --branch=${{ github.ref_name }} https://gitea.airlabs.art/${{ github.repository }}.git .
- name: Set environment by branch
run: |
SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7)
BUILD_DATE=$(date +%Y%m%d)
if [[ "${{ github.ref_name }}" == "main" || "${{ github.ref_name }}" == "master" ]]; then
echo "IMAGE_TAG=prod-${BUILD_DATE}-${SHORT_SHA}" >> $GITHUB_ENV
echo "CR_SERVER_ACTIVE=gitea-prod-cn-shanghai.cr.volces.com" >> $GITHUB_ENV
echo "CR_USERNAME_ACTIVE=seaislee@76339115" >> $GITHUB_ENV
echo "CR_PASSWORD_ACTIVE=${{ secrets.CR_PROD_PASSWORD }}" >> $GITHUB_ENV
echo "CR_ORG=prod" >> $GITHUB_ENV
echo "DEPLOY_ENV=production" >> $GITHUB_ENV
echo "DOMAIN_API=qy-lty.airlabs.art" >> $GITHUB_ENV
echo "DOMAIN_ADMIN=qy-lty-admin.airlabs.art" >> $GITHUB_ENV
echo "DB_HOST=pgm-7xv4811oj11j86htzo.pg.rds.aliyuncs.com" >> $GITHUB_ENV
echo "REDIS_LOCATION=redis://zyc:Zyc188208@redis-shzlsczo52dft8mia.redis.volces.com:6379/3" >> $GITHUB_ENV
echo "REDIS_PASSWORD=Zyc188208" >> $GITHUB_ENV
elif [[ "${{ github.ref_name }}" == "dev" ]]; then
echo "IMAGE_TAG=dev-${BUILD_DATE}-${SHORT_SHA}" >> $GITHUB_ENV
echo "CR_SERVER_ACTIVE=${{ secrets.CR_SERVER }}" >> $GITHUB_ENV
echo "CR_USERNAME_ACTIVE=${{ secrets.CR_USERNAME }}" >> $GITHUB_ENV
echo "CR_PASSWORD_ACTIVE=${{ secrets.CR_PASSWORD }}" >> $GITHUB_ENV
echo "CR_ORG=dev" >> $GITHUB_ENV
echo "DEPLOY_ENV=development" >> $GITHUB_ENV
echo "DOMAIN_API=qy-lty.test.airlabs.art" >> $GITHUB_ENV
echo "DOMAIN_ADMIN=qy-lty-admin.test.airlabs.art" >> $GITHUB_ENV
echo "DB_HOST=pgm-7xv4811oj11j86htzo.pg.rds.aliyuncs.com" >> $GITHUB_ENV
echo "REDIS_LOCATION=redis://zyc:Zyc188208@redis-shzlsczo52dft8mia.redis.volces.com:6379/3" >> $GITHUB_ENV
echo "REDIS_PASSWORD=Zyc188208" >> $GITHUB_ENV
fi
- name: Login to Container Registry
run: |
echo "${{ env.CR_PASSWORD_ACTIVE }}" | docker login --username "${{ env.CR_USERNAME_ACTIVE }}" --password-stdin ${{ env.CR_SERVER_ACTIVE }}
- name: Build and Push Backend
id: build_backend
run: |
set -o pipefail
for attempt in 1 2 3; do
echo "Build backend attempt $attempt/3..."
DOCKER_BUILDKIT=0 docker build \
--tag ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/lty-backend:${{ env.IMAGE_TAG }} \
--tag ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/lty-backend:latest \
./qy_lty 2>&1 | tee /tmp/build.log && break
echo "Attempt $attempt failed, retrying in 10s..." && sleep 10
done
for attempt in 1 2 3; do
docker push ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/lty-backend:${{ env.IMAGE_TAG }} && \
docker push ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/lty-backend:latest && break
echo "Push attempt $attempt failed, retrying in 10s..." && sleep 10
done
- name: Build and Push Admin Frontend
id: build_admin
run: |
set -o pipefail
for attempt in 1 2 3; do
echo "Build admin attempt $attempt/3..."
DOCKER_BUILDKIT=0 docker build \
--build-arg NEXT_PUBLIC_API_BASE_URL=https://${{ env.DOMAIN_API }}/api \
--tag ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/lty-admin:${{ env.IMAGE_TAG }} \
--tag ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/lty-admin:latest \
./qy-lty-admin 2>&1 | tee -a /tmp/build.log && break
echo "Attempt $attempt failed, retrying in 10s..." && sleep 10
done
for attempt in 1 2 3; do
docker push ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/lty-admin:${{ env.IMAGE_TAG }} && \
docker push ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/lty-admin:latest && break
echo "Push attempt $attempt failed, retrying in 10s..." && sleep 10
done
- name: Setup Kubectl
run: |
if ! command -v kubectl &>/dev/null; then
for attempt in 1 2 3; do
curl -LO "https://files.m.daocloud.io/dl.k8s.io/release/v1.28.0/bin/linux/amd64/kubectl" && break
echo "Download attempt $attempt failed, retrying in 5s..." && sleep 5
done
chmod +x kubectl && mv kubectl /usr/bin/kubectl
fi
kubectl version --client
- name: Set kubeconfig
run: |
mkdir -p $HOME/.kube
if [[ "${{ github.ref_name }}" == "main" || "${{ github.ref_name }}" == "master" ]]; then
echo "${{ secrets.KUBE_CONFIG }}" > $HOME/.kube/config
elif [[ "${{ github.ref_name }}" == "dev" ]]; then
echo "${{ secrets.VOLCANO_TEST_KUBE_CONFIG }}" > $HOME/.kube/config
fi
chmod 600 $HOME/.kube/config
- name: Deploy to K3s
id: deploy
run: |
echo "Environment: ${{ env.DEPLOY_ENV }}"
CR_IMAGE="${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}"
# Replace image placeholders
sed -i "s|\${CI_REGISTRY_IMAGE}/lty-backend:latest|${CR_IMAGE}/lty-backend:${{ env.IMAGE_TAG }}|g" k8s/backend-deployment-prod.yaml
sed -i "s|\${CI_REGISTRY_IMAGE}/lty-admin:latest|${CR_IMAGE}/lty-admin:${{ env.IMAGE_TAG }}|g" k8s/admin-deployment-prod.yaml
# Replace domain placeholders by environment
sed -i "s|qy-lty.airlabs.art|${{ env.DOMAIN_API }}|g" k8s/ingress.yaml
sed -i "s|qy-lty-admin.airlabs.art|${{ env.DOMAIN_ADMIN }}|g" k8s/ingress.yaml
# NEXT_PUBLIC_API_BASE_URL 已改为 docker build --build-arg 注入(见 admin 构建步骤),
# admin-deployment-prod.yaml 中不再保留可被 sed 替换的占位
# Replace DB host by environment
sed -i "s|pgm-7xv4811oj11j86htzo.pg.rds.aliyuncs.com|${{ env.DB_HOST }}|g" k8s/backend-deployment-prod.yaml
# Replace Redis by environmentsed 源串需与 k8s yaml 中 REDIS_LOCATION/PASSWORD 的字面值一致)
sed -i "s|redis://zyc:Zyc188208@redis-shzlsczo52dft8mia.redis.volces.com:6379/3|${{ env.REDIS_LOCATION }}|g" k8s/backend-deployment-prod.yaml
sed -i "s|Zyc188208|${{ env.REDIS_PASSWORD }}|g" k8s/backend-deployment-prod.yaml
# All kubectl operations with retry
for attempt in 1 2 3; do
echo "Deploy attempt $attempt/3..."
{
# Create/update image pull secret
kubectl create secret docker-registry cr-pull-secret \
--docker-server="${{ env.CR_SERVER_ACTIVE }}" \
--docker-username="${{ env.CR_USERNAME_ACTIVE }}" \
--docker-password="${{ env.CR_PASSWORD_ACTIVE }}" \
--dry-run=client -o yaml | kubectl apply -f -
# Apply manifests
kubectl apply -f k8s/backend-deployment-prod.yaml
kubectl apply -f k8s/admin-deployment-prod.yaml
kubectl apply -f k8s/ingress.yaml
kubectl apply -f k8s/traefik-config.yaml
# Preserve real client IP
kubectl patch svc traefik -n kube-system -p '{"spec":{"externalTrafficPolicy":"Local"}}' 2>/dev/null || true
kubectl rollout restart deployment/lty-backend
kubectl rollout restart deployment/lty-admin
} 2>&1 | tee /tmp/deploy.log && break
echo "Attempt $attempt failed, retrying in 10s..."
sleep 10
done
# ===== Log Center: failure reporting =====
- name: Report failure to Log Center
if: failure()
run: |
BUILD_LOG=""
DEPLOY_LOG=""
FAILED_STEP="unknown"
if [[ "${{ steps.build_backend.outcome }}" == "failure" || "${{ steps.build_admin.outcome }}" == "failure" ]]; then
FAILED_STEP="build"
if [ -f /tmp/build.log ]; then
BUILD_LOG=$(tail -50 /tmp/build.log | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
fi
elif [[ "${{ steps.deploy.outcome }}" == "failure" ]]; then
FAILED_STEP="deploy"
if [ -f /tmp/deploy.log ]; then
DEPLOY_LOG=$(tail -50 /tmp/deploy.log | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
fi
fi
ERROR_LOG="${BUILD_LOG}${DEPLOY_LOG}"
if [ -z "$ERROR_LOG" ]; then
ERROR_LOG="No captured output. Check Gitea Actions UI for details."
fi
if [[ "$FAILED_STEP" == "deploy" ]]; then
SOURCE="deployment"
ERROR_TYPE="DeployError"
else
SOURCE="cicd"
ERROR_TYPE="DockerBuildError"
fi
curl -s -X POST "https://qiyuan-log-center-api.airlabs.art/api/v1/logs/report" \
-H "Content-Type: application/json" \
-d "{
\"project_id\": \"lty\",
\"environment\": \"${{ env.DEPLOY_ENV }}\",
\"level\": \"ERROR\",
\"source\": \"${SOURCE}\",
\"commit_hash\": \"${{ github.sha }}\",
\"repo_url\": \"https://gitea.airlabs.art/zyc/lty.git\",
\"error\": {
\"type\": \"${ERROR_TYPE}\",
\"message\": \"[${FAILED_STEP}] Build and Deploy failed on branch ${{ github.ref_name }}\",
\"stack_trace\": [\"${ERROR_LOG}\"]
},
\"context\": {
\"job_name\": \"build-and-deploy\",
\"step_name\": \"${FAILED_STEP}\",
\"workflow\": \"${{ github.workflow }}\",
\"run_id\": \"${{ github.run_number }}\",
\"branch\": \"${{ github.ref_name }}\",
\"actor\": \"${{ github.actor }}\",
\"commit\": \"${{ github.sha }}\",
\"run_url\": \"https://gitea.airlabs.art/${{ github.repository }}/actions/runs/${{ github.run_number }}\"
}
}" || true
# ===== Cleanup: remove unused Docker resources =====
- name: Docker Cleanup
if: always()
run: |
docker container prune -f
docker image prune -f
docker builder prune -a -f
echo "Disk usage after cleanup:"
df -h / | tail -1