name: Deploy Production

on:
  push:
    tags:
      - 'v*'

permissions:
  contents: read

env:
  BUILD_NO_LOCK: '1'

# Serialize releases. Cancelling between the deploy and its post-deploy gates
# would leave a live worker with gates skipped.
concurrency:
  group: deploy-production
  cancel-in-progress: false

jobs:
  release-gate-verify:
    name: Release gate / typecheck, unit, provenance
    runs-on: [self-hosted, linux, x64, multideal-gate]
    timeout-minutes: 45
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: ./.github/actions/setup
        with:
          github-packages-token: ${{ secrets.GH_PKG_READ_TOKEN }}
      - name: Tag commit must be an ancestor of main
        run: |
          git fetch origin main
          git merge-base --is-ancestor "$GITHUB_SHA" origin/main
      - name: Typecheck
        run: bash apps/web/scripts/cpu-limit.sh pnpm --filter web typecheck
      - name: Default test lane
        run: bash apps/web/scripts/cpu-limit.sh pnpm --filter web test

  release-gate-money:
    name: Release gate / money-path database lanes
    runs-on: [self-hosted, linux, x64, multideal-gate]
    timeout-minutes: 60
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      NEON_API_KEY: ${{ secrets.NEON_CI_API_KEY }}
      NEON_PROJECT_ID: ${{ secrets.NEON_CI_PROJECT_ID }}
      NEON_MAIN_BRANCH_ID: ${{ secrets.NEON_CI_MAIN_BRANCH_ID }}
      SOURCE_DATABASE_URL: ${{ secrets.DATABASE_URL }}
      JWT_SECRET: ${{ secrets.JWT_SECRET }}
      E2E_SECRET: ${{ secrets.E2E_SECRET }}
    steps:
      - uses: actions/checkout@v7
      - uses: ./.github/actions/setup
        with:
          github-packages-token: ${{ secrets.GH_PKG_READ_TOKEN }}
      - name: Real-Postgres cart lane
        run: bash apps/web/scripts/cpu-limit.sh pnpm --filter web test:cart-realpg
      - name: Integration database tests
        run: bash apps/web/scripts/cpu-limit.sh bash apps/web/scripts/ci-with-disposable-pg.sh pnpm test:integration-db

  release-gate-migration:
    name: Release gate / production migration replay
    runs-on: [self-hosted, linux, x64, multideal-gate]
    timeout-minutes: 60
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      NEON_API_KEY: ${{ secrets.NEON_CI_API_KEY }}
      NEON_PROJECT_ID: ${{ secrets.NEON_CI_PROJECT_ID }}
      NEON_MAIN_BRANCH_ID: ${{ secrets.NEON_CI_MAIN_BRANCH_ID }}
      SOURCE_DATABASE_URL: ${{ secrets.DATABASE_URL }}
    steps:
      - uses: actions/checkout@v7
      - uses: ./.github/actions/setup
        with:
          github-packages-token: ${{ secrets.GH_PKG_READ_TOKEN }}
      - name: Migration replay on disposable Postgres
        run: bash apps/web/scripts/cpu-limit.sh bash apps/web/scripts/ci-with-disposable-pg.sh pnpm test:realpg

  deploy-production:
    needs: [release-gate-verify, release-gate-money, release-gate-migration]
    runs-on: [self-hosted, linux, x64, multideal-gate]
    env:
      CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
      CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
      CRON_SECRET: ${{ secrets.CRON_SECRET }}
      TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
      TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
      SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
      SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
      SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
      GIT_TAG: ${{ github.ref_name }}
      NODE_OPTIONS: --max-old-space-size=6144
      # Flip to https://www.multideal.co.il when marketplace traffic launches.
      DEPLOY_URL: https://app.multideal.co.il
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: ./.github/actions/setup
        with:
          github-packages-token: ${{ secrets.GH_PKG_READ_TOKEN }}
      - name: Deploy production (gated)
        id: deploy
        run: bash apps/web/scripts/deploy-prod.sh
      - name: Upload Sentry source maps
        if: success()
        run: |
          if [ -n "$SENTRY_AUTH_TOKEN" ] && [ -n "$SENTRY_ORG" ] && [ -n "$SENTRY_PROJECT" ]; then
            pnpm exec sentry-cli releases new "$GIT_TAG"
            pnpm exec sentry-cli releases files "$GIT_TAG" upload-sourcemaps ./apps/web/dist --rewrite
            pnpm exec sentry-cli releases finalize "$GIT_TAG"
            pnpm exec sentry-cli releases deploys "$GIT_TAG" new -e production
          else
            echo "Sentry env vars not set - skipping source map upload"
          fi
      - name: Notify success
        if: success()
        env:
          SERVER_URL: ${{ github.server_url }}
          REPOSITORY: ${{ github.repository }}
          RUN_ID: ${{ github.run_id }}
        run: |
          if [ -z "$TELEGRAM_BOT_TOKEN" ] || [ -z "$TELEGRAM_CHAT_ID" ]; then exit 0; fi
          RUN_URL="${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID}"
          TG_MESSAGE=$(printf "🚀 Deployed %s to production\n%s" "$GIT_TAG" "$DEPLOY_URL")
          export TG_MESSAGE
          curl -s -X POST \
            "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
            --data-urlencode "text=${TG_MESSAGE}" \
            -d "chat_id=${TELEGRAM_CHAT_ID}" \
            -d "parse_mode=HTML" \
            -d "disable_web_page_preview=true"
      - name: Notify failure
        if: failure()
        env:
          SERVER_URL: ${{ github.server_url }}
          REPOSITORY: ${{ github.repository }}
          RUN_ID: ${{ github.run_id }}
        run: |
          if [ -z "$TELEGRAM_BOT_TOKEN" ] || [ -z "$TELEGRAM_CHAT_ID" ]; then exit 0; fi
          RUN_URL="${SERVER_URL}/${REPOSITORY}/actions/runs/${RUN_ID}"
          TG_MESSAGE=$(printf "💥 Production deploy failed - %s\nRollback: pnpm --filter @multideal/web exec wrangler rollback --env production\n%s" "$GIT_TAG" "$RUN_URL")
          export TG_MESSAGE
          curl -s -X POST \
            "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
            --data-urlencode "text=${TG_MESSAGE}" \
            -d "chat_id=${TELEGRAM_CHAT_ID}" \
            -d "parse_mode=HTML" \
            -d "disable_web_page_preview=true"
