Skip to content

Commit 69774b7

Browse files
committed
Merge remote-tracking branch 'upstream/main' into cybind-catchup
2 parents 81770c1 + a9156b6 commit 69774b7

11 files changed

Lines changed: 451 additions & 31 deletions

File tree

.github/workflows/build-docs.yml

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ on:
3333
required: false
3434
default: false
3535
type: boolean
36+
deploy-docs:
37+
description: "Deploy generated docs to GitHub Pages or preview branches"
38+
required: false
39+
default: true
40+
type: boolean
41+
docs-branch:
42+
description: "Branch that receives deployed docs"
43+
required: false
44+
default: "gh-pages"
45+
type: string
3646

3747
jobs:
3848
build:
@@ -52,7 +62,14 @@ jobs:
5262

5363
- name: Read build CTK version
5464
run: |
55-
BUILD_CTK_VER=$(yq '.cuda.build.version' ci/versions.yml)
65+
if [[ -f ci/versions.yml ]]; then
66+
BUILD_CTK_VER=$(yq '.cuda.build.version' ci/versions.yml)
67+
elif [[ -f ci/versions.json ]]; then
68+
BUILD_CTK_VER=$(jq -r '.cuda.build.version' ci/versions.json)
69+
else
70+
echo "error: cannot find ci/versions.yml or ci/versions.json" >&2
71+
exit 1
72+
fi
5673
if [[ ! "${BUILD_CTK_VER}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
5774
echo "error: derived CTK build version ${BUILD_CTK_VER} does not match MAJOR.MINOR.MICRO" >&2
5875
exit 1
@@ -305,25 +322,35 @@ jobs:
305322
key: ${{ steps.restore-lychee-cache.outputs.cache-primary-key }}
306323

307324
- name: Upload docs GitHub Pages artifact
325+
if: ${{ inputs.deploy-docs }}
308326
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
309327
with:
310328
path: artifacts/
311329
retention-days: 3
312330

331+
- name: Upload dry-run docs artifact
332+
if: ${{ !inputs.deploy-docs || (inputs.is-release && inputs.docs-branch != 'gh-pages') }}
333+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
334+
with:
335+
name: release-docs-dry-run-${{ inputs.component }}-${{ inputs.git-tag }}
336+
path: artifacts/docs/
337+
retention-days: 3
338+
313339
- name: Deploy or clean up doc preview
314-
if: ${{ !inputs.is-release }}
340+
if: ${{ inputs.deploy-docs && !inputs.is-release }}
315341
uses: ./.github/actions/doc_preview
316342
with:
317343
source-folder: ${{ (github.ref_name != 'main' && 'artifacts/docs') ||
318344
'artifacts/empty_docs' }}
319345
pr-number: ${{ env.PR_NUMBER }}
320346

321347
- name: Deploy doc update
322-
if: ${{ github.ref_name == 'main' || inputs.is-release }}
348+
if: ${{ inputs.deploy-docs && (github.ref_name == 'main' || inputs.is-release) }}
323349
uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4.8.0
324350
with:
325351
git-config-name: cuda-python-bot
326352
git-config-email: cuda-python-bot@users.noreply.github.com
353+
branch: ${{ inputs.docs-branch }}
327354
folder: artifacts/docs/
328355
target-folder: docs/
329356
commit-message: "Deploy ${{ (inputs.is-release && 'release') || 'latest' }} docs: ${{ env.CUDA_PYTHON_DOCS_GITHUB_REF }}"

.github/workflows/ci-pixi-source-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ jobs:
112112
timeout-minutes: 90
113113
container:
114114
options: -u root --security-opt seccomp=unconfined --shm-size 16g
115-
image: ubuntu:22.04
115+
image: ubuntu:24.04
116116
steps:
117117
- name: Ensure GPU is working
118118
run: nvidia-smi

.github/workflows/coverage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
# TODO: use a different (nvidia?) container
4848
container:
4949
options: -u root --security-opt seccomp=unconfined --shm-size 16g
50-
image: ubuntu:22.04
50+
image: ubuntu:24.04
5151
env:
5252
NVIDIA_VISIBLE_DEVICES: ${{ env.NVIDIA_VISIBLE_DEVICES }}
5353
PIP_CACHE_DIR: "/tmp/pip-cache"

.github/workflows/release-upload.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1+
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

@@ -18,6 +18,11 @@ on:
1818
description: "Component to download wheels for"
1919
type: string
2020
required: true
21+
dry-run:
22+
description: "Validate release artifacts without uploading them to the GitHub release"
23+
type: boolean
24+
required: false
25+
default: false
2126

2227
concurrency:
2328
# Concurrency group that uses the workflow name and PR number if available
@@ -64,6 +69,7 @@ jobs:
6469
> "release/${{ env.ARCHIVE_NAME }}.tar.gz.sha256sum"
6570
6671
- name: Upload Archive
72+
if: ${{ !inputs.dry-run }}
6773
env:
6874
GH_TOKEN: ${{ github.token }}
6975
run: >
@@ -72,7 +78,7 @@ jobs:
7278
--repo "${{ github.repository }}"
7379
release/*
7480
75-
- name: Download and Upload Wheels
81+
- name: Download and Validate Wheels
7682
env:
7783
GH_TOKEN: ${{ github.token }}
7884
run: |
@@ -82,8 +88,20 @@ jobs:
8288
# Validate that release wheels match the expected version from tag.
8389
./ci/tools/validate-release-wheels "${{ inputs.git-tag }}" "${{ inputs.component }}" "release/wheels"
8490
85-
# Upload wheels to the release
91+
- name: Upload Wheels
92+
if: ${{ !inputs.dry-run }}
93+
env:
94+
GH_TOKEN: ${{ github.token }}
95+
run: |
8696
if [[ -d "release/wheels" && $(ls -A release/wheels 2>/dev/null | wc -l) -gt 0 ]]; then
8797
echo "Uploading wheels to release ${{ inputs.git-tag }}"
8898
gh release upload --clobber "${{ inputs.git-tag }}" --repo "${{ github.repository }}" release/wheels/*
8999
fi
100+
101+
- name: Upload dry-run release artifacts
102+
if: ${{ inputs.dry-run }}
103+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
104+
with:
105+
name: release-artifacts-dry-run-${{ inputs.component }}-${{ inputs.git-tag }}
106+
path: release/
107+
retention-days: 3

.github/workflows/release.yml

Lines changed: 78 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,34 @@
1-
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1+
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

55
name: "CI: Release"
66

77
# Manually-triggered release workflow. Creates a release draft if one doesn't exist
88
# for the given tag, or uses an existing draft, then publishes the selected wheels
9-
# to TestPyPI followed by PyPI.
9+
# to TestPyPI followed by PyPI. The dry-run mode validates the release path
10+
# without publishing to external release surfaces.
11+
#
12+
# Maintenance note: non-trivial changes to this workflow should be validated
13+
# with dry-run workflow_dispatch runs before merging. Suggested focused matrix:
14+
# - mainline:
15+
# component=cuda-bindings
16+
# git-tag=<latest cuda-bindings release tag>
17+
# backport-git-tag=not planned
18+
# run-id=<blank>
19+
# dry-run-docs-branch=gh-pages-dry-run
20+
# - backport sequence:
21+
# 1. component=cuda-bindings
22+
# git-tag=<latest cuda-bindings backport release tag>
23+
# backport-git-tag=<blank>
24+
# 2. component=cuda-python
25+
# git-tag=<matching cuda-python backport release tag>
26+
# backport-git-tag=<blank>
27+
# run-id=<blank>
28+
# dry-run-docs-branch=gh-pages-dry-run
29+
# Leave run-id blank so determine-run-id is exercised. For exhaustive coverage,
30+
# add a mainline cuda-python dry-run when changes could affect metapackage
31+
# artifact validation, docs routing, or component-specific release behavior.
1032

1133
on:
1234
workflow_dispatch:
@@ -20,15 +42,33 @@ on:
2042
- cuda-bindings
2143
- cuda-pathfinder
2244
- cuda-python
45+
release-action:
46+
description: "What to run"
47+
required: true
48+
type: choice
49+
options:
50+
- dry-run
51+
- full-release
52+
default: dry-run
2353
git-tag:
2454
description: "The release git tag"
2555
required: true
2656
type: string
57+
backport-git-tag:
58+
description: "Mainline cuda-bindings/cuda-python only: planned backport tag, or 'not planned'. Leave blank for backport releases."
59+
required: false
60+
type: string
61+
default: ""
2762
run-id:
2863
description: "The GHA run ID that generated validated artifacts (optional - auto-detects successful tag-triggered CI run for git-tag)"
2964
required: false
3065
type: string
3166
default: ""
67+
dry-run-docs-branch:
68+
description: "Dry-run only: optional gh-pages-* branch to receive generated docs, for example gh-pages-dry-run"
69+
required: false
70+
type: string
71+
default: ""
3272

3373
defaults:
3474
run:
@@ -52,9 +92,14 @@ jobs:
5292
env:
5393
GH_TOKEN: ${{ github.token }}
5494
run: |
55-
echo "Auto-detecting successful tag-triggered run ID for tag: ${{ inputs.git-tag }}"
56-
RUN_ID=$(./ci/tools/lookup-run-id "${{ inputs.git-tag }}" "${{ github.repository }}")
57-
echo "Auto-detected run ID: $RUN_ID"
95+
if [[ -n "${{ inputs.run-id }}" ]]; then
96+
echo "Using provided run ID: ${{ inputs.run-id }}"
97+
RUN_ID="${{ inputs.run-id }}"
98+
else
99+
echo "Auto-detecting successful tag-triggered run ID for tag: ${{ inputs.git-tag }}"
100+
RUN_ID=$(./ci/tools/lookup-run-id "${{ inputs.git-tag }}" "${{ github.repository }}")
101+
echo "Auto-detected run ID: $RUN_ID"
102+
fi
58103
echo "run-id=$RUN_ID" >> "$GITHUB_OUTPUT"
59104
60105
check-tag:
@@ -63,12 +108,31 @@ jobs:
63108
- name: Checkout Source
64109
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
65110
with:
111+
# Dry-run validation resolves the requested tag locally; we need tags but not history.
66112
fetch-depth: 1
113+
fetch-tags: true
67114

68-
- name: Check or create draft release for the tag
115+
- name: Check release tag and draft state
69116
env:
70117
GH_TOKEN: ${{ github.token }}
118+
RELEASE_ACTION: ${{ inputs.release-action }}
119+
RELEASE_GIT_TAG: ${{ inputs.git-tag }}
120+
DRY_RUN_DOCS_BRANCH: ${{ inputs.dry-run-docs-branch }}
71121
run: |
122+
if [[ "$RELEASE_ACTION" == "full-release" && -n "$DRY_RUN_DOCS_BRANCH" ]]; then
123+
echo "error: dry-run-docs-branch is only valid with release-action=dry-run" >&2
124+
exit 1
125+
fi
126+
if [[ "$RELEASE_ACTION" == "dry-run" && -n "$DRY_RUN_DOCS_BRANCH" && ! "$DRY_RUN_DOCS_BRANCH" =~ ^gh-pages-[[:alnum:]._/-]+$ ]]; then
127+
echo "error: dry-run-docs-branch must be a non-production gh-pages-* branch" >&2
128+
exit 1
129+
fi
130+
if [[ "$RELEASE_ACTION" == "dry-run" ]]; then
131+
git rev-parse --verify "${RELEASE_GIT_TAG}^{commit}"
132+
echo "Dry-run selected; not checking or creating a GitHub release draft."
133+
exit 0
134+
fi
135+
72136
mapfile -t tags < <(gh release list -R "${{ github.repository }}" --json tagName --jq '.[] | .tagName')
73137
mapfile -t is_draft < <(gh release list -R "${{ github.repository }}" --json isDraft --jq '.[] | .isDraft')
74138
@@ -94,8 +158,6 @@ jobs:
94158
steps:
95159
- name: Checkout Source
96160
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
97-
with:
98-
ref: ${{ inputs.git-tag }}
99161

100162
- name: Set up Python
101163
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
@@ -111,7 +173,8 @@ jobs:
111173
run: |
112174
python ci/tools/check_release_notes.py \
113175
--git-tag "${{ inputs.git-tag }}" \
114-
--component "${{ inputs.component }}"
176+
--component "${{ inputs.component }}" \
177+
--backport-git-tag "${{ inputs.backport-git-tag }}"
115178
116179
doc:
117180
name: Build release docs
@@ -132,9 +195,11 @@ jobs:
132195
git-tag: ${{ inputs.git-tag }}
133196
run-id: ${{ needs.determine-run-id.outputs.run-id }}
134197
is-release: true
198+
deploy-docs: ${{ inputs.release-action == 'full-release' || inputs.dry-run-docs-branch != '' }}
199+
docs-branch: ${{ (inputs.release-action == 'dry-run' && inputs.dry-run-docs-branch) || 'gh-pages' }}
135200

136201
upload-archive:
137-
name: Upload source archive
202+
name: Validate release artifacts
138203
permissions:
139204
contents: write
140205
needs:
@@ -148,9 +213,11 @@ jobs:
148213
git-tag: ${{ inputs.git-tag }}
149214
run-id: ${{ needs.determine-run-id.outputs.run-id }}
150215
component: ${{ inputs.component }}
216+
dry-run: ${{ inputs.release-action == 'dry-run' }}
151217

152218
publish-testpypi:
153219
name: Publish wheels to TestPyPI
220+
if: ${{ inputs.release-action == 'full-release' }}
154221
runs-on: ubuntu-latest
155222
needs:
156223
- check-tag
@@ -183,6 +250,7 @@ jobs:
183250

184251
publish-pypi:
185252
name: Publish wheels to PyPI
253+
if: ${{ inputs.release-action == 'full-release' }}
186254
runs-on: ubuntu-latest
187255
needs:
188256
- determine-run-id

.github/workflows/test-wheel-linux.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ jobs:
118118
# can nsenter to the host for the install + refresh the toolkit bind mounts
119119
# back inside the container. Stock options for latest/earliest rows.
120120
options: ${{ ((matrix.DRIVER == 'latest' || matrix.DRIVER == 'earliest') && '-u root --security-opt seccomp=unconfined --shm-size 16g') || '-u root --security-opt seccomp=unconfined --shm-size 16g --privileged --pid=host' }}
121-
image: ubuntu:22.04
121+
image: ubuntu:24.04
122122
env:
123123
NVIDIA_VISIBLE_DEVICES: ${{ env.NVIDIA_VISIBLE_DEVICES }}
124124
PIP_CACHE_DIR: "/tmp/pip-cache"

ci/test-matrix.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ linux:
5252
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.0.2', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
5353
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.3.0', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
5454
- { ARCH: 'amd64', PY_VER: '3.15', CUDA_VER: '13.3.0', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
55-
# Blocked by NVIDIA/cuda-python#2171
56-
# - { ARCH: 'amd64', PY_VER: '3.15t', CUDA_VER: '13.3.0', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
55+
- { ARCH: 'amd64', PY_VER: '3.15t', CUDA_VER: '13.3.0', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
5756
# linux-aarch64
5857
- { ARCH: 'arm64', PY_VER: '3.10', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest' }
5958
- { ARCH: 'arm64', PY_VER: '3.10', CUDA_VER: '13.0.2', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }

0 commit comments

Comments
 (0)