Skip to content

Commit be315e3

Browse files
authored
Merge pull request #1 from knecasov/add-coverage-workflow
ci: add Go test coverage workflow
2 parents d636930 + 743da24 commit be315e3

4 files changed

Lines changed: 115 additions & 1 deletion

File tree

.github/workflows/coverage.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
on:
2+
push:
3+
branches:
4+
- main
5+
pull_request:
6+
7+
name: Go test coverage
8+
9+
jobs:
10+
coverage:
11+
name: Measure test coverage (unit + integration tests)
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Install golang
15+
uses: actions/setup-go@v5
16+
with:
17+
go-version: "1.25"
18+
19+
- name: Check out repository code
20+
uses: actions/checkout@v4
21+
22+
- name: Run tests with coverage
23+
run: make test-coverage
24+
25+
- name: Download base coverage breakdown
26+
id: download-main-breakdown
27+
uses: dawidd6/action-download-artifact@v6
28+
with:
29+
branch: main
30+
workflow_conclusion: success
31+
name: main.breakdown
32+
if_no_artifact_found: warn
33+
34+
# continue-on-error: allow workflow to proceed to post PR comment and upload artifacts
35+
- name: Check coverage thresholds
36+
id: coverage
37+
uses: vladopajic/go-test-coverage@v2
38+
continue-on-error: true
39+
with:
40+
config: .testcoverage.yml
41+
breakdown-file-name: ${{ github.ref_name == 'main' && 'main.breakdown' || '' }}
42+
diff-base-breakdown-file-name: ${{ steps.download-main-breakdown.outputs.found_artifact == 'true' && 'main.breakdown' || '' }}
43+
44+
- name: Find pull request ID
45+
run: |
46+
PR_DATA=$(curl -s -H "Authorization: token ${{ github.token }}" \
47+
"https://api.github.com/repos/${{ github.repository }}/pulls?head=${{ github.repository_owner }}:${{ github.head_ref || github.ref_name }}&state=open")
48+
PR_ID=$(echo "$PR_DATA" | jq -r '.[0].number')
49+
if [ "$PR_ID" != "null" ]; then
50+
echo "pull_request_id=$PR_ID" >> "$GITHUB_ENV"
51+
else
52+
echo "No open pull request found for branch ${{ github.head_ref || github.ref_name }}."
53+
fi
54+
55+
- name: Post coverage report to PR
56+
if: env.pull_request_id
57+
uses: thollander/actions-comment-pull-request@v3
58+
with:
59+
github-token: ${{ github.token }}
60+
comment-tag: coverage-report
61+
pr-number: ${{ env.pull_request_id }}
62+
message: |
63+
`go-test-coverage` report
64+
```
65+
${{ fromJSON(steps.coverage.outputs.report) }}```
66+
67+
- name: Upload coverage breakdown
68+
uses: actions/upload-artifact@v4
69+
if: github.ref_name == 'main'
70+
with:
71+
name: main.breakdown
72+
path: main.breakdown
73+
if-no-files-found: error
74+
75+
- name: Upload coverage report
76+
if: always()
77+
uses: actions/upload-artifact@v4
78+
with:
79+
name: coverage-report
80+
path: test/coverage/coverage.html
81+
82+
# fail the workflow if coverage thresholds are not met, after PR comment and artifacts are posted
83+
- name: Fail if coverage thresholds not met
84+
if: steps.coverage.outcome == 'failure'
85+
shell: bash
86+
run: echo "Coverage thresholds are not met." && exit 1

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ go.work.sum
66
go-fdo-client
77
go-fdo-client-*.tar.*
88
rpmbuild
9+
test/coverage

.testcoverage.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
profile: test/coverage/coverage.out
2+
threshold:
3+
file: 0
4+
package: 0
5+
total: 0

Makefile

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ SPEC_FILE_NAME := $(PROJECT).spec
77
SPEC_FILE := $(SOURCEDIR)/$(SPEC_FILE_NAME)
88
COMMIT_SHORT := $(shell git rev-parse --short HEAD)
99
VERSION := $(shell grep 'Version:' $(SPEC_FILE) | awk '{printf "%s", $$2}').git$(COMMIT_SHORT)
10+
GOFLAGS ?=
11+
COVERDIR ?= $(CURDIR)/test/coverage
12+
GOCOVERDIR ?= $(COVERDIR)/integration
1013

1114
GO_VENDOR_TOOLS_FILE_NAME := go-vendor-tools.toml
1215
GO_VENDOR_TOOLS_FILE := $(SOURCEDIR)/$(GO_VENDOR_TOOLS_FILE_NAME)
@@ -20,7 +23,7 @@ all: build test
2023

2124
.PHONY: build
2225
build: tidy fmt vet
23-
go build -ldflags="-X github.com/fido-device-onboard/go-fdo-client/internal/version.VERSION=$(VERSION)"
26+
go build $(GOFLAGS) -ldflags="-X github.com/fido-device-onboard/go-fdo-client/internal/version.VERSION=$(VERSION)"
2427

2528
.PHONY: tidy
2629
tidy:
@@ -38,6 +41,25 @@ vet:
3841
test:
3942
go test -v ./...
4043

44+
.PHONY: test-coverage
45+
test-coverage: SHELL := /usr/bin/env bash
46+
test-coverage:
47+
rm -rf "$(COVERDIR)"
48+
mkdir -p "$(GOCOVERDIR)"
49+
go test -coverpkg=./... -coverprofile="$(COVERDIR)/unit.out" -covermode=atomic ./...
50+
export GOCOVERDIR="$(GOCOVERDIR)"; \
51+
set -e; \
52+
$(MAKE) build GOFLAGS="-cover -covermode=atomic" && sudo install -D -m 755 $(PROJECT) /usr/bin/; \
53+
source .github/scripts/fdo-utils.sh; \
54+
generate_certs; \
55+
docker compose -f .github.qkg1.toppose/servers.yaml up -d --build; \
56+
trap 'docker compose -f .github.qkg1.toppose/servers.yaml logs; docker compose -f .github.qkg1.toppose/servers.yaml down' EXIT; \
57+
test_onboarding; \
58+
go tool covdata textfmt -i="$(GOCOVERDIR)" -o="$(COVERDIR)/integration.out"
59+
go install github.com/wadey/gocovmerge@latest
60+
gocovmerge "$(COVERDIR)/unit.out" "$(COVERDIR)/integration.out" > "$(COVERDIR)/coverage.out"
61+
go tool cover -html="$(COVERDIR)/coverage.out" -o "$(COVERDIR)/coverage.html"
62+
4163
.PHONY: vendor-tarball
4264
vendor-tarball: $(VENDOR_TARBALL)
4365

0 commit comments

Comments
 (0)