name: Build and Deploy on: push: branches: - airlabs 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) echo "IMAGE_TAG=internal-${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=internal" >> $GITHUB_ENV echo "DEPLOY_ENV=internal" >> $GITHUB_ENV echo "DOMAIN_APP=videoflow.airlabs.art" >> $GITHUB_ENV - name: Validate deploy domain run: | if [ "$DOMAIN_APP" = "toonflow.example.com" ]; then echo "DOMAIN_APP is still toonflow.example.com. Replace it with the real domain before deploying." exit 1 fi if [ -z "${{ secrets.SMS_ACCESS_KEY_ID }}" ] || [ -z "${{ secrets.SMS_ACCESS_KEY_SECRET }}" ]; then echo "SMS_ACCESS_KEY_ID and SMS_ACCESS_KEY_SECRET must be configured as repository secrets." exit 1 fi - name: Login to Volcano Engine CR run: | echo "${{ env.CR_PASSWORD_ACTIVE }}" | docker login --username "${{ env.CR_USERNAME_ACTIVE }}" --password-stdin ${{ env.CR_SERVER_ACTIVE }} - name: Build and Push ToonFlow id: build_toonflow run: | set -o pipefail BUILD_OK=0 for attempt in 1 2 3; do echo "Build ToonFlow attempt $attempt/3..." if DOCKER_BUILDKIT=0 docker build \ --tag ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/toonflow:${{ env.IMAGE_TAG }} \ --tag ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/toonflow:latest \ . 2>&1 | tee /tmp/build.log; then BUILD_OK=1 break fi echo "Attempt $attempt failed, retrying in 10s..." && sleep 10 done if [ "$BUILD_OK" -ne 1 ]; then echo "Docker build failed after 3 attempts." exit 1 fi PUSH_OK=0 for attempt in 1 2 3; do if docker push ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/toonflow:${{ env.IMAGE_TAG }} && \ docker push ${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}/toonflow:latest; then PUSH_OK=1 break fi echo "Push attempt $attempt failed, retrying in 10s..." && sleep 10 done if [ "$PUSH_OK" -ne 1 ]; then echo "Docker push failed after 3 attempts." exit 1 fi - name: Setup Kubectl run: | if [ -f /usr/local/bin/kubectl ]; then echo "Using mounted kubectl" elif command -v kubectl &>/dev/null; then echo "kubectl already in PATH" else echo "Downloading kubectl..." curl -sLO "https://dl.k8s.io/release/v1.28.0/bin/linux/amd64/kubectl" chmod +x kubectl && mv kubectl /usr/local/bin/kubectl fi kubectl version --client - name: Set kubeconfig run: | mkdir -p $HOME/.kube printf '%s\n' '${{ secrets.VOLCANO_INTERNAL_KUBE_CONFIG }}' > $HOME/.kube/config chmod 600 $HOME/.kube/config echo "kubeconfig lines: $(wc -l < $HOME/.kube/config)" grep server $HOME/.kube/config || echo "WARNING: no server found in kubeconfig" kubectl cluster-info 2>&1 | head -3 || true - name: Deploy to K3s id: deploy run: | echo "Environment: ${{ env.DEPLOY_ENV }}" CR_IMAGE="${{ env.CR_SERVER_ACTIVE }}/${{ env.CR_ORG }}" sed -i "s|\${CI_REGISTRY_IMAGE}/toonflow:latest|${CR_IMAGE}/toonflow:${{ env.IMAGE_TAG }}|g" k8s/toonflow-deployment.yaml sed -i "s|toonflow.example.com|${{ env.DOMAIN_APP }}|g" k8s/toonflow-deployment.yaml k8s/toonflow-ingress.yaml for attempt in 1 2 3; do echo "Deploy attempt $attempt/3..." { 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 - kubectl create secret generic toonflow-sms-secret \ --from-literal=SMS_ACCESS_KEY_ID='${{ secrets.SMS_ACCESS_KEY_ID }}' \ --from-literal=SMS_ACCESS_KEY_SECRET='${{ secrets.SMS_ACCESS_KEY_SECRET }}' \ --dry-run=client -o yaml | kubectl apply -f - kubectl apply -f k8s/cert-manager-issuer.yaml kubectl apply -f k8s/redirect-https-middleware.yaml kubectl apply -f k8s/toonflow-pvc.yaml kubectl apply -f k8s/toonflow-deployment.yaml kubectl apply -f k8s/toonflow-ingress.yaml kubectl rollout restart deployment/toonflow kubectl rollout status deployment/toonflow --timeout=300s } 2>&1 | tee /tmp/deploy.log && break echo "Attempt $attempt failed, retrying in 10s..." sleep 10 done - name: Docker Cleanup if: always() run: | docker container prune -f docker image prune -f echo "Disk usage:" df -h / | tail -1