Skip to content

Commit 30c2bb5

Browse files
committed
Update to unified kth/0.78.0 Conan 2 package + modern CI
The standalone c-api/<ver>@kth/stable recipe was rolled into a single unified `kth` package; this branch updates py-native to consume it, modernizes the build pipeline, brings the C bindings up to date with the C-API drift accumulated over the last ~4 years, and replaces the deprecated CI workflow with a cibuildwheel-based one. Build pipeline: - conanfile.py: Conan 2 syntax (requirements()/generate()), pins kth/0.78.0 with currency=BCH and db=dynamic, stages headers and static libs from kth and ALL transitive deps into ./kth/. - setup.py: drop dead Conan 1.x Conan.factory() path; shell out to `conan install` instead. BuildExtCommand discovers staged libs at build time and wraps them in -Wl,--start-group/--end-group so the linker resolves circular deps regardless of glob order. C++23, explicit -lstdc++. run_conan_install() also reads KTH_MARCH_ID and KTH_CURRENCY from env (CLI flags still win) so CI can override. - Move .sh helpers to scripts/, drop .bat, .travis/, .appveyor.yml, AUTHORS, residual __init__.py. C-API drift fixes (Python signatures changed accordingly β€” py-api will need matching updates): - block/header/transaction factory_from_data: drop `version` arg - block/header serialized_size, header_to_data: drop `version` arg - output_point_construct_from_hash_index: takes kth_hash_t const* now - chain_script_construct -> chain_script_construct_from_bytes - wallet_payment_address_encoded split into _legacy / _cashaddr (with token_aware bool) / _token (the BCH-only ones gated by KTH_CURRENCY_BCH) - transaction_hash_sighash_type removed (no longer in C-API) - node_get_chain -> node_chain - node.cpp: explicitly include kth/capi/node_info.h (no longer pulled in transitively by kth/capi.h) Settings struct sync: - DatabaseSettings: drop flush_writes/file_growth_rate/ index_start_height; add db_mode (kth_db_mode_t enum: 0=pruned, 1=normal, 2=full_indexed). - BlockchainSettings: drop gauss_activation_time/ descartes_activation_time; add bch_gauss/bch_descartes/ bch_lobachevski/bch_galois bools and the new leibniz_activation_time (2026) / cantor_activation_time (2027). module.c quality pass: - Replace 8 functions full of `int res2 = ...; res2 = ...; res2 = ...` (set-but-never-checked) with KTH_TRY_SETATTR macro that Py_DECREFs the half-built object and returns NULL on the first failure, propagating the Python exception correctly. The macro name is provisional; flagged for the cleanup pass. Tests: - test_config.py rewritten with shared `_assert_common_*` helpers (mainnet and testnet4 share ~80 asserts), named constants (DB_MODE_NORMAL, LEIBNIZ_ACTIVATION_TIME, CANTOR_ACTIVATION_TIME), loops over BIP/BCH flag families instead of 30 copy-pasted lines, and `>=` bounds instead of exact-equality on things that grow organically (checkpoint count, seed count). Covers the new db_mode and bch_* fields, drops the removed gauss/descartes ones. - test_node.py: rename node_get_chain -> node_chain. All 3 tests pass against a real Knuth v0.78.0 node startup on mainnet (32+32 threads, march_id=ZLm9Pjh). CI (replaces the old knuth.yml): - The old workflow was a Frankenstein of npm/node-pre-gyp/twine/ Docker-custom across three shells, pinned to ubuntu-20.04 (deprecated by GitHub) and node-pre-gyp paths that don't even apply to a Python package. Replaced wholesale. - New ci.yml: sdist job + cibuildwheel matrix on Linux x86_64 (manylinux container) and macOS arm64 (macos-latest is Apple Silicon now). cp39-cp313, no PyPy, no musllinux, no 32-bit. - Conan installed in CIBW_BEFORE_ALL, kth remote registered, and CIBW_BEFORE_BUILD pre-installs the build deps so we can run pip with --no-build-isolation (our setup.py shells out to `conan install`). - Smoke test inside each built wheel: `import kth_native` + pytest. - publish job scaffolded for Trusted Publishing on tag pushes, gated behind `if: false` until PyPI auth is wired up. - KTH_MARCH_ID/KTH_CURRENCY pinned at workflow level so the build flavor lives in exactly one place. - Concurrency group cancels superseded PR runs to save minutes. - Windows is intentionally out of this pass β€” the old workflow's Windows path was 100% npm/node-gyp/node-pre-gyp and never built a Python wheel in the first place. Add `windows-latest` later as a follow-up once Linux/macOS is green.
1 parent 0c71a98 commit 30c2bb5

34 files changed

Lines changed: 694 additions & 1405 deletions

