Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
126c4f9
Test and document both bindings lines from main
rwgk Oct 21, 2026
3fb21d7
CI: label metapackage GPU suites as meta
rwgk Oct 21, 2026
4c9458b
Adapt CUDA 12 NVML tests for current CI runners
rwgk Oct 21, 2026
372c76b
Bound cuDSS test dependencies to the supported loader ABI
rwgk Oct 22, 2026
0fa5f63
Align multi-major CI with main's security and loader updates
rwgk Oct 25, 2026
681750f
Use the checked-out docs control plane for pip hardening
rwgk Oct 25, 2026
265349a
Build CUDA 13 documentation against the checkout's bindings
rwgk Oct 26, 2026
578df8d
Share wheel-test matrix selection across platforms
rwgk Oct 26, 2026
b828038
Remove obsolete artifact filters from CI run lookup
rwgk Oct 26, 2026
54e21fe
Keep CI source and wheel tests focused on silent failures
rwgk Oct 26, 2026
62006bf
Keep matrix tooling separate from artifact source checkouts
rwgk Oct 26, 2026
68d4f7a
Align build and test documentation with both bindings roots
rwgk Oct 26, 2026
431bf98
Describe artifact retention as workflow-specific
rwgk Oct 26, 2026
8ab43ed
Prepare maintenance versions before Pixi GPU source tests
rwgk Oct 27, 2026
4ba01e0
Explain compatible nightly sources and historical release reruns
rwgk Oct 27, 2026
9805635
Serialize the matching CUDA 12 global coredump test
rwgk Oct 27, 2026
a9dd74c
Record the CUDA 12 driver documentation correction
rwgk Oct 27, 2026
b970e1e
Harden CI tooling across docs and source workflows
rwgk Oct 30, 2026
6ede633
Qualify historical CI sources with current security prerequisites
rwgk Oct 30, 2026
632711b
Remove command-shaped source tests and unused checkout credentials
rwgk Nov 1, 2026
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
2 changes: 1 addition & 1 deletion .github/actions/doc_preview/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ runs:
steps:
- name: Deploy doc preview
if: ${{ startsWith(github.ref_name, 'pull-request/') }}
uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4.8.0
uses: JamesIves/github-pages-deploy-action@fa24774553152dd7873cd16ebd8d959b010c5445 # v4.9.0
with:
git-config-name: cuda-python-bot
git-config-email: cuda-python-bot@users.noreply.github.com
Expand Down
145 changes: 99 additions & 46 deletions .github/workflows/build-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ on:
required: false
default: "gh-pages"
type: string
bindings-package:
description: "Resolved CUDA bindings package JSON"
required: false
default: ""
type: string

jobs:
build:
Expand All @@ -62,31 +67,58 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 1
ref: ${{ inputs.git-tag }}
persist-credentials: false
ref: ${{ inputs.is-release && format('refs/tags/{0}', inputs.git-tag) || inputs.git-tag }}

# Release sources and workflow tools can come from different commits.
# Keep the shared CI helpers at this workflow revision while reading
# package paths and toolkit settings from the checked-out release tag.
- name: Checkout docs control plane
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
path: .ci-control
Comment on lines +76 to +80

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor · Security & Privacy · Quick win

Supported by static analysis

Script executed:

rg -n 'persist-credentials|zizmor' .github .pre-commit-config.yaml ci 2>/dev/null | head -60
sed -n '60,125p' .github/workflows/build-docs.yml
rg -n 'git (push|fetch|pull|clone)' .github/workflows/build-docs.yml

Repository: NVIDIA/cuda-python

Length of output: 3651


Script executed:

set +e
printf '%s\n' '--- build-docs.yml lines 1-260 ---'
nl -ba .github/workflows/build-docs.yml | sed -n '1,260p'
printf '%s\n' '--- checkout and git operations in workflows ---'
rg -n -F --glob '.github/workflows/*.yml' --glob '.github/workflows/*.yaml' \
  -e 'actions/checkout@' -e 'persist-credentials' -e 'git push' -e 'git fetch' -e 'git pull' -e 'git clone' \
  .github/workflows
