Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .github/ISSUE_TEMPLATE/release_checklist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,26 @@ body:
- type: markdown
attributes:
value: |
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).
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.
- type: checkboxes
id: subpackage-tasks
attributes:
label: Tasks for cuda-core and cuda-bindings patch release
options:
- label: File an internal nvbug to communicate test plan & release schedule with QA
- label: Ensure all pending PRs are reviewed, tested, and merged
- label: Record the release scope and ensure all PRs selected for this release are reviewed, tested, and merged
- label: Check (or update if needed) the dependency requirements
- label: Sweep deprecations whose stated removal version has arrived (`grep -rn 'deprecated::' cuda_core/cuda`) and remove any that are due
- label: "Finalize the doc update, including release notes (\"Note: Touching docstrings/type annotations in code is OK during code freeze, apply your best judgement!\")"
- label: Update the docs for the new version
- label: Create a public release tag
- 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)
- label: Record the exact source commit, workflow control revision, and selected package root before creating the approved public release tag
- label: Wait for the exact tag-triggered CI run to pass and complete a release dry run before approving publication
- label: Publish the release at https://github.com/NVIDIA/cuda-python/releases (this will trigger the conda package update)
- label: Approve the conda-package update PR
- label: Post-release QA
- label: Finalize the announcement update
- label: Send out the announcement internally (on `#swcuda-python`)
- label: Send out the announcement externally (GitHub Release -> Announcement)
- 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
- 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
- label: For a bindings stabilization or emergency branch, link the PRs returning applicable fixes to `main` and record their applicability to both bindings roots
105 changes: 105 additions & 0 deletions .github/RELEASE-bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!--
SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->

# Releasing CUDA bindings

## Choose the release scope and source

Develop the current and maintenance CUDA major lines together on `main`, in
the two package roots listed in [`ci/versions.yml`](../ci/versions.yml).
Release each line independently. A bindings release also needs its matching
`cuda-python` metapackage release; it does not require a release of the other
CUDA major, `cuda-core`, or `cuda-pathfinder`.

Major-line maintenance may include selected API, Python, platform, or other
compatibility changes. Decide those changes explicitly and describe them in
the release notes. Once a patch release is frozen, admit only its approved
fixes and release prerequisites. Do not infer patch-release scope solely
from the registry's `maintenance` role.

For an ordinary release, select a tested commit on `main`. If stabilization
must continue while development advances, create a short release branch such
as `release/bindings-12.9.11` from the chosen commit. For an emergency after a
release, start from its exact tag, provided that tag contains the new package
layout. For the first release after this transition, use a validated commit
containing both roots. Keep routine development on `main`; the historical
`12.9.x` branch stays frozen except for emergency fixes using compatible
historical tooling. Reconcile those fixes into the main-tree maintenance
root. Keep the package layout and release tooling together on new release branches.

Record the source commit, intended tag, selected package root, release owner,
and accepted changes in the release checklist. A branch is a temporary scope
boundary, not a separate long-term home for shared infrastructure.

## Move fixes between integration and release branches

Prefer a reviewed fix on `main`, then backport it to the selected release
branch in a separate PR. Inspect the diff, request CI using the normal PR
approval procedure, and review it before merging. Conflicts and toolkit-specific
generated changes require an explicitly reviewed adaptation.

If urgency requires a fix on the release branch first, link a follow-up PR
reconciling the fix back into `main` before closing the release checklist. In either
direction, assess both bindings roots and record why a change applies to one
or both. Regenerate affected generated files from the intended toolkit and
cybind inputs instead of blindly copying generated output between majors.

## Validate and publish the selected line

1. Finalize the bindings and metapackage release notes, dependency constraints,
and selected toolkit pin in the release source tree. The registry and
packaging metadata must agree. Run the CI-tool suite and pre-commit checks.
2. Test the candidate through a reviewed PR or manual CI dispatch on its
branch. Normal development CI includes dependent packages and may cover
both majors. Resolve failures in affected code before selecting the tag.
3. Create the approved immutable `vX.Y.Z` tag at the selected source commit.
Tag-triggered CI builds both bindings lines and their consumers. The release
workflow selects only the requested line's bindings or metapackage artifacts.
The tag does not have to be on `main`. Wait for this exact tag's CI to pass.
4. Run **CI: Release** with `release-action=dry-run`, the tag, and
`component=cuda-bindings`; repeat for `cuda-python`. Leave `run-id` blank
to exercise automatic lookup, and leave `dry-run-docs-branch` blank to avoid
deploying docs. The workflow verifies a successful tag-triggered CI run
with the exact source SHA, validates artifacts, and builds docs.
5. Review the dry runs, then separately approve and run `full-release` for
each component under the team's release procedure. A successful candidate
rehearsal or ordinary branch CI is not a substitute for exact-tag CI.
6. After both component releases succeed, review and publish the shared
`vX.Y.Z` GitHub Release draft. Check its release notes, versioned
documentation links, source archive, checksum, and wheels. These component
workflows leave the draft for the release owner to publish.
7. Finish post-release QA and announcements, return every applicable fix to
`main`, and close the stabilization effort. Retain immutable tags and the
branch history needed for diagnosis.

For either bindings line, add the released version to
[`cuda_bindings_13/docs/nv-versions.json`](../cuda_bindings_13/docs/nv-versions.json)
and its matching metapackage version to
[`cuda_python/docs/nv-versions.json`](../cuda_python/docs/nv-versions.json)
on `main`. Documentation deployments from `main` own these shared version
selectors. Release deployments publish versioned pages without replacing the
selectors or shared `latest` pages; updating a selector only on a stabilization
branch will not update the public selector.

The workflow revision used for a release is its **control revision**; the
tagged commit is its **source revision**. Record both and the artifact CI run
ID. Release routing uses the package layout and toolkit settings in
`ci/versions.yml` at the release tag. Retained CUDA 13 tags also support the
older `cuda.build.version` configuration, the `cuda_bindings` source directory,
and their original build matrix and metapackage artifact name. New CUDA 12
releases require the local `cuda_bindings_12` root and toolkit-qualified
artifacts. The workflow control revision never supplies missing tagged toolkit
settings or replaces tagged release notes. Older CUDA 12 branch releases use
their compatible historical tooling.

In **CI: Release**, normal bindings and metapackage releases each require
their own exact-version, nonempty release notes in the tagged source. Notes
from the workflow control revision or a different component cannot fill a gap.
Preserve their existing exemption for `.postN` releases, which do not require
new notes.

Local synthetic tags used in publication-incapable rehearsals must remain local;
they do not authorize publishing a package, creating a remote tag, or moving
an existing tag.
46 changes: 27 additions & 19 deletions .github/RELEASE-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@

# cuda.core Release Process

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

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

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

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

## Upload wheels to PyPI

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

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

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

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

3. After completion, verify the final PyPI upload:
3. Wait for that run to complete. It deploys versioned documentation and uploads
the source archive, checksum, and wheels to the GitHub Release draft. It
publishes the selected wheel set to TestPyPI followed by PyPI. The release
owner publishes the GitHub Release draft in the announcement step.

4. After completion, verify the final PyPI upload:

```bash
pip install cuda-core==0.6.0
Expand Down
Loading
Loading