protowire-python 0.70.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. protowire_python-0.70.0/.editorconfig +27 -0
  2. protowire_python-0.70.0/.github/CODEOWNERS +22 -0
  3. protowire_python-0.70.0/.github/ISSUE_TEMPLATE/bug_report.md +49 -0
  4. protowire_python-0.70.0/.github/ISSUE_TEMPLATE/config.yml +28 -0
  5. protowire_python-0.70.0/.github/ISSUE_TEMPLATE/feature_request.md +36 -0
  6. protowire_python-0.70.0/.github/PULL_REQUEST_TEMPLATE.md +36 -0
  7. protowire_python-0.70.0/.github/dependabot.yml +28 -0
  8. protowire_python-0.70.0/.github/workflows/ci.yml +179 -0
  9. protowire_python-0.70.0/.github/workflows/codeql.yml +73 -0
  10. protowire_python-0.70.0/.github/workflows/publish.yml +203 -0
  11. protowire_python-0.70.0/.gitignore +23 -0
  12. protowire_python-0.70.0/CHANGELOG.md +53 -0
  13. protowire_python-0.70.0/CMakeLists.txt +63 -0
  14. protowire_python-0.70.0/CODE_OF_CONDUCT.md +14 -0
  15. protowire_python-0.70.0/CONTRIBUTING.md +113 -0
  16. protowire_python-0.70.0/GOVERNANCE.md +74 -0
  17. protowire_python-0.70.0/LICENSE +21 -0
  18. protowire_python-0.70.0/PKG-INFO +180 -0
  19. protowire_python-0.70.0/README.md +146 -0
  20. protowire_python-0.70.0/SECURITY.md +80 -0
  21. protowire_python-0.70.0/pyproject.toml +57 -0
  22. protowire_python-0.70.0/scripts/bench_pxf.py +101 -0
  23. protowire_python-0.70.0/scripts/bench_sbe.py +123 -0
  24. protowire_python-0.70.0/scripts/cibw_install_protobuf_linux.sh +42 -0
  25. protowire_python-0.70.0/scripts/dump_envelope.py +31 -0
  26. protowire_python-0.70.0/src/_protowire/module.cc +329 -0
  27. protowire_python-0.70.0/src/protowire/__init__.py +8 -0
  28. protowire_python-0.70.0/src/protowire/_schema.py +69 -0
  29. protowire_python-0.70.0/src/protowire/envelope.py +351 -0
  30. protowire_python-0.70.0/src/protowire/pxf.py +95 -0
  31. protowire_python-0.70.0/src/protowire/py.typed +0 -0
  32. protowire_python-0.70.0/src/protowire/sbe.py +101 -0
  33. protowire_python-0.70.0/testdata/order.proto +18 -0
  34. protowire_python-0.70.0/testdata/test.proto +47 -0
  35. protowire_python-0.70.0/tests/conftest.py +84 -0
  36. protowire_python-0.70.0/tests/test_envelope.py +187 -0
  37. protowire_python-0.70.0/tests/test_pxf.py +55 -0
  38. protowire_python-0.70.0/tests/test_pxf_full_roundtrip.py +261 -0
  39. protowire_python-0.70.0/tests/test_sbe.py +126 -0
  40. protowire_python-0.70.0/tests/test_sbe_view_navigation.py +226 -0