β€Ž.appveyor.ymlβ€Ž

Lines changed: 0 additions & 131 deletions
This file was deleted.

β€Ž.github/workflows/ci.ymlβ€Ž

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
# Copyright (c) 2016-present Knuth Project developers.
2+
# Distributed under the MIT software license, see the accompanying
3+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
name: πŸ› οΈ CI
6+
7+
on:
8+
push:
9+
branches: [master]
10+
tags: ['v*']
11+
pull_request:
12+
workflow_dispatch:
13+
14+
# Cancel superseded runs on the same ref to save minutes.
15+
concurrency:
16+
group: ${{ github.workflow }}-${{ github.ref }}
17+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
18+
19+
# Default permissions: read-only. Jobs that need more (publish, OIDC)
20+
# elevate them locally.
21+
permissions:
22+
contents: read
23+
24+
env:
25+
# ──────────────────────────────────────────────────────────────────
26+
# Knuth build flavor pinned for every wheel CI produces. Override
27+
# here (and only here) when bumping the upstream node version.
28+
# ──────────────────────────────────────────────────────────────────
29+
KTH_MARCH_ID: ZLm9Pjh
30+
KTH_CURRENCY: BCH
31+
32+
# CPython versions we ship wheels for.
33+
CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*"
34+
# No PyPy, no musllinux, no 32-bit, no Windows (yet).
35+
CIBW_SKIP: "pp* *-musllinux_* *-manylinux_i686 *-win32"
36+
37+
jobs:
38+
# ══════════════════════════════════════════════════════════════════
39+
# πŸ“¦ sdist β€” built once on Linux, fed into the publish job and
40+
# uploaded as a release artifact.
41+
# ══════════════════════════════════════════════════════════════════
42+
sdist:
43+
name: πŸ“¦ Build sdist
44+
runs-on: ubuntu-latest
45+
steps:
46+
- name: ⬇️ Checkout
47+
uses: actions/checkout@v5
48+
49+
- name: 🐍 Set up Python
50+
uses: actions/setup-python@v6
51+
with:
52+
python-version: '3.13'
53+
54+
- name: πŸ”§ Install build tooling
55+
run: python -m pip install --upgrade pip build
56+
57+
- name: πŸ“¦ Build source distribution
58+
run: python -m build --sdist
59+
60+
- name: πŸ“‹ Summary
61+
run: |
62+
{
63+
echo "### πŸ“¦ Source distribution"
64+
echo
65+
echo '```'
66+
ls -lh dist/
67+
echo '```'
68+
} >> "$GITHUB_STEP_SUMMARY"
69+
70+
- name: ⬆️ Upload sdist artifact
71+
uses: actions/upload-artifact@v4
72+
with:
73+
name: sdist
74+
path: dist/*.tar.gz
75+
if-no-files-found: error
76+
retention-days: 14
77+
78+
# ══════════════════════════════════════════════════════════════════
79+
# πŸ›ž wheels β€” cibuildwheel matrix.
80+
# Linux x86_64 (manylinux_2_28 container) and macOS
81+
# arm64 (Apple Silicon, default for macos-latest now).
82+
# ══════════════════════════════════════════════════════════════════
83+
wheels:
84+
name: πŸ›ž ${{ matrix.label }}
85+
runs-on: ${{ matrix.os }}
86+
strategy:
87+
fail-fast: false
88+
matrix:
89+
include:
90+
- os: ubuntu-latest
91+
label: Wheels Β· Linux x86_64
92+
cache_key: linux-x64
93+
- os: macos-latest
94+
label: Wheels Β· macOS arm64
95+
cache_key: macos-arm64
96+
97+
steps:
98+
- name: ⬇️ Checkout
99+
uses: actions/checkout@v5
100+
101+
- name: 🐍 Set up Python
102+
uses: actions/setup-python@v6
103+
with:
104+
python-version: '3.13'
105+
106+
# Conan downloads ~hundreds of MB of pre-built deps from the kth
107+
# remote. Persisting the cache between runs cuts cold-build time
108+
# dramatically. Key on the conanfile so a recipe bump invalidates.
109+
- name: πŸ’Ύ Cache Conan packages
110+
uses: actions/cache@v4
111+
with:
112+
path: |
113+
~/.conan2
114+
key: conan-${{ matrix.cache_key }}-${{ hashFiles('conanfile.py') }}
115+
restore-keys: |
116+
conan-${{ matrix.cache_key }}-
117+
118+
- name: πŸ›ž Build wheels with cibuildwheel
119+
uses: pypa/cibuildwheel@v3.2
120+
env:
121+
# ──── Conan setup, runs once inside each manylinux container
122+
# (Linux) or once on the macOS host before any wheel build.
123+
CIBW_BEFORE_ALL_LINUX: |
124+
python3 -m pip install --upgrade pip conan kthbuild
125+
conan profile detect --force
126+
conan remote add kth https://packages.kth.cash/api/ --force
127+
CIBW_BEFORE_ALL_MACOS: |
128+
python3 -m pip install --upgrade pip conan kthbuild
129+
conan profile detect --force
130+
conan remote add kth https://packages.kth.cash/api/ --force
131+
132+
# Our setup.py shells out to `conan` from the build env, so
133+
# disable pip's PEP 517 build isolation and pre-install the
134+
# build deps in the target Python before each wheel build.
135+
CIBW_BUILD_FRONTEND: "pip; args: --no-build-isolation"
136+
CIBW_BEFORE_BUILD: |
137+
pip install --upgrade pip setuptools wheel conan kthbuild
138+
139+
# Pass our build-flavor envs through to the cibuildwheel
140+
# container/host so setup.py picks them up.
141+
CIBW_ENVIRONMENT: >-
142+
KTH_MARCH_ID=${{ env.KTH_MARCH_ID }}
143+
KTH_CURRENCY=${{ env.KTH_CURRENCY }}
144+
145+
# Smoke test inside each freshly built wheel: import the
146+
# extension and run pytest. {package} is the project root
147+
# that cibuildwheel passes in.
148+
CIBW_TEST_REQUIRES: pytest
149+
CIBW_TEST_COMMAND: >-
150+
python -c "import kth_native; print(f'symbols: {len(dir(kth_native))}')"
151+
&& pytest {package}/tests/test_config.py -v
152+
153+
- name: πŸ“‹ Summary
154+
if: always()
155+
run: |
156+
{
157+
echo "### πŸ›ž ${{ matrix.label }}"
158+
echo
159+
if [ -d ./wheelhouse ] && ls ./wheelhouse/*.whl >/dev/null 2>&1; then
160+
echo '```'
161+
ls -lh ./wheelhouse/
162+
echo '```'
163+
else
164+
echo "_No wheels produced._"
165+
fi
166+
} >> "$GITHUB_STEP_SUMMARY"
167+
168+
- name: ⬆️ Upload wheel artifacts
169+
uses: actions/upload-artifact@v4
170+
with:
171+
name: wheels-${{ matrix.cache_key }}
172+
path: ./wheelhouse/*.whl
173+
if-no-files-found: error
174+
retention-days: 14
175+
176+
# ══════════════════════════════════════════════════════════════════
177+
# πŸš€ publish β€” PyPI release on tag pushes.
178+
# Disabled by default (`if: false`); flip the gate and
179+
# pick an auth method when ready to ship.
180+
# ══════════════════════════════════════════════════════════════════
181+
publish:
182+
name: πŸš€ Publish to PyPI
183+
needs: [sdist, wheels]
184+
runs-on: ubuntu-latest
185+
if: false # TODO: enable when PyPI auth is set up
186+
# if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
187+
environment:
188+
name: pypi
189+
url: https://pypi.org/p/kth-py-native
190+
permissions:
191+
id-token: write # required for Trusted Publishing (OIDC)
192+
steps:
193+
- name: ⬇️ Download all artifacts
194+
uses: actions/download-artifact@v4
195+
with:
196+
path: dist
197+
merge-multiple: true
198+
199+
- name: πŸ“‹ Show what we're about to publish
200+
run: ls -lh dist/
201+
202+
- name: πŸš€ Publish to PyPI
203+
uses: pypa/gh-action-pypi-publish@release/v1
204+
# If you prefer a token instead of Trusted Publishing, drop
205+
# the `permissions:` block above and uncomment:
206+
# with:
207+
# password: ${{ secrets.PYPI_API_TOKEN }}
208+
209+
# ══════════════════════════════════════════════════════════════════
210+
# βœ… ci β€” single status check that gates branch protection. Add
211+
# this one to required checks instead of the matrix legs,
212+
# so the protection rule survives matrix changes.
213+
# ══════════════════════════════════════════════════════════════════
214+
ci:
215+
name: βœ… CI
216+
needs: [sdist, wheels]
217+
runs-on: ubuntu-latest
218+
if: always()
219+
steps:
220+
- name: 🎯 Aggregate result
221+
run: |
222+
if [ "${{ needs.sdist.result }}" != "success" ] || \
223+
[ "${{ needs.wheels.result }}" != "success" ]; then
224+
echo "One or more jobs failed."
225+
echo " sdist: ${{ needs.sdist.result }}"
226+
echo " wheels: ${{ needs.wheels.result }}"
227+
exit 1
228+
fi
229+
echo "πŸŽ‰ All required jobs succeeded."

0 commit comments

Comments
Β (0)