-
Notifications
You must be signed in to change notification settings - Fork 1
323 lines (295 loc) · 11 KB
/
Copy pathrelease.yml
File metadata and controls
323 lines (295 loc) · 11 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
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
name: Release
on:
push:
tags:
- "v*"
jobs:
classify-release:
runs-on: ubuntu-24.04
outputs:
is_patch: ${{ steps.classify.outputs.is_patch }}
is_minor_or_major: ${{ steps.classify.outputs.is_minor_or_major }}
steps:
- name: Classify tag
id: classify
shell: bash
run: |
TAG="${GITHUB_REF_NAME#v}"
if [[ ! "$TAG" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
echo "ERROR: tag '$TAG' is not semantic version X.Y.Z"
exit 1
fi
PATCH="${BASH_REMATCH[3]}"
if [ "$PATCH" = "0" ]; then
echo "is_patch=false" >> "$GITHUB_OUTPUT"
echo "is_minor_or_major=true" >> "$GITHUB_OUTPUT"
else
echo "is_patch=true" >> "$GITHUB_OUTPUT"
echo "is_minor_or_major=false" >> "$GITHUB_OUTPUT"
fi
validate-version:
needs: classify-release
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Verify version matches tag
run: |
TAG_VERSION="${GITHUB_REF_NAME#v}"
CMAKE_VERSION=$(grep -oP 'VERSION \K[0-9]+\.[0-9]+\.[0-9]+' CMakeLists.txt)
if [ "$TAG_VERSION" != "$CMAKE_VERSION" ]; then
echo "ERROR: Tag version ($TAG_VERSION) does not match CMakeLists.txt version ($CMAKE_VERSION)"
exit 1
fi
echo "Version check passed: $TAG_VERSION == $CMAKE_VERSION"
strict-build:
needs: [classify-release, validate-version]
if: needs.classify-release.outputs.is_minor_or_major == 'true'
name: ${{ matrix.label }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
label: Linux GCC 14 (Debug)
shell: bash
cxx_compiler: g++-14
c_compiler: gcc-14
cmake_flags: -DGLFW_BUILD_WAYLAND=OFF
build_type: Debug
- os: ubuntu-24.04
label: Linux GCC 14 (Release)
shell: bash
cxx_compiler: g++-14
c_compiler: gcc-14
cmake_flags: -DGLFW_BUILD_WAYLAND=OFF
build_type: Release
- os: ubuntu-24.04
label: Linux Clang 18
shell: bash
cxx_compiler: clang++-18
c_compiler: clang-18
cmake_flags: -DGLFW_BUILD_WAYLAND=OFF
build_type: Debug
- os: windows-latest
label: Windows MinGW-w64
shell: msys2 - {0}
cxx_compiler: g++
c_compiler: gcc
cmake_flags: ""
build_type: Debug
runs-on: ${{ matrix.os }}
defaults:
run:
shell: ${{ matrix.shell }}
steps:
- uses: actions/checkout@v6
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq ninja-build cmake pkg-config xvfb \
libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev libgl1-mesa-dev
if [ "${{ matrix.cxx_compiler }}" = "clang++-18" ]; then
sudo apt-get install -y -qq clang-18
else
sudo apt-get install -y -qq g++-14
fi
- name: Install Windows dependencies (MSYS2 + MinGW-w64)
if: runner.os == 'Windows'
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
git
mingw-w64-x86_64-gcc
mingw-w64-x86_64-cmake
mingw-w64-x86_64-ninja
mingw-w64-x86_64-pkg-config
mingw-w64-x86_64-python
- name: Configure
run: >-
cmake -B build -G Ninja
-DCMAKE_CXX_COMPILER=${{ matrix.cxx_compiler }}
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
${{ matrix.cmake_flags }}
- name: Build
run: cmake --build build
- name: Test
run: |
if [ "${{ runner.os }}" = "Linux" ]; then
xvfb-run --auto-servernum ctest --test-dir build --output-on-failure -E "Benchmark"
else
# test_ui is excluded on Windows: it drives an interactive ImGui
# window and needs a display, so it cannot run headless in CI.
# ("ADC DDC output grid spans [-Fs/4, Fs/4)" was previously excluded
# by name too. Root cause: the bracket-paren pattern in that name
# broke catch_discover_tests' unquoted list parsing, merging it and
# every later test into one ';'-joined CTest entry that Catch2
# rejects as "Invalid Filter". The test was renamed to "ADC DDC
# output grid spans from -Fs/4 to Fs/4" (tests/test_adc.cpp) and now
# registers as its own CTest entry, so the exclusion is removed.)
ctest --test-dir build --output-on-failure -E "Benchmark|test_ui"
fi
- name: Verify MinGW TEST_CASE registration count
if: runner.os == 'Windows'
run: |
# The MinGW-w64 toolchain silently drops TEST_CASEs registered beyond
# a ceiling in the main `tests` binary (see tests/AGENTS.md). Count
# the registered cases (each emits one indented tag line) and fail if
# the count ever falls below the verified floor, so a silent drop is
# caught in CI instead of shipping unrun tests. Bump EXPECTED when the
# registered count changes; new coverage that must run on Windows goes
# in a standalone executable (e.g. test_signal_domain), not the main
# tests binary.
EXPECTED=223
COUNT=$(build/bin/tests.exe --list-tests | grep -c '^ \[')
echo "registered TEST_CASEs: $COUNT (expected >= $EXPECTED)"
if [ "$COUNT" -lt "$EXPECTED" ]; then
echo "ERROR: tests.exe registered $COUNT TEST_CASEs, below the verified floor of $EXPECTED"
exit 1
fi
sanitizer:
needs: [classify-release, validate-version]
if: needs.classify-release.outputs.is_minor_or_major == 'true'
runs-on: ubuntu-24.04
name: AddressSanitizer
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq ninja-build cmake pkg-config g++-14 \
libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev libgl1-mesa-dev
- name: Configure (ASan)
run: >-
cmake -B build -G Ninja
-DCMAKE_CXX_COMPILER=g++-14
-DCMAKE_C_COMPILER=gcc-14
-DCMAKE_BUILD_TYPE=Debug
-DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer"
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address"
-DGLFW_BUILD_WAYLAND=OFF
- name: Build
run: cmake --build build
- name: Test (ASan)
run: |
cd build
ASAN_OPTIONS=halt_on_error=1:detect_leaks=0 ctest --output-on-failure -E "Benchmark|test_ui"
package:
needs: [classify-release, validate-version]
name: ${{ matrix.label }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
label: Linux package build
shell: bash
cxx_compiler: g++-14
c_compiler: gcc-14
cmake_flags: -DGLFW_BUILD_WAYLAND=OFF
build_type: Debug
artifact_name: build-linux
- os: windows-latest
label: Windows package build
shell: msys2 - {0}
cxx_compiler: g++
c_compiler: gcc
cmake_flags: ""
build_type: Debug
artifact_name: build-windows
runs-on: ${{ matrix.os }}
defaults:
run:
shell: ${{ matrix.shell }}
steps:
- uses: actions/checkout@v6
- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq ninja-build cmake pkg-config \
libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libxext-dev libgl1-mesa-dev
sudo apt-get install -y -qq g++-14
- name: Install Windows dependencies (MSYS2 + MinGW-w64)
if: runner.os == 'Windows'
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
git
mingw-w64-x86_64-gcc
mingw-w64-x86_64-cmake
mingw-w64-x86_64-ninja
mingw-w64-x86_64-pkg-config
mingw-w64-x86_64-python
- name: Configure
run: >-
cmake -B build -G Ninja
-DCMAKE_CXX_COMPILER=${{ matrix.cxx_compiler }}
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
${{ matrix.cmake_flags }}
- name: Build
run: cmake --build build
- name: Collect MinGW runtime DLLs
if: runner.os == 'Windows'
run: |
mkdir -p mingw-dlls
for dll in libgcc_s_seh-1.dll libstdc++-6.dll libwinpthread-1.dll; do
cp /mingw64/bin/$dll mingw-dlls/
done
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: |
build/bin/tiny-rf-simulator${{ runner.os == 'Windows' && '.exe' || '' }}
mingw-dlls/
release:
needs: [classify-release, validate-version, strict-build, sanitizer, package]
if: >-
always() &&
needs.validate-version.result == 'success' &&
needs.package.result == 'success' &&
(needs.classify-release.outputs.is_minor_or_major != 'true' ||
(needs.strict-build.result == 'success' && needs.sanitizer.result == 'success'))
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Generate release notes
run: |
npm install -g git-cliff --silent
git-cliff --config cliff.toml --latest --strip header -o release-notes.md
- name: Download all build artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Package Linux binary
run: |
cp artifacts/build-linux/build/bin/tiny-rf-simulator rf-simulator-linux
chmod +x rf-simulator-linux
tar czf rf-simulator-linux-x86_64.tar.gz rf-simulator-linux
- name: Package Windows binary + DLLs
run: |
mkdir -p rf-simulator-windows
cp artifacts/build-windows/build/bin/tiny-rf-simulator.exe rf-simulator-windows/
cp artifacts/build-windows/mingw-dlls/*.dll rf-simulator-windows/ 2>/dev/null || true
zip -r rf-simulator-windows-x86_64.zip rf-simulator-windows/
- name: Create Release (draft)
uses: softprops/action-gh-release@v2
with:
body_path: release-notes.md
files: |
rf-simulator-linux-x86_64.tar.gz
rf-simulator-windows-x86_64.zip
draft: true