printf '%s\n' '--- zizmor/pre-commit/automation configuration ---'
rg -n -i -F --glob '!**/.git/**' \
  -e 'zizmor' -e 'artipacked' -e 'pre-commit' -e 'actionlint' -e 'workflow lint' -e 'workflow-check' \
  .github .pre-commit-config.yaml pyproject.toml setup.cfg tox.ini Makefile ci 2>/dev/null
printf '%s\n' '--- workflow validation files ---'
find .github -maxdepth 3 -type f -print | sort

Repository: NVIDIA/cuda-python

Length of output: 30654


Script executed:

printf '%s\n' '--- build-docs.yml tail ---'
nl -ba .github/workflows/build-docs.yml | sed -n '248,480p'
printf '%s\n' '--- workflow health ---'
nl -ba .github/workflows/ci-workflow-health.yml | sed -n '1,240p'
printf '%s\n' '--- pre-commit actionlint configuration ---'
nl -ba .pre-commit-config.yaml | sed -n '205,245p'
nl -ba .github/workflows/pre-commit.yml | sed -n '145,180p'
nl -ba .github/actionlint.yaml | sed -n '1,80p'
printf '%s\n' '--- exact git commands and checkout options in build-docs ---'
rg -n -C 4 -i -e 'git[[:space:]]+(push|fetch|pull|clone|config|remote)' -e 'actions/checkout@' -e 'persist-credentials' .github/workflows/build-docs.yml

Repository: NVIDIA/cuda-python

Length of output: 28641


Script executed:

printf '%s\n' '--- invoked scripts and local actions for git operations ---'
rg -n -i -e '(^|[[:space:]])git[[:space:]]+(push|fetch|pull|clone|config|remote)' \
  ci/tools/checkout_source_links.py cuda_python/docs cuda_core/docs cuda_bindings_12/docs cuda_bindings_13/docs \
  .github/actions/get_pr_number .github/actions/fetch_ctk .github/actions/lychee-links 2>/dev/null || true
printf '%s\n' '--- relevant caller references and permissions ---'
rg -n -C 8 -F -e 'build-docs.yml' -e './.github/workflows/build-docs.yml' -e 'contents: write' .github/workflows .github/actions 2>/dev/null || true

Repository: NVIDIA/cuda-python

Length of output: 15628


Script executed:

printf '%s\n' '--- pre-commit configuration header ---'
nl -ba .pre-commit-config.yaml | sed -n '1,65p'
printf '%s\n' '--- security suite ---'
nl -ba .github/workflows/security-suite.yml | sed -n '1,240p'
printf '%s\n' '--- workflow-security tool references ---'
rg -n -i -e 'pulse' -e 'zizmor' -e 'artipacked' -e 'actionlint' -e 'workflow.*(lint|security|audit)' .github .pre-commit-config.yaml ci 2>/dev/null || true

Repository: NVIDIA/cuda-python

Length of output: 7028


suggestion: Disable credential persistence for the build-job checkouts.

Neither build-job checkout performs a later Git push or fetch. The publishing job uses a separate checkout, so keep credentials enabled there. The build callers grant contents: write, so the two unused tokens remain in local Git configuration while later actions run.

Suggested fix
       - name: Checkout ${{ github.event.repository.name }}
         uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1  # v7.0.1
         with:
           fetch-depth: 1
           ref: ${{ inputs.is-release && format('refs/tags/{0}', inputs.git-tag) || inputs.git-tag }}
+          persist-credentials: false

       - name: Checkout docs control plane
         uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1  # v7.0.1
         with:
           ref: ${{ github.sha }}
           path: .ci-control
+          persist-credentials: false
Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Checkout docs control plane
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
path: .ci-control
- name: Checkout docs control plane
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.sha }}
path: .ci-control
persist-credentials: false
Tools
zizmor (1.30.1)

[warning] 75-79: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

persist-credentials: false

- name: Read build CTK version
- name: Set up Python for CI tools
# The release checkout can predate this action; use the workflow revision.
uses: ./.ci-control/.github/actions/setup-hardened-python
with:
python-version: "3.12"

