Skip to content

Commit 1fce6af

Browse files
committed
ci: release CUDA 12 bindings from main
Signed-off-by: Ralf W. Grosse-Kunstleve <rgrossekunst@nvidia.com>
1 parent b252422 commit 1fce6af

29 files changed

Lines changed: 3075 additions & 1252 deletions

‎.github/ISSUE_TEMPLATE/release_checklist.yml‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,26 @@ body:
1010
- type: markdown
1111
attributes:
1212
value: |
13-
This checklist is for cuda-core releases as well as cuda-bindings patches. Please go through this checklist and ensure all tasks are completed. See [RELEASE-core.md](../RELEASE-core.md) for detailed guidance on each step (cuda.core).
13+
This checklist is for cuda-core releases as well as cuda-bindings patches. See [RELEASE-core.md](../RELEASE-core.md) for cuda.core and [RELEASE-bindings.md](../RELEASE-bindings.md) for bindings release scope, stabilization branches, and validation.
1414
1515
- type: checkboxes
1616
id: subpackage-tasks
1717
attributes:
1818
label: Tasks for cuda-core and cuda-bindings patch release
1919
options:
2020
- label: File an internal nvbug to communicate test plan & release schedule with QA
21-
- label: Ensure all pending PRs are reviewed, tested, and merged
21+
- label: Record the release scope and ensure all PRs selected for this release are reviewed, tested, and merged
2222
- label: Check (or update if needed) the dependency requirements
2323
- label: Sweep deprecations whose stated removal version has arrived (`grep -rn 'deprecated::' cuda_core/cuda`) and remove any that are due
2424
- label: "Finalize the doc update, including release notes (\"Note: Touching docstrings/type annotations in code is OK during code freeze, apply your best judgement!\")"
2525
- label: Update the docs for the new version
26-
- label: Create a public release tag
27-
- label: Wait for the tag-triggered CI run to complete, and use that run ID for release workflows (this will upload the release to PyPI)
26+
- label: Record the exact source commit, workflow control revision, and selected package root before creating the approved public release tag
27+
- label: Wait for the exact tag-triggered CI run to pass and complete a release dry run before approving publication
2828
- label: Publish the release at https://github.com/NVIDIA/cuda-python/releases (this will trigger the conda package update)
2929
- label: Approve the conda-package update PR
3030
- label: Post-release QA
3131
- label: Finalize the announcement update
3232
- label: Send out the announcement internally (on `#swcuda-python`)
3333
- label: Send out the announcement externally (GitHub Release -> Announcement)
34-
- label: For a `cuda-bindings` release, make sure MAJOR and MAJOR-1 releases are made, as well as releases of `cuda-python` for MAJOR and MAJOR-1
34+
- label: For a `cuda-bindings` release, confirm which supported release lines are in scope using `ci/versions.yml`, and release the matching `cuda-python` package for each planned line
35+
- label: For a bindings stabilization or emergency branch, link the PRs returning applicable fixes to `main` and record their applicability to both bindings roots

