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@v4
        with:
          go-version: 1.21.0

      - name: Setup Python
        uses: actions/setup-python@v4
        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@latest
          go install honnef.co/go/tools/cmd/staticcheck@latest

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

      - name: Run tests
        run: make test

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

  fmt:
    runs-on: ubuntu-latest

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

      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version: 1.21.0

          # 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
