X Tutup
Skip to content

Commit ff9c80d

Browse files
authored
Merge branch 'master' into claude/fix-graphql-java-4278-v6Z3y
2 parents d37c600 + 471b676 commit ff9c80d

12 files changed

+904
-27
lines changed

.github/workflows/master.yml

Lines changed: 153 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,29 @@ on:
44
push:
55
branches:
66
- master
7-
permissions: # For test summary bot
7+
permissions:
8+
contents: write
89
checks: write
910
jobs:
1011
buildAndTest:
1112
runs-on: ubuntu-latest
1213
strategy:
1314
matrix:
14-
gradle-argument: [ 'assemble && ./gradlew check -x test','testWithJava11', 'testWithJava17','testWithJava21', 'test -x testWithJava11 -x testWithJava17 -x testWithJava21' ]
15+
include:
16+
- gradle-argument: 'assemble && ./gradlew check -x test -x testng -x testngWithJava11 -x testngWithJava17 -x testngWithJava21'
17+
label: 'check'
18+
- gradle-argument: 'testWithJava11 testngWithJava11'
19+
label: 'java11'
20+
test-results-dirs: 'testWithJava11 testngWithJava11'
21+
- gradle-argument: 'testWithJava17 testngWithJava17'
22+
label: 'java17'
23+
test-results-dirs: 'testWithJava17 testngWithJava17'
24+
- gradle-argument: 'testWithJava21 testngWithJava21'
25+
label: 'java21'
26+
test-results-dirs: 'testWithJava21 testngWithJava21'
27+
- gradle-argument: 'test -x testWithJava11 -x testWithJava17 -x testWithJava21 testng jacocoTestReport'
28+
label: 'java25'
29+
test-results-dirs: 'test testng'
1530
steps:
1631
- uses: actions/checkout@v6
1732
- uses: gradle/actions/wrapper-validation@v5
@@ -24,13 +39,143 @@ jobs:
2439
run: ./gradlew ${{matrix.gradle-argument}} --info --stacktrace
2540
- name: Publish Test Results
2641
uses: EnricoMi/publish-unit-test-result-action@v2.23.0
27-
if: always()
42+
if: always() && matrix.label != 'check'
2843
with:
2944
files: |
30-
**/build/test-results/test/TEST-*.xml
31-
**/build/test-results/testWithJava11/TEST-*.xml
32-
**/build/test-results/testWithJava17/TEST-*.xml
33-
**/build/test-results/testWithJava21/TEST-*.xml
45+
**/build/test-results/*/TEST-*.xml
46+
- name: Upload Coverage XML Report
47+
uses: actions/upload-artifact@v4
48+
if: always() && matrix.label == 'java25'
49+
with:
50+
name: coverage-report
51+
path: build/reports/jacoco/test/jacocoTestReport.xml
52+
retention-days: 1
53+
- name: Parse Test Results
54+
if: always() && matrix.label != 'check'
55+
run: |
56+
total=0; failures=0; errors=0; skipped=0
57+
for dir_name in ${{ matrix.test-results-dirs }}; do
58+
dir="build/test-results/$dir_name"
59+
for f in "$dir"/TEST-*.xml; do
60+
[ -f "$f" ] || continue
61+
t=$(grep -o 'tests="[0-9]*"' "$f" | head -1 | grep -o '[0-9]*')
62+
fl=$(grep -o 'failures="[0-9]*"' "$f" | head -1 | grep -o '[0-9]*')
63+
e=$(grep -o 'errors="[0-9]*"' "$f" | head -1 | grep -o '[0-9]*')
64+
s=$(grep -o 'skipped="[0-9]*"' "$f" | head -1 | grep -o '[0-9]*')
65+
total=$((total + ${t:-0}))
66+
failures=$((failures + ${fl:-0}))
67+
errors=$((errors + ${e:-0}))
68+
skipped=$((skipped + ${s:-0}))
69+
done
70+
done
71+
passed=$((total - failures - errors - skipped))
72+
mkdir -p /tmp/test-stats
73+
echo "{\"total\":$total,\"passed\":$passed,\"failed\":$failures,\"errors\":$errors,\"skipped\":$skipped}" \
74+
> "/tmp/test-stats/${{ matrix.label }}.json"
75+
- name: Upload Test Stats
76+
if: always() && matrix.label != 'check'
77+
uses: actions/upload-artifact@v4
78+
with:
79+
name: test-stats-${{ matrix.label }}
80+
path: /tmp/test-stats/${{ matrix.label }}.json
81+
update-baseline:
82+
needs: buildAndTest
83+
runs-on: ubuntu-latest
84+
steps:
85+
- uses: actions/checkout@v6
86+
- name: Download Test Stats
87+
uses: actions/download-artifact@v4
88+
with:
89+
pattern: test-stats-*
90+
merge-multiple: true
91+
path: test-stats/
92+
- name: Download Coverage Report
93+
uses: actions/download-artifact@v4
94+
continue-on-error: true
95+
with:
96+
name: coverage-report
97+
path: coverage/
98+
- name: Update Baseline
99+
uses: actions/github-script@v7
100+
with:
101+
script: |
102+
const fs = require('fs');
103+
const path = require('path');
104+
105+
const versions = ['java11', 'java17', 'java21', 'java25'];
106+
const zeroTest = { total: 0, passed: 0, failed: 0, errors: 0, skipped: 0 };
107+
const zeroCov = { covered: 0, missed: 0 };
108+
109+
// Read current baseline
110+
const baselineFile = 'test-baseline.json';
111+
let baseline = { tests: {}, coverage: {} };
112+
if (fs.existsSync(baselineFile)) {
113+
baseline = JSON.parse(fs.readFileSync(baselineFile, 'utf8'));
114+
}
115+
116+
// Update test stats from artifacts
117+
const tests = baseline.tests || {};
118+
for (const v of versions) {
119+
const file = path.join('test-stats', `${v}.json`);
120+
if (fs.existsSync(file)) {
121+
tests[v] = JSON.parse(fs.readFileSync(file, 'utf8'));
122+
} else {
123+
tests[v] = tests[v] || zeroTest;
124+
}
125+
}
126+
127+
// Update coverage from JaCoCo XML
128+
let coverage = { overall: {}, classes: {} };
129+
const jacocoFile = path.join('coverage', 'jacocoTestReport.xml');
130+
if (fs.existsSync(jacocoFile)) {
131+
const xml = fs.readFileSync(jacocoFile, 'utf8');
132+
133+
// Overall counters (outside <package> tags)
134+
const stripped = xml.replace(/<package[\s\S]*?<\/package>/g, '');
135+
const re = /<counter type="(\w+)" missed="(\d+)" covered="(\d+)"\/>/g;
136+
let m;
137+
while ((m = re.exec(stripped)) !== null) {
138+
if (m[1] === 'LINE') coverage.overall.line = { covered: parseInt(m[3]), missed: parseInt(m[2]) };
139+
else if (m[1] === 'BRANCH') coverage.overall.branch = { covered: parseInt(m[3]), missed: parseInt(m[2]) };
140+
else if (m[1] === 'METHOD') coverage.overall.method = { covered: parseInt(m[3]), missed: parseInt(m[2]) };
141+
}
142+
143+
// Per-class counters from <package>/<class> elements
144+
const pkgRe = /<package\s+name="([^"]+)">([\s\S]*?)<\/package>/g;
145+
let pkgMatch;
146+
while ((pkgMatch = pkgRe.exec(xml)) !== null) {
147+
const pkgName = pkgMatch[1].replace(/\//g, '.');
148+
const pkgBody = pkgMatch[2];
149+
const classRe = /<class\s+name="([^"]+)"[^>]*>([\s\S]*?)<\/class>/g;
150+
let classMatch;
151+
while ((classMatch = classRe.exec(pkgBody)) !== null) {
152+
const className = classMatch[1].replace(/\//g, '.');
153+
const classBody = classMatch[2];
154+
const counters = { line: { ...zeroCov }, branch: { ...zeroCov }, method: { ...zeroCov } };
155+
const cntRe = /<counter type="(\w+)" missed="(\d+)" covered="(\d+)"\/>/g;
156+
let cntMatch;
157+
while ((cntMatch = cntRe.exec(classBody)) !== null) {
158+
const entry = { covered: parseInt(cntMatch[3]), missed: parseInt(cntMatch[2]) };
159+
if (cntMatch[1] === 'LINE') counters.line = entry;
160+
else if (cntMatch[1] === 'BRANCH') counters.branch = entry;
161+
else if (cntMatch[1] === 'METHOD') counters.method = entry;
162+
}
163+
coverage.classes[className] = counters;
164+
}
165+
}
166+
}
167+
168+
const updated = { tests, coverage };
169+
fs.writeFileSync(baselineFile, JSON.stringify(updated, null, 2) + '\n');
170+
- name: Commit Updated Baseline
171+
run: |
172+
git config user.name "github-actions[bot]"
173+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
174+
git add test-baseline.json
175+
git diff --cached --quiet || {
176+
git commit -m "Update test baseline [skip ci]"
177+
git push
178+
}
34179
javadoc:
35180
runs-on: ubuntu-latest
36181
steps:
@@ -62,4 +207,4 @@ jobs:
62207
java-version: '25'
63208
distribution: 'corretto'
64209
- name: publishToMavenCentral
65-
run: ./gradlew assemble && ./gradlew check -x test -x testng --info && ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -x check --info --stacktrace
210+
run: ./gradlew assemble && ./gradlew check -x test -x testng -x testngWithJava11 -x testngWithJava17 -x testngWithJava21 --info && ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository -x check --info --stacktrace

0 commit comments

Comments
 (0)
X Tutup