name: build

on:
  pull_request:
    types: [opened, synchronize]
  merge_group:
    types: [checks_requested]
  push:
    # Always run on push to main. The build cache can only be reused
    # if it was saved by a run from the repository's default branch.
    # The run result will be identical to that from the merge queue
    # because the commit is identical, yet we need to perform it to
    # seed the build cache.
    branches:
      - main

jobs:
  tests:
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        os:
          - macos-latest
          - ubuntu-latest
          - windows-latest

    steps:
      - name: Checkout repository and submodules
        uses: actions/checkout@v4

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: 1.23.2

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.9'

      - name: Set go env
        run: |
          echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
          echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
          go install gotest.tools/gotestsum@v1.12.0

      - name: Pull external libraries
        run: |
          make vendor
          pip3 install wheel

      - name: Run tests
        run: make testonly

      - name: Publish test coverage
        uses: codecov/codecov-action@v4

  fmt:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: 1.23.2

          # No need to download cached dependencies when running gofmt.
          cache: false

      - name: Install goimports
        run: |
          go install golang.org/x/tools/cmd/goimports@latest

      - name: Run make fmt
        run: |
          make fmt

      - name: Run go mod tidy
        run: |
          go mod tidy

      - name: Fail on differences
        run: |
          # Exit with status code 1 if there are differences (i.e. unformatted files)
          git diff --exit-code

  golangci:
    name: lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: 1.23.2
      - name: golangci-lint
        uses: golangci/golangci-lint-action@v6
        with:
          version: v1.62.2
          args: --timeout=15m

  validate-bundle-schema:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Go
        uses: actions/setup-go@v5
        with:
          go-version: 1.23.2

      # Github repo: https://github.com/ajv-validator/ajv-cli
      - name: Install ajv-cli
        run: npm install -g ajv-cli@5.0.0

      # Assert that the generated bundle schema is a valid JSON schema by using
      # ajv-cli to validate it against bundle configuration files.
      # By default the ajv-cli runs in strict mode which will fail if the schema
      # itself is not valid. Strict mode is more strict than the JSON schema
      # specification. See for details: https://ajv.js.org/options.html#strict-mode-options
      - name: Validate bundle schema
        run: |
          go run main.go bundle schema > schema.json

          for file in ./bundle/internal/schema/testdata/pass/*.yml; do
            ajv test -s schema.json -d $file --valid
          done

          for file in ./bundle/internal/schema/testdata/fail/*.yml; do
            ajv test -s schema.json -d $file --invalid
          done