@@ -52,12 +52,130 @@ jobs:
5252 # MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
5353 run : ./mvnw -B -q -ff -DskipTests -ntp source:jar deploy
5454 - name : Generate code coverage
55- if : ${{ matrix.release_build && github.event_name != 'pull_request' }}
56- run : ./mvnw -B -q -ff -ntp test
55+ if : ${{ matrix.release_build }}
56+ run : ./mvnw -B -q -ff -ntp test jacoco:report
5757 - name : Publish code coverage
5858 if : ${{ matrix.release_build && github.event_name != 'pull_request' }}
5959 uses : codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2
6060 with :
6161 token : ${{ secrets.CODECOV_TOKEN }}
6262 files : ./target/site/jacoco/jacoco.xml
6363 flags : unittests
64+ - name : Upload coverage report as artifact
65+ if : ${{ matrix.release_build && github.event_name != 'pull_request' }}
66+ uses : actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
67+ with :
68+ name : jacoco-report
69+ path : target/site/jacoco/jacoco.csv
70+ retention-days : 30
71+ - name : Download base branch coverage
72+ if : ${{ matrix.release_build && github.event_name == 'pull_request' }}
73+ uses : dawidd6/action-download-artifact@2536c51d3d126276eb39f74d6bc9c72ac6ef30d3 # v16
74+ continue-on-error : true
75+ with :
76+ workflow : main.yml
77+ branch : ${{ github.event.pull_request.base.ref }}
78+ name : jacoco-report
79+ path : base-coverage/
80+ - name : Generate coverage summary
81+ if : ${{ matrix.release_build && github.event_name == 'pull_request' }}
82+ id : jacoco
83+ uses : cicirello/jacoco-badge-generator@72266185b7ee48a6fd74eaf0238395cc8b14fef8 # v2.12.1
84+ with :
85+ jacoco-csv-file : target/site/jacoco/jacoco.csv
86+ generate-coverage-badge : false
87+ generate-branches-badge : false
88+ generate-summary : true
89+ - name : Generate coverage comment
90+ if : ${{ matrix.release_build && github.event_name == 'pull_request' }}
91+ run : |
92+ # Helper functions
93+ parse_coverage() {
94+ local csv_file=$1 col_missed=$2 col_covered=$3
95+ awk -F',' -v m="$col_missed" -v c="$col_covered" \
96+ 'NR>1 && $1=="jackson-dataformat-xml" {
97+ total_missed += $m;
98+ total_covered += $c;
99+ }
100+ END {
101+ if (total_missed + total_covered > 0)
102+ printf "%.2f", (total_covered * 100.0) / (total_missed + total_covered)
103+ }' "$csv_file"
104+ }
105+
106+ format_delta() {
107+ local delta=$1
108+ if awk -v d="$delta" 'BEGIN { exit (d >= 0) ? 0 : 1 }'; then
109+ echo "+${delta}%|📈"
110+ else
111+ echo "${delta}%|📉"
112+ fi
113+ }
114+
115+ get_color() {
116+ awk -v v="$1" 'BEGIN {
117+ if (v >= 80) print "brightgreen"
118+ else if (v >= 60) print "green"
119+ else if (v >= 40) print "yellow"
120+ else print "red"
121+ }'
122+ }
123+
124+ # Convert decimal to percentage and round to 1 decimal place
125+ COVERAGE=$(awk -v cov="${{ steps.jacoco.outputs.coverage }}" 'BEGIN { printf "%.2f", cov * 100 }')
126+ BRANCHES=$(awk -v br="${{ steps.jacoco.outputs.branches }}" 'BEGIN { printf "%.2f", br * 100 }')
127+
128+ # Check if base coverage artifact was downloaded and calculate deltas
129+ HAS_DELTA=false
130+ if [ -f "base-coverage/jacoco.csv" ]; then
131+ echo "Found base branch coverage from artifact"
132+ BASE_COVERAGE=$(parse_coverage "base-coverage/jacoco.csv" 4 5)
133+ BASE_BRANCHES=$(parse_coverage "base-coverage/jacoco.csv" 6 7)
134+
135+ if [ -n "$BASE_COVERAGE" ] && [ -n "$BASE_BRANCHES" ]; then
136+ COV_DELTA=$(awk -v curr="$COVERAGE" -v base="$BASE_COVERAGE" 'BEGIN { printf "%.3f", curr - base }')
137+ BR_DELTA=$(awk -v curr="$BRANCHES" -v base="$BASE_BRANCHES" 'BEGIN { printf "%.3f", curr - base }')
138+
139+ IFS='|' read -r COV_DELTA_STR COV_DELTA_EMOJI <<< "$(format_delta "$COV_DELTA")"
140+ IFS='|' read -r BR_DELTA_STR BR_DELTA_EMOJI <<< "$(format_delta "$BR_DELTA")"
141+
142+ HAS_DELTA=true
143+ fi
144+ fi
145+
146+ # Determine badge colors
147+ COV_COLOR=$(get_color "$COVERAGE")
148+ BR_COLOR=$(get_color "$BRANCHES")
149+
150+ # Build coverage table with or without deltas
151+ if [ "$HAS_DELTA" = "true" ]; then
152+ COVERAGE_TABLE="| Metric | Coverage | Change |
153+ |--------|----------|--------|
154+ | **Instructions** |  **${COVERAGE}%** | ${COV_DELTA_EMOJI} **${COV_DELTA_STR}** |
155+ | **Branches** |  **${BRANCHES}%** | ${BR_DELTA_EMOJI} **${BR_DELTA_STR}** |"
156+ else
157+ COVERAGE_TABLE="| Metric | Coverage |
158+ |--------|----------|
159+ | **Instructions** |  **${COVERAGE}%** |
160+ | **Branches** |  **${BRANCHES}%** |"
161+ fi
162+
163+ COMMENT_BODY="## :test_tube: Code Coverage Report
164+
165+ $COVERAGE_TABLE
166+
167+ > Coverage data generated from JaCoCo test results
168+
169+ <!-- jacoco-coverage-comment -->"
170+
171+ # Save comment for the workflow_run
172+ mkdir -p pr-comment
173+ echo "${{ github.event.pull_request.number }}" > pr-comment/pr-number.txt
174+ echo "$COMMENT_BODY" > pr-comment/comment-body.txt
175+ - name : Upload PR comment
176+ if : ${{ matrix.release_build && github.event_name == 'pull_request' }}
177+ uses : actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
178+ with :
179+ name : pr-comment
180+ path : pr-comment/
181+ retention-days : 1
0 commit comments