name: API - Build and Publish

on:
  release:
    types: [created]

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: api
    steps:x
      - name: Checkout source code
        uses: actions/checkout@v4

      - name: Setup Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version: "1.3.6"

      - name: Install dependencies
        run: bun install --frozen-lockfile

      - name: Generate Prisma client
        run: DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy" bunx prisma generate

      - name: Run tests
        run: bun test --preload ./tests/setup.ts

  build:
    name: Build
    needs: [test]
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push the Docker image
        uses: docker/build-push-action@v6
        with:
          context: ./api
          push: true
          target: runtime
          tags: |
            ghcr.io/project-optima/ttscm-api:latest
            ghcr.io/project-optima/ttscm-api:${{ github.event.release.tag_name }}

      - name: Build and push the migration image
        uses: docker/build-push-action@v6
        with:
          context: ./api
          push: true
          target: migration
          tags: |
            ghcr.io/project-optima/ttscm-api-migrate:latest
            ghcr.io/project-optima/ttscm-api-migrate:${{ github.event.release.tag_name }}

  migrate:
    name: Run Migrations
    needs: [build]
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: api
    steps:
      - name: Set the Kubernetes context
        uses: azure/k8s-set-context@v2
        with:
          method: kubeconfig
          kubeconfig: ${{ secrets.KUBECONFIG }}

      - name: Checkout source code
        uses: actions/checkout@v4

      - name: Delete previous migration job if exists
        run: kubectl delete job -n optima -l app=prisma-migrate --ignore-not-found

      - name: Apply migration job
        run: |
          TAG=${{ github.event.release.tag_name }}
          sed "s/RELEASE_TAG/${TAG}/g" kubernetes/migration-job.yaml | kubectl apply -f -

      - name: Wait for migration to complete
        run: |
          TAG=${{ github.event.release.tag_name }}
          kubectl wait --for=condition=complete --timeout=120s -n optima job/prisma-migrate-${TAG}

  deploy:
    name: Deploy
    needs: [migrate]
    runs-on: ubuntu-latest
    steps:
      - name: Set the Kubernetes context
        uses: azure/k8s-set-context@v2
        with:
          method: kubeconfig
          kubeconfig: ${{ secrets.KUBECONFIG }}

      - name: Checkout source code
        uses: actions/checkout@v4

      - name: Lint Kubernetes manifests
        uses: azure/k8s-lint@v3
        with:
          lintType: dryrun
          manifests: |
            api/kubernetes/deployment.yaml
            api/kubernetes/ingress.yaml
          namespace: optima

      - name: Deploy to the Kubernetes cluster
        uses: azure/k8s-deploy@v5
        with:
          namespace: optima
          force: true
          skip-tls-verify: true
          manifests: |
            api/kubernetes/deployment.yaml
            api/kubernetes/ingress.yaml
          images: |
            ghcr.io/project-optima/ttscm-api:${{ github.event.release.tag_name }}
