name: build_and_test
on:
  push:
    branches:
      - main
  pull_request:
permissions:
  contents: read
env:
  # path to where test results will be saved
  TEST_RESULTS: /tmp/test-results
  # Default version of Go to use by CI workflows. This should be the latest
  # release of Go; developers likely use the latest release in development and
  # we want to catch any bugs (e.g. lint errors, race detection) with this
  # release before they are merged. The Go compatibility guarantees ensure
  # backwards compatibility with the previous two minor releases and we
  # explicitly test our code for these versions so keeping this at prior
  # versions does not add value.
  DEFAULT_GO_VERSION: "~1.26.0"
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout Repo
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      with:
        fetch-depth: 0 ## Needed for "Set tools/go.mod timestamp" step.
    - name: Install Go
      uses: actions/setup-go@v6
      with:
        go-version: ${{ env.DEFAULT_GO_VERSION }}
        check-latest: true
        cache-dependency-path: "**/go.sum"
    - name: Tools cache
      uses: actions/cache@v5
      env:
        cache-name: go-tools-cache
      with:
        path: .tools
        key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.DEFAULT_GO_VERSION }}-${{ hashFiles('./tools/**') }}
    # The step below is needed to not rebuild all the build tools.
    - name: Set tools/go.mod timestamp
      run: |
        filename="tools/go.mod"
        unixtime=$(git log -1 --format="%at" -- "${filename}")
        touchtime=$(date -d @$unixtime +'%Y%m%d%H%M.%S')
        touch -t ${touchtime} "${filename}"
        ls -la --time-style=full-iso "${filename}"
    - name: Generate
      run: make generate
    - name: Run linters
      run: make toolchain-check license-check lint vanity-import-check
    - name: Build
      run: make build
    - name: Check clean repository
      run: make check-clean-work-tree

  govulncheck:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout Repo
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      with:
        fetch-depth: 0 ## Needed for "Set tools/go.mod timestamp" step.
    - name: Install Go
      uses: actions/setup-go@v6
      with:
        go-version: ${{ env.DEFAULT_GO_VERSION }}
        check-latest: true
        cache-dependency-path: "**/go.sum"
    - name: Tools cache
      uses: actions/cache@v5
      env:
        cache-name: go-tools-cache
      with:
        path: .tools
        key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.DEFAULT_GO_VERSION }}-${{ hashFiles('./tools/**') }}
    # The step below is needed to not rebuild all the build tools.
    - name: Set tools/go.mod timestamp
      run: |
        filename="tools/go.mod"
        unixtime=$(git log -1 --format="%at" -- "${filename}")
        touchtime=$(date -d @$unixtime +'%Y%m%d%H%M.%S')
        touch -t ${touchtime} "${filename}"
        ls -la --time-style=full-iso "${filename}"
    - name: Run govulncheck
      run: make govulncheck

  test-race:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout Repo
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
    - name: Install Go
      uses: actions/setup-go@v6
      with:
        go-version: ${{ env.DEFAULT_GO_VERSION }}
        check-latest: true
        cache-dependency-path: "**/go.sum"
    - name: Run tests with race detector
      run: make test-race

  test-coverage:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout Repo
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
    - name: Install Go
      uses: actions/setup-go@v6
      with:
        go-version: ${{ env.DEFAULT_GO_VERSION }}
        check-latest: true
        cache-dependency-path: "**/go.sum"
    - name: Run coverage tests
      run: |
        make test-coverage
        mkdir $TEST_RESULTS
        cp coverage.out $TEST_RESULTS
        cp coverage.txt $TEST_RESULTS
        cp coverage.html $TEST_RESULTS
    - name: Upload coverage report
      uses: codecov/codecov-action@v6.0.0
      with:
        fail_ci_if_error: true
        files: ./coverage.txt
        verbose: true
    - name: Store coverage test output
      uses: actions/upload-artifact@v7
      with:
        name: opentelemetry-go-contrib-test-output
        path: ${{ env.TEST_RESULTS }}

  compatibility-test:
    strategy:
      matrix:
        go-version: ["1.26.0", "1.25.0"]
        platform:
          - os: ubuntu-latest
            arch: "386"
          - os: ubuntu-latest
            arch: amd64
          - os: macos-latest
            arch: amd64
          - os: macos-latest
            arch: arm64
          - os: windows-latest
            arch: "386"
          - os: windows-latest
            arch: amd64
    runs-on: ${{ matrix.platform.os }}
    steps:
    - name: Checkout code
      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
    - name: Install Go
      uses: actions/setup-go@v6
      with:
        go-version: ${{ matrix.go-version }}
        check-latest: true
        cache-dependency-path: "**/go.sum"
    - name: Run tests
      env:
        GOARCH: ${{ matrix.platform.arch }}
      run: make test-short

  test-compatibility:
    runs-on: ubuntu-latest
    needs: [compatibility-test]
    if: always()
    steps:
      - name: Test if compatibility-test workflow passed
        run: |
          echo ${{ needs.compatibility-test.result }}
          test ${{ needs.compatibility-test.result }} == "success"
