-
Notifications
You must be signed in to change notification settings - Fork 2
198 lines (169 loc) · 5.98 KB
/
test.yml
File metadata and controls
198 lines (169 loc) · 5.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
name: Test
on:
push:
branches: [develop, main]
pull_request:
branches: [develop, main]
permissions:
contents: read
pull-requests: write
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
test:
name: "Tests (shard ${{ matrix.shard_index }})"
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
shard_index: [0, 1, 2]
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '1.26.0'
cache: true
- name: Set up buf
uses: bufbuild/buf-setup-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Generate protobuf files
run: buf generate
- name: Download dependencies
run: go mod download
- name: Install gotestsum
run: go install gotest.tools/gotestsum@v1.13.0
- name: Run tests with coverage
env:
SKIP_KAFKA_TESTS: "1"
run: |
mkdir -p coverage
# Split packages across 3 shards via round-robin for parallel execution
shard_pkgs=$(go list ./... | awk "NR % 3 == ${{ matrix.shard_index }}")
pkg_count=$(printf '%s\n' "$shard_pkgs" | sed '/^\s*$/d' | wc -l | tr -d ' ')
echo "Shard ${{ matrix.shard_index }}/3: testing $pkg_count packages"
if [ -z "$shard_pkgs" ] || [ "$pkg_count" -eq 0 ]; then
echo "No packages in this shard, skipping"
exit 0
fi
# Use -short flag to skip timing-sensitive tests in CI
gotestsum --format testdox \
--junitfile test-results.xml \
--jsonfile test-results.json \
-- -short -race -coverprofile=coverage/coverage.out -covermode=atomic $shard_pkgs
- name: Upload coverage artifact
uses: actions/upload-artifact@v7
if: always()
with:
name: coverage-shard-${{ matrix.shard_index }}
path: coverage/coverage.out
if-no-files-found: ignore
- name: Upload test results
uses: actions/upload-artifact@v7
if: always()
with:
name: test-results-shard-${{ matrix.shard_index }}
path: |
test-results.xml
test-results.json
if-no-files-found: ignore
- name: Test summary
uses: test-summary/action@v2
if: ${{ always() && hashFiles('test-results.xml') != '' }}
with:
paths: test-results.xml
- name: Annotate failures
if: failure()
run: |
jq -r 'select(.Action == "fail" and .Test != null) | "::error file=\(.Package | sub("github.com/meridianhub/meridian/"; "")),line=1::\(.Test) failed"' test-results.json | sort -u || true
coverage:
name: Coverage Report
needs: test
runs-on: ubuntu-latest
timeout-minutes: 15
if: always() && !cancelled()
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: '1.26.0'
cache: true
- name: Set up buf
uses: bufbuild/buf-setup-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Generate protobuf files
run: buf generate
- name: Download dependencies
run: go mod download
- name: Download coverage artifacts
uses: actions/download-artifact@v8
with:
pattern: coverage-shard-*
path: coverage-shards
- name: Install gocovmerge
run: go install github.com/wadey/gocovmerge@b5bfa59
- name: Merge coverage from shards
run: |
mkdir -p coverage
shopt -s nullglob
cov_files=(coverage-shards/coverage-shard-*/coverage.out)
if [ ${#cov_files[@]} -eq 0 ]; then
echo "No coverage files found, creating empty profile"
echo "mode: atomic" > coverage/coverage.out
cp coverage/coverage.out coverage/coverage-filtered.out
exit 0
fi
gocovmerge "${cov_files[@]}" > coverage/coverage.out
echo "Filtering generated proto files from coverage..."
grep -v -E '\.pb\.go|\.pb\.validate\.go|_grpc\.pb\.go' coverage/coverage.out > coverage/coverage-filtered.out || true
- name: Generate coverage report
run: go tool cover -html=coverage/coverage.out -o coverage/coverage.html
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
files: ./coverage/coverage.out
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Upload coverage artifacts
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: coverage/
retention-days: 30
- name: Check test coverage threshold
run: |
coverage=$(go tool cover -func=coverage/coverage-filtered.out | grep total | awk '{print $3}' | sed 's/%//')
echo "Coverage (excluding generated proto files): ${coverage}%"
if (( $(echo "$coverage < 50.0" | bc -l) )); then
echo "❌ Coverage ${coverage}% is below 50% threshold"
exit 1
fi
echo "✅ Coverage ${coverage}% meets threshold"
# Gate job preserves the "Run Tests" check name for required status checks
test-gate:
name: Run Tests
needs: [test, coverage]
runs-on: ubuntu-latest
if: always()
steps:
- name: Check results
run: |
if [ "${{ needs.test.result }}" != "success" ]; then
echo "Test shards failed"
exit 1
fi
if [ "${{ needs.coverage.result }}" != "success" ]; then
echo "Coverage check failed"
exit 1
fi
echo "All tests and coverage checks passed"