name: Deploy

on:
  push:
    branches: [main]

concurrency:
  group: deploy-production
  cancel-in-progress: false

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: astral-sh/setup-uv@v4
        with:
          version: "latest"

      - run: uv sync --extra dev

      - name: Lint
        run: uv run ruff check

      - name: Format check
        run: uv run ruff format --check

      - name: Test
        run: uv run pytest

  deploy:
    needs: check
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - name: Fetch secrets from Doppler
        uses: dopplerhq/secrets-fetch-action@v1.3.1
        id: secrets
        with:
          doppler-token: ${{ secrets.DOPPLER_SERVICE_TOKEN }}
          doppler-project: specwright
          doppler-config: prd

      - name: Install doctl
        uses: digitalocean/action-doctl@v2
        with:
          token: ${{ steps.secrets.outputs.DIGITALOCEAN_ACCESS_TOKEN }}

      - name: Log in to DOCR
        run: doctl registry login --expiry-seconds 600

      - name: Build and push Docker image
        run: |
          IMAGE="registry.digitalocean.com/${{ steps.secrets.outputs.DOCR_REGISTRY_NAME }}/specwright"
          TAG="sha-${GITHUB_SHA::7}"
          docker build -t "${IMAGE}:${TAG}" -t "${IMAGE}:latest" .
          docker push "${IMAGE}:${TAG}"
          docker push "${IMAGE}:latest"
          echo "IMAGE_TAG=${TAG}" >> "$GITHUB_ENV"

      - name: Save kubeconfig
        run: doctl kubernetes cluster kubeconfig save ${{ steps.secrets.outputs.DOKS_CLUSTER_NAME }}

      - name: Ensure DOCR pull secret
        run: |
          kubectl create namespace specwright --dry-run=client -o yaml | kubectl apply -f -
          doctl registry kubernetes-manifest --namespace specwright | kubectl apply -f -

      - name: Ensure app secrets
        env:
          GH_APP_ID: ${{ steps.secrets.outputs.GH_APP_ID }}
          GH_PRIVATE_KEY: ${{ steps.secrets.outputs.GH_PRIVATE_KEY }}
          GH_WEBHOOK_SECRET: ${{ steps.secrets.outputs.GH_WEBHOOK_SECRET }}
          GH_INSTALLATION_ID: ${{ steps.secrets.outputs.GH_INSTALLATION_ID }}
          ANTHROPIC_API_KEY: ${{ steps.secrets.outputs.ANTHROPIC_API_KEY }}
          DATABASE_URL: ${{ steps.secrets.outputs.DATABASE_URL }}
          GCP_SERVICE_ACCOUNT_KEY: ${{ steps.secrets.outputs.GCP_SERVICE_ACCOUNT_KEY }}
          GOOGLE_CLOUD_PROJECT: ${{ steps.secrets.outputs.GOOGLE_CLOUD_PROJECT }}
          GOOGLE_CLOUD_LOCATION: ${{ steps.secrets.outputs.GOOGLE_CLOUD_LOCATION }}
          AUTH0_DOMAIN: ${{ steps.secrets.outputs.AUTH0_DOMAIN }}
          AUTH0_CLIENT_ID: ${{ steps.secrets.outputs.AUTH0_CLIENT_ID }}
          AUTH0_CLIENT_SECRET: ${{ steps.secrets.outputs.AUTH0_CLIENT_SECRET }}
          AUTH0_AUDIENCE: ${{ steps.secrets.outputs.AUTH0_AUDIENCE }}
          AUTH0_DEVICE_CLIENT_ID: ${{ steps.secrets.outputs.AUTH0_DEVICE_CLIENT_ID }}
          POSTHOG_KEY: ${{ steps.secrets.outputs.POSTHOG_KEY }}
        run: |
          kubectl create secret generic specwright-github \
            --from-literal=GH_APP_ID="$GH_APP_ID" \
            --from-literal=GH_PRIVATE_KEY="$GH_PRIVATE_KEY" \
            --from-literal=GH_WEBHOOK_SECRET="$GH_WEBHOOK_SECRET" \
            --from-literal=GH_INSTALLATION_ID="$GH_INSTALLATION_ID" \
            -n specwright --dry-run=client -o yaml | kubectl apply -f -
          kubectl create secret generic specwright-anthropic \
            --from-literal=ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
            -n specwright --dry-run=client -o yaml | kubectl apply -f -
          kubectl create secret generic specwright-neon \
            --from-literal=DATABASE_URL="$DATABASE_URL" \
            -n specwright --dry-run=client -o yaml | kubectl apply -f -
          kubectl create secret generic specwright-gcp \
            --from-literal=GCP_SERVICE_ACCOUNT_KEY="$GCP_SERVICE_ACCOUNT_KEY" \
            --from-literal=GOOGLE_CLOUD_PROJECT="$GOOGLE_CLOUD_PROJECT" \
            --from-literal=GOOGLE_CLOUD_LOCATION="$GOOGLE_CLOUD_LOCATION" \
            -n specwright --dry-run=client -o yaml | kubectl apply -f -
          kubectl create secret generic specwright-auth0 \
            --from-literal=AUTH0_DOMAIN="$AUTH0_DOMAIN" \
            --from-literal=AUTH0_CLIENT_ID="$AUTH0_CLIENT_ID" \
            --from-literal=AUTH0_CLIENT_SECRET="$AUTH0_CLIENT_SECRET" \
            --from-literal=AUTH0_AUDIENCE="$AUTH0_AUDIENCE" \
            --from-literal=AUTH0_DEVICE_CLIENT_ID="$AUTH0_DEVICE_CLIENT_ID" \
            -n specwright --dry-run=client -o yaml | kubectl apply -f -
          kubectl create secret generic specwright-posthog \
            --from-literal=POSTHOG_KEY="$POSTHOG_KEY" \
            -n specwright --dry-run=client -o yaml | kubectl apply -f -

      - name: Deploy with Helm
        run: |
          helm upgrade --install specwright chart/specwright/ \
            -f chart/specwright/values-production.yaml \
            --set image.tag="${IMAGE_TAG}" \
            -n specwright --create-namespace \
            --wait --timeout 5m