- name: Install CI tool dependencies
# Keep the hardened interpreter ahead of any login-shell activation.
shell: bash --noprofile --norc -euo pipefail {0}
run: python3 -m pip install -e ./.ci-control/ci

- name: Resolve CUDA bindings package
shell: bash --noprofile --norc -euo pipefail {0}
env:
BINDINGS_PACKAGE: ${{ inputs.bindings-package }}
IS_RELEASE: ${{ inputs.is-release }}
RELEASE_TAG: ${{ inputs.git-tag }}
run: |
if [[ -f ci/versions.yml ]]; then
BUILD_CTK_VER=$(yq '.cuda.build.version' ci/versions.yml)
elif [[ -f ci/versions.json ]]; then
BUILD_CTK_VER=$(jq -r '.cuda.build.version' ci/versions.json)
set -euo pipefail
if [[ -n "$BINDINGS_PACKAGE" ]]; then
resolved_bindings_package="$BINDINGS_PACKAGE"
elif [[ "${IS_RELEASE}" == "true" ]]; then
resolved_bindings_package=$(cd .ci-control && python3 -m ci.tools.bindings_config \
--release-tag "$RELEASE_TAG" \
--release-source-root ..)
else
echo "error: cannot find ci/versions.yml or ci/versions.json" >&2
exit 1
fi
if [[ ! "${BUILD_CTK_VER}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "error: derived CTK build version ${BUILD_CTK_VER} does not match MAJOR.MINOR.MICRO" >&2
exit 1
resolved_bindings_package=$(cd .ci-control && python3 -m ci.tools.bindings_config \
--release-status current)
fi
echo "BUILD_CTK_VER=${BUILD_CTK_VER}" >> "$GITHUB_ENV"
(cd .ci-control && python3 -m ci.tools.bindings_config \
write-github-env "$GITHUB_ENV" <<< "$resolved_bindings_package")

# TODO: This workflow runs on GH-hosted runner and cannot use the proxy cache

- name: Set up miniforge
uses: conda-incubator/setup-miniconda@be893c923ea9cf1cf7cd510fbdde27c7e18cbdcb # v4.1.0
with:
activate-environment: cuda-python-docs
environment-file: ./cuda_python/docs/environment-docs.yml
environment-file: ./.ci-control/cuda_python/docs/environment-docs.yml
miniforge-version: latest
conda-remove-defaults: "true"
python-version: 3.12
Expand All @@ -106,24 +138,16 @@ jobs:
cuda-version: ${{ env.BUILD_CTK_VER }}

- name: Set environment variables
env:
IS_RELEASE: ${{ inputs.is-release }}
RELEASE_TAG: ${{ inputs.git-tag }}
run: |
PYTHON_VERSION_FORMATTED="312" # see above
REPO_DIR=$(pwd)

# Release docs may check out tags from before the source-root rename.
if [[ -d cuda_bindings_13 ]]; then
CUDA_BINDINGS_SOURCE_DIR=cuda_bindings_13
elif [[ -d cuda_bindings ]]; then
CUDA_BINDINGS_SOURCE_DIR=cuda_bindings
else
echo "error: cannot find the cuda.bindings source directory" >&2
exit 1
fi
echo "CUDA_BINDINGS_SOURCE_DIR=${CUDA_BINDINGS_SOURCE_DIR}" >> "$GITHUB_ENV"

if [[ ${{ inputs.is-release }} == "true" ]]; then
if [[ "$IS_RELEASE" == "true" ]]; then
FILE_HASH="*"
DOCS_GITHUB_REF="${{ inputs.git-tag }}"
DOCS_GITHUB_REF="$RELEASE_TAG"
if [[ -z "${DOCS_GITHUB_REF}" ]]; then
DOCS_GITHUB_REF="${GITHUB_REF_NAME}"
fi
Expand All @@ -132,6 +156,8 @@ jobs:
DOCS_GITHUB_REF=$(python ci/tools/checkout_source_links.py --github-ref)
fi

echo "CUDA_BINDINGS_SOURCE_DIR=${BINDINGS_PACKAGE_ROOT}" >> "$GITHUB_ENV"

# make outputs from the previous job as env vars
CUDA_CORE_ARTIFACT_BASENAME="cuda-core-python${PYTHON_VERSION_FORMATTED}-linux-64"
echo "CUDA_PYTHON_DOCS_GITHUB_REF=${DOCS_GITHUB_REF}" >> $GITHUB_ENV
Expand All @@ -141,22 +167,27 @@ jobs:
CUDA_BINDINGS_ARTIFACT_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda${BUILD_CTK_VER}-linux-64"
echo "CUDA_BINDINGS_ARTIFACT_BASENAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}" >> $GITHUB_ENV
echo "CUDA_BINDINGS_ARTIFACT_NAME=${CUDA_BINDINGS_ARTIFACT_BASENAME}-${FILE_HASH}" >> $GITHUB_ENV
echo "CUDA_BINDINGS_ARTIFACTS_DIR=$(realpath "$REPO_DIR/$CUDA_BINDINGS_SOURCE_DIR/dist")" >> $GITHUB_ENV
echo "CUDA_BINDINGS_ARTIFACTS_DIR=$(realpath "$REPO_DIR/${BINDINGS_PACKAGE_ROOT}/dist")" >> $GITHUB_ENV
CUDA_PYTHON_ARTIFACT_NAME="cuda-python-wheel-cuda${BUILD_CTK_VER}"
echo "CUDA_PYTHON_ARTIFACT_NAME=${CUDA_PYTHON_ARTIFACT_NAME}" >> $GITHUB_ENV

- name: Download cuda-python build artifacts
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-python' }}
uses: $/.github/actions/download-artifact-retry
with:
name: cuda-python-wheel
name: ${{ env.CUDA_PYTHON_ARTIFACT_NAME }}
path: .
run-id: ${{ inputs.run-id }}
github-token: ${{ github.token }}

- name: Display structure of downloaded cuda-python artifacts
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-python' }}
run: |
pwd
ls -lahR .

- name: Download cuda-pathfinder build artifacts
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-pathfinder' || inputs.component == 'cuda-core' }}
uses: $/.github/actions/download-artifact-retry
with:
name: cuda-pathfinder-wheel
Expand All @@ -165,6 +196,7 @@ jobs:
github-token: ${{ github.token }}

- name: Display structure of downloaded cuda-pathfinder artifacts
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-pathfinder' || inputs.component == 'cuda-core' }}
run: |
pwd
ls -lahR cuda_pathfinder
Expand All @@ -177,7 +209,7 @@ jobs:
path: ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}

- name: Download cuda.bindings build artifacts
if: ${{ inputs.is-release }}
if: ${{ inputs.is-release && (inputs.component == 'all' || inputs.component == 'cuda-bindings' || inputs.component == 'cuda-core') }}
uses: $/.github/actions/download-artifact-retry
with:
pattern: ${{ env.CUDA_BINDINGS_ARTIFACT_NAME }}
Expand All @@ -187,6 +219,7 @@ jobs:
github-token: ${{ github.token }}

- name: Display structure of downloaded cuda.bindings artifacts
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-bindings' || inputs.component == 'cuda-core' }}
run: |
pwd
ls -lahR $CUDA_BINDINGS_ARTIFACTS_DIR
Expand All @@ -199,7 +232,7 @@ jobs:
path: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}

