name: Tiles Worker
on:
  workflow_dispatch:
  pull_request:
  push:
    branches: [main]

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

env:
  tofu_version: '1.10.2'
  tg_version: '0.83.0'

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./tiles

    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Setup Node
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
        with:
          node-version-file: './tiles/.nvmrc'

      - name: Run npm install
        run: npm ci

      - name: Run linter
        run: npm run lint
        if: ${{ !cancelled() }}

      - name: Run formatter
        run: npm run format
        if: ${{ !cancelled() }}

      - name: Run tsc
        run: npm run check
        if: ${{ !cancelled() }}

      - name: Run unit tests & coverage
        run: npm run test:cov
        if: ${{ !cancelled() }}

  build:
    name: Build
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./tiles

    steps:
      - name: Checkout code
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Setup Node
        uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
        with:
          node-version-file: './tiles/.nvmrc'

      - name: Run npm install
        run: npm ci

      - name: Run tsc
        run: npm run check
        if: ${{ !cancelled() }}

      - name: Wrangler build
        run: npm run build
        if: ${{ !cancelled() }}

      - name: Upload build output
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
        with:
          name: tiles-build-output
          path: tiles/dist
          retention-days: 14
        if: ${{ !cancelled() }}

  check-terragrunt:
    name: Check Terragrunt
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: deployment
    steps:
      - name: 'Checkout'
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install 1Password CLI
        uses: 1password/install-cli-action@8d006a0d0a4fd505af7f7ce589e7f768385ff5e4 # v3.0.0

      - name: Install Terragrunt
        uses: eLco/setup-terragrunt@2c5116f8979bb261072ef57c97ac026cd9c27434 # v1.0.3
        with:
          terragrunt_version: ${{ env.tg_version }}

      - name: 'Install OpenTofu'
        uses: opentofu/setup-opentofu@fc711fa910b93cba0f3fbecaafc9f42fd0c411cb # v2
        with:
          tofu_version: ${{ env.tofu_version }}
          tofu_wrapper: false

      - name: Check Formatting
        run: terragrunt hclfmt --terragrunt-check --terragrunt-diff

      - name: Check TF fmt
        env:
          ENVIRONMENT: dev
          OP_SERVICE_ACCOUNT_TOKEN: ${{ matrix.environment == 'prod' && secrets.OP_TF_PROD_ENV || secrets.OP_TF_DEV_ENV }}
          TF_VAR_tiles_build_dir: "${{ github.workspace }}/dist"
        run: op run --env-file=".env" -- terragrunt run --all fmt -- -diff -check

  plan-terragrunt:
    needs: build
    name: Plan Terragrunt
    runs-on: ubuntu-latest
    strategy:
      matrix:
        environment: [dev, prod]
    if: github.ref != 'refs/heads/main' && github.event_name != 'workflow_dispatch'
    steps:
      - name: 'Checkout'
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install Terragrunt
        uses: eLco/setup-terragrunt@2c5116f8979bb261072ef57c97ac026cd9c27434 # v1.0.3
        with:
          terragrunt_version: ${{ env.tg_version }}

      - name: Install 1Password CLI
        uses: 1password/install-cli-action@8d006a0d0a4fd505af7f7ce589e7f768385ff5e4 # v3.0.0

      - name: 'Install OpenTofu'
        uses: opentofu/setup-opentofu@fc711fa910b93cba0f3fbecaafc9f42fd0c411cb # v2
        with:
          tofu_version: ${{ env.tofu_version }}
          tofu_wrapper: false

      - name: 'Get build artifact'
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          name: tiles-build-output
          path: "${{ github.workspace }}/dist"

      - name: Plan All
        working-directory: ${{ github.workspace }}/deployment
        env:
          ENVIRONMENT: ${{ matrix.environment }}
          OP_SERVICE_ACCOUNT_TOKEN: ${{ matrix.environment == 'prod' && secrets.OP_TF_PROD_ENV || secrets.OP_TF_DEV_ENV }}
          TF_VAR_tiles_build_dir: "${{ github.workspace }}/dist"
        run: op run --env-file=".env" -- terragrunt run --all plan

  deploy-terragrunt:
    needs: [build, test]
    name: Deploy Terragrunt
    runs-on: ubuntu-latest
    if: github.event_name == 'workflow_dispatch' || github.ref == 'refs/heads/main'
    env:
      ENVIRONMENT: ${{ github.ref == 'refs/heads/main' && 'prod' || 'dev' }}
    steps:
      - name: 'Checkout'
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Install 1Password CLI
        uses: 1password/install-cli-action@8d006a0d0a4fd505af7f7ce589e7f768385ff5e4 # v3.0.0

      - name: Install Terragrunt
        uses: eLco/setup-terragrunt@2c5116f8979bb261072ef57c97ac026cd9c27434 # v1.0.3
        with:
          terragrunt_version: ${{ env.tg_version }}

      - name: 'Install OpenTofu'
        uses: opentofu/setup-opentofu@fc711fa910b93cba0f3fbecaafc9f42fd0c411cb # v2
        with:
          tofu_version: ${{ env.tofu_version }}
          tofu_wrapper: false

      - name: 'Get build artifact'
        uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
        with:
          name: tiles-build-output
          path: "${{ github.workspace }}/dist"

      - name: Deploy All
        working-directory: ${{ github.workspace }}/deployment
        env:
          OP_SERVICE_ACCOUNT_TOKEN: ${{ github.ref == 'refs/heads/main' && secrets.OP_TF_PROD_ENV || secrets.OP_TF_DEV_ENV }}
          TF_VAR_tiles_build_dir: "${{ github.workspace }}/dist"
        run: op run --env-file=".env" -- terragrunt run --all apply --non-interactive
