From 78ce0fca5b0aff911884a7acb88ca02d9ee60662 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Thu, 4 Jul 2024 23:19:07 +1000 Subject: [PATCH] gha: collate and calculate coverage for all test runs By combining the coverage from all platforms as well as privileged and non-privileged Linux runs, the coverage is now 87.7% for the entire project. It was necessary to split the Windows CI scripts because mktemp doesn't work in Powershell and it's necessary to reimplement the whole thing to get what you need (not to mention that -test.gocoverdir needs to be quoted in a particular way to not make Powershell angry). Signed-off-by: Aleksa Sarai --- .github/workflows/ci.yml | 98 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1e819e3..dcccd2d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,14 +11,51 @@ on: - cron: "30 10 * * 0" jobs: - test: + test-windows: + strategy: + fail-fast: false + matrix: + go-version: + - "1.21" + - "1.22" + - "^1" + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.go-version }} + - name: mkdir gocoverdir + run: | + # mktemp --tmpdir -d gocoverdir.XXXXXXXX + function New-TemporaryDirectory { + param ( + [string] $Prefix + ) + $parent = [System.IO.Path]::GetTempPath() + do { + [string] $guid = [System.Guid]::NewGuid() + $item = New-Item -Path "$parent" -Name "$Prefix.$guid" -ItemType "directory" -ErrorAction SilentlyContinue + } while (-not "$item") + return $item.FullName + } + $GOCOVERDIR = (New-TemporaryDirectory -Prefix "gocoverdir") + echo "GOCOVERDIR=$GOCOVERDIR" >>"$env:GITHUB_ENV" + - name: unit tests + run: go test -v -cover '-test.gocoverdir' "$env:GOCOVERDIR" ./... + - name: upload coverage + uses: actions/upload-artifact@v4 + with: + name: coverage-${{ runner.os }}-${{ github.job }}-${{ strategy.job-index }} + path: ${{ env.GOCOVERDIR }} + + test-unix: strategy: fail-fast: false matrix: os: - ubuntu-latest - macos-latest - - windows-latest go-version: - "1.21" - "1.22" @@ -33,9 +70,56 @@ jobs: - uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} + - name: mkdir gocoverdir + run: | + GOCOVERDIR="$(mktemp --tmpdir -d gocoverdir.XXXXXXXX)" + echo "GOCOVERDIR=$GOCOVERDIR" >>"$GITHUB_ENV" - name: unit tests - run: go test -v -cover ./... - # TODO: Merge the code coverage stats from both runs... - - name: unit tests (root) - if: ${{ ! startsWith(matrix.os, 'windows-') }} - run: sudo go test -v -cover ./... + run: | + go test -v -cover -test.gocoverdir="$GOCOVERDIR" ./... + sudo go test -v -cover -test.gocoverdir="$GOCOVERDIR" ./... + - name: upload coverage + uses: actions/upload-artifact@v4 + with: + name: coverage-${{ runner.os }}-${{ github.job }}-${{ strategy.job-index }} + path: ${{ env.GOCOVERDIR }} + + coverage: + runs-on: ubuntu-latest + needs: + - test-windows + - test-unix + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: "^1" + - name: download all coverage + uses: actions/download-artifact@v4 + with: + path: coverage + - name: generate coverage list + run: | + find coverage/ + GOCOVERDIRS="$(printf '%s,' coverage/* | sed 's|,$||')" + echo "GOCOVERDIRS=$GOCOVERDIRS" >>"$GITHUB_ENV" + FULLCOVERAGE_FILE="$(mktemp --tmpdir fullcoverage.XXXXXXXX)" + echo "FULLCOVERAGE_FILE=$FULLCOVERAGE_FILE" >>"$GITHUB_ENV" + - name: compute coverage + run: go tool covdata percent -i "$GOCOVERDIRS" + - name: compute func coverage + run: go tool covdata func -i "$GOCOVERDIRS" + - name: merge coverage + run: | + go tool covdata textfmt -i "$GOCOVERDIRS" -o "$FULLCOVERAGE_FILE" + go tool cover -html="$FULLCOVERAGE_FILE" -o "$FULLCOVERAGE_FILE.html" + - name: upload merged coverage + uses: actions/upload-artifact@v4 + with: + name: fullcoverage-${{ github.job }} + path: ${{ env.FULLCOVERAGE_FILE }} + - name: upload coverage html + uses: actions/upload-artifact@v4 + with: + name: fullcoverage-${{ github.job }}.html + path: ${{ env.FULLCOVERAGE_FILE }}.html