- name: Download cuda.core build artifacts
if: ${{ inputs.is-release }}
if: ${{ inputs.is-release && (inputs.component == 'all' || inputs.component == 'cuda-core') }}
uses: $/.github/actions/download-artifact-retry
with:
pattern: ${{ env.CUDA_CORE_ARTIFACT_NAME }}
Expand All @@ -209,26 +242,37 @@ jobs:
github-token: ${{ github.token }}

- name: Display structure of downloaded cuda.core build artifacts
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-core' }}
run: |
pwd
ls -lahR $CUDA_CORE_ARTIFACTS_DIR

- name: Install all packages
- name: Install cuda-pathfinder
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-pathfinder' || inputs.component == 'cuda-core' }}
run: |
pushd cuda_pathfinder
pip install *.whl
popd

- name: Install cuda.bindings
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-bindings' || inputs.component == 'cuda-core' }}
run: |
pushd "${CUDA_BINDINGS_ARTIFACTS_DIR}"
pip install *.whl
popd

- name: Install cuda.core
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-core' }}
run: |
pushd "${CUDA_CORE_ARTIFACTS_DIR}"
pip install *.whl
popd

# Subpackages are already installed from CI artifacts above.
# --no-deps avoids re-resolving cuda-core from PyPI during tag releases.
- name: Install cuda-python
if: ${{ !inputs.is-release || inputs.component == 'all' || inputs.component == 'cuda-python' }}
run: |
# Documentation builds do not exercise runtime dependencies.
# --no-deps also avoids resolving artifacts absent from focused tag runs.
pip install --no-deps cuda_python*.whl

