Skip to content

Commit 6882e45

Browse files
committed
[update] workflow to update original code coverage comment and have it list out code coverage by modified file.
1 parent 19662f1 commit 6882e45

File tree

1 file changed

+125
-19
lines changed

1 file changed

+125
-19
lines changed

.github/workflows/coverage.yml

Lines changed: 125 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,46 +57,152 @@ jobs:
5757
echo "VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json" >> "$GITHUB_ENV"
5858
vulkaninfo --summary || true
5959
60-
- name: Generate coverage JSON (summary only)
60+
- name: Generate full coverage JSON
6161
run: |
6262
cargo llvm-cov --workspace \
6363
--features lambda-rs/with-vulkan,lambda-rs/audio-output-device \
64-
--json --summary-only \
64+
--json \
6565
--output-path coverage.json
6666
67-
- name: Extract total line coverage percentage
67+
- name: Get changed files in PR
68+
if: github.event_name == 'pull_request'
69+
id: changed
70+
run: |
71+
git fetch origin ${{ github.base_ref }} --depth=1
72+
changed_files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- '*.rs' | tr '\n' ' ')
73+
echo "files=$changed_files" >> "$GITHUB_OUTPUT"
74+
75+
- name: Generate coverage report data
6876
id: cov
6977
run: |
78+
# Extract total coverage
7079
pct=$(jq -r '(.data[0].totals.lines.percent // 0)' coverage.json)
7180
covered=$(jq -r '(.data[0].totals.lines.covered // 0)' coverage.json)
7281
total=$(jq -r '(.data[0].totals.lines.count // 0)' coverage.json)
7382
echo "pct=$pct" >> "$GITHUB_OUTPUT"
7483
echo "covered=$covered" >> "$GITHUB_OUTPUT"
7584
echo "total=$total" >> "$GITHUB_OUTPUT"
7685
77-
- name: Comment on PR
86+
# Extract per-file coverage as JSON for changed files
87+
jq -r '.data[0].files[] | "\(.filename)|\(.summary.lines.percent // 0)|\(.summary.lines.covered // 0)|\(.summary.lines.count // 0)"' coverage.json > file_coverage.txt
88+
89+
- name: Build PR coverage comment
7890
if: github.event_name == 'pull_request'
91+
id: comment
92+
env:
93+
CHANGED_FILES: ${{ steps.changed.outputs.files }}
94+
run: |
95+
# Build the comment body
96+
{
97+
echo "### ✅ Coverage Report"
98+
echo ""
99+
echo "#### Overall Coverage"
100+
echo ""
101+
echo "| Metric | Value |"
102+
echo "|--------|-------|"
103+
echo "| **Total Line Coverage** | ${{ steps.cov.outputs.pct }}% |"
104+
echo "| **Lines Covered** | ${{ steps.cov.outputs.covered }} / ${{ steps.cov.outputs.total }} |"
105+
echo ""
106+
107+
# Calculate coverage for changed files
108+
if [ -n "$CHANGED_FILES" ]; then
109+
echo "#### Changed Files in This PR"
110+
echo ""
111+
echo "| File | Coverage | Lines |"
112+
echo "|------|----------|-------|"
113+
114+
pr_covered=0
115+
pr_total=0
116+
117+
for file in $CHANGED_FILES; do
118+
# Find this file in coverage data (match by filename ending)
119+
match=$(grep -E "/${file}\|" file_coverage.txt || grep -E "^${file}\|" file_coverage.txt || true)
120+
if [ -n "$match" ]; then
121+
file_pct=$(echo "$match" | cut -d'|' -f2)
122+
file_covered=$(echo "$match" | cut -d'|' -f3)
123+
file_total=$(echo "$match" | cut -d'|' -f4)
124+
# Format percentage to 2 decimal places
125+
file_pct_fmt=$(printf "%.2f" "$file_pct")
126+
echo "| \`${file}\` | ${file_pct_fmt}% | ${file_covered}/${file_total} |"
127+
pr_covered=$((pr_covered + file_covered))
128+
pr_total=$((pr_total + file_total))
129+
else
130+
echo "| \`${file}\` | N/A | (no coverage data) |"
131+
fi
132+
done
133+
134+
echo ""
135+
if [ "$pr_total" -gt 0 ]; then
136+
pr_pct=$(echo "scale=2; $pr_covered * 100 / $pr_total" | bc)
137+
echo "**PR Files Coverage:** ${pr_pct}% (${pr_covered}/${pr_total} lines)"
138+
fi
139+
else
140+
echo "*No Rust files changed in this PR.*"
141+
fi
142+
143+
echo ""
144+
echo "---"
145+
echo "*Generated by [cargo-llvm-cov](https://github.com/taiki-e/cargo-llvm-cov)*"
146+
} > comment_body.md
147+
148+
# Store as output (handle multiline)
149+
{
150+
echo "body<<EOF"
151+
cat comment_body.md
152+
echo "EOF"
153+
} >> "$GITHUB_OUTPUT"
154+
155+
- name: Find existing coverage comment
156+
if: github.event_name == 'pull_request'
157+
id: find_comment
79158
uses: actions/github-script@v7
80159
with:
81160
script: |
82-
const pct = `${{ steps.cov.outputs.pct }}`;
83-
const covered = `${{ steps.cov.outputs.covered }}`;
84-
const total = `${{ steps.cov.outputs.total }}`;
85-
86-
const body = [
87-
'### ✅ Coverage Report',
88-
'',
89-
'| Metric | Value |',
90-
'|--------|-------|',
91-
`| **Total Line Coverage** | ${pct}% |`,
92-
`| **Lines Covered** | ${covered} / ${total} |`,
93-
'',
94-
'*Generated by [cargo-llvm-cov](https://github.com/taiki-e/cargo-llvm-cov)*'
95-
].join('\n');
161+
const { owner, repo } = context.repo;
162+
const issue_number = context.issue.number;
96163
164+
const comments = await github.rest.issues.listComments({
165+
owner,
166+
repo,
167+
issue_number,
168+
});
169+
170+
const botComment = comments.data.find(comment =>
171+
comment.user.type === 'Bot' &&
172+
comment.body.includes('### ✅ Coverage Report')
173+
);
174+
175+
return botComment ? botComment.id : null;
176+
result-encoding: string
177+
178+
- name: Create or update PR comment
179+
if: github.event_name == 'pull_request'
180+
uses: actions/github-script@v7
181+
with:
182+
script: |
183+
const fs = require('fs');
184+
const body = fs.readFileSync('comment_body.md', 'utf8');
97185
const { owner, repo } = context.repo;
98186
const issue_number = context.issue.number;
99-
await github.rest.issues.createComment({ owner, repo, issue_number, body });
187+
const existingCommentId = ${{ steps.find_comment.outputs.result }};
188+
189+
if (existingCommentId) {
190+
await github.rest.issues.updateComment({
191+
owner,
192+
repo,
193+
comment_id: existingCommentId,
194+
body,
195+
});
196+
console.log(`Updated existing comment ${existingCommentId}`);
197+
} else {
198+
await github.rest.issues.createComment({
199+
owner,
200+
repo,
201+
issue_number,
202+
body,
203+
});
204+
console.log('Created new coverage comment');
205+
}
100206
101207
- name: Upload coverage JSON as artifact
102208
uses: actions/upload-artifact@v4

0 commit comments

Comments
 (0)