name: Rollback k3s production # One-command escape hatch for medical-chatbot-app (ArgoCD, k3s) — the # Application build-practice-images.yml normally advances, and the same one # serving realvuxbaro.me since the 2026-08-17 cutover. This workflow does not # build anything: it only repoints the Application at an OLDER image tag that # a previous build-practice-images.yml run already pushed to GHCR, using the # exact same sync_practice_argocd.py logic that workflow uses to move # forward — a rollback is just that script pointed backward. # # Does not touch the Compose EC2 (stopped 2026-08-18, no CI/CD path left — # see docs/operations.md). on: workflow_dispatch: inputs: target_sha: description: >- Commit SHA to roll back to. Must have a successful "Build and sync k3s images" run (check: gh run list --workflow=build-practice-images.yml). required: true concurrency: # Same group as build-practice-images.yml: a rollback and a forward deploy # must never race to repoint the same Application at the same time. group: practice-images cancel-in-progress: false jobs: rollback: runs-on: ubuntu-latest permissions: contents: read packages: read steps: - uses: actions/checkout@v4 - uses: docker/setup-buildx-action@v3 - uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} # Fails fast and clearly on the most likely operator mistake: a typo'd # or never-built SHA, rather than that surfacing later as a confusing # ArgoCD/pod-level image pull failure. - name: Confirm images exist for target_sha run: | set -eu docker buildx imagetools inspect "ghcr.io/baovu2k4/vsf-duocthu-ai-service:${{ inputs.target_sha }}" > /dev/null docker buildx imagetools inspect "ghcr.io/baovu2k4/vsf-duocthu-web:${{ inputs.target_sha }}" > /dev/null - name: Point medical-chatbot-app at target_sha env: ARGOCD_PRACTICE_URL: ${{ secrets.ARGOCD_PRACTICE_URL }} ARGOCD_PRACTICE_PASSWORD: ${{ secrets.ARGOCD_PRACTICE_PASSWORD }} IMAGE_TAG: ${{ inputs.target_sha }} run: python3 .github/scripts/sync_practice_argocd.py # Blocks until the rollout has actually landed, not just until the sync # call returned — sync_practice_argocd.py deliberately doesn't wait # (see its own comment on the selfHeal race), so a rollback specifically # needs this extra confirmation before it can claim success. - name: Wait for the Application to be Synced, Healthy, and on target_sha env: ARGOCD_PRACTICE_URL: ${{ secrets.ARGOCD_PRACTICE_URL }} ARGOCD_PRACTICE_PASSWORD: ${{ secrets.ARGOCD_PRACTICE_PASSWORD }} EXPECT_TAG: ${{ inputs.target_sha }} run: python3 .github/scripts/wait_for_argocd_sync.py - name: Confirm realvuxbaro.me is serving the rolled-back build run: | for attempt in $(seq 1 18); do code=$(curl -s -o /dev/null -w '%{http_code}' \ "https://realvuxbaro.me/api/history?conversation_id=rollback-smoke-${{ inputs.target_sha }}") if [ "$code" = "200" ]; then echo "realvuxbaro.me is live on ${{ inputs.target_sha }}" exit 0 fi sleep 10 done echo "realvuxbaro.me did not respond healthy within 3 minutes after rollback" exit 1