@@ -33,57 +33,55 @@ jobs:
3333 run : ./gradlew build
3434
3535 - name : JaCoCo 커버리지 PR 코멘트
36- uses : madrapps/jacoco-report@v1.7.1
37- with :
38- paths : ${{ github.workspace }}/build/reports/jacoco/test/jacocoTestReport.xml
39- token : ${{ secrets.GITHUB_TOKEN }}
40- title : " 테스트 커버리지 리포트"
41- update-comment : true
42- min-coverage-overall : 0
43- min-coverage-changed-files : 0
44-
45- - name : JaCoCo 패키지별 상세 커버리지 코멘트
4636 uses : actions/github-script@v7
4737 with :
4838 github-token : ${{ secrets.GITHUB_TOKEN }}
4939 script : |
5040 const fs = require('fs');
5141 const xml = fs.readFileSync('build/reports/jacoco/test/jacocoTestReport.xml', 'utf8');
5242
53- const packageMatches = [...xml.matchAll(/<package name="([^"]+)"[\s\S]*?<\/package>/g)];
54-
5543 const pct = (covered, missed) => {
5644 const total = covered + missed;
5745 if (total === 0) return -1;
5846 return parseFloat(((covered / total) * 100).toFixed(1));
5947 };
6048
49+ // Overall 커버리지: <report> 바로 아래 <counter> 태그에서 추출
50+ const reportCounters = [...xml.matchAll(/<\/package>\s*([\s\S]*?)<\/report>/g)][0]?.[1] || '';
51+ const overallLine = reportCounters.match(/<counter type="LINE" missed="(\d+)" covered="(\d+)"/);
52+ const overallBranch = reportCounters.match(/<counter type="BRANCH" missed="(\d+)" covered="(\d+)"/);
53+ const overallLinePct = overallLine ? pct(parseInt(overallLine[2]), parseInt(overallLine[1])) : -1;
54+ const overallBranchPct = overallBranch ? pct(parseInt(overallBranch[2]), parseInt(overallBranch[1])) : -1;
55+ const overallEmoji = overallLinePct >= 80 ? '🟢' : overallLinePct >= 50 ? '🟡' : '🔴';
56+
57+ // 패키지별 커버리지
58+ const packageMatches = [...xml.matchAll(/<package name="([^"]+)"[\s\S]*?<\/package>/g)];
6159 const packages = packageMatches.map(match => {
62- const pkgRaw = match[1];
63- const parts = pkgRaw.split('/');
60+ const parts = match[1].split('/');
6461 const pkg = parts.slice(-2).join('/');
65-
6662 const counters = [...match[0].matchAll(/<counter type="([^"]+)" missed="(\d+)" covered="(\d+)"/g)];
6763 const lineCounter = counters.find(c => c[1] === 'LINE');
6864 const branchCounter = counters.find(c => c[1] === 'BRANCH');
69-
7065 const linePct = lineCounter ? pct(parseInt(lineCounter[3]), parseInt(lineCounter[2])) : -1;
7166 const branchPct = branchCounter ? pct(parseInt(branchCounter[3]), parseInt(branchCounter[2])) : -1;
72-
7367 return { pkg, linePct, branchPct };
7468 });
7569
7670 packages.sort((a, b) => b.linePct - a.linePct);
7771
7872 const rows = packages.map(({ pkg, linePct, branchPct }) => {
79- const lineStr = linePct < 0 ? 'N/A' : linePct + '%';
80- const branchStr = branchPct < 0 ? 'N/A' : branchPct + '%';
8173 const emoji = linePct >= 80 ? '🟢' : linePct >= 50 ? '🟡' : '🔴';
82- return `| ${emoji} \`${pkg}\` | ${lineStr } | ${branchStr } |`;
74+ return `| ${emoji} \`${pkg}\` | ${linePct < 0 ? 'N/A' : linePct + '%' } | ${branchPct < 0 ? 'N/A' : branchPct + '%' } |`;
8375 });
8476
8577 const body = [
86- '## 📦 패키지별 테스트 커버리지',
78+ '## 📊 테스트 커버리지 리포트',
79+ '',
80+ `### Overall: ${overallEmoji} Line \`${overallLinePct < 0 ? 'N/A' : overallLinePct + '%'}\` | Branch \`${overallBranchPct < 0 ? 'N/A' : overallBranchPct + '%'}\``,
81+ '',
82+ '---',
83+ '',
84+ '### 📦 패키지별 커버리지',
8785 '',
8886 '| 패키지 | Line | Branch |',
8987 '|--------|------|--------|',
10098
10199 const existing = comments.find(c =>
102100 c.user.login === 'github-actions[bot]' &&
103- c.body.includes('패키지별 테스트 커버리지')
101+ c.body.includes('테스트 커버리지 리포트 ')
104102 );
105103
106104 if (existing) {
0 commit comments