‎.github/RELEASE-bindings.md‎

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<!--
2+
SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
SPDX-License-Identifier: Apache-2.0
4+
-->
5+
6+
# Releasing CUDA bindings
7+
8+
## Choose the release scope and source
9+
10+
Develop the current and maintenance CUDA major lines together on `main`, in
11+
the two package roots listed in [`ci/versions.yml`](../ci/versions.yml).
12+
Release each line independently. A bindings release also needs its matching
13+
`cuda-python` metapackage release; it does not require a release of the other
14+
CUDA major, `cuda-core`, or `cuda-pathfinder`.
15+
16+
Major-line maintenance may include selected API, Python, platform, or other
17+
compatibility changes. Decide those changes explicitly and describe them in
18+
the release notes. Once a patch release is frozen, admit only its approved
19+
fixes and release prerequisites. Do not infer patch-release scope solely
20+
from the registry's `maintenance` role.
21+
22+
For an ordinary release, select a tested commit on `main`. If stabilization
23+
must continue while development advances, create a short release branch such
24+
as `release/bindings-12.9.11` from the chosen commit. For an emergency after a
25+
release, start from its exact tag, provided that tag contains the new package
26+
layout. For the first release after this transition, use a validated commit
27+
containing both roots. Keep routine development on `main`; the historical
28+
`12.9.x` branch stays frozen except for emergency fixes using compatible
29+
historical tooling. Reconcile those fixes into the main-tree maintenance
30+
root. Keep the package layout and release tooling together on new release branches.
31+
32+
Record the source commit, intended tag, selected package root, release owner,
33+
and accepted changes in the release checklist. A branch is a temporary scope
34+
boundary, not a separate long-term home for shared infrastructure.
35+
36+
## Move fixes between integration and release branches
37+
38+
Prefer a reviewed fix on `main`, then backport it to the selected release
39+
branch in a separate PR. Inspect the diff, request CI using the normal PR
40+
approval procedure, and review it before merging. Conflicts and toolkit-specific
41+
generated changes require an explicitly reviewed adaptation.
42+
43+
If urgency requires a fix on the release branch first, link a follow-up PR
44+
reconciling the fix back into `main` before closing the release checklist. In either
45+
direction, assess both bindings roots and record why a change applies to one
46+
or both. Regenerate affected generated files from the intended toolkit and
47+
cybind inputs instead of blindly copying generated output between majors.
48+
49+
## Validate and publish the selected line
50+
51+
1. Finalize the bindings and metapackage release notes, dependency constraints,
52+
and selected toolkit pin in the release source tree. The registry and
53+
packaging metadata must agree. Run the CI-tool suite and pre-commit checks.
54+
2. Test the candidate through a reviewed PR or manual CI dispatch on its
55+
branch. Normal development CI includes dependent packages and may cover
56+
both majors. Resolve failures in affected code before selecting the tag.
57+
3. Create the approved immutable `vX.Y.Z` tag at the selected source commit.
58+
Tag-triggered CI builds both bindings lines and their consumers. The release
59+
workflow selects only the requested line's bindings or metapackage artifacts.
60+
The tag does not have to be on `main`. Wait for this exact tag's CI to pass.
61+
4. Run **CI: Release** with `release-action=dry-run`, the tag, and
62+
`component=cuda-bindings`; repeat for `cuda-python`. Leave `run-id` blank
63+
to exercise automatic lookup, and leave `dry-run-docs-branch` blank to avoid
64+
deploying docs. The workflow verifies a successful tag-triggered CI run
65+
with the exact source SHA, validates artifacts, and builds docs.
66+
5. Review the dry runs, then separately approve and run `full-release` for
67+
each component under the team's release procedure. A successful candidate
68+
rehearsal or ordinary branch CI is not a substitute for exact-tag CI.
69+
6. After both component releases succeed, review and publish the shared
70+
`vX.Y.Z` GitHub Release draft. Check its release notes, versioned
71+
documentation links, source archive, checksum, and wheels. These component
72+
workflows leave the draft for the release owner to publish.
73+
7. Finish post-release QA and announcements, return every applicable fix to
74+
`main`, and close the stabilization effort. Retain immutable tags and the
75+
branch history needed for diagnosis.
76+
77+
For either bindings line, add the released version to
78+
[`cuda_bindings_13/docs/nv-versions.json`](../cuda_bindings_13/docs/nv-versions.json)
79+
and its matching metapackage version to
80+
[`cuda_python/docs/nv-versions.json`](../cuda_python/docs/nv-versions.json)
81+
on `main`. Documentation deployments from `main` own these shared version
82+
selectors. Release deployments publish versioned pages without replacing the
83+
selectors or shared `latest` pages; updating a selector only on a stabilization
84+
branch will not update the public selector.
85+
86+
The workflow revision used for a release is its **control revision**; the
87+
tagged commit is its **source revision**. Record both and the artifact CI run
88+
ID. Release routing uses the package layout and toolkit settings in
89+
`ci/versions.yml` at the release tag. Retained CUDA 13 tags also support the
90+
older `cuda.build.version` configuration, the `cuda_bindings` source directory,
91+
and their original build matrix and metapackage artifact name. New CUDA 12
92+
releases require the local `cuda_bindings_12` root and toolkit-qualified
93+
artifacts. The workflow control revision never supplies missing tagged toolkit
94+
settings or replaces tagged release notes. Older CUDA 12 branch releases use
95+
their compatible historical tooling.
96+
97+
In **CI: Release**, normal bindings and metapackage releases each require
98+
their own exact-version, nonempty release notes in the tagged source. Notes
99+
from the workflow control revision or a different component cannot fill a gap.
100+
Preserve their existing exemption for `.postN` releases, which do not require
101+
new notes.
102+
103+
Local synthetic tags used in publication-incapable rehearsals must remain local;
104+
they do not authorize publishing a package, creating a remote tag, or moving
105+
an existing tag.

