-
Notifications
You must be signed in to change notification settings - Fork 1
197 lines (178 loc) · 7.31 KB
/
analysis.yml
File metadata and controls
197 lines (178 loc) · 7.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
name: Code Analysis
on:
workflow_run:
workflows: ["Build and Test"]
types: [completed]
jobs:
sonar:
name: SonarQube Analysis
runs-on: ubuntu-latest
permissions:
checks: write
actions: read
if: >-
github.event.workflow_run.conclusion == 'success' &&
(github.event.workflow_run.event == 'push' || github.event.workflow_run.event == 'pull_request') &&
github.event.workflow_run.head_repository.full_name == github.repository
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
ref: ${{ github.event.workflow_run.head_sha }}
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654
with:
java-version: '17'
distribution: 'zulu'
cache: 'gradle'
- name: Cache SonarQube packages
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
with:
path: ~/.sonar/cache
key: ${{ runner.os }}-sonar
restore-keys: ${{ runner.os }}-sonar
- name: Setup Gradle
uses: gradle/actions/setup-gradle@39e147cb9de83bb9910b8ef8bd7fff0ee20fcd6f # v6.0.1
- name: Download coverage report
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: coverage-report
path: build/reports/kover
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Download test results
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: junit-test-results
path: build/test-results
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Resolve PR details
id: pr
if: github.event.workflow_run.event == 'pull_request'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WR_PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
WR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
WR_HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
WR_BASE_REF: ${{ github.event.workflow_run.pull_requests[0].base.ref }}
run: |
# workflow_run.pull_requests can be empty for fork PRs, fall back to API search
PR_NUMBER="$WR_PR_NUMBER"
if [ -z "$PR_NUMBER" ]; then
PR_NUMBER=$(gh pr list --search "$WR_HEAD_SHA" --state open --json number --jq '.[0].number // empty')
fi
if [ -z "$PR_NUMBER" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "Could not resolve PR number, skipping PR-specific analysis"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
echo "branch=$WR_HEAD_BRANCH" >> "$GITHUB_OUTPUT"
echo "base=${WR_BASE_REF:-main}" >> "$GITHUB_OUTPUT"
fi
- name: Run SonarQube Analysis (PR)
if: github.event.workflow_run.event == 'pull_request' && steps.pr.outputs.skip != 'true'
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: >-
./gradlew sonar
-Dsonar.coverage.jacoco.xmlReportPaths=${{ github.workspace }}/build/reports/kover/report.xml
-Dsonar.pullrequest.key=${{ steps.pr.outputs.number }}
-Dsonar.pullrequest.branch=${{ steps.pr.outputs.branch }}
-Dsonar.pullrequest.base=${{ steps.pr.outputs.base }}
- name: Run SonarQube Analysis (push)
if: github.event.workflow_run.event == 'push'
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: >-
./gradlew sonar
-Dsonar.coverage.jacoco.xmlReportPaths=${{ github.workspace }}/build/reports/kover/report.xml
coverage-comment:
name: Coverage PR Comment
runs-on: ubuntu-latest
permissions:
pull-requests: write
actions: read
if: >-
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.event == 'pull_request'
steps:
- name: Download coverage report
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: coverage-report
path: build/reports/kover
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Resolve PR number
id: pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WR_PR_NUMBER: ${{ github.event.workflow_run.pull_requests[0].number }}
WR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
run: |
PR_NUMBER="$WR_PR_NUMBER"
if [ -z "$PR_NUMBER" ]; then
PR_NUMBER=$(gh pr list --search "$WR_HEAD_SHA" --state open --json number --jq '.[0].number // empty')
fi
if [ -n "$PR_NUMBER" ]; then
echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT"
else
echo "Could not resolve PR number"
exit 1
fi
- name: Parse coverage and post comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WR_HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
PR_NUMBER: ${{ steps.pr.outputs.number }}
REPO: ${{ github.repository }}
run: |
REPORT="build/reports/kover/report.xml"
if [ ! -f "$REPORT" ]; then
echo "Coverage report not found at $REPORT"
exit 1
fi
# Extract coverage counters from the Kover/JaCoCo XML report
# Parse the top-level <counter> elements for INSTRUCTION, BRANCH, and LINE
extract_coverage() {
local type=$1
local missed covered total pct
missed=$(grep -oP "<counter type=\"$type\" missed=\"\K[0-9]+" "$REPORT" | tail -1)
covered=$(grep -oP "<counter type=\"$type\" covered=\"\K[0-9]+" "$REPORT" | tail -1)
if [ -n "$missed" ] && [ -n "$covered" ]; then
total=$((missed + covered))
if [ "$total" -gt 0 ]; then
pct=$(( (covered * 10000) / total ))
echo "$(( pct / 100 )).$(printf '%02d' $(( pct % 100 )))%"
else
echo "N/A"
fi
else
echo "N/A"
fi
}
LINE_COV=$(extract_coverage "LINE")
BRANCH_COV=$(extract_coverage "BRANCH")
INSTRUCTION_COV=$(extract_coverage "INSTRUCTION")
BODY=$(cat <<EOF
## Code Coverage
| Metric | Coverage |
|--------|----------|
| Line | $LINE_COV |
| Branch | $BRANCH_COV |
| Instruction | $INSTRUCTION_COV |
*Updated for commit ${WR_HEAD_SHA}*
EOF
)
# Find existing coverage comment to update, or create a new one
EXISTING_COMMENT=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" \
--jq '.[] | select(.body | startswith("## Code Coverage")) | .id' | head -1)
if [ -n "$EXISTING_COMMENT" ]; then
gh api "repos/${REPO}/issues/comments/${EXISTING_COMMENT}" \
-X PATCH -f body="$BODY"
else
gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" \
-X POST -f body="$BODY"
fi