Repository navigation
269 lines (227 loc) · 9.71 KB
/
Copy pathci.yml
File metadata and controls
269 lines (227 loc) · 9.71 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
name: CI
on:
push:
branches:
- master
- dev
pull_request:
branches:
- master
- dev
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
occt:
# The C++ module links a static OpenCASCADE built from source (the same build the release wheels use). It is built
# once per version of the build script and cached; the jobs below restore it.
name: Static OpenCASCADE
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- name: Check out repository
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- name: Restore the static OpenCASCADE build
id: cache
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/occt
key: occt-ci-linux-${{ hashFiles('src/cpp/tools/build_occt.py') }}
- name: Build OpenCASCADE
if: steps.cache.outputs.cache-hit != 'true'
run: python3 src/cpp/tools/build_occt.py --prefix "$HOME/occt"
format:
# No OpenCASCADE needed: runs in seconds, ahead of the heavy jobs.
name: clang-format
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check out repository
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- name: Install clang-format
run: python3 -m pip install clang-format==18.1.8
- name: Check formatting
run: CLANG_FORMAT=clang-format src/cpp/tools/check_format.sh
occt-guard:
# Every boolean / fillet / offset builder is constructed in a function that runs under occt_guard (or says, with
# `// occt_guard: the caller X ...`, that its one caller does). See src/cpp/tools/check_occt_guard.py.
name: OCCT guard audit
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Check out repository
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- name: Audit
run: python3 src/cpp/tools/check_occt_guard.py --strict
cpp-tests:
# The engine's own doctest executables (one per area), Release, no sanitizer: what the Python jobs below never run.
name: C++ tests (Release)
needs: occt
runs-on: ubuntu-latest
timeout-minutes: 90
steps:
- name: Check out repository
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- name: Restore the static OpenCASCADE build
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/occt
key: occt-ci-linux-${{ hashFiles('src/cpp/tools/build_occt.py') }}
fail-on-cache-miss: true
- name: Configure
run: >
cmake -S src/cpp -B build/release -G Ninja
-DCMAKE_BUILD_TYPE=Release -DSCAD_BUILD_PYTHON=OFF -DSCAD_BUILD_TESTS=ON
-DSCAD_OCCT_PREFIX="$HOME/occt"
- name: Build
run: cmake --build build/release -j"$(nproc)"
- name: Run the doctest executables
run: ctest --test-dir build/release --output-on-failure -j"$(nproc)"
sanitize:
# The OCCT it links is not instrumented, so OCCT's own reports are suppressed (tools/ubsan.supp, tools/lsan.supp);
# only the doctest executables are built (no Python layer).
name: C++ tests (ASan + UBSan)
needs: occt
runs-on: ubuntu-latest
timeout-minutes: 90
steps:
- name: Check out repository
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- name: Restore the static OpenCASCADE build
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/occt
key: occt-ci-linux-${{ hashFiles('src/cpp/tools/build_occt.py') }}
fail-on-cache-miss: true
- name: Configure
# SCAD_SANITIZE adds -fsanitize=address,undefined (no thread sanitizer option exists). The Python module is not
# built: loading an ASan module into an uninstrumented interpreter needs LD_PRELOAD games, and the doctest
# executables cover the engine.
run: >
cmake -S src/cpp -B build/asan -G Ninja
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DSCAD_SANITIZE=ON -DSCAD_BUILD_PYTHON=OFF -DSCAD_BUILD_TESTS=ON
-DSCAD_OCCT_PREFIX="$HOME/occt"
- name: Build
run: cmake --build build/asan -j"$(nproc)"
- name: Run the doctest executables
env:
ASAN_OPTIONS: halt_on_error=1:abort_on_error=1:detect_leaks=1:strict_string_checks=1:check_initialization_order=1
LSAN_OPTIONS: suppressions=${{ github.workspace }}/src/cpp/tools/lsan.supp:print_suppressions=0
UBSAN_OPTIONS: halt_on_error=1:print_stacktrace=1:suppressions=${{ github.workspace }}/src/cpp/tools/ubsan.supp
run: ctest --test-dir build/asan --output-on-failure -j"$(nproc)"
clang-tidy:
# Advisory: .clang-tidy is small but the code base has never been run through it. Changed files only.
name: clang-tidy (advisory)
needs: occt
runs-on: ubuntu-latest
timeout-minutes: 60
continue-on-error: true
steps:
- name: Check out repository
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
with:
fetch-depth: 0
- name: Restore the static OpenCASCADE build
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/occt
key: occt-ci-linux-${{ hashFiles('src/cpp/tools/build_occt.py') }}
fail-on-cache-miss: true
- name: Install clang-tidy
run: python3 -m pip install clang-tidy==18.1.8
- name: Configure (compile_commands.json)
run: >
cmake -S src/cpp -B build/tidy -G Ninja
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DSCAD_BUILD_PYTHON=OFF
-DSCAD_OCCT_PREFIX="$HOME/occt"
- name: Run clang-tidy on the changed files
run: |
base="${{ github.event.pull_request.base.sha || github.event.before }}"
if [ -z "$base" ] || ! git cat-file -e "$base^{commit}" 2>/dev/null; then base="HEAD~1"; fi
# The engine only: the bindings need Python.h and pybind11, which a configure without the Python layer
# (SCAD_BUILD_PYTHON=OFF) does not put in the compile database.
files=$(git diff --name-only --diff-filter=d "$base" HEAD -- 'src/cpp/src/*.cpp' || true)
if [ -z "$files" ]; then echo "no C++ sources changed"; exit 0; fi
# shellcheck disable=SC2086
clang-tidy -p build/tidy --quiet $files
test:
name: Python ${{ matrix.python-version }}
needs: occt
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
python-version:
- "3.10"
- "3.11"
- "3.12"
- "3.13"
steps:
- name: Check out repository
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- name: Install uv and Python
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
cache-python: true
- name: Restore the static OpenCASCADE build
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/occt
key: occt-ci-linux-${{ hashFiles('src/cpp/tools/build_occt.py') }}
fail-on-cache-miss: true
- name: Install locked dependencies and build the C++ module
run: CMAKE_ARGS="-DSCAD_OCCT_PREFIX=$HOME/occt" uv sync --locked --group dev
- name: Compile package
run: uv run python -m compileall -q src/simplecadapi
- name: Run tests
run: uv run pytest test tests -q
- name: Run the C++ parity tests (goldens must exist)
# SCAD_GOLDEN_STRICT (read by tests/python/ref.py) makes a missing golden file a failure, not a silent recording;
# SCAD_REGOLDEN is refused under it.
env:
SCAD_GOLDEN_STRICT: "1"
run: uv run pytest src/cpp/tests/python -q
- name: Check the type stubs are current
# The checked-in stubs (generated on macOS arm64) are reproduced on Linux.
if: matrix.python-version == '3.12'
run: |
uv pip install pybind11-stubgen==2.5.5
PYTHON="uv run --no-sync python" src/cpp/tools/gen_stubs.sh --check
# The verifier bridge needs OCP, which the SDK and the suite above never do: it is overlaid for this one run.
- name: Verifier bridge (OCP)
run: uv run --with "cadquery-ocp-novtk>=7.9.3.1,<8" pytest src/cpp/tests/python/test_verify_bridge.py -q
editor-e2e:
needs: occt
# The editor tests that boot a real marimo kernel (about a minute); the main
# job runs the rest of test/test_editor.py without it.
name: Editor end to end
runs-on: ubuntu-latest
timeout-minutes: 20
env:
SCA_EDITOR_E2E: "1"
steps:
- name: Check out repository
uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- name: Install uv and Python
uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2
with:
python-version: "3.12"
enable-cache: true
cache-python: true
- name: Restore the static OpenCASCADE build
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: ~/occt
key: occt-ci-linux-${{ hashFiles('src/cpp/tools/build_occt.py') }}
fail-on-cache-miss: true
- name: Install locked dependencies and build the C++ module
run: CMAKE_ARGS="-DSCAD_OCCT_PREFIX=$HOME/occt" uv sync --locked --group dev
- name: Run the editor tests, kernel included
run: uv run pytest test/test_editor.py -q