‎.github/RELEASE-core.md‎

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33

44
# cuda.core Release Process
55

6-
This document covers the `cuda.core` release process. For other packages:
7-
`cuda-bindings` and `cuda-python` involve a private repository and are not
8-
documented here; `cuda-pathfinder` is largely automated by the
9-
[CI: Release](workflows/release.yml)
10-
workflow.
6+
This document covers the `cuda.core` release process. See the
7+
[bindings release guide](RELEASE-bindings.md) for `cuda-bindings` and
8+
`cuda-python`. The `cuda-pathfinder` release process is largely automated by
9+
the [CI: Release](workflows/release.yml) workflow.
1110

1211
To release `cuda-pathfinder`, dispatch **CI: Release** with
1312
`component` set to `cuda-pathfinder`, `release-action` set
@@ -20,12 +19,13 @@ version, then publishes to PyPI and verifies again before publishing the
2019
GitHub Release without marking it as latest. A failed
2120
docs build prevents asset uploads, package publication, and finalization.
2221

23-
The release-note checker runs from `git-tag`, not the workflow revision.
24-
For Pathfinder, that tag must contain a version
25-
of `ci/tools/check_release_notes.py` that writes `version=<VERSION>` to
26-
`GITHUB_OUTPUT`. The release-notes job rejects an empty version before
27-
documentation, asset uploads, or package publication can start. Pathfinder
28-
package publication also requires successful draft metadata preparation.
22+
The workflow revision supplies the release tools; release notes and the
23+
package registry (`ci/versions.yml`) come from `git-tag`. Current tooling
24+
uses the toolkit configuration in the tagged source, including retained CUDA 13
25+
sources that predate the package-root registry. The release-notes job exports
26+
the checked version and rejects an empty version before documentation, asset
27+
uploads, or package publication can start. Pathfinder package publication also
28+
requires successful draft metadata preparation. Existing tags stay immutable.
2929

3030
The default `dry-run` action validates preparation, builds docs, and
3131
collects release artifacts without creating a GitHub Release or publishing
@@ -174,21 +174,29 @@ Pushing the tag triggers a CI run automatically. Monitor it in the
174174

175175
## Upload wheels to PyPI
176176

177-
This is a single `CI: Release` workflow run with two sequential stages:
178-
publish to TestPyPI, then publish the same wheel set to PyPI.
177+
First validate the release with a dry run. After reviewing that result, a
178+
`full-release` run publishes to TestPyPI, then publishes the same wheel set to
179+
PyPI.
179180

180181
1. Go to **Actions > CI: Release** and run the workflow with:
181182
- **Component**: `cuda-core`
182183
- **The release git tag**: `cuda-core-v0.6.0`
184+
- **What to run**: `dry-run`
183185

184-
The workflow automatically looks up the successful tag-triggered CI run
185-
for the selected release tag.
186+
Leave `run-id` blank to exercise automatic lookup of the successful
187+
tag-triggered CI run. Leave `dry-run-docs-branch` blank to validate the docs
188+
without deploying them.
186189

187-
2. Wait for the workflow to complete. It will:
188-
- publish the selected wheels to TestPyPI
189-
- publish the same wheel set to PyPI
190+
2. Review the completed dry run, then approve publication under the team's
191+
release procedure and run the workflow for the same component and tag with
192+
**What to run** set to `full-release`.
190193

191-
3. After completion, verify the final PyPI upload:
194+
3. Wait for that run to complete. It deploys versioned documentation and uploads
195+
the source archive, checksum, and wheels to the GitHub Release draft. It
196+
publishes the selected wheel set to TestPyPI followed by PyPI. The release
197+
owner publishes the GitHub Release draft in the announcement step.
198+
199+
4. After completion, verify the final PyPI upload:
192200

193201
```bash
194202
pip install cuda-core==0.6.0

0 commit comments

Comments
 (0)