@@ -0,0 +1,27 @@
1
+ # EditorConfig — https://editorconfig.org
2
+
3
+ root = true
4
+
5
+ [*]
6
+ charset = utf-8
7
+ end_of_line = lf
8
+ insert_final_newline = true
9
+ trim_trailing_whitespace = true
10
+ indent_style = space
11
+ indent_size = 4
12
+
13
+ [*.{md,markdown}]
14
+ trim_trailing_whitespace = false # markdown uses trailing spaces for line breaks
15
+ indent_size = 2
16
+
17
+ [*.{yml,yaml,json,toml}]
18
+ indent_size = 2
19
+
20
+ [*.{cc,h,hpp,proto,cmake}]
21
+ indent_size = 2
22
+
23
+ [CMakeLists.txt]
24
+ indent_size = 2
25
+
26
+ [Makefile]
27
+ indent_style = tab
@@ -0,0 +1,22 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 TrendVidia, LLC.
3
+ #
4
+ # Code ownership for protowire-python.
5
+
6
+ * @trendvidia/maintainers
7
+
8
+ # --- FFI boundary (cross-language safety scrutiny applies) --------------
9
+ /src/_protowire/ @trendvidia/maintainers
10
+
11
+ # --- Public Python API --------------------------------------------------
12
+ /src/protowire/ @trendvidia/maintainers
13
+
14
+ # --- Tests + cross-port harnesses (open to broader reviewer pool) -------
15
+ /tests/ @trendvidia/contributors @trendvidia/maintainers
16
+ /scripts/ @trendvidia/contributors @trendvidia/maintainers
17
+ /testdata/ @trendvidia/contributors @trendvidia/maintainers
18
+
19
+ # --- Build, packaging, CI -----------------------------------------------
20
+ /.github/ @trendvidia/maintainers
21
+ /CMakeLists.txt @trendvidia/maintainers
22
+ /pyproject.toml @trendvidia/maintainers
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a defect — wrong output, crash, parse error on valid input, etc.
4
+ title: "bug: "
5
+ labels: bug
6
+ ---
7
+
8
+ <!--
9
+ Cross-port issues (the same input behaves differently on multiple ports)
10
+ belong upstream at trendvidia/protowire, not here. See CONTRIBUTING.md.
11
+
12
+ Codec-level bugs that also reproduce in protowire-cpp directly belong
13
+ in trendvidia/protowire-cpp.
14
+
15
+ Security issues (decoder crash/hang/OOM on adversarial input, FFI
16
+ refcount errors, GIL violations) go to security@trendvidia.com
17
+ instead. See SECURITY.md.
18
+ -->
19
+
20
+ ## What happened
21
+
22
+ A clear description of the bug.
23
+
24
+ ## How to reproduce
25
+
26
+ Smallest possible PXF / PB / SBE / envelope input + Python snippet that
27
+ triggers it.
28
+
29
+ ```python
30
+ from protowire import pxf
31
+ # ...
32
+ ```
33
+
34
+ ## What you expected
35
+
36
+ What you thought should happen.
37
+
38
+ ## Versions
39
+
40
+ - `protowire` version (`pip show protowire`):
41
+ - Python version (`python --version`):
42
+ - OS / arch:
43
+ - Installed via wheel or source build (`pip install -v` last lines):
44
+ - If source build: protobuf + CMake + compiler versions
45
+
46
+ ## Reproduces in protowire-cpp directly?
47
+
48
+ If yes, please file at https://github.com/trendvidia/protowire-cpp/issues
49
+ instead — the codec lives there. (Skip if unknown.)
@@ -0,0 +1,28 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 TrendVidia, LLC.
3
+
4
+ blank_issues_enabled: false
5
+ contact_links:
6
+ - name: Security vulnerability
7
+ url: https://github.com/trendvidia/protowire-python/blob/main/SECURITY.md
8
+ about: >-
9
+ Decoder crashes, hangs, OOMs, FFI refcount errors, GIL violations
10
+ — email security@trendvidia.com per SECURITY.md, do not file a
11
+ public issue.
12
+ - name: Codec bug (also reproduces in C++)
13
+ url: https://github.com/trendvidia/protowire-cpp/issues/new?template=bug_report.md
14
+ about: >-
15
+ The wire codec is in protowire-cpp and reaches Python through
16
+ nanobind. Codec bugs that also reproduce in C++ directly belong
17
+ there.
18
+ - name: Cross-port wire-equivalence regression
19
+ url: https://github.com/trendvidia/protowire/issues/new?template=bug_report.md
20
+ about: >-
21
+ Same input produces different output on different ports. File
22
+ these upstream against trendvidia/protowire so all 9 port repos
23
+ can coordinate the fix.
24
+ - name: Spec / grammar / annotation discussion
25
+ url: https://github.com/trendvidia/protowire/discussions
26
+ about: >-
27
+ Wire format, PXF grammar, proto annotation design — the spec
28
+ project owns these decisions.
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: Feature request
3
+ about: Propose a Python-port-only API addition or ergonomics improvement
4
+ title: "feat: "
5
+ labels: enhancement
6
+ ---
7
+
8
+ <!--
9
+ Wire-format / spec / annotation proposals belong upstream at
10
+ trendvidia/protowire — they affect every port.
11
+
12
+ Codec-level changes belong in trendvidia/protowire-cpp — this port is a
13
+ nanobind wrapper.
14
+
15
+ This template is for PYTHON-PORT-ONLY changes: better Pythonic
16
+ ergonomics, new convenience overloads, packaging improvements, support
17
+ for a new Python version or platform.
18
+ -->
19
+
20
+ ## Problem
21
+
22
+ What's awkward to express today, or what's missing?
23
+
24
+ ## Proposal
25
+
26
+ What you'd like to add. If it's a new public API, sketch the signature
27
+ and the typical call-site. If it's a perf change, ideally include a
28
+ microbench number from `scripts/bench_pxf.py` or `scripts/bench_sbe.py`.
29
+
30
+ ## Alternatives considered
31
+
32
+ What else you tried, and why it isn't enough.
33
+
34
+ ## Out of scope (optional)
35
+
36
+ Things this proposal is **not** trying to do, to keep review focused.
@@ -0,0 +1,36 @@
1
+ <!--
2
+ For changes that touch wire-format behaviour: please open the upstream
3
+ PR in trendvidia/protowire and trendvidia/protowire-cpp FIRST. This port
4
+ implements the spec via the C++ codec; it shouldn't lead spec or codec
5
+ changes. See CONTRIBUTING.md.
6
+
7
+ For FFI-boundary changes (src/_protowire/module.cc, anything crossing
8
+ the nanobind shim): include a manual round-trip check against the
9
+ protowire-cpp reference fixtures.
10
+ -->
11
+
12
+ ## Summary
13
+
14
+ What this PR changes, in 1–3 sentences.
15
+
16
+ ## Why
17
+
18
+ Link to the issue or upstream spec/codec change that motivated this.
19
+
20
+ ## Scope
21
+
22
+ - [ ] FFI boundary (`src/_protowire/`)
23
+ - [ ] Public Python API (`src/protowire/`)
24
+ - [ ] Tests / fixtures / harnesses (`tests/`, `testdata/`, `scripts/`)
25
+ - [ ] Build / packaging / CI (`pyproject.toml`, `CMakeLists.txt`, `.github/`)
26
+ - [ ] Documentation only
27
+
28
+ ## Test plan
29
+
30
+ - [ ] Local build clean: `pip install -e '.[test]' && pytest`
31
+ - [ ] If FFI-boundary change: round-tripped at least one PXF + SBE fixture
32
+ against the sibling `protowire-cpp` checkout
33
+ - [ ] If wire-impacting: matching upstream PRs linked above
34
+ - [ ] If new public symbol: exported from `protowire/__init__.py` and
35
+ covered by a test under `tests/`
36
+ - [ ] If packaging change: cibuildwheel matrix smoke build still passes
@@ -0,0 +1,28 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 TrendVidia, LLC.
3
+
4
+ version: 2
5
+ updates:
6
+ - package-ecosystem: "github-actions"
7
+ directory: "/"
8
+ schedule:
9
+ interval: "weekly"
10
+ day: "monday"
11
+ commit-message:
12
+ prefix: "deps(actions)"
13
+ open-pull-requests-limit: 5
14
+ groups:
15
+ actions-minor-and-patch:
16
+ update-types: ["minor", "patch"]
17
+
18
+ - package-ecosystem: "pip"
19
+ directory: "/"
20
+ schedule:
21
+ interval: "weekly"
22
+ day: "monday"
23
+ commit-message:
24
+ prefix: "deps(pip)"
25
+ open-pull-requests-limit: 5
26
+ groups:
27
+ pip-minor-and-patch:
28
+ update-types: ["minor", "patch"]
@@ -0,0 +1,179 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 TrendVidia, LLC.
3
+
4
+ name: CI
5
+
6
+ on:
7
+ pull_request:
8
+ push:
9
+ branches: [main]
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ concurrency:
15
+ group: ${{ github.workflow }}-${{ github.ref }}
16
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
17
+
18
+ env:
19
+ # Pin the sibling C++ checkout to a specific commit. cpp@v0.70.0
20
+ # predates the __int128 → checked_arith refactor (MSVC), the
21
+ # protobuf-API-skew shim, and the MSVC source-charset fix; 9af2ec0
22
+ # is the first commit with all of those. Bump to a v0.70.x tag
23
+ # once cpp cuts one that includes them.
24
+ PROTOWIRE_CPP_REF: 9af2ec04918a417933848de1577cd61f83a710b0
25
+
26
+ jobs:
27
+ # ---------------------------------------------------------------------
28
+ # Build + pytest matrix across {Linux, macOS, Windows} ×
29
+ # CPython 3.10–3.13. The native extension is rebuilt on every job
30
+ # because the C++ codec is a build-time dependency, not a wheel.
31
+ # ---------------------------------------------------------------------
32
+ test:
33
+ name: ${{ matrix.os }} / py${{ matrix.python }}
34
+ runs-on: ${{ matrix.os }}
35
+ strategy:
36
+ fail-fast: false
37
+ matrix:
38
+ os: [ubuntu-latest, macos-latest, windows-latest]
39
+ python: ["3.10", "3.11", "3.12", "3.13"]
40
+ steps:
41
+ - uses: actions/checkout@v6
42
+
43
+ # Sibling protowire-cpp checkout. CMakeLists.txt looks here by
44
+ # default (../protowire-cpp). The ref is pinned via env var above
45
+ # so a codec change requires explicitly bumping both repos.
46
+ - name: Checkout protowire-cpp
47
+ uses: actions/checkout@v6
48
+ with:
49
+ repository: trendvidia/protowire-cpp
50
+ ref: ${{ env.PROTOWIRE_CPP_REF }}
51
+ path: protowire-cpp-checkout
52
+
53
+ - name: Set up Python ${{ matrix.python }}
54
+ uses: actions/setup-python@v6
55
+ with:
56
+ python-version: ${{ matrix.python }}
57
+
58
+ - name: Install protobuf (Linux)
59
+ if: runner.os == 'Linux'
60
+ run: |
61
+ sudo apt-get update
62
+ sudo apt-get install -y --no-install-recommends \
63
+ protobuf-compiler libprotobuf-dev libprotoc-dev
64
+
65
+ - name: Install protobuf (macOS)
66
+ if: runner.os == 'macOS'
67
+ run: brew install protobuf
68
+
69
+ - name: Install protobuf (Windows / vcpkg)
70
+ if: runner.os == 'Windows'
71
+ shell: pwsh
72
+ # Default dynamic triplet — wheel repair handles DLL bundling
73
+ # at publish time (see publish.yml). The pytest job below
74
+ # imports the in-place build, where the DLLs in vcpkg's bin
75
+ # are reachable via PATH set up by the toolchain file.
76
+ run: vcpkg install protobuf:x64-windows
77
+
78
+ - name: Install package + test deps (Linux / macOS)
79
+ if: runner.os != 'Windows'
80
+ env:
81
+ PROTOWIRE_CPP_DIR: ${{ github.workspace }}/protowire-cpp-checkout
82
+ run: |
83
+ python -m pip install --upgrade pip
84
+ pip install -e '.[test]' -v
85
+
86
+ - name: Install package + test deps (Windows)
87
+ if: runner.os == 'Windows'
88
+ shell: pwsh
89
+ env:
90
+ PROTOWIRE_CPP_DIR: ${{ github.workspace }}\protowire-cpp-checkout
91
+ run: |
92
+ python -m pip install --upgrade pip
93
+ pip install -e '.[test]' -v `
94
+ --config-settings=cmake.define.CMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" `
95
+ --config-settings=cmake.define.VCPKG_TARGET_TRIPLET=x64-windows
96
+
97
+ - name: pytest (Linux / macOS)
98
+ if: runner.os != 'Windows'
99
+ env:
100
+ PROTOWIRE_CPP_DIR: ${{ github.workspace }}/protowire-cpp-checkout
101
+ run: pytest -v
102
+
103
+ - name: pytest (Windows)
104
+ if: runner.os == 'Windows'
105
+ shell: pwsh
106
+ env:
107
+ PROTOWIRE_CPP_DIR: ${{ github.workspace }}\protowire-cpp-checkout
108
+ # editable installs don't bundle DLLs — _protowire.pyd resolves
109
+ # libprotobuf.dll / libabsl_*.dll out of vcpkg's bin dir at
110
+ # import time. Put it on PATH for the pytest run.
111
+ run: |
112
+ $env:PATH = "$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows\bin;$env:PATH"
113
+ pytest -v
114
+
115
+ # ---------------------------------------------------------------------
116
+ # cibuildwheel smoke build — exercises the wheel-publishing path on
117
+ # every PR so packaging regressions surface before release time.
118
+ # Builds one Python version per OS to keep CI fast; the full matrix
119
+ # runs in publish.yml on tag push.
120
+ # ---------------------------------------------------------------------
121
+ cibuildwheel-smoke:
122
+ name: cibuildwheel smoke / ${{ matrix.os }}
123
+ runs-on: ${{ matrix.os }}
124
+ strategy:
125
+ fail-fast: false
126
+ matrix:
127
+ os: [ubuntu-latest, macos-latest, windows-latest]
128
+ steps:
129
+ - uses: actions/checkout@v6
130
+
131
+ - name: Checkout protowire-cpp
132
+ uses: actions/checkout@v6
133
+ with:
134
+ repository: trendvidia/protowire-cpp
135
+ ref: ${{ env.PROTOWIRE_CPP_REF }}
136
+ path: protowire-cpp-checkout
137
+
138
+ - name: Build one wheel
139
+ uses: pypa/cibuildwheel@v3.4.1
140
+ env:
141
+ # Build only one CPython version per OS for the smoke job —
142
+ # the full matrix is reserved for the release workflow.
143
+ CIBW_BUILD: cp312-*
144
+ CIBW_SKIP: "*-musllinux_* *-manylinux_i686 pp*"
145
+ CIBW_ARCHS_LINUX: x86_64
146
+ CIBW_ARCHS_MACOS: arm64
147
+ CIBW_ARCHS_WINDOWS: AMD64
148
+ # Linux: source is mounted at /project inside the manylinux
149
+ # container; host paths don't resolve. Override there.
150
+ CIBW_ENVIRONMENT_LINUX: PROTOWIRE_CPP_DIR=/project/protowire-cpp-checkout
151
+ PROTOWIRE_CPP_DIR: ${{ github.workspace }}/protowire-cpp-checkout
152
+ # Linux uses manylinux containers — base image protobuf is
153
+ # too old (3.5 / 3.14) for our annotations, so build 25.3
154
+ # from source. See scripts/cibw_install_protobuf_linux.sh
155
+ # for the why.
156
+ CIBW_BEFORE_ALL_LINUX: bash {project}/scripts/cibw_install_protobuf_linux.sh
157
+ CIBW_BEFORE_ALL_MACOS: brew install protobuf
158
+ CIBW_BEFORE_ALL_WINDOWS: vcpkg install protobuf:x64-windows
159
+ # delvewheel is only auto-installed when cibuildwheel uses
160
+ # its default Windows repair command — once we override
161
+ # CIBW_REPAIR_WHEEL_COMMAND_WINDOWS we have to install it.
162
+ CIBW_BEFORE_BUILD_WINDOWS: pip install delvewheel
163
+ # macOS: Homebrew's bottled dylibs are built for the runner's
164
+ # OS (macos-latest = 15). Set the wheel's deployment target
165
+ # to match so delocate accepts them.
166
+ MACOSX_DEPLOYMENT_TARGET: "15.0"
167
+ CIBW_ENVIRONMENT_WINDOWS: >-
168
+ CMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake"
169
+ VCPKG_TARGET_TRIPLET=x64-windows
170
+ # Drop delocate's per-dylib INFO chatter from the macOS
171
+ # repair step (cibuildwheel default includes -v).
172
+ CIBW_REPAIR_WHEEL_COMMAND_MACOS: delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}
173
+ # cibuildwheel has no Windows wheel-repair by default —
174
+ # delvewheel bundles the DLL deps the wheel links against.
175
+ # See publish.yml for the full rationale.
176
+ CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >-
177
+ delvewheel repair
178
+ --add-path "%VCPKG_INSTALLATION_ROOT%\installed\x64-windows\bin"
179
+ -w {dest_dir} {wheel}
@@ -0,0 +1,73 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 TrendVidia, LLC.
3
+
4
+ name: CodeQL
5
+
6
+ on:
7
+ push:
8
+ branches: [main]
9
+ pull_request:
10
+ branches: [main]
11
+ schedule:
12
+ - cron: "37 6 * * 1"
13
+
14
+ permissions:
15
+ contents: read
16
+ security-events: write
17
+
18
+ env:
19
+ # See ci.yml for why this is a SHA, not v0.70.0.
20
+ PROTOWIRE_CPP_REF: 9af2ec04918a417933848de1577cd61f83a710b0
21
+
22
+ jobs:
23
+ analyze:
24
+ name: Analyze (${{ matrix.language }})
25
+ runs-on: ubuntu-latest
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ # python: pure-Python wrapper code. cpp: src/_protowire/module.cc
30
+ # (the FFI shim) plus the linked protowire-cpp sources.
31
+ language: [python, cpp]
32
+ steps:
33
+ - uses: actions/checkout@v6
34
+
35
+ - name: Checkout protowire-cpp
36
+ if: matrix.language == 'cpp'
37
+ uses: actions/checkout@v6
38
+ with:
39
+ repository: trendvidia/protowire-cpp
40
+ ref: ${{ env.PROTOWIRE_CPP_REF }}
41
+ path: protowire-cpp-checkout
42
+
43
+ - name: Install build deps (cpp)
44
+ if: matrix.language == 'cpp'
45
+ run: |
46
+ sudo apt-get update
47
+ sudo apt-get install -y --no-install-recommends \
48
+ gcc-13 g++-13 protobuf-compiler libprotobuf-dev libprotoc-dev
49
+
50
+ - name: Set up Python (cpp build needs nanobind in PATH)
51
+ if: matrix.language == 'cpp'
52
+ uses: actions/setup-python@v6
53
+ with:
54
+ python-version: "3.12"
55
+
56
+ - uses: github/codeql-action/init@v4
57
+ with:
58
+ languages: ${{ matrix.language }}
59
+ queries: security-and-quality
60
+
61
+ - name: Configure + build the FFI extension (drives cpp extraction)
62
+ if: matrix.language == 'cpp'
63
+ env:
64
+ CC: gcc-13
65
+ CXX: g++-13
66
+ PROTOWIRE_CPP_DIR: ${{ github.workspace }}/protowire-cpp-checkout
67
+ run: |
68
+ python -m pip install --upgrade pip
69
+ pip install -e . -v
70
+
71
+ - uses: github/codeql-action/analyze@v4
72
+ with:
73
+ category: "/language:${{ matrix.language }}"
@@ -0,0 +1,203 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 TrendVidia, LLC.
3
+ #
4
+ # Wheel + sdist publishing pipeline.
5
+ #
6
+ # Triggered manually or on a `v*` tag push. The trusted-publishing OIDC
7
+ # step requires the GitHub repo to be configured as a "trusted publisher"
8
+ # for the `protowire` PyPI project (see
9
+ # https://docs.pypi.org/trusted-publishers/). No long-lived API tokens
10
+ # are stored anywhere.
11
+
12
+ name: Publish to PyPI
13
+
14
+ on:
15
+ push:
16
+ tags: ["v*"]
17
+ workflow_dispatch:
18
+
19
+ permissions:
20
+ contents: read
21
+
22
+ env:
23
+ # Pin the sibling C++ checkout to a specific commit. This is a
24
+ # frozen FFI surface, so it must be an immutable ref — never a
25
+ # branch.
26
+ #
27
+ # Using a SHA (not the v0.70.0 tag) because cpp@v0.70.0 predates
28
+ # the f1d3eb0 __int128 → checked_arith refactor needed for MSVC,
29
+ # plus the protobuf-API-skew shim and MSVC source-charset fixes.
30
+ # 9af2ec0 (cpp main, ci: MSVC source-charset + skip pxf_escapes)
31
+ # is the first commit with all of those. Bump to v0.70.x once cpp
32
+ # cuts a tag that includes them.
33
+ PROTOWIRE_CPP_REF: 9af2ec04918a417933848de1577cd61f83a710b0
34
+
35
+ jobs:
36
+ # ---------------------------------------------------------------------
37
+ # Full wheel matrix: CPython 3.10–3.13 × {linux x86_64, linux aarch64,
38
+ # macos x86_64, macos arm64, windows x86_64}. cibuildwheel handles
39
+ # the manylinux/musllinux/macos universal2 toolchain plumbing.
40
+ # ---------------------------------------------------------------------
41
+ wheels:
42
+ name: ${{ matrix.os }} (${{ matrix.archs }})
43
+ runs-on: ${{ matrix.os }}
44
+ strategy:
45
+ fail-fast: false
46
+ matrix:
47
+ include:
48
+ - os: ubuntu-latest
49
+ archs: "x86_64"
50
+ - os: ubuntu-latest
51
+ archs: "aarch64"
52
+ # macOS Apple Silicon only. The macos-13 (Intel) runner pool
53
+ # is being deprecated by GitHub Actions — runner availability
54
+ # is sporadic with no SLA, and we waited 9+ hours for the
55
+ # x86_64 leg to even start during the v0.70.0 release. Intel
56
+ # macOS users fall back to a source build via the published
57
+ # sdist for now; we'll add the x86_64 wheel back via
58
+ # universal2 (or a self-hosted runner) in a follow-up.
59
+ # Deployment target must match the runner: Homebrew's bottled
60
+ # protobuf/abseil dylibs are built for the runner's macOS
61
+ # version (macos-latest = 15), and delocate refuses to bundle
62
+ # dylibs whose min target is newer than the wheel's.
63
+ - os: macos-latest
64
+ archs: "arm64"
65
+ macosx_deployment_target: "15.0"
66
+ - os: windows-latest
67
+ archs: "AMD64"
68
+ steps:
69
+ - uses: actions/checkout@v6
70
+
71
+ - name: Checkout protowire-cpp
72
+ uses: actions/checkout@v6
73
+ with:
74
+ repository: trendvidia/protowire-cpp
75
+ ref: ${{ env.PROTOWIRE_CPP_REF }}
76
+ path: protowire-cpp-checkout
77
+
78
+ # Linux aarch64 runs through QEMU emulation inside the manylinux
79
+ # container — register binfmt handlers first.
80
+ - name: Set up QEMU
81
+ if: matrix.os == 'ubuntu-latest' && matrix.archs == 'aarch64'
82
+ uses: docker/setup-qemu-action@v4
83
+ with:
84
+ platforms: arm64
85
+
86
+ - name: Build wheels
87
+ uses: pypa/cibuildwheel@v3.4.1
88
+ env:
89
+ CIBW_BUILD: "cp310-* cp311-* cp312-* cp313-*"
90
+ CIBW_SKIP: "*-musllinux_* *-manylinux_i686 pp*"
91
+ CIBW_ARCHS: ${{ matrix.archs }}
92
+ # Linux: cibuildwheel runs the build inside a manylinux
93
+ # container that mounts the project source at /project, so
94
+ # the host PROTOWIRE_CPP_DIR path doesn't resolve. Point at
95
+ # the in-container path instead.
96
+ CIBW_ENVIRONMENT_LINUX: PROTOWIRE_CPP_DIR=/project/protowire-cpp-checkout
97
+ # macOS + Windows: cibuildwheel runs natively, so the host
98
+ # path passed via the action-level env block works directly.
99
+ PROTOWIRE_CPP_DIR: ${{ github.workspace }}/protowire-cpp-checkout
100
+ # The manylinux base image's protobuf-devel rpm is too old
101
+ # (3.5 / 3.14) and generates broken C++ for fields named
102
+ # `default`. Build 25.3 from source instead.
103
+ CIBW_BEFORE_ALL_LINUX: bash {project}/scripts/cibw_install_protobuf_linux.sh
104
+ CIBW_BEFORE_ALL_MACOS: brew install protobuf
105
+ # Use the default dynamic triplet — vcpkg integrates with
106
+ # CMake's find_package via the toolchain file, and delvewheel
107
+ # bundles the resulting libprotobuf.dll / libabsl_*.dll into
108
+ # the wheel (see CIBW_REPAIR_WHEEL_COMMAND_WINDOWS below).
109
+ # The static-md triplet would also work but scikit-build-core
110
+ # didn't reliably pick up the toolchain switch through
111
+ # CIBW_ENVIRONMENT_WINDOWS in earlier attempts.
112
+ CIBW_BEFORE_ALL_WINDOWS: vcpkg install protobuf:x64-windows
113
+ # delvewheel is only auto-installed when cibuildwheel uses its
114
+ # default Windows repair command; once we override
115
+ # CIBW_REPAIR_WHEEL_COMMAND_WINDOWS we have to install it
116
+ # ourselves.
117
+ CIBW_BEFORE_BUILD_WINDOWS: pip install delvewheel
118
+ # See matrix comment: align wheel target with runner OS so
119
+ # delocate accepts brew's dylibs.
120
+ MACOSX_DEPLOYMENT_TARGET: ${{ matrix.macosx_deployment_target }}
121
+ CIBW_ENVIRONMENT_WINDOWS: >-
122
+ CMAKE_TOOLCHAIN_FILE="$VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake"
123
+ VCPKG_TARGET_TRIPLET=x64-windows
124
+ # Override cibuildwheel's default macOS repair command to
125
+ # drop the -v flag — the per-dylib INFO chatter from delocate
126
+ # is noise.
127
+ CIBW_REPAIR_WHEEL_COMMAND_MACOS: delocate-wheel --require-archs {delocate_archs} -w {dest_dir} {wheel}
128
+ # cibuildwheel ships with no Windows wheel-repair by default,
129
+ # so libprotobuf.dll and libabsl_*.dll never get bundled into
130
+ # the wheel — `import protowire` fails with "DLL load failed"
131
+ # at user install time. Use delvewheel and point it at
132
+ # vcpkg's bin dir so it can find the runtime DLLs to bundle.
133
+ # The repair command runs in cmd.exe on Windows, so use
134
+ # %VAR% syntax (not bash $VAR) for env-var expansion.
135
+ CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: >-
136
+ delvewheel repair
137
+ --add-path "%VCPKG_INSTALLATION_ROOT%\installed\x64-windows\bin"
138
+ -w {dest_dir} {wheel}
139
+ # Smoke-import the wheel after build to catch link errors and
140
+ # missing symbols before they hit users.
141
+ CIBW_TEST_COMMAND: python -c "import protowire; from protowire import pxf, sbe, envelope"
142
+
143
+ - uses: actions/upload-artifact@v7
144
+ with:
145
+ name: wheels-${{ matrix.os }}-${{ matrix.archs }}
146
+ path: ./wheelhouse/*.whl
147
+
148
+ # ---------------------------------------------------------------------
149
+ # Source distribution. Built once on Linux; PyPI requires the sdist
150
+ # alongside the wheels for from-source installs on platforms we don't
151
+ # cover.
152
+ # ---------------------------------------------------------------------
153
+ sdist:
154
+ name: sdist
155
+ runs-on: ubuntu-latest
156
+ steps:
157
+ - uses: actions/checkout@v6
158
+
159
+ - name: Set up Python
160
+ uses: actions/setup-python@v6
161
+ with:
162
+ python-version: "3.12"
163
+
164
+ - name: Build sdist
165
+ run: |
166
+ python -m pip install --upgrade pip
167
+ pip install build
168
+ python -m build --sdist
169
+
170
+ - uses: actions/upload-artifact@v7
171
+ with:
172
+ name: sdist
173
+ path: dist/*.tar.gz
174
+
175
+ # ---------------------------------------------------------------------
176
+ # Aggregate all artifacts and publish to PyPI via OIDC trusted
177
+ # publishing. The `pypi` environment is configured in repo settings
178
+ # to require approval before publishing — a final human gate.
179
+ # ---------------------------------------------------------------------
180
+ publish:
181
+ name: Publish to PyPI
182
+ needs: [wheels, sdist]
183
+ runs-on: ubuntu-latest
184
+ environment:
185
+ name: pypi
186
+ url: https://pypi.org/p/protowire-python
187
+ permissions:
188
+ id-token: write # required for OIDC trusted publishing
189
+ attestations: write # required for Sigstore provenance attestations
190
+ contents: read
191
+ steps:
192
+ - name: Download all wheels + sdist
193
+ uses: actions/download-artifact@v8
194
+ with:
195
+ path: dist
196
+ merge-multiple: true
197
+
198
+ - name: Publish to PyPI
199
+ uses: pypa/gh-action-pypi-publish@release/v1
200
+ with:
201
+ packages-dir: dist
202
+ attestations: true
203
+ print-hash: true