# PR CI uses pull-request/<number> refs regardless of the target branch.
Expand All @@ -252,9 +296,11 @@ jobs:

- name: Build all docs
if: ${{ inputs.component == 'all' }}
env:
IS_RELEASE: ${{ inputs.is-release }}
run: |
pushd cuda_python/docs/
if [[ "${{ inputs.is-release }}" == "false" ]]; then
if [[ "$IS_RELEASE" == "false" ]]; then
./build_all_docs.sh latest-only
else
./build_all_docs.sh
Expand All @@ -271,13 +317,20 @@ jobs:

- name: Build component docs
if: ${{ inputs.component != 'all' }}
env:
DOCS_COMPONENT: ${{ inputs.component }}
IS_RELEASE: ${{ inputs.is-release }}
run: |
COMPONENT=$(echo "${{ inputs.component }}" | tr '-' '_')
if [[ "${{ inputs.component }}" == "cuda-bindings" ]]; then
COMPONENT="${CUDA_BINDINGS_SOURCE_DIR}"
case "$DOCS_COMPONENT" in
cuda-bindings|cuda-core|cuda-pathfinder|cuda-python) ;;
*) echo "error: unsupported docs component: $DOCS_COMPONENT" >&2; exit 1 ;;
esac
COMPONENT="${DOCS_COMPONENT//-/_}"
if [[ "$DOCS_COMPONENT" == "cuda-bindings" ]]; then
COMPONENT="${BINDINGS_PACKAGE_ROOT}"
fi
pushd ${COMPONENT}/docs/
if [[ "${{ inputs.is-release }}" == "false" ]]; then
pushd "${COMPONENT}/docs/"
if [[ "$IS_RELEASE" == "false" ]]; then
./build_docs.sh latest-only
else
./build_docs.sh
Expand All @@ -290,13 +343,13 @@ jobs:
fi
ls -l build
popd
if [[ "${{ inputs.component }}" != "cuda-python" ]]; then
TARGET="${{ inputs.component }}"
mkdir -p artifacts/docs/${TARGET}
if [[ "$DOCS_COMPONENT" != "cuda-python" ]]; then
TARGET="$DOCS_COMPONENT"
mkdir -p "artifacts/docs/${TARGET}"
else
TARGET=""
fi
mv ${COMPONENT}/docs/build/html/* artifacts/docs/${TARGET}
mv "${COMPONENT}"/docs/build/html/* "artifacts/docs/${TARGET}"

# Check links and anchors in the rendered HTML built above.
# Links in authored Markdown and reST files are checked separately by the
Expand All @@ -305,7 +358,7 @@ jobs:
# interpreter instead of the conda environment used above.
- name: Set up Python for link checks
if: ${{ !inputs.is-release && startsWith(github.ref_name, 'pull-request/') }}
uses: ./.github/actions/setup-hardened-python
uses: ./.ci-control/.github/actions/setup-hardened-python
with:
python-version: "3.14"

Expand Down Expand Up @@ -363,7 +416,7 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 1
ref: ${{ inputs.git-tag }}
ref: ${{ inputs.is-release && format('refs/tags/{0}', inputs.git-tag) || inputs.git-tag }}

- name: Download docs deployment payload
uses: $/.github/actions/download-artifact-retry
Expand Down
Loading
Loading