name: Test & Deploy

on:
  workflow_dispatch:
  pull_request:
  push:
    tags: ["*"]
    branches: ["main"]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  lint:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v6
      - uses: jdx/mise-action@v4
        with:
          experimental: true
      - name: Install Hex
        run: mix local.hex --force
      - name: Install Rebar
        run: mix local.rebar --force
      - name: Add Fluxon UI repo
        run: |
          mix hex.repo add fluxon https://repo.fluxonui.com \
            --fetch-public-key $FLUXON_KEY_FINGERPRINT \
            --auth-key $FLUXON_LICENSE_KEY
        env:
          FLUXON_LICENSE_KEY: ${{ secrets.FLUXON_LICENSE_KEY }}
          FLUXON_KEY_FINGERPRINT: ${{ secrets.FLUXON_KEY_FINGERPRINT }}
      - name: Cache deps
        uses: actions/cache@v5
        env:
          cache-name: cache-elixir-deps
        with:
          path: deps
          key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('.tool-versions') }}-${{ hashFiles('**/mix.lock') }}
          restore-keys: |
            ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('.tool-versions') }}-
      - name: Cache compiled build
        uses: actions/cache@v5
        env:
          cache-name: cache-compiled-build-lint
        with:
          path: _build
          key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('.tool-versions') }}-${{ hashFiles('**/mix.lock') }}
          restore-keys: |
            ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('.tool-versions') }}-
            ${{ runner.os }}-mix-${{ env.cache-name }}-
      - name: Clean to rule out incremental build as a source of flakiness
        if: github.run_attempt != '1'
        run: |
          mix deps.clean --all
          mix clean
      - name: Fetch dependencies
        run: mix deps.get
      - name: 📦 Check unused dependencies
        run: mix deps.unlock --check-unused
      - name: Override env defaults
        # Half the number of available cores
        # See https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories
        run: |
          mise set MIX_ENV=dev
          mise set MIX_OS_DEPS_COMPILE_PARTITION_COUNT=2
      - name: 🔮 Compile for DEV
        run: mix compile --warnings-as-errors
      - name: 🌍 Check translations
        run: mix gettext.extract --check-up-to-date
      - name: 💅 Check formatting
        run: mix format --check-formatted
      - name: 👨‍🏫 Check Credo
        run: mix credo --strict
      - name: 👮 Run Sobelow
        run: mix sobelow
      - name: 🐚 Run Shellcheck
        run: |
          fd . 'scripts/' --exclude '*.hurl' -t file --exec shellcheck --color
          fd . '.claude/hooks' -t file --exec shellcheck --color
      - name: 🐳 Validate Docker builder image
        run: mise run dev:validate-docker-image

  test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v6
      - uses: jdx/mise-action@v4
        with:
          experimental: true
      - name: Install Hex
        run: mix local.hex --force
      - name: Install Rebar
        run: mix local.rebar --force
      - name: Add Fluxon UI repo
        run: |
          mix hex.repo add fluxon https://repo.fluxonui.com \
            --fetch-public-key $FLUXON_KEY_FINGERPRINT \
            --auth-key $FLUXON_LICENSE_KEY
        env:
          FLUXON_LICENSE_KEY: ${{ secrets.FLUXON_LICENSE_KEY }}
          FLUXON_KEY_FINGERPRINT: ${{ secrets.FLUXON_KEY_FINGERPRINT }}
      - name: Cache deps
        uses: actions/cache@v5
        env:
          cache-name: cache-elixir-deps
        with:
          path: deps
          key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('.tool-versions') }}-${{ hashFiles('**/mix.lock') }}
          restore-keys: |
            ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('.tool-versions') }}-
      - name: Cache compiled build
        uses: actions/cache@v5
        env:
          cache-name: cache-compiled-build-test
        with:
          path: _build
          key: ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('.tool-versions') }}-${{ hashFiles('**/mix.lock') }}
          restore-keys: |
            ${{ runner.os }}-mix-${{ env.cache-name }}-${{ hashFiles('.tool-versions') }}-
            ${{ runner.os }}-mix-${{ env.cache-name }}-
      - name: Clean to rule out incremental build as a source of flakiness
        if: github.run_attempt != '1'
        run: |
          mix deps.clean --all
          mix clean
      - name: Fetch dependencies
        run: mix deps.get
      - name: Override env defaults
        # Half the number of available cores
        # See https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories
        run: |
          mise set CLOAK_ENCRYPTION_KEY=f5ol1dJROsm9yi/tvtHiblN8aLH1FUN/obEvUcASx3U=
          mise set MIX_ENV=test
          mise set MIX_OS_DEPS_COMPILE_PARTITION_COUNT=2
      - name: 🔮 Compile for TEST
        run: mix compile
      - name: 🧪 Run tests
        run: mix test --max-cases 8

  deploy:
    name: Deploy
    needs: [lint, test]
    runs-on: ubuntu-latest
    environment: production
    if: github.ref == 'refs/heads/main'
    concurrency: deploy-group
    steps:
      - uses: actions/checkout@v6
      - uses: gacts/install-hurl@v1
      - name: 🚀 Deploy to production
        run: hurl --test --report-tap deploy.tap scripts/prod/deploy.hurl
        env:
          HURL_coolify_token: ${{ secrets.COOLIFY_TOKEN }}
          HURL_coolify_host: ${{ vars.COOLIFY_HOST }}
          HURL_coolify_app_uuid: ${{ vars.COOLIFY_APP_UUID }}
      - name: ⏳ Wait for container to start
        run: hurl --test --report-tap healthcheck.tap test/healthcheck.hurl
      - name: ✅ Run verification tests
        run: hurl --test --report-tap verification.tap test/prod.hurl
        env:
          HURL_api_token: ${{ secrets.API_TOKEN }}
      - uses: pcolby/tap-summary@v1
