@@ -164,6 +164,238 @@ jobs:
164164
165165 - run : " nix develop .#devShells.x86_64-linux.default --command ./ci/build/nix.sh"
166166
167+ build-python-packages :
168+ needs :
169+ - lint-bash
170+ - lint-nim
171+ - lint-nix
172+ - lint-rust
173+ - lint-ui-tests
174+ strategy :
175+ fail-fast : false
176+ matrix :
177+ include :
178+ - name : linux-amd64
179+ runner : ubuntu-latest
180+ target_os : linux
181+ arch : amd64
182+ plat_name : manylinux_2_17_x86_64
183+ # - name: linux-arm64
184+ # runner: ubuntu-22.04-arm64
185+ # target_os: linux
186+ # arch: arm64
187+ # plat_name: manylinux_2_17_aarch64
188+
189+ - name : macos-amd64
190+ runner : macos-13
191+ target_os : macos
192+ arch : amd64
193+ plat_name : macosx_10_9_x86_64
194+ - name : macos-arm64
195+ runner : macos-14
196+ target_os : macos
197+ arch : arm64
198+ plat_name : macosx_11_0_arm64
199+
200+ runs-on : ${{ matrix.runner }}
201+ steps :
202+ - name : Check out repository
203+ uses : actions/checkout@v4
204+ with :
205+ submodules : ' true'
206+
207+
208+ - name : Set up Python
209+ uses : actions/setup-python@v5
210+ with :
211+ python-version : ' 3.11'
212+
213+ - name : Install Python build backend
214+ run : python -m pip install --upgrade build
215+
216+ - name : Install nim
217+ run : |
218+ set -euo pipefail
219+
220+ wget https://nim-lang.org/download/nim-1.6.20.tar.xz
221+ tar xf nim-1.6.20.tar.xz
222+ pushd nim-1.6.20
223+ sh build.sh
224+ bin/nim c koch
225+ ./koch boot -d:release
226+ export PATH="$(pwd)/bin:${PATH}"
227+ popd
228+
229+ - name : Get sqlite
230+ run : |
231+ set -euo pipefail
232+
233+ wget https://sqlite.org/2025/sqlite-amalgamation-3500400.zip
234+ unzip sqlite-amalgamation-3500400.zip
235+ cp sqlite-amalgamation-3500400/sqlite3.c .
236+
237+ - name : Install libssl (Linux)
238+ if : ${{ matrix.target_os == 'linux' }}
239+ run : |
240+ sudo apt-get update
241+ sudo apt-get install -y libssl-dev
242+
243+ - name : Install libssl (MacOS)
244+ if : ${{ matrix.target_os == 'macos' }}
245+ run : |
246+ git clone https://github.com/openssl/openssl
247+ pushd openssl
248+ git checkout openssl-3.5.4
249+
250+ ./Configure --prefix=$(pwd)/../openssl-res
251+ make -j$(sysctl -n hw.ncpu)
252+ make install_sw
253+
254+ popd
255+
256+ - name : Install zlib (Linux)
257+ if : ${{ matrix.target_os == 'linux' }}
258+ run : |
259+ sudo apt-get update
260+ sudo apt-get install -y zlib1g-dev
261+
262+ - name : Install zlib (MacOS)
263+ if : ${{ matrix.target_os == 'macos' }}
264+ run : |
265+ wget https://zlib.net/zlib-1.3.1.tar.gz
266+ tar xf zlib-1.3.1.tar.gz
267+ pushd zlib-1.3.1
268+
269+ ./configure --static --prefix=$(pwd)/../zlib-res
270+ make -j$(sysctl -n hw.ncpu)
271+ make install
272+
273+ popd
274+
275+ - name : Build codetracer binaries (Linux)
276+ if : ${{ matrix.target_os == 'linux' }}
277+ shell : bash
278+ run : |
279+ set -euo pipefail
280+
281+ TARGET_DIR="build-python/src/ct/bin/${{ matrix.target_os }}-${{ matrix.arch }}"
282+ mkdir -p "${TARGET_DIR}"
283+
284+ ./nim-1.6.20/bin/nim -d:release \
285+ --d:asyncBackend=asyncdispatch \
286+ --dynlibOverride:std -d:staticStd \
287+ --gc:refc --hints:on --warnings:off \
288+ --boundChecks:on \
289+ -d:useOpenssl3 \
290+ -d:ssl \
291+ -d:chronicles_sinks=json -d:chronicles_line_numbers=true \
292+ -d:chronicles_timestamps=UnixTime \
293+ -d:ctTest -d:testing --hint"[XDeclaredButNotUsed]":off \
294+ -d:builtWithNix \
295+ -d:ctEntrypoint \
296+ -d:pythonPackage \
297+ -d:linksPathConst=.. \
298+ -d:libcPath=libc \
299+ -d:pathToNodeModules=../node_modules \
300+ --nimcache:nimcache \
301+ -d:staticSqlite \
302+ -d:useLibzipSrc \
303+ --passL:"-Wl,-Bstatic -L/usr/lib/x86_64-linux-gnu -l:libz.a -Wl,-Bdynamic" \
304+ --dynlibOverride:ssl --dynlibOverride:crypto \
305+ --passL:"-Wl,-Bstatic -L/usr/lib/x86_64-linux-gnu -l:libssl.a -l:libcrypto.a -Wl,-Bdynamic" \
306+ --out:"${TARGET_DIR}/ct" c ./src/ct/codetracer.nim
307+
308+ ./nim-1.6.20/bin/nim \
309+ -d:release -d:asyncBackend=asyncdispatch \
310+ --gc:refc --hints:off --warnings:off \
311+ --debugInfo --lineDir:on \
312+ --boundChecks:on --stacktrace:on --linetrace:on \
313+ -d:chronicles_sinks=json -d:chronicles_line_numbers=true \
314+ -d:chronicles_timestamps=UnixTime \
315+ -d:ssl \
316+ -d:ctTest -d:testing --hint"[XDeclaredButNotUsed]":off \
317+ -d:linksPathConst=.. \
318+ -d:libcPath=libc \
319+ -d:builtWithNix \
320+ -d:ctEntrypoint \
321+ -d:pythonPackage \
322+ --nimcache:nimcache \
323+ -d:staticSqlite \
324+ -d:useLibzipSrc \
325+ --passL:"-Wl,-Bstatic -L/usr/lib/x86_64-linux-gnu -l:libz.a -Wl,-Bdynamic" \
326+ --dynlibOverride:ssl --dynlibOverride:crypto \
327+ --passL:"-Wl,-Bstatic -L/usr/lib/x86_64-linux-gnu -l:libssl.a -l:libcrypto.a -Wl,-Bdynamic" \
328+ --out:"${TARGET_DIR}/db-backend-record" c ./src/ct/db_backend_record.nim
329+
330+ - name : Build codetracer binaries (MacOS)
331+ if : ${{ matrix.target_os == 'macos' }}
332+ run : |
333+ set -euo pipefail
334+
335+ TARGET_DIR="build-python/src/ct/bin/${{ matrix.target_os }}-${{ matrix.arch }}"
336+ mkdir -p "${TARGET_DIR}"
337+
338+ ./nim-1.6.20/bin/nim -d:release \
339+ --d:asyncBackend=asyncdispatch \
340+ --dynlibOverride:std -d:staticStd \
341+ --gc:refc --hints:on --warnings:off \
342+ --boundChecks:on \
343+ -d:useOpenssl3 \
344+ -d:ssl \
345+ -d:chronicles_sinks=json -d:chronicles_line_numbers=true \
346+ -d:chronicles_timestamps=UnixTime \
347+ -d:ctTest -d:testing --hint"[XDeclaredButNotUsed]":off \
348+ -d:builtWithNix \
349+ -d:ctEntrypoint \
350+ -d:pythonPackage \
351+ -d:linksPathConst=.. \
352+ -d:libcPath=libc \
353+ -d:pathToNodeModules=../node_modules \
354+ --nimcache:nimcache \
355+ -d:staticSqlite \
356+ -d:useLibzipSrc \
357+ --passL:"$(pwd)/zlib-res/lib/libz.a" \
358+ --dynlibOverride:ssl --dynlibOverride:crypto \
359+ --passL:"$(pwd)/openssl-res/lib/libssl.a $(pwd)/openssl-res/lib/libcrypto.a" \
360+ --out:"${TARGET_DIR}/ct" c ./src/ct/codetracer.nim
361+
362+ ./nim-1.6.20/bin/nim \
363+ -d:release -d:asyncBackend=asyncdispatch \
364+ --gc:refc --hints:off --warnings:off \
365+ --debugInfo --lineDir:on \
366+ --boundChecks:on --stacktrace:on --linetrace:on \
367+ -d:chronicles_sinks=json -d:chronicles_line_numbers=true \
368+ -d:chronicles_timestamps=UnixTime \
369+ -d:ssl \
370+ -d:ctTest -d:testing --hint"[XDeclaredButNotUsed]":off \
371+ -d:linksPathConst=.. \
372+ -d:libcPath=libc \
373+ -d:builtWithNix \
374+ -d:ctEntrypoint \
375+ -d:pythonPackage \
376+ --nimcache:nimcache \
377+ -d:staticSqlite \
378+ -d:useLibzipSrc \
379+ --passL:"$(pwd)/zlib-res/lib/libz.a" \
380+ --dynlibOverride:ssl --dynlibOverride:crypto \
381+ --passL:"$(pwd)/openssl-res/lib/libssl.a $(pwd)/openssl-res/lib/libcrypto.a" \
382+ --out:"${TARGET_DIR}/db-backend-record" c ./src/ct/db_backend_record.nim
383+
384+ - name : Build wheel
385+ run : |
386+ set -euo pipefail
387+
388+ pushd build-python
389+ python -m build --wheel -C--build-option=--plat-name=${{ matrix.plat_name }}
390+ popd
391+
392+ - name : Upload distributions
393+ uses : actions/upload-artifact@v4
394+ with :
395+ name : python-dist-${{ matrix.name }}
396+ path : build-python/dist/*.whl
397+ if-no-files-found : error
398+
167399 appimage-build :
168400 runs-on : [self-hosted, nixos]
169401 needs :
@@ -315,6 +547,7 @@ jobs:
315547 - nix-build
316548 - appimage-build
317549 - dmg-build
550+ - build-python-packages
318551 steps :
319552 - name : Checkout
320553 uses : actions/checkout@v5
@@ -338,6 +571,7 @@ jobs:
338571 - nix-build
339572 - appimage-build
340573 - dmg-build
574+ - build-python-packages
341575 steps :
342576 - name : Checkout
343577 uses : actions/checkout@v5
@@ -361,6 +595,7 @@ jobs:
361595 - nix-build
362596 - appimage-build
363597 - dmg-build
598+ - build-python-packages
364599 steps :
365600 - name : Checkout
366601 uses : actions/checkout@v5
@@ -377,6 +612,33 @@ jobs:
377612
378613 - run : " nix develop .#devShells.x86_64-linux.default --command ./ci/test/ui-tests.sh"
379614
615+ publish-pypi :
616+ needs :
617+ - build-python-packages
618+ - test-rust
619+ - test-python-recorder
620+ - test-ui-tests
621+ # - create-release
622+ # if: startsWith(github.ref, 'refs/tags/')
623+ runs-on : ubuntu-latest
624+ steps :
625+ - name : Download built distributions
626+ uses : actions/download-artifact@v4
627+ with :
628+ path : dist
629+ merge-multiple : true
630+
631+ - name : Publish to TestPyPI
632+ uses : pypa/gh-action-pypi-publish@release/v1
633+ with :
634+ packages_dir : dist
635+ repository-url : https://test.pypi.org/legacy/
636+
637+ # - name: Publish to PyPI
638+ # uses: pypa/gh-action-pypi-publish@release/v1
639+ # with:
640+ # packages_dir: dist
641+
380642 push-to-cachix :
381643 runs-on : [self-hosted, nixos]
382644 needs :
@@ -450,7 +712,7 @@ jobs:
450712 git config --global user.name "github-actions[bot]"
451713 git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
452714 git config --global init.defaultBranch main
453-
715+
454716 git remote set-url origin https://x-access-token:${{ secrets.CODETRACER_PUSH_GITHUB_TOKEN }}@github.com/metacraft-labs/codetracer
455717
456718 git tag -a "$YEAR.$MONTH.$BUILD" -m "Release $YEAR.$MONTH.$BUILD" || echo "Tag already exists"
0 commit comments