-
-
Notifications
You must be signed in to change notification settings - Fork 54
387 lines (353 loc) · 16.8 KB
/
ci-sonar-scan.yml
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# Static code analysis workflow for Sonar Cloud, results are published to projects:
# - Windows: https://sonarcloud.io/project/overview?id=methane-powered-kit-windows
# - Linux: https://sonarcloud.io/project/overview?id=methane-powered-kit-linux
# - MacOS: https://sonarcloud.io/project/overview?id=methane-powered-kit-macos
name: '🎯 CI Sonar Scan'
on:
push:
branches: [ master, develop ]
paths:
- '.github/**/*sonar*.yml'
- 'sonar-project.properties'
- 'Apps/**'
- 'Modules/**'
- 'Tests/**'
- 'Externals/**'
- 'CMake/**'
- 'CMakeLists.txt'
- 'CMakePresets.json'
pull_request:
branches: [ master ]
types: [opened, synchronize, reopened]
paths:
- '.github/**/*sonar*.yml'
- 'sonar-project.properties'
- 'Apps/**'
- 'Modules/**'
- 'Tests/**'
- 'Externals/**'
- 'CMake/**'
- 'CMakeLists.txt'
- 'CMakePresets.json'
schedule:
- cron: '20 23 * * 3' # Scheduled workflow will not run in GitHub forks by default
env:
product_ver_major: 0
product_ver_minor: 7
product_ver_patch: 3
product_ver_build: ${{ github.run_number }}
sonar_server_url: "https://sonarcloud.io"
sonar_organization: methane-powered
TRACY_NO_INVARIANT_CHECK: 1
jobs:
sonar_scan:
name: ${{ matrix.name }}
if: ${{ github.repository == 'MethanePowered/MethaneKit' }}
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
os_name: windows
name: "Win64_DX_SonarScan"
named_logo: Windows
config_preset: "Ninja-Win-DX-Scan"
build_preset: "Ninja-Win-DX-Scan"
sonar_project_key: "methane-powered-kit-windows"
tests_coverage_reports: "Build/Output/Ninja-Win-DX-Scan/Install/Tests/Coverage/*.xml"
- os: ubuntu-latest
os_name: linux
name: "Ubuntu_VK_SonarScan"
named_logo: Linux
config_preset: "Ninja-Lin-VK-Scan"
build_preset: "Ninja-Lin-VK-Scan"
sonar_project_key: "methane-powered-kit-linux"
tests_coverage_reports: "Build/Output/Ninja-Lin-VK-Scan/Build/MethaneTestCoverage.info"
- os: macos-latest
os_name: macosx
name: "MacOS_MTL_SonarScan"
named_logo: Apple
config_preset: "Ninja-Mac-MTL-Scan"
build_preset: "Ninja-Mac-MTL-Scan"
sonar_project_key: "methane-powered-kit-macos"
tests_coverage_reports: "Build/Output/Ninja-Mac-MTL-Scan/Install/Tests/Coverage/*.lcov"
runs-on: ${{ matrix.os }}
env:
BUILD_DIR: Build/Output/${{ matrix.config_preset }}/Build
INSTALL_DIR: Build/Output/${{ matrix.config_preset }}/Install
BUILD_LOG_FILE: Build/Output/${{ matrix.config_preset }}/Install/Build.log
COVERAGE_LOG_FILE: Build/Output/${{ matrix.config_preset }}/Install/Coverage.log
SCAN_LOG_FILE: Build/Output/${{ matrix.config_preset }}/Install/SonarScan.log
COMPILE_COMMANDS_FILE: Build/Output/${{ matrix.config_preset }}/Build/compile_commands.json
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Linux prerequisites
if: ${{ matrix.os_name == 'linux' }}
run: |
sudo apt update
sudo apt install xcb libx11-dev libx11-xcb-dev libxcb-sync-dev libxcb-randr0-dev lcov
- name: Install Testspace
uses: testspace-com/setup-testspace@v1
with:
domain: ${{ github.repository_owner }}
- name: Install .NET Core # Required to use ReportGenerator
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.0.400
- name: Install Sonar-Scanner
uses: sonarsource/sonarcloud-github-c-cpp@v2
- name: Install Ninja
uses: MethanePowered/gha-setup-ninja@master
with:
version: 1.11.1
- name: Initialize Externals Cache
uses: actions/cache@v3
with:
path: Build/Output/ExternalsCache
key: ExternalsCache-${{ matrix.config_preset }}-${{ hashFiles('Externals/*.cmake') }}
- name: Setup Developer Command Prompt for MSVC (VS2022 x64) to build with Ninja
if: ${{ matrix.os_name == 'windows' }}
uses: ilammy/msvc-dev-cmd@v1
with:
arch: x64
- name: CMake Configure Preset ${{ matrix.config_preset }}
shell: bash
run: |
set -o pipefail
mkdir -p "$INSTALL_DIR"
# set METHANE_VERSION_BUILD=0 to benefit from SonarCloud analysis cache, build version invalidates cache at each run
cmake --preset ${{ matrix.config_preset }} -DMETHANE_VERSION_MAJOR=${{ env.product_ver_major }} -DMETHANE_VERSION_MINOR=${{ env.product_ver_minor }} -DMETHANE_VERSION_PATCH=${{ env.product_ver_patch }} -DMETHANE_VERSION_BUILD=0 2>&1 | tee $BUILD_LOG_FILE
ls -la "$BUILD_DIR" 2>&1 | tee -a $BUILD_LOG_FILE
if [ -f $COMPILE_COMMANDS_FILE ]; then
cp "$COMPILE_COMMANDS_FILE" "$INSTALL_DIR"
else
echo "Compile commands file was not found!"
fi
- name: CMake Build Preset ${{ matrix.build_preset }}
shell: bash
run: |
set -o pipefail
cmake --build --preset ${{ matrix.build_preset }} --target install 2>&1 | tee -a $BUILD_LOG_FILE
- name: Download OpenCppCoverage
if: ${{ matrix.os_name == 'windows' }}
shell: powershell
working-directory: 'Build/Output/${{ matrix.config_preset }}/Install/Tests'
run: |
Invoke-WebRequest -Uri 'https://github.com/MethanePowered/OpenCppCoverage/releases/download/release-0.9.9.0/OpenCppCoverage.zip' -OutFile 'OpenCppCoverage.zip'
Expand-Archive -Path 'OpenCppCoverage.zip' -DestinationPath 'OpenCppCoverage'
if (-not(Test-Path -Path 'OpenCppCoverage/OpenCppCoverage.exe' -PathType Leaf)) {
Get-ChildItem 'OpenCppCoverage'
throw 'OpenCppCoverage/OpenCppCoverage.exe executable was not found in unpacked content!'
}
- name: Run all unit-tests with OpenCppCoverage code coverage on Windows
if: ${{ matrix.os_name == 'windows' }}
shell: cmd
working-directory: 'Build\Output\${{ matrix.config_preset }}\Install\Tests'
run: |
chcp 65001 #set code page to utf-8
setlocal enabledelayedexpansion
set open_cpp_coverage_exe=OpenCppCoverage\OpenCppCoverage.exe
set test_results=
if not exist "%open_cpp_coverage_exe%" (
echo File path "%open_cpp_coverage_exe%" does not exist!
exit 101
)
echo Running unit-tests in directory "%cd%"
mkdir Results
mkdir Coverage
set /A result_error_level=0
for /r "." %%a in (*Test.exe) do (
echo %open_cpp_coverage_exe% --sources "${{ github.workspace }}\Modules" --export_type=cobertura:Coverage\%%~na.xml -- "%%~fa" -r sonarqube -o "Results\%%~na.xml"
%open_cpp_coverage_exe% --sources "${{ github.workspace }}\Modules" --export_type=cobertura:Coverage\%%~na.xml -- "%%~fa" -r sonarqube -o "Results\%%~na.xml"
echo - %%~na - completed with !errorlevel! exit status
if not !errorlevel!==0 (
set /A result_error_level=!errorlevel!
)
if .!test_results!==. (
set test_results=Build/Output/${{ matrix.config_preset }}/Install/Tests/Results/%%~na.xml
) else (
set test_results=!test_results!,Build/Output/${{ matrix.config_preset }}/Install/Tests/Results/%%~na.xml
)
)
echo Test Result Files: %test_results%
echo test_results=%test_results%>> %GITHUB_ENV%
exit !result_error_level!
- name: Run all unit-tests with GCov code coverage on Linux
if: ${{ matrix.os_name == 'linux' }}
working-directory: 'Build/Output/${{ matrix.config_preset }}/Install/Tests'
run: |
set +e
result_ext='.xml'
test_results=''
result_error_level=0
echo Running unit-tests in directory $PWD
mkdir Results
for test_exe in *Test
do
./$test_exe -r sonarqube -o "Results/$test_exe$result_ext"
last_error_level=$?
echo - $test_exe - completed with $last_error_level exit status
if [ $last_error_level != 0 ]; then
result_error_level=$last_error_level
fi
if [ -f "$PWD/Results/$test_exe$result_ext" ]; then
test_results+="$PWD/Results/$test_exe$result_ext,"
fi
done
echo "Test Result Files: $test_results"
echo "test_results=$test_results" >> $GITHUB_ENV
exit $result_error_level
- name: Collect tests code coverage using ctest and gcov/lcov on Linux
if: ${{ matrix.os_name == 'linux' && (success() || failure()) }}
run: |
set -o pipefail
cmake --build --preset ${{ matrix.build_preset }} --target MethaneTestCoverage 2>&1 | tee $COVERAGE_LOG_FILE
- name: Run all unit-tests with LCov code coverage on MacOS
if: ${{ matrix.os_name == 'macosx' }}
working-directory: 'Build/Output/${{ matrix.config_preset }}/Install/Tests'
run: |
set +e
result_error_level=0
result_ext='.xml'
prof_data_ext='.profdata'
prof_raw_ext='.profraw'
lcov_ext='.lcov'
test_results=''
echo Running unit-tests and Converting LLVM code coverage data to lcov text format in directory $PWD
mkdir Results
mkdir Coverage
for test_exe in *Test
do
./$test_exe -r sonarqube -o "Results/$test_exe$result_ext"
last_error_level=$?
echo - $test_exe - completed with $last_error_level exit status
if [ $last_error_level != 0 ]; then
result_error_level=$last_error_level
fi
if [ -f "$PWD/Results/$test_exe$result_ext" ]; then
test_results+="$PWD/Results/$test_exe$result_ext,"
fi
if [ ! -f default.profraw ]; then
continue
fi
mv default.profraw "$test_exe$prof_raw_ext"
xcrun llvm-profdata merge -o "$test_exe$prof_data_ext" "$test_exe$prof_raw_ext"
xcrun llvm-cov export -format lcov -instr-profile="$test_exe$prof_data_ext" -arch=x86_64 ./$test_exe > "./Coverage/$test_exe$lcov_ext"
echo - Converted code coverage from "$test_exe$prof_raw_ext" to lcov text format "./Coverage/$test_exe$lcov_ext", $? exit status
done
echo "Test Result Files: $test_results"
echo "test_results=$test_results" >> $GITHUB_ENV
echo List of generated coverage files in directory $PWD/Coverage
ls -la ./Coverage
exit $result_error_level
- name: Generate Code Coverage Reports
if: ${{ success() || failure() }}
uses: danielpalme/[email protected]
with:
reports: ${{ matrix.tests_coverage_reports }}
targetdir: 'Build/Output/${{ matrix.config_preset }}/Install/Tests/Coverage/Report'
reporttypes: 'Cobertura;SonarQube'
title: 'Methane Tests Code Coverage for ${{ matrix.build_preset }}'
tag: '${{ env.product_ver_major }}.${{ env.product_ver_minor }}.${{ env.product_ver_patch }}.${{ env.product_ver_build }}'
- name: Upload Code Coverage Cobertura Report
if: ${{ success() || failure() }}
uses: actions/upload-artifact@v3
with:
name: MethaneKit_${{ matrix.name }}_CoverageResults
path: Build/Output/${{ matrix.config_preset }}/Install/Tests/Coverage/Report/Cobertura.xml
- name: Upload Build Log and Code Coverage to Testspace server
if: ${{ success() || failure() }}
run: testspace "[ ${{ matrix.name }} ]Build/Output/${{ matrix.config_preset }}/Install/Tests/Coverage/Report/Cobertura.xml" "[ ${{ matrix.name }} ]${{ env.BUILD_LOG_FILE }}"
- name: Upload Code Coverage to CodeCov server
if: ${{ success() || failure() }}
uses: codecov/codecov-action@v3
with:
files: Build/Output/${{ matrix.config_preset }}/Install/Tests/Coverage/Report/Cobertura.xml
flags: unittests,${{ matrix.os_name }}
name: ${{ matrix.name }}
- name: Run Sonar Scanner
if: ${{ success() || failure() }}
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: |
if [ "${{ matrix.os_name }}" == "windows" ]; then
SONAR_SCANNER_EXE=sonar-scanner.bat
else
SONAR_SCANNER_EXE=sonar-scanner
fi
# SONAR_SCANNER_EXE="$SONAR_SCANNER_EXE -X" # Uncomment to enable debug output
TESTS_DIR=Build/Output/${{ matrix.config_preset }}/Install/Tests
SONAR_SCAN_CMD="$SONAR_SCANNER_EXE --define sonar.host.url=${{ env.sonar_server_url }}"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.organization=${{ env.sonar_organization }}"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.projectKey=${{ matrix.sonar_project_key }}"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.projectVersion=${{ env.product_ver_major }}.${{ env.product_ver_minor }}.${{ env.product_ver_patch }}.${{ env.product_ver_build }}"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.cfamily.compile-commands=Build/Output/${{ matrix.config_preset }}/Build/compile_commands.json"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.testExecutionReportPaths=${{ env.test_results }}"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.coverageReportPaths=$TESTS_DIR/Coverage/Report/SonarQube.xml"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.scm.revision=${{ github.sha }}"
if [ "${{ github.event_name }}" == "pull_request" ]; then
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.pullrequest.provider=GitHub"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.pullrequest.github.repository=MethanePowered/MethaneKit"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.pullrequest.key=${{ github.event.pull_request.number }}"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.pullrequest.branch=${{ github.event.pull_request.head.ref }}"
SONAR_SCAN_CMD="$SONAR_SCAN_CMD --define sonar.pullrequest.base=${{ github.event.pull_request.base.ref }}"
fi
set -o pipefail
echo "$SONAR_SCAN_CMD" | tee $SCAN_LOG_FILE
eval "$SONAR_SCAN_CMD" 2>&1 | tee -a $SCAN_LOG_FILE
cp sonar-project.properties $INSTALL_DIR
prop_files=(`find .sonar -name "sonar-scanner.properties"`)
for prop_file in "${prop_files[@]}"; do
cp $prop_file $INSTALL_DIR
done
- name: Archive Scan Artifacts
if: ${{ success() || failure() }}
shell: bash
working-directory: Build/Output/${{ matrix.config_preset }}/Install
run: 7z a -t7z -mx=9 MethaneKit_${{ matrix.name }}.7z *
- name: Upload Archived Scan Artifacts
if: ${{ success() || failure() }}
uses: actions/upload-artifact@v3
with:
name: MethaneKit_${{ matrix.name }}_${{ env.product_ver_major }}.${{ env.product_ver_minor }}.${{ env.product_ver_patch }}.${{ env.product_ver_build }}
path: Build/Output/${{ matrix.config_preset }}/Install/MethaneKit_${{ matrix.name }}.7z
- name: Update Badge Parameters
if: ${{ github.event_name == 'push' && always() }}
shell: bash
run: |
case "${{ job.status }}" in
"success")
echo "badge_message=passed" >> $GITHUB_ENV
echo "badge_color=#56a93c" >> $GITHUB_ENV
;;
"failure")
echo "badge_message=failed" >> $GITHUB_ENV
echo "badge_color=#cd6e57" >> $GITHUB_ENV
;;
"cancelled")
echo "badge_message=cancelled" >> $GITHUB_ENV
echo "badge_color=#9b9b9c" >> $GITHUB_ENV
;;
*)
echo "badge_message=undefined" >> $GITHUB_ENV
echo "badge_color=purple" >> $GITHUB_ENV
;;
esac
- name: Update Badge JSON
if: ${{ github.event_name == 'push' && always() }}
uses: schneegans/[email protected] # https://github.com/marketplace/actions/dynamic-badges
with:
auth: ${{ secrets.GIST_TOKEN }}
gistID: 96d788046ccd52b45b3354a99f8569c3
filename: MethaneKit_${{ matrix.name }}_${{ github.ref_name }}.json
namedLogo: ${{ matrix.named_logo }} # https://simpleicons.org
label: ${{ matrix.name }}
labelColor: #f5f5f5
logoColor: #f5f5f5
message: ${{ env.badge_message }}
color: ${{ env.badge_color }}