Skip to content

Commit 2f3dc07

Browse files
committed
ci: define bindings package roots and release statuses
Narrative review layer 2 of 6. Replace branch-oriented CUDA build fields with package-root-keyed release statuses and toolkit pins. Add the shared bindings configuration and tag-resolution helpers, their focused tests, CI-tools packaging, and consistency checks for package metadata. The release resolver is defined here; layer 5 connects its workflow consumers. Review focus: ci/versions.yml, ci/tools/bindings_config.py, metadata consistency, and their tests. The two supported public roots are maintenance CUDA 12.9 and current CUDA 13.4.
1 parent 2756860 commit 2f3dc07

11 files changed

Lines changed: 1184 additions & 71 deletions

‎.pre-commit-config.yaml‎

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ repos:
2828
hooks:
2929
- id: ruff-check
3030
args: [--fix, --show-fixes]
31-
exclude: (^cuda_bindings/cuda/bindings/_internal/_fast_enum\.py$)|(.*\.pyi$)
31+
exclude: (^cuda_bindings(?:_[^/]+)?/cuda/bindings/_internal/_fast_enum\.py$)|(.*\.pyi$)
3232
- id: ruff-format
3333
exclude: .*\.pyi$
3434

@@ -55,15 +55,23 @@ repos:
5555
name: Check generated-file seals
5656
entry: python ./toolshed/check_generated_file_seals.py
5757
language: python
58-
files: ^cuda_bindings/
58+
files: ^cuda_bindings(?:_[^/]+)?/
5959
types: [text]
6060

61+
- id: check-bindings-config
62+
name: Validate bindings package-root registry
63+
entry: python -m ci.tools.bindings_config
64+
language: python
65+
additional_dependencies: [packaging==26.0, pyyaml==6.0.3]
66+
files: '^(ci/versions\.yml|cuda_bindings(?:_[^/]+)?/pyproject\.toml)$'
67+
pass_filenames: false
68+
6169
- id: check-pixi-cuda-version
6270
name: Check pixi cuda-version pins track ci/versions.yml
63-
entry: python ./ci/tools/check_pixi_cuda_version.py
71+
entry: python -m ci.tools.check_pixi_cuda_version
6472
language: python
65-
additional_dependencies: [pyyaml==6.0.3]
66-
files: '^(ci/versions\.yml|cuda_bindings/pixi\.toml|cuda_core/pixi\.toml)$'
73+
additional_dependencies: [packaging==26.0, pyyaml==6.0.3]
74+
files: '^(ci/versions\.yml|cuda_bindings(?:_[^/]+)?/pixi\.toml|cuda_core/pixi\.toml)$'
6775
pass_filenames: false
6876

6977
- id: check-mempool-hygiene
@@ -80,6 +88,9 @@ repos:
8088
- "_" # fake script name, because bash considers $0 (the first argument) to be the script name
8189
language: system
8290
files: '^.*/docs/source/.*\.md$'
91+
# The imported CUDA 12.9 documentation retains its historical MyST
92+
# sources; new documentation elsewhere must continue to use reST.
93+
exclude: '^cuda_bindings_12/docs/source/'
8394

8495
- id: stubgen-pyx-cuda-core
8596
name: Generate .pyi stubs for cuda_core
@@ -110,7 +121,7 @@ repos:
110121
rev: "3e8a8703264a2f4a69428a0aa4dcb512790b2c8c" # frozen: v6.0.0
111122
hooks:
112123
- id: check-added-large-files
113-
exclude: cuda_bindings/cuda/bindings/nvml.pyx
124+
exclude: '^(?:cuda_bindings(?:_[^/]+)?/(?:cuda/bindings/(?:driver\.pyx|runtime\.pyx\.in|nvml\.pyx)|pixi\.lock))$'
114125
- id: check-case-conflict
115126
- id: check-docstring-first
116127
- id: check-merge-conflict
@@ -119,14 +130,14 @@ repos:
119130
- id: check-yaml
120131
- id: debug-statements
121132
- id: end-of-file-fixer
122-
exclude: &gen_exclude '^(?:cuda_python/README\.md|(?:.*/)?CLAUDE\.md|(?:.*/)?\.git_archival\.txt|cuda_bindings/cuda/bindings/.*\.in?|cuda_bindings/docs/source/module/.*\.rst?|.*\.pyi)$'
133+
exclude: &gen_exclude '^(?:cuda_python/README\.md|(?:.*/)?CLAUDE\.md|(?:.*/)?\.git_archival\.txt|cuda_bindings(?:_[^/]+)?/cuda/bindings/.*\.in?|cuda_bindings(?:_[^/]+)?/docs/source/module/.*\.rst?|.*\.pyi)$'
123134
- id: mixed-line-ending
124135
- id: trailing-whitespace
125136
exclude: |
126137
(?x)^(?:
127138
cuda_python/README\.md|
128-
cuda_bindings/cuda/bindings/.*\.in?|
129-
cuda_bindings/docs/source/module/.*\.rst?|
139+
cuda_bindings(?:_[^/]+)?/cuda/bindings/.*\.in?|
140+
cuda_bindings(?:_[^/]+)?/docs/source/module/.*\.rst?|
130141
.*\.patch$
131142
)$
132143
@@ -168,7 +179,7 @@ repos:
168179
hooks:
169180
- id: cython-lint
170181
args: [--no-pycodestyle]
171-
exclude: ^cuda_bindings/
182+
exclude: ^cuda_bindings(?:_[^/]+)?/
172183
additional_dependencies:
173184
- Cython==3.2.9
174185

