name: testing

on:
  push:
    branches: ['master']
  pull_request:
    branches: ['master']

permissions:
  contents: read

jobs:
  test:
    strategy:
      fail-fast: true
      matrix:
        os: [ubuntu-latest, macos-latest]
        go: [
          '1.18',
          '1.19',
          '1.20',
          '1.21',
        ]
        include:
          # Set the minimum Go patch version for the given Go minor
          - go: '1.18'
            GO_VERSION: '~1.18.0'
          - go: '1.19'
            GO_VERSION: '~1.19.0'
          - go: '1.20'
            GO_VERSION: '~1.20.0'
          - go: '1.21'
            GO_VERSION: '~1.21.0'
    runs-on: ${{ matrix.os }}

    steps:
      - name: Set up Go ${{ matrix.go }}
        uses: actions/setup-go@v3
        with:
          go-version: ${{ matrix.GO_VERSION }}
          check-latest: true

      - name: Print environment
        id: vars
        run: |
          printf "Using Go at $(which go) (version $(go version))\n"
          printf "\n\nGo environment:\n\n"
          go env
          printf "\n\nSystem environment:\n\n"
          env

      - name: Cache the build cache
        uses: actions/cache@v3
        with:
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
          key: build-go-${{ matrix.go }}-${{ matrix.os }}-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            build-go-${{ matrix.go }}-${{ matrix.os }}

      - name: Check out the source code
        uses: actions/checkout@v3

      - name: Run tests
        run: GO_ARGS="-v -race -covermode=atomic -coverprofile=coverage.out" make tests

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        if: github.ref == 'refs/heads/master'
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: true
          verbose: true
