name: build-and-test
on:
  push:
    branches: [main]
    tags:
      - "v[0-9]+.[0-9]+.[0-9]+*"
  pull_request:

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref }}
  cancel-in-progress: true

jobs:
  setup-environment:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version: ~1.20.8
      - name: Cache Go
        id: go-cache
        uses: actions/cache@v3
        with:
          path: |
            ~/go/bin
            ~/go/pkg/mod
          key: go-cache-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
      - name: Install dependencies
        if: steps.go-cache.outputs.cache-hit != 'true'
        run: make gomoddownload

  lint:
    runs-on: ubuntu-latest
    needs: [setup-environment]
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version: ~1.20.8
      - name: Cache Go
        id: go-cache
        uses: actions/cache@v3
        with:
          path: |
            ~/go/bin
            ~/go/pkg/mod
          key: go-cache-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
      - name: golint
        run: make -j2 golint
      - name: goimpi
        run: make goimpi

  govulncheck:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version: ~1.20.8
      - name: Cache Go
        id: go-cache
        uses: actions/cache@v3
        with:
          path: |
            ~/go/bin
            ~/go/pkg/mod
          key: go-cache-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
      - name: Install Tools
        if: steps.go-cache.outputs.cache-hit != 'true'
        run: make install-tools
      - name: Run `govulncheck`
        run: make govulncheck

  checks:
    runs-on: ubuntu-latest
    needs: [setup-environment]
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version: ~1.20.8
      - name: Cache Go
        id: go-cache
        uses: actions/cache@v3
        with:
          path: |
            ~/go/bin
            ~/go/pkg/mod
          key: go-cache-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
      - name: checklicense
        run: make checklicense
      - name: misspell
        run: make misspell
      - name: checkdoc
        run: make checkdoc
      - name: go:porto
        run: |
          make goporto
          git diff --exit-code || (echo 'Porto links are out of date, please run "make goporto" and commit the changes in this PR.' && exit 1)
      - name: go:generate
        run: |
          make gogenerate
          git diff --exit-code || (echo 'Generated code is out of date, please run "make gogenerate" and commit the changes in this PR.' && exit 1)
      - name: Gen Pdata
        run: |
          make genpdata
          git diff --exit-code || (echo 'Generated code is out of date, please run "make genpdata" and commit the changes in this PR.' && exit 1)
      - name: Gen dependabot
        run: |
          make gendependabot
          git diff -s --exit-code || (echo 'ALL_MODULES have been changed, please run "make gendependabot" and commit the changes in this PR.' && exit 1)
      - name: Gen otelcorecol
        run: |
          make genotelcorecol
          git diff -s --exit-code || (echo 'Generated code is out of date, please run "make genotelcorecol" and commit the changes in this PR.' && exit 1)
      - name: Multimod verify
        run: make multimod-verify
      - name: crosslink
        run: |
          make crosslink
          git diff -s --exit-code || (echo 'Replace statements are out of date, please run "make crosslink" and commit the changes in this PR.' && exit 1)

  unittest-matrix:
    strategy:
      matrix:
        go-version: ["~1.21.1", "~1.20.8"] # 1.20 needs quotes otherwise it's interpreted as 1.2
    runs-on: ubuntu-latest
    needs: [setup-environment]
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version: ${{ matrix.go-version }}
      - name: Cache Go
        id: go-cache
        uses: actions/cache@v3
        with:
          path: |
            ~/go/bin
            ~/go/pkg/mod
          key: go-cache-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
      - name: Cache Build
        uses: actions/cache@v3
        with:
          path: ~/.cache/go-build
          key: unittest-${{ runner.os }}-go-build-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }}
      - name: Run Unit Tests
        run: make gotest
  unittest:
    if: always()
    runs-on: ubuntu-latest
    needs: [setup-environment, unittest-matrix]
    steps:
      - name: Print result
        run: echo ${{ needs.unittest-matrix.result }}
      - name: Interpret result
        run: |
          if [[ success == ${{ needs.unittest-matrix.result }} ]]
          then
            echo "All matrix jobs passed!"
          else
            echo "One or more matrix jobs failed."
            false
          fi

  test-coverage:
    runs-on: ubuntu-latest
    needs: [setup-environment]
    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version: ~1.20.6
      - name: Cache Go
        id: go-cache
        uses: actions/cache@v3
        with:
          path: |
            ~/go/bin
            ~/go/pkg/mod
          key: go-cache-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
      - name: Cache Build
        uses: actions/cache@v3
        with:
          path: ~/.cache/go-build
          key: coverage-${{ runner.os }}-go-build-${{ hashFiles('**/go.sum') }}
      - name: Run Unit Tests With Coverage
        run: make gotest-with-cover
      - name: Upload coverage report
        uses: Wandalen/wretry.action@v1.3.0
        with:
          action: codecov/codecov-action@v3
          with: |
            file: ./coverage.txt
            fail_ci_if_error: true
            verbose: true
          attempt_limit: 10
          attempt_delay: 15000

  cross-build-collector:
    needs: [setup-environment]
    runs-on: ubuntu-latest
    timeout-minutes: 10
    strategy:
      fail-fast: false
      matrix:
        include:
          # Go 1.15 dropped support for 32-bit binaries
          # on macOS: https://go.dev/doc/go1.15
          #- goos: darwin
          #  goarch: 386
          - goos: darwin
            goarch: amd64
          - goos: darwin
            goarch: arm64
          - goos: linux
            goarch: 386
          - goos: linux
            goarch: amd64
          - goos: linux
            goarch: arm64
          - goos: linux
            goarch: ppc64le
          - goos: linux
            goarch: arm
            goarm: 7
          - goos: windows
            goarch: 386
          - goos: windows
            goarch: amd64

    steps:
      - name: Checkout Repo
        uses: actions/checkout@v4
      - name: Setup Go
        uses: actions/setup-go@v4
        with:
          go-version: ~1.20.8
      - name: Cache Go
        id: go-cache
        uses: actions/cache@v3
        with:
          path: |
            ~/go/bin
            ~/go/pkg/mod
          key: go-cache-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
      - name: Build
        env:
          GOOS: ${{matrix.goos}}
          GOARCH: ${{matrix.goarch}}
          GOARM: ${{matrix.goarm}}
        run: |
          make otelcorecol
