diff --git a/.github/workflows/collect-coverage.yml b/.github/workflows/collect-coverage.yml index 67d68b1..d044bb2 100644 --- a/.github/workflows/collect-coverage.yml +++ b/.github/workflows/collect-coverage.yml @@ -20,6 +20,12 @@ jobs: with: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} + - + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0 + with: + go-version: stable + check-latest: true + cache: true - name: Download coverage artifacts uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 @@ -28,6 +34,19 @@ jobs: pattern: "*.coverage.*" # artifacts resolve as folders path: coverage/ + - + name: Reprocess coverage paths + # on projects with a v2 suffix, the go import path reported by coverage doesn't match + # well the actual path. codecov knows about that for the root module, but is unable + # to find its way with versioned go sub-modules. + # We rewrite paths in coverage paths to match actual repo folders. + run: | + go list -m -f '{"name":{{ printf "%q" .Path }},"path":{{ printf "%q" .Dir }}}'|\ + jq -r '[.name,.path] | @tsv' |\ + while IFS=$'\t' read -r name path ; do + target="github.com/${GITHUB_REPOSITORY}/${path#${GITHUB_WORKSPACE}/}" + sed -i "s|${name}|${target}|" $(find coverage -type f -name \*.coverage.\*.out) + done - name: Upload coverage to codecov uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 diff --git a/.github/workflows/go-test-monorepo.yml b/.github/workflows/go-test-monorepo.yml index a1aa4b3..905a963 100644 --- a/.github/workflows/go-test-monorepo.yml +++ b/.github/workflows/go-test-monorepo.yml @@ -25,6 +25,8 @@ jobs: bash-paths: ${{ steps.detect-monorepo.outputs.bash-paths }} bash-subpaths: ${{ steps.detect-monorepo.outputs.bash-subpaths }} module-names: ${{ steps.detect-monorepo.outputs.names }} + coverpkg: ${{ steps.prepare-tests.outputs.coverpkg }} + all-modules: ${{ steps.prepare-tests.outputs.all-modules }} steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -59,6 +61,18 @@ jobs: version: latest only-new-issues: true skip-cache: true + - + name: Prepare tests + id: prepare-tests + run: | + coverpkg=$(echo '${{ steps.detect-monorepo.outputs.names }}' | jq -rc '.[]|.+"/..."'|tr '\n' ','|head -c -1) + echo "coverpkg=${coverpkg}" >> "${GITHUB_OUTPUT}" + echo "::notice::title=coverpkg::${coverpkg}" + + declare -a ALL_MODULES + ALL_MODULES=(${{ steps.detect-monorepo.outputs.bash-subpaths }}) # a bash array with all module folders, suffixed with "/..." + echo "all-modules=${ALL_MODULES[@]}" >> "${GITHUB_OUTPUT}" + echo "::notice::title=Modules found::${ALL_MODULES[@]}" # Carry out the linting the traditional way, within a shell loop #- @@ -105,6 +119,7 @@ jobs: name: Ensure TMP is created on windows runners # On windows, some tests require testing.TempDir to reside on the same drive as the code. # TMP is used by os.TempDir() to determine the location of temporary files. + # This is in particular the case for all programs that use [filepath.Rel]. if: ${{ runner.os == 'Windows' }} shell: bash run: | @@ -117,12 +132,15 @@ jobs: # with go.work file enabled, go test recognizes sub-modules and collects all packages to be covered # without specifying -coverpkg. # + # However, cross-module test coverage is only reported with the appropriate -coverpkg setting. + # # This requires: # * go.work properly initialized with use of all known modules # * go.work committed to git env: EXTRA_FLAGS: ${{ inputs.extra-flags }} run: > + gotestsum --jsonfile 'unit.report.${{ matrix.os }}-${{ matrix.go }}.json' -- @@ -133,7 +151,7 @@ jobs: -timeout=20m -coverprofile='unit.coverage.${{ matrix.os }}-${{ matrix.go }}.out' -covermode=atomic - -coverpkg="$(go list)"/... ${EXTRA_FLAGS} + -coverpkg='${{ needs.lint.outputs.coverpkg }}' ${EXTRA_FLAGS} ./... - name: Run unit tests on all modules ( + gotestsum + --jsonfile 'unit.report.${{ matrix.os }}-${{ matrix.go }}.json' + -- + -race + -p 2 + -count 1 + -timeout=20m + -coverprofile='unit.coverage.${{ matrix.os }}-${{ matrix.go }}.out' + -covermode=atomic + -coverpkg='${{ needs.lint.outputs.coverpkg }}' ${EXTRA_FLAGS} + ${ALL_MODULES} - name: Run unit tests if: ${{ needs.lint.outputs.is-monorepo != 'true' }}