name: Build and sync k3s images # This IS the production deploy path. `medical-chatbot-app` (ArgoCD, k3s) is # the same release behind both realvuxbaro.me and readytochat.realvuxbaro.me # since the 2026-08-17 cutover — there is no longer a separate "practice" # Application this workflow avoids touching. The Compose EC2 is unaffected # only because it has no CI/CD path left at all (deploy.yml/rollback.yml were # removed); it is a manual DNS fallback, not a deploy target. # # ArgoCD's Applications already autosync (syncPolicy.automated) — the gap # this closes is that the image tag they deploy was a static string # (`:practice`) that nothing ever rebuilt. This tags every build with the # commit SHA and repoints the Application at it. on: push: branches: [master] paths: - apps/ai-service/** - apps/web/** - apps/auth-service/** - apps/api-gateway/** - packages/** - ingestion/data/verified/drug_entities.json - .github/workflows/build-practice-images.yml - .github/scripts/sync_practice_argocd.py workflow_dispatch: concurrency: group: practice-images cancel-in-progress: false jobs: build-and-sync: runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - name: Log in to GHCR uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push ai-service uses: docker/build-push-action@v6 with: context: . file: apps/ai-service/Dockerfile push: true tags: ghcr.io/baovu2k4/vsf-duocthu-ai-service:${{ github.sha }} cache-from: type=gha,scope=practice-ai-service cache-to: type=gha,mode=max,scope=practice-ai-service - name: Build and push web uses: docker/build-push-action@v6 with: context: . file: apps/web/Dockerfile push: true tags: ghcr.io/baovu2k4/vsf-duocthu-web:${{ github.sha }} cache-from: type=gha,scope=practice-web cache-to: type=gha,mode=max,scope=practice-web - name: Build and push auth-service uses: docker/build-push-action@v6 with: context: . file: apps/auth-service/Dockerfile push: true tags: ghcr.io/baovu2k4/vsf-duocthu-auth-service:${{ github.sha }} cache-from: type=gha,scope=practice-auth-service cache-to: type=gha,mode=max,scope=practice-auth-service - name: Build and push api-gateway uses: docker/build-push-action@v6 with: context: . file: apps/api-gateway/Dockerfile push: true tags: ghcr.io/baovu2k4/vsf-duocthu-api-gateway:${{ github.sha }} cache-from: type=gha,scope=practice-api-gateway cache-to: type=gha,mode=max,scope=practice-api-gateway # auth-service/api-gateway are NOT in sync_practice_argocd.py's IMAGES # tuple yet — that script fails the whole run if a tag it expects to # rewrite isn't already present inline on the Application, so extending # it must wait until someone has added `authService.image` / # `apiGateway.image` blocks to the live Application by hand (see # infra/helm/medical-chatbot/values-production.yaml). Until then, these # two images are pushed here but must be repointed manually. - name: Point the practice ArgoCD Application at the new images env: ARGOCD_PRACTICE_URL: ${{ secrets.ARGOCD_PRACTICE_URL }} ARGOCD_PRACTICE_PASSWORD: ${{ secrets.ARGOCD_PRACTICE_PASSWORD }} IMAGE_TAG: ${{ github.sha }} run: python3 .github/scripts/sync_practice_argocd.py - name: Confirm readytochat is serving the new build run: | for attempt in $(seq 1 18); do code=$(curl -s -o /dev/null -w '%{http_code}' \ "https://readytochat.realvuxbaro.me/api/history?conversation_id=ci-smoke-${{ github.sha }}") if [ "$code" = "200" ]; then echo "readytochat.realvuxbaro.me is live on ${{ github.sha }}" exit 0 fi sleep 10 done echo "readytochat.realvuxbaro.me did not pick up ${{ github.sha }} within 3 minutes" exit 1