Skip to content

Commit d8fdcd2

Browse files
committed
feat(ci): Add 80% coverage threshold enforcement
- Add coverage-check target to Makefile with 80% threshold - Add coverage threshold check step to CI workflow for Go 1.25 - Create codecov.yml with project/patch coverage targets (80%) - Add input validation for missing coverage file and empty results - Keep Codecov as informational only (inline check is the hard gate) Task: #3835
1 parent 2adff82 commit d8fdcd2

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

.github/workflows/ci.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,35 @@ jobs:
7373
go tool cover -func=coverage-integration.out | grep total | awk '{print "Integration test coverage: " $3}'
7474
fi
7575
76+
- name: Check coverage threshold
77+
if: matrix.go-version == '1.25'
78+
run: |
79+
if [ ! -f coverage.out ]; then
80+
echo "::error::Coverage file not found"
81+
exit 1
82+
fi
83+
84+
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
85+
86+
if [ -z "$COVERAGE" ]; then
87+
echo "::error::Failed to extract coverage percentage"
88+
exit 1
89+
fi
90+
91+
THRESHOLD=80
92+
echo "Current coverage: ${COVERAGE}%"
93+
echo "Minimum threshold: ${THRESHOLD}%"
94+
95+
if (( $(echo "$COVERAGE < $THRESHOLD" | bc -l) )); then
96+
echo "::error::Coverage ${COVERAGE}% is below minimum threshold of ${THRESHOLD}%"
97+
exit 1
98+
fi
99+
echo "Coverage check passed!"
100+
76101
- name: Upload coverage to Codecov
77102
if: matrix.go-version == '1.25'
78103
uses: codecov/codecov-action@v4
104+
continue-on-error: true # Codecov is informational; inline check above is the hard gate
79105
with:
80106
files: ./coverage.out,./coverage-integration.out
81107
flags: unittests

Makefile

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
check-prerequisites check-docker check-kubectl \
2424
build test test-integration test-e2e test-all \
2525
lint fmt clean install-deps \
26-
docker-build docker-push
26+
docker-build docker-push \
27+
coverage-check
2728

2829
# ================================================================================================
2930
# Project Configuration
@@ -232,6 +233,20 @@ test-all:
232233
@go tool cover -func=coverage/coverage.out | grep total | awk '{print "Total coverage: " $$3}'
233234
@$(call print_success,"All tests passed - coverage report: coverage/coverage.html")
234235

236+
# Check coverage meets minimum threshold (80%)
237+
COVERAGE_THRESHOLD := 80
238+
coverage-check:
239+
@$(call print_status,"Checking coverage threshold (minimum $(COVERAGE_THRESHOLD)%)...")
240+
@mkdir -p coverage
241+
@go test ./... -covermode=atomic -coverprofile=coverage/coverage.out -short > /dev/null 2>&1
242+
@COVERAGE=$$(go tool cover -func=coverage/coverage.out | grep total | awk '{print $$3}' | sed 's/%//'); \
243+
echo "Current coverage: $${COVERAGE}%"; \
244+
if [ $$(echo "$${COVERAGE} < $(COVERAGE_THRESHOLD)" | bc -l) -eq 1 ]; then \
245+
$(call print_error,"Coverage $${COVERAGE}% is below minimum threshold of $(COVERAGE_THRESHOLD)%"); \
246+
exit 1; \
247+
fi
248+
@$(call print_success,"Coverage check passed (>= $(COVERAGE_THRESHOLD)%)")
249+
235250
# Lint code with golangci-lint
236251
lint:
237252
@$(call print_status,"Running golangci-lint...")
@@ -546,6 +561,7 @@ help:
546561
@echo " make test-integration Run integration tests"
547562
@echo " make test-e2e Run end-to-end tests"
548563
@echo " make test-all Run all tests with coverage report"
564+
@echo " make coverage-check Verify coverage >= 80% threshold"
549565
@echo " make lint Run golangci-lint"
550566
@echo " make fmt Format code with gofmt and goimports"
551567
@echo ""

codecov.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Codecov Configuration
2+
# https://docs.codecov.com/docs/codecov-yaml
3+
4+
coverage:
5+
# Global coverage thresholds
6+
precision: 2
7+
round: down
8+
range: "70...100"
9+
10+
status:
11+
# Project-level coverage (overall repository)
12+
project:
13+
default:
14+
target: 80%
15+
threshold: 2%
16+
if_ci_failed: error
17+
18+
# Patch-level coverage (only changed lines in PR)
19+
patch:
20+
default:
21+
target: 80%
22+
threshold: 5%
23+
if_ci_failed: error
24+
25+
# Comment configuration for PRs
26+
comment:
27+
layout: "reach,diff,flags,tree,betaprofiling"
28+
behavior: default
29+
require_changes: true
30+
require_base: false
31+
require_head: true
32+
33+
# Ignore certain paths from coverage
34+
ignore:
35+
- "**/*_test.go"
36+
- "**/test/**"
37+
- "**/testdata/**"
38+
- "docs/**"
39+
- "deployment/**"
40+
- "helm/**"
41+
42+
# Flag management
43+
flags:
44+
unittests:
45+
paths:
46+
- pkg/
47+
- cmd/
48+
carryforward: true

0 commit comments

Comments
 (0)