|
11 | 11 | permissions: |
12 | 12 | actions: read |
13 | 13 | contents: read |
| 14 | + pull-requests: write |
14 | 15 |
|
15 | 16 | jobs: |
16 | 17 | coverage: |
@@ -180,85 +181,144 @@ jobs: |
180 | 181 | path: baseline-coverage |
181 | 182 |
|
182 | 183 | - name: Install lcov (Linux) |
183 | | - if: startsWith(matrix.os, 'ubuntu') && steps.download-baseline.outcome == 'success' |
| 184 | + if: startsWith(matrix.os, 'ubuntu') |
184 | 185 | run: sudo apt-get update && sudo apt-get install -y lcov |
185 | 186 |
|
186 | 187 | - name: Install lcov (Windows) |
187 | | - if: startsWith(matrix.os, 'windows') && steps.download-baseline.outcome == 'success' |
| 188 | + if: startsWith(matrix.os, 'windows') |
188 | 189 | run: choco install lcov -y |
189 | 190 | shell: bash |
190 | 191 |
|
191 | | - - name: Compare Coverage (Linux) |
192 | | - if: startsWith(matrix.os, 'ubuntu') && steps.download-baseline.outcome == 'success' |
| 192 | + - name: Generate Coverage Report (Linux) |
| 193 | + if: startsWith(matrix.os, 'ubuntu') |
| 194 | + id: coverage-linux |
193 | 195 | run: | |
194 | | - echo "## Coverage Comparison for ${{ matrix.os }}" >> $GITHUB_STEP_SUMMARY |
195 | | - echo "" >> $GITHUB_STEP_SUMMARY |
| 196 | + # Extract PR coverage |
| 197 | + PR_LINES=$(lcov --summary lcov.info 2>&1 | grep "lines" | sed 's/.*: //' | sed 's/%.*//' | tr -d ' ') |
| 198 | + PR_FUNCTIONS=$(lcov --summary lcov.info 2>&1 | grep "functions" | sed 's/.*: //' | sed 's/%.*//' | tr -d ' ') |
196 | 199 |
|
197 | | - # Extract line coverage from baseline |
| 200 | + # Extract baseline coverage (default to 0 if not available) |
198 | 201 | if [ -f baseline-coverage/lcov.info ]; then |
199 | | - BASELINE_LINES=$(lcov --summary baseline-coverage/lcov.info 2>&1 | grep "lines" | sed 's/.*: //' | sed 's/%.*//') |
200 | | - BASELINE_FUNCTIONS=$(lcov --summary baseline-coverage/lcov.info 2>&1 | grep "functions" | sed 's/.*: //' | sed 's/%.*//') |
201 | | - echo "**Baseline Coverage:**" >> $GITHUB_STEP_SUMMARY |
202 | | - echo "- Lines: ${BASELINE_LINES}%" >> $GITHUB_STEP_SUMMARY |
203 | | - echo "- Functions: ${BASELINE_FUNCTIONS}%" >> $GITHUB_STEP_SUMMARY |
| 202 | + BASELINE_LINES=$(lcov --summary baseline-coverage/lcov.info 2>&1 | grep "lines" | sed 's/.*: //' | sed 's/%.*//' | tr -d ' ') |
| 203 | + BASELINE_FUNCTIONS=$(lcov --summary baseline-coverage/lcov.info 2>&1 | grep "functions" | sed 's/.*: //' | sed 's/%.*//' | tr -d ' ') |
204 | 204 | else |
205 | | - echo "No baseline coverage found" >> $GITHUB_STEP_SUMMARY |
| 205 | + BASELINE_LINES="0" |
| 206 | + BASELINE_FUNCTIONS="0" |
206 | 207 | fi |
207 | 208 |
|
208 | | - # Extract line coverage from PR |
209 | | - PR_LINES=$(lcov --summary lcov.info 2>&1 | grep "lines" | sed 's/.*: //' | sed 's/%.*//') |
210 | | - PR_FUNCTIONS=$(lcov --summary lcov.info 2>&1 | grep "functions" | sed 's/.*: //' | sed 's/%.*//') |
211 | | - echo "" >> $GITHUB_STEP_SUMMARY |
212 | | - echo "**PR Coverage:**" >> $GITHUB_STEP_SUMMARY |
213 | | - echo "- Lines: ${PR_LINES}%" >> $GITHUB_STEP_SUMMARY |
214 | | - echo "- Functions: ${PR_FUNCTIONS}%" >> $GITHUB_STEP_SUMMARY |
215 | | -
|
216 | | - # Calculate diff if baseline exists |
217 | | - if [ -f baseline-coverage/lcov.info ] && [ -n "$BASELINE_LINES" ]; then |
218 | | - LINE_DIFF=$(echo "$PR_LINES - $BASELINE_LINES" | bc) |
219 | | - FUNC_DIFF=$(echo "$PR_FUNCTIONS - $BASELINE_FUNCTIONS" | bc) |
220 | | - echo "" >> $GITHUB_STEP_SUMMARY |
221 | | - echo "**Coverage Change:**" >> $GITHUB_STEP_SUMMARY |
222 | | - echo "- Lines: ${LINE_DIFF}%" >> $GITHUB_STEP_SUMMARY |
223 | | - echo "- Functions: ${FUNC_DIFF}%" >> $GITHUB_STEP_SUMMARY |
| 209 | + # Calculate diff |
| 210 | + LINE_DIFF=$(echo "$PR_LINES - $BASELINE_LINES" | bc) |
| 211 | + FUNC_DIFF=$(echo "$PR_FUNCTIONS - $BASELINE_FUNCTIONS" | bc) |
| 212 | +
|
| 213 | + # Determine delta indicator |
| 214 | + if (( $(echo "$LINE_DIFF > 0" | bc -l) )); then |
| 215 | + DELTA_INDICATOR=":white_check_mark:" |
| 216 | + elif (( $(echo "$LINE_DIFF < 0" | bc -l) )); then |
| 217 | + DELTA_INDICATOR=":x:" |
| 218 | + else |
| 219 | + DELTA_INDICATOR=":heavy_minus_sign:" |
224 | 220 | fi |
| 221 | +
|
| 222 | + # Set outputs |
| 223 | + echo "pr_lines=$PR_LINES" >> $GITHUB_OUTPUT |
| 224 | + echo "baseline_lines=$BASELINE_LINES" >> $GITHUB_OUTPUT |
| 225 | + echo "line_diff=$LINE_DIFF" >> $GITHUB_OUTPUT |
| 226 | + echo "delta_indicator=$DELTA_INDICATOR" >> $GITHUB_OUTPUT |
| 227 | +
|
| 228 | + # Write step summary |
| 229 | + echo "## Test Coverage Report (${{ matrix.os }})" >> $GITHUB_STEP_SUMMARY |
| 230 | + echo "" >> $GITHUB_STEP_SUMMARY |
| 231 | + echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY |
| 232 | + echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY |
| 233 | + echo "| Current Coverage | ${PR_LINES}% |" >> $GITHUB_STEP_SUMMARY |
| 234 | + echo "| Base Branch Coverage | ${BASELINE_LINES}% |" >> $GITHUB_STEP_SUMMARY |
| 235 | + echo "| Delta | ${LINE_DIFF}% ${DELTA_INDICATOR} |" >> $GITHUB_STEP_SUMMARY |
225 | 236 | shell: bash |
226 | 237 |
|
227 | | - - name: Compare Coverage (Windows) |
228 | | - if: startsWith(matrix.os, 'windows') && steps.download-baseline.outcome == 'success' |
| 238 | + - name: Generate Coverage Report (Windows) |
| 239 | + if: startsWith(matrix.os, 'windows') |
| 240 | + id: coverage-windows |
229 | 241 | run: | |
230 | | - echo "## Coverage Comparison for ${{ matrix.os }}" >> $env:GITHUB_STEP_SUMMARY |
231 | | - echo "" >> $env:GITHUB_STEP_SUMMARY |
| 242 | + # Extract PR coverage |
| 243 | + $prContent = Get-Content -Path "lcov.info" -Raw |
| 244 | + $prLinesFound = ($prContent | Select-String -Pattern "LF:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum |
| 245 | + $prLinesHit = ($prContent | Select-String -Pattern "LH:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum |
| 246 | + if ($prLinesFound -gt 0) { |
| 247 | + $prPct = [math]::Round(($prLinesHit / $prLinesFound) * 100, 2) |
| 248 | + } else { |
| 249 | + $prPct = 0 |
| 250 | + } |
232 | 251 |
|
233 | | - # Extract coverage info using PowerShell |
| 252 | + # Extract baseline coverage (default to 0 if not available) |
234 | 253 | if (Test-Path "baseline-coverage/lcov.info") { |
235 | 254 | $baselineContent = Get-Content -Path "baseline-coverage/lcov.info" -Raw |
236 | 255 | $baselineLinesFound = ($baselineContent | Select-String -Pattern "LF:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum |
237 | 256 | $baselineLinesHit = ($baselineContent | Select-String -Pattern "LH:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum |
238 | 257 | if ($baselineLinesFound -gt 0) { |
239 | 258 | $baselinePct = [math]::Round(($baselineLinesHit / $baselineLinesFound) * 100, 2) |
240 | | - echo "**Baseline Coverage:** ${baselinePct}% lines" >> $env:GITHUB_STEP_SUMMARY |
| 259 | + } else { |
| 260 | + $baselinePct = 0 |
241 | 261 | } |
| 262 | + } else { |
| 263 | + $baselinePct = 0 |
242 | 264 | } |
243 | 265 |
|
244 | | - $prContent = Get-Content -Path "lcov.info" -Raw |
245 | | - $prLinesFound = ($prContent | Select-String -Pattern "LF:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum |
246 | | - $prLinesHit = ($prContent | Select-String -Pattern "LH:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum |
247 | | - if ($prLinesFound -gt 0) { |
248 | | - $prPct = [math]::Round(($prLinesHit / $prLinesFound) * 100, 2) |
249 | | - echo "**PR Coverage:** ${prPct}% lines" >> $env:GITHUB_STEP_SUMMARY |
250 | | - } |
| 266 | + $diff = [math]::Round($prPct - $baselinePct, 2) |
251 | 267 |
|
252 | | - if ($baselinePct -and $prPct) { |
253 | | - $diff = [math]::Round($prPct - $baselinePct, 2) |
254 | | - echo "**Coverage Change:** ${diff}%" >> $env:GITHUB_STEP_SUMMARY |
| 268 | + if ($diff -gt 0) { |
| 269 | + $deltaIndicator = ":white_check_mark:" |
| 270 | + } elseif ($diff -lt 0) { |
| 271 | + $deltaIndicator = ":x:" |
| 272 | + } else { |
| 273 | + $deltaIndicator = ":heavy_minus_sign:" |
255 | 274 | } |
| 275 | +
|
| 276 | + # Set outputs |
| 277 | + echo "pr_lines=$prPct" >> $env:GITHUB_OUTPUT |
| 278 | + echo "baseline_lines=$baselinePct" >> $env:GITHUB_OUTPUT |
| 279 | + echo "line_diff=$diff" >> $env:GITHUB_OUTPUT |
| 280 | + echo "delta_indicator=$deltaIndicator" >> $env:GITHUB_OUTPUT |
| 281 | +
|
| 282 | + # Write step summary |
| 283 | + echo "## Test Coverage Report (${{ matrix.os }})" >> $env:GITHUB_STEP_SUMMARY |
| 284 | + echo "" >> $env:GITHUB_STEP_SUMMARY |
| 285 | + echo "| Metric | Value |" >> $env:GITHUB_STEP_SUMMARY |
| 286 | + echo "|--------|-------|" >> $env:GITHUB_STEP_SUMMARY |
| 287 | + echo "| Current Coverage | ${prPct}% |" >> $env:GITHUB_STEP_SUMMARY |
| 288 | + echo "| Base Branch Coverage | ${baselinePct}% |" >> $env:GITHUB_STEP_SUMMARY |
| 289 | + echo "| Delta | ${diff}% ${deltaIndicator} |" >> $env:GITHUB_STEP_SUMMARY |
256 | 290 | shell: pwsh |
257 | 291 |
|
258 | | - - name: No Baseline Available |
259 | | - if: steps.download-baseline.outcome != 'success' |
260 | | - run: | |
261 | | - echo "## Coverage Report for ${{ matrix.os }}" >> $GITHUB_STEP_SUMMARY |
262 | | - echo "" >> $GITHUB_STEP_SUMMARY |
263 | | - echo "No baseline coverage available for comparison. This is expected for new repositories or when coverage-baseline workflow hasn't run yet on main branch." >> $GITHUB_STEP_SUMMARY |
264 | | - shell: bash |
| 292 | + - name: Post Coverage Comment (Linux) |
| 293 | + if: startsWith(matrix.os, 'ubuntu') |
| 294 | + uses: marocchino/sticky-pull-request-comment@v2 |
| 295 | + with: |
| 296 | + header: coverage-linux |
| 297 | + message: | |
| 298 | + ## Test Coverage Report (Linux) |
| 299 | +
|
| 300 | + | Metric | Value | |
| 301 | + |--------|-------| |
| 302 | + | Current Coverage | ${{ steps.coverage-linux.outputs.pr_lines }}% | |
| 303 | + | Base Branch Coverage | ${{ steps.coverage-linux.outputs.baseline_lines }}% | |
| 304 | + | Delta | ${{ steps.coverage-linux.outputs.line_diff }}% ${{ steps.coverage-linux.outputs.delta_indicator }} | |
| 305 | +
|
| 306 | + --- |
| 307 | + ${{ steps.coverage-linux.outputs.line_diff > 0 && 'Coverage increased! Great work!' || (steps.coverage-linux.outputs.line_diff < 0 && 'Coverage decreased. Please add tests for new code.' || 'Coverage unchanged.') }} |
| 308 | +
|
| 309 | + - name: Post Coverage Comment (Windows) |
| 310 | + if: startsWith(matrix.os, 'windows') |
| 311 | + uses: marocchino/sticky-pull-request-comment@v2 |
| 312 | + with: |
| 313 | + header: coverage-windows |
| 314 | + message: | |
| 315 | + ## Test Coverage Report (Windows) |
| 316 | +
|
| 317 | + | Metric | Value | |
| 318 | + |--------|-------| |
| 319 | + | Current Coverage | ${{ steps.coverage-windows.outputs.pr_lines }}% | |
| 320 | + | Base Branch Coverage | ${{ steps.coverage-windows.outputs.baseline_lines }}% | |
| 321 | + | Delta | ${{ steps.coverage-windows.outputs.line_diff }}% ${{ steps.coverage-windows.outputs.delta_indicator }} | |
| 322 | +
|
| 323 | + --- |
| 324 | + ${{ steps.coverage-windows.outputs.line_diff > 0 && 'Coverage increased! Great work!' || (steps.coverage-windows.outputs.line_diff < 0 && 'Coverage decreased. Please add tests for new code.' || 'Coverage unchanged.') }} |
0 commit comments