name: CI
on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

# PRs share a concurrency group (cancel/serialize); Pushes use unique groups to avoid cancellation/queuing
concurrency:
  group: ${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.ref) || github.run_id }}
  cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
  contents: read

jobs:
  run-test:
    timeout-minutes: 15
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Source
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
        with:
          go-version-file: go.mod

      - name: Build and Test
        run: |
          go mod tidy
          go build
          go test -coverprofile=coverage.txt -v ./...

      - name: Upload Coverage
        if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || github.event_name == 'push'
        uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

  # Runs the darwin-tagged tests (sandbox/platform/*_darwin_test.go) that no
  # other job can execute. Convention for darwin integration tests requiring
  # sandbox-exec: fail instead of skip when running in CI
  # (os.Getenv("CI") != "" => t.Fatal) so missing tooling cannot silently
  # hide security tests.
  test-macos:
    timeout-minutes: 15
    runs-on: macos-latest
    steps:
      - name: Checkout Source
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
        with:
          go-version-file: go.mod
          cache: true

      - name: Build and Test
        run: |
          go mod tidy
          go build
          go test -count=1 -v ./...

  test-windows:
    timeout-minutes: 15
    runs-on: windows-latest
    steps:
      - name: Checkout Source
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Set up Go
        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
        with:
          go-version-file: go.mod

      - name: Build and Test
        run: |
          go mod tidy
          go build -o pmg.exe main.go
          go test -v ./internal/flows/...

  e2e-test:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Checkout Source
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Setup Go
        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
        with:
          go-version-file: go.mod

      - name: Setup Node
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: 20
          check-latest: true

      - name: Setup PNPM
        uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5

      - name: Build Binary
        run: make

      - name: Run E2E Tests
        run: chmod +x test/e2e.sh && ./test/e2e.sh
        shell: bash

  goreleaser-test:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Checkout Source
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Setup Go
        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
        with:
          go-version-file: go.mod

      - name: Run Goreleaser
        uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
        with:
          distribution: goreleaser
          version: "~> v2"
          args: build --clean --snapshot

  build-container-test:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Checkout Source
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

      - name: Setup QEMU
        uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4

      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4

      - name: Build Container Image
        run: |
          docker buildx build --platform linux/amd64 --load \
          -t build-container-test:latest .

  release-preflight:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Checkout
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          fetch-depth: 0

      - name: Set up Go
        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6
        with:
          go-version-file: go.mod
          cache: true

      - name: Enable corepack
        run: corepack enable

      - name: Set up Node
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: "24"
          cache: "pnpm"

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

      - name: Install GoReleaser
        uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
        with:
          install-only: true
          version: "~> v2"

      - name: Release preflight
        run: pnpm nx run pmg:release-preflight
