name: go
on:
  pull_request:
  push:

permissions:
  contents: read

jobs:
  build-and-test:
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      GO111MODULE: 'on'
      CGO_ENABLED: '0'
    strategy:
      fail-fast: true
      matrix:
        go: ['1.26']
        os:
        - ubuntu-latest
        - windows-latest
        - macos-latest
    runs-on: ${{ matrix.os }}
    defaults:
      run:
        shell: bash
    name: ${{ matrix.go }} on ${{ matrix.os }}
    steps:

    - name: Check out code
      uses: actions/checkout@v6

    - uses: actions/setup-go@v5
      with:
        go-version: ${{ matrix.go }}

    - id: go-cache-paths
      run: |
        echo "go-build=$(go env GOCACHE)" >> $GITHUB_OUTPUT
        echo "go-mod=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT
    - run: echo ${{ steps.go-cache-paths.outputs.go-build }}
    - run: echo ${{ steps.go-cache-paths.outputs.go-mod }}

    - name: Go Build Cache
      uses: actions/cache@v4
      with:
        path: ${{ steps.go-cache-paths.outputs.go-build }}
        key: ${{ runner.os }}-go-${{ matrix.go }}-build-v2-${{ hashFiles('**/go.sum', 'checker/localizations_src/**/*.yaml') }}
        restore-keys: |
          ${{ runner.os }}-go-${{ matrix.go }}-build-v2-

    - name: Go Mod Cache
      uses: actions/cache@v4
      with:
        path: ${{ steps.go-cache-paths.outputs.go-mod }}
        key: ${{ runner.os }}-go-${{ matrix.go }}-mod-v2-${{ hashFiles('**/go.sum') }}
        restore-keys: |
          ${{ runner.os }}-go-${{ matrix.go }}-mod-v2-

    - run: go mod download && go mod tidy && go mod verify
    - run: git --no-pager diff --exit-code

    - run: go vet ./...
    - run: git --no-pager diff --exit-code

    - if: runner.os == 'Linux'
      name: Generate breaking-changes examples
      run: make doc-breaking-changes
    
    - if: runner.os == 'Linux'
      name: Check breaking-changes examples are up to date
      run: git --no-pager diff --exit-code docs/BREAKING-CHANGES-EXAMPLES.md

    - if: runner.os == 'Linux'
      name: Generate localized messages
      run: |
        make localize
    
    - if: runner.os == 'Linux'
      name: Check localized messages are up to date (excluding timestamp)
      run: |
        # Compare from line 4 onwards (skipping the timestamp on line 3)
        git diff --no-index <(tail -n +4 checker/localizations/localizations.go) <(git show HEAD:checker/localizations/localizations.go | tail -n +4) || exit 0

    - run: go fmt ./...
    - run: git --no-pager diff --exit-code -- ':!checker/localizations/localizations.go'

    - run: go test ./... -coverprofile=coverage.txt -covermode=atomic
      env:
        CGO_ENABLED: '1'

    - if: runner.os == 'Linux'
      name: Errors must not be capitalized https://github.com/golang/go/wiki/CodeReviewComments#error-strings
      run: |
        ! git grep -E '(fmt\.Errorf|errors\.New)\(.[A-Z]'
        
    # - if: runner.os == 'Linux'
    #   name: Did you mean %q
    #   run: |
    #     ! git grep -E "'[%].'"

    - if: runner.os == 'Linux'
      name: Also add yaml tags
      run: |
        ! git grep -InE 'json:"' | grep -v _test.go | grep -v yaml:

    - uses: codecov/codecov-action@v5
      with:
        files: ./coverage.txt
        flags: unittests # optional
        name: codecov-umbrella # optional
        fail_ci_if_error: false # optional (default = false)
        verbose: true # optional (default = false)
        token: ${{ secrets.CODECOV_TOKEN }} # required