‎ci/README.md‎

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,88 @@ The canonical `NVIDIA/cuda-python` repository does not need this variable
2222
because its standard workflow behavior is enabled directly. Before enabling a
2323
customization elsewhere, document the repository-specific prerequisites and
2424
verification procedure in that repository's own documentation.
25+
26+
## CUDA Bindings Package-Root Registry
27+
28+
`ci/versions.yml` is the authoritative public registry for CUDA bindings
29+
package roots. Each mapping key is a repository-relative package root; its
30+
record declares an exact toolkit build/test pin and a `release_status` of
31+
`current` or `maintenance`. Release routing uses the tag's CUDA major/minor
32+
and the toolkit pin to select a root. Bindings and metapackage builds use
33+
setuptools-scm's default tag parser. Each root's `git_describe_command`
34+
selects its tag series for source builds; update its `--match` pattern when
35+
the root moves to a new toolkit minor.
36+
37+
The Python helpers share registry parsing and validation, so they are modules
38+
in the repository-private `cuda-python-ci-tools` distribution rather than
39+
standalone scripts with repeated PEP 723 dependency metadata. Install the
40+
package in editable mode from the repository root:
41+
42+
```console
43+
python -m pip install -e ./ci
44+
```
45+
46+
Use `ci.tools.bindings_config` instead of reading the YAML directly. It
47+
validates the registry and emits normalized JSON with the configured values
48+
plus the derived CTK target and CUDA ABI major/variant:
49+
50+
```console
51+
python -m ci.tools.bindings_config
52+
python -m ci.tools.bindings_config --package-roots
53+
python -m ci.tools.bindings_config --release-status current
54+
```
55+
56+
Install the test extra to run the CI-tool tests:
57+
58+
```console
59+
python -m pip install -e './ci[test]'
60+
python -m pytest --noconftest ci/tools/tests
61+
```
62+
63+
The public wheel builder requires one `current` package root and one
64+
`maintenance` package root with different CUDA ABI majors.
65+
66+
## Maintaining Both Bindings Roots
67+
68+
`main` is the source of truth for both bindings release lines. The old
69+
`12.9.x` branch remains available as a record of earlier releases; develop
70+
new CUDA 12 fixes and releases in `cuda_bindings_12/` on `main`. The
71+
[CUDA 12 maintenance guide](../cuda_bindings_12/MAINTENANCE.md) identifies the
72+
maintenance root.
73+
74+
For generated bindings, change cybind first and regenerate each affected
75+
package root against its intended toolkit inputs. Review the generated diff,
76+
record the cybind revision, toolkit inputs, and command in the pull request,
77+
and check modified files with
78+
`python toolshed/check_generated_file_seals.py <paths...>`. The seal verifies
79+
the content of an individual generated file; it does not identify the cybind
80+
revision or prove that the two roots should have identical output. Generated
81+
output may legitimately differ across toolkit targets.
82+
83+
For a handwritten bindings fix, inspect the corresponding code in the other
84+
root. In the pull request, identify the matching change or explain concretely
85+
why the fix does not apply there. A reviewer must verify that judgment: there
86+
is no general deterministic check for semantic equivalence of handwritten
87+
code across the two roots. Where files are intentionally identical, a narrowly
88+
scoped byte-for-byte check can be added after establishing that invariant.
89+
90+
## Changing Supported Release Lines
91+
92+
When support moves from CUDA 12/13 to CUDA 13/14, keep the CUDA 13 source in
93+
its own package root while introducing a distinct CUDA 14 root. Decide the
94+
root names as part of that change; do not replace the current root's source
95+
until the CUDA 13 maintenance source has a home. Then:
96+
97+
1. Update `ci/versions.yml`: remove the retired CUDA 12 root, mark the CUDA
98+
13 root `maintenance`, mark the CUDA 14 root `current`, and set each exact
99+
toolkit build/test version.
100+
2. Align each root's `pyproject.toml` `git_describe_command --match` selector
101+
and version fallback with its release family. Update other per-root packaging,
102+
pixi environments, documentation, and dependent package constraints for the
103+
supported lines.
104+
3. Build and test both roots and their dependent packages on the supported
105+
platforms. Validate release selection and run publication-incapable dry
106+
runs for tags from each line before releasing from the new layout.
107+
108+
The same branch policy applies after the rollover: `main` owns the current
109+
and maintenance roots; retired release branches are retained for history.

‎ci/__init__.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
"""CUDA Python continuous-integration support."""

‎ci/pyproject.toml‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
[build-system]
5+
requires = ["setuptools>=77.0.0"]
6+
build-backend = "setuptools.build_meta"
7+
8+
[project]
9+
name = "cuda-python-ci-tools"
10+
version = "0.0.0"
11+
description = "Private CI support for the CUDA Python repository"
12+
authors = [{ name = "NVIDIA Corporation" }]
13+
license = "Apache-2.0"
14+
requires-python = ">=3.11"
15+
dependencies = [
16+
"packaging==26.0",
17+
"PyYAML==6.0.3",
18+
]
19+
20+
[project.optional-dependencies]
21+
test = ["pytest==9.1.0", "setuptools-scm>=8,!=10.1"]
22+
23+
[tool.setuptools]
24+
packages = ["ci", "ci.tools"]
25+
package-dir = { ci = "." }

‎ci/tools/__init__.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
"""Shared CI tools used by workflows and local validation."""

0 commit comments

Comments
 (0)