From deec047a6ba740580f8014c711b2c1cc5d58ce9d Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Mon, 1 Jun 2026 15:35:06 -0400 Subject: [PATCH 01/22] Check versioned docs example links --- .github/workflows/build-docs.yml | 20 +++++++++++++------- cuda_bindings/docs/build_docs.sh | 16 ++++++++++++++-- cuda_bindings/docs/source/conf.py | 2 ++ cuda_core/docs/build_docs.sh | 14 ++++++++++++-- cuda_core/docs/source/conf.py | 2 ++ 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index e95a50b2a03..62895ff2a9b 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # SPDX-License-Identifier: Apache-2.0 @@ -91,14 +91,20 @@ jobs: if [[ ${{ inputs.is-release }} == "true" ]]; then FILE_HASH="*" - COMMIT_HASH="${{ inputs.git-tag }}" + DOCS_GITHUB_REF="${{ inputs.git-tag }}" + if [[ -z "${DOCS_GITHUB_REF}" ]]; then + DOCS_GITHUB_REF="${GITHUB_REF_NAME}" + fi + COMMIT_HASH="${DOCS_GITHUB_REF}" else FILE_HASH="${{ github.sha }}" - COMMIT_HASH="${{ github.sha }}" + DOCS_GITHUB_REF="${{ github.sha }}" + COMMIT_HASH="${DOCS_GITHUB_REF}" fi # 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 echo "COMMIT_HASH=${COMMIT_HASH}" >> $GITHUB_ENV echo "CUDA_CORE_ARTIFACT_BASENAME=${CUDA_CORE_ARTIFACT_BASENAME}" >> $GITHUB_ENV echo "CUDA_CORE_ARTIFACT_NAME=${CUDA_CORE_ARTIFACT_BASENAME}-${FILE_HASH}" >> $GITHUB_ENV @@ -210,9 +216,9 @@ jobs: run: | pushd cuda_python/docs/ if [[ "${{ inputs.is-release }}" == "false" ]]; then - ./build_all_docs.sh latest-only + DOCS_LINKCHECK=1 ./build_all_docs.sh latest-only else - ./build_all_docs.sh + DOCS_LINKCHECK=1 ./build_all_docs.sh # At release time, we don't want to update the latest docs rm -rf build/html/latest fi @@ -226,9 +232,9 @@ jobs: COMPONENT=$(echo "${{ inputs.component }}" | tr '-' '_') pushd ${COMPONENT}/docs/ if [[ "${{ inputs.is-release }}" == "false" ]]; then - ./build_docs.sh latest-only + DOCS_LINKCHECK=1 ./build_docs.sh latest-only else - ./build_docs.sh + DOCS_LINKCHECK=1 ./build_docs.sh # At release time, we don't want to update the latest docs rm -rf build/html/latest fi diff --git a/cuda_bindings/docs/build_docs.sh b/cuda_bindings/docs/build_docs.sh index 15a42b93464..ab52431c092 100755 --- a/cuda_bindings/docs/build_docs.sh +++ b/cuda_bindings/docs/build_docs.sh @@ -1,6 +1,6 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE set -ex @@ -30,7 +30,19 @@ if [[ "${LATEST_ONLY}" == "1" && -z "${BUILD_PREVIEW:-}" && -z "${BUILD_LATEST:- fi # build the docs (in parallel) -SPHINXOPTS="-j 4 -d build/.doctrees" make html +if [[ -z "${SPHINXOPTS:-}" ]]; then + HTML_SPHINXOPTS="-j 4 -d build/.doctrees" +else + HTML_SPHINXOPTS="${SPHINXOPTS}" +fi +SPHINXOPTS="${HTML_SPHINXOPTS}" make html + +if [[ "${DOCS_LINKCHECK:-0}" == "1" ]]; then + if [[ -z "${LINKCHECK_SPHINXOPTS:-}" ]]; then + LINKCHECK_SPHINXOPTS="-W --keep-going -j 4 -d build/.linkcheck-doctrees" + fi + SPHINXOPTS="${LINKCHECK_SPHINXOPTS}" make linkcheck BUILDDIR="build/linkcheck/${SPHINX_CUDA_BINDINGS_VER}" +fi # for debugging/developing (conf.py), please comment out the above line and # use the line below instead, as we must build in serial to avoid getting diff --git a/cuda_bindings/docs/source/conf.py b/cuda_bindings/docs/source/conf.py index 69a05d6e52f..45344cc4710 100644 --- a/cuda_bindings/docs/source/conf.py +++ b/cuda_bindings/docs/source/conf.py @@ -27,6 +27,8 @@ def _github_examples_ref(): + if ref := os.environ.get("CUDA_PYTHON_DOCS_GITHUB_REF"): + return ref if int(os.environ.get("BUILD_PREVIEW", 0)) or int(os.environ.get("BUILD_LATEST", 0)): return "main" return f"v{release}" diff --git a/cuda_core/docs/build_docs.sh b/cuda_core/docs/build_docs.sh index 78038438bcc..d723a8bdbfe 100755 --- a/cuda_core/docs/build_docs.sh +++ b/cuda_core/docs/build_docs.sh @@ -1,6 +1,6 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 set -ex @@ -30,10 +30,20 @@ fi # build the docs. Allow callers to override SPHINXOPTS for serial/debug runs. if [[ -z "${SPHINXOPTS:-}" ]]; then - SPHINXOPTS="-W --keep-going -j 4 -d build/.doctrees" + HTML_SPHINXOPTS="-W --keep-going -j 4 -d build/.doctrees" +else + HTML_SPHINXOPTS="${SPHINXOPTS}" fi +SPHINXOPTS="${HTML_SPHINXOPTS}" make html +if [[ "${DOCS_LINKCHECK:-0}" == "1" ]]; then + if [[ -z "${LINKCHECK_SPHINXOPTS:-}" ]]; then + LINKCHECK_SPHINXOPTS="-W --keep-going -j 4 -d build/.linkcheck-doctrees" + fi + SPHINXOPTS="${LINKCHECK_SPHINXOPTS}" make linkcheck BUILDDIR="build/linkcheck/${SPHINX_CUDA_CORE_VER}" +fi + # to support version dropdown menu cp ./versions.json build/html cp ./nv-versions.json build/html diff --git a/cuda_core/docs/source/conf.py b/cuda_core/docs/source/conf.py index 14d93297937..0549d3f0dcf 100644 --- a/cuda_core/docs/source/conf.py +++ b/cuda_core/docs/source/conf.py @@ -28,6 +28,8 @@ def _github_examples_ref(): + if ref := os.environ.get("CUDA_PYTHON_DOCS_GITHUB_REF"): + return ref if int(os.environ.get("BUILD_PREVIEW", 0)) or int(os.environ.get("BUILD_LATEST", 0)): return "main" return f"cuda-core-v{release}" From 8c67216f81f726a98550a947867e0f30a27e4c92 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Mon, 1 Jun 2026 16:19:26 -0400 Subject: [PATCH 02/22] Add pathfinder docs linkcheck --- cuda_pathfinder/docs/build_docs.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/cuda_pathfinder/docs/build_docs.sh b/cuda_pathfinder/docs/build_docs.sh index a7889b58dda..7e1ae3992c7 100755 --- a/cuda_pathfinder/docs/build_docs.sh +++ b/cuda_pathfinder/docs/build_docs.sh @@ -1,6 +1,6 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 set -ex @@ -25,8 +25,24 @@ if [[ -z "${SPHINX_CUDA_PATHFINDER_VER}" ]]; then | awk -F'+' '{print $1}') fi +if [[ "${LATEST_ONLY}" == "1" && -z "${BUILD_PREVIEW:-}" && -z "${BUILD_LATEST:-}" ]]; then + export BUILD_LATEST=1 +fi + # build the docs (in parallel) -SPHINXOPTS="-W --keep-going -j 4 -d build/.doctrees" make html +if [[ -z "${SPHINXOPTS:-}" ]]; then + HTML_SPHINXOPTS="-W --keep-going -j 4 -d build/.doctrees" +else + HTML_SPHINXOPTS="${SPHINXOPTS}" +fi +SPHINXOPTS="${HTML_SPHINXOPTS}" make html + +if [[ "${DOCS_LINKCHECK:-0}" == "1" ]]; then + if [[ -z "${LINKCHECK_SPHINXOPTS:-}" ]]; then + LINKCHECK_SPHINXOPTS="-W --keep-going -j 4 -d build/.linkcheck-doctrees" + fi + SPHINXOPTS="${LINKCHECK_SPHINXOPTS}" make linkcheck BUILDDIR="build/linkcheck/${SPHINX_CUDA_PATHFINDER_VER}" +fi # for debugging/developing (conf.py), please comment out the above line and # use the line below instead, as we must build in serial to avoid getting From bad8f0f79e9e7b602ed55d1ca37df912545fd5ca Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Mon, 1 Jun 2026 16:58:56 -0400 Subject: [PATCH 03/22] Check docs example links locally --- cuda_bindings/docs/build_docs.sh | 14 +- cuda_bindings/docs/source/conf.py | 1 + cuda_core/docs/build_docs.sh | 14 +- cuda_core/docs/source/conf.py | 5 + cuda_core/docs/source/release/0.3.1-notes.rst | 6 +- cuda_pathfinder/docs/build_docs.sh | 14 +- cuda_python/docs/check_example_links.py | 125 ++++++++++++++++++ 7 files changed, 167 insertions(+), 12 deletions(-) create mode 100644 cuda_python/docs/check_example_links.py diff --git a/cuda_bindings/docs/build_docs.sh b/cuda_bindings/docs/build_docs.sh index ab52431c092..ca2f49b1036 100755 --- a/cuda_bindings/docs/build_docs.sh +++ b/cuda_bindings/docs/build_docs.sh @@ -38,10 +38,18 @@ fi SPHINXOPTS="${HTML_SPHINXOPTS}" make html if [[ "${DOCS_LINKCHECK:-0}" == "1" ]]; then - if [[ -z "${LINKCHECK_SPHINXOPTS:-}" ]]; then - LINKCHECK_SPHINXOPTS="-W --keep-going -j 4 -d build/.linkcheck-doctrees" + if [[ -n "${CUDA_PYTHON_DOCS_GITHUB_REF:-}" ]]; then + DOCS_EXAMPLES_REF="${CUDA_PYTHON_DOCS_GITHUB_REF}" + elif [[ "${BUILD_PREVIEW:-0}" == "1" || "${BUILD_LATEST:-0}" == "1" ]]; then + DOCS_EXAMPLES_REF="main" + else + DOCS_EXAMPLES_REF="v${SPHINX_CUDA_BINDINGS_VER}" fi - SPHINXOPTS="${LINKCHECK_SPHINXOPTS}" make linkcheck BUILDDIR="build/linkcheck/${SPHINX_CUDA_BINDINGS_VER}" + python ../../cuda_python/docs/check_example_links.py \ + --source-dir source \ + --examples-root cuda_bindings/examples \ + --expected-ref "${DOCS_EXAMPLES_REF}" \ + --placeholder cuda_bindings_github_ref fi # for debugging/developing (conf.py), please comment out the above line and diff --git a/cuda_bindings/docs/source/conf.py b/cuda_bindings/docs/source/conf.py index 45344cc4710..297815a2956 100644 --- a/cuda_bindings/docs/source/conf.py +++ b/cuda_bindings/docs/source/conf.py @@ -133,6 +133,7 @@ def _github_examples_ref(): def rewrite_source(app, docname, source): text = source[0] + text = text.replace("|cuda_bindings_github_ref|", GITHUB_EXAMPLES_REF) if docname.startswith("release/"): text = text.replace(".. module:: cuda.bindings\n\n", "", 1) diff --git a/cuda_core/docs/build_docs.sh b/cuda_core/docs/build_docs.sh index d723a8bdbfe..0b14c3f4369 100755 --- a/cuda_core/docs/build_docs.sh +++ b/cuda_core/docs/build_docs.sh @@ -38,10 +38,18 @@ SPHINXOPTS="${HTML_SPHINXOPTS}" make html if [[ "${DOCS_LINKCHECK:-0}" == "1" ]]; then - if [[ -z "${LINKCHECK_SPHINXOPTS:-}" ]]; then - LINKCHECK_SPHINXOPTS="-W --keep-going -j 4 -d build/.linkcheck-doctrees" + if [[ -n "${CUDA_PYTHON_DOCS_GITHUB_REF:-}" ]]; then + DOCS_EXAMPLES_REF="${CUDA_PYTHON_DOCS_GITHUB_REF}" + elif [[ "${BUILD_PREVIEW:-0}" == "1" || "${BUILD_LATEST:-0}" == "1" ]]; then + DOCS_EXAMPLES_REF="main" + else + DOCS_EXAMPLES_REF="cuda-core-v${SPHINX_CUDA_CORE_VER}" fi - SPHINXOPTS="${LINKCHECK_SPHINXOPTS}" make linkcheck BUILDDIR="build/linkcheck/${SPHINX_CUDA_CORE_VER}" + python ../../cuda_python/docs/check_example_links.py \ + --source-dir source \ + --examples-root cuda_core/examples \ + --expected-ref "${DOCS_EXAMPLES_REF}" \ + --placeholder cuda_core_github_ref fi # to support version dropdown menu diff --git a/cuda_core/docs/source/conf.py b/cuda_core/docs/source/conf.py index 0549d3f0dcf..28d0f6add6a 100644 --- a/cuda_core/docs/source/conf.py +++ b/cuda_core/docs/source/conf.py @@ -200,6 +200,11 @@ def skip_member(app, what, name, obj, skip, options): return None +def rewrite_source(app, docname, source): + source[0] = source[0].replace("|cuda_core_github_ref|", GITHUB_EXAMPLES_REF) + + def setup(app): app.connect("autodoc-process-docstring", autodoc_process_docstring) app.connect("autodoc-skip-member", skip_member) + app.connect("source-read", rewrite_source) diff --git a/cuda_core/docs/source/release/0.3.1-notes.rst b/cuda_core/docs/source/release/0.3.1-notes.rst index 82138763db2..6783011d731 100644 --- a/cuda_core/docs/source/release/0.3.1-notes.rst +++ b/cuda_core/docs/source/release/0.3.1-notes.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: Apache-2.0 .. currentmodule:: cuda.core.experimental @@ -31,8 +31,8 @@ None. New examples ------------ -- Add a `CUDA graph `_ example. -- Add a `memory resource `_ example. +- Add a `CUDA graph `_ example. +- Add a `memory resource `_ example. Fixes and enhancements diff --git a/cuda_pathfinder/docs/build_docs.sh b/cuda_pathfinder/docs/build_docs.sh index 7e1ae3992c7..598a51249b4 100755 --- a/cuda_pathfinder/docs/build_docs.sh +++ b/cuda_pathfinder/docs/build_docs.sh @@ -38,10 +38,18 @@ fi SPHINXOPTS="${HTML_SPHINXOPTS}" make html if [[ "${DOCS_LINKCHECK:-0}" == "1" ]]; then - if [[ -z "${LINKCHECK_SPHINXOPTS:-}" ]]; then - LINKCHECK_SPHINXOPTS="-W --keep-going -j 4 -d build/.linkcheck-doctrees" + if [[ -n "${CUDA_PYTHON_DOCS_GITHUB_REF:-}" ]]; then + DOCS_EXAMPLES_REF="${CUDA_PYTHON_DOCS_GITHUB_REF}" + elif [[ "${BUILD_PREVIEW:-0}" == "1" || "${BUILD_LATEST:-0}" == "1" ]]; then + DOCS_EXAMPLES_REF="main" + else + DOCS_EXAMPLES_REF="cuda-pathfinder-v${SPHINX_CUDA_PATHFINDER_VER}" fi - SPHINXOPTS="${LINKCHECK_SPHINXOPTS}" make linkcheck BUILDDIR="build/linkcheck/${SPHINX_CUDA_PATHFINDER_VER}" + python ../../cuda_python/docs/check_example_links.py \ + --source-dir source \ + --examples-root cuda_pathfinder/examples \ + --expected-ref "${DOCS_EXAMPLES_REF}" \ + --allow-empty fi # for debugging/developing (conf.py), please comment out the above line and diff --git a/cuda_python/docs/check_example_links.py b/cuda_python/docs/check_example_links.py new file mode 100644 index 00000000000..5f76c412ea7 --- /dev/null +++ b/cuda_python/docs/check_example_links.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 + +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE + +from __future__ import annotations + +import argparse +import re +import sys +from pathlib import Path +from urllib.parse import unquote + +CUDA_PYTHON_URL_RE = re.compile( + r"https://github\.com/NVIDIA/cuda-python/" + r"(?Pblob|tree)/" + r"(?P[^/\s<>`]+)/" + r"(?P[^\s<>`)]+)" +) +SOURCE_SUFFIXES = {".md", ".rst"} + + +def _source_files(source_dir: Path): + for path in sorted(source_dir.rglob("*")): + if path.suffix in SOURCE_SUFFIXES and path.is_file(): + yield path + + +def _normalize_url_path(url_path: str) -> str: + path = unquote(url_path) + for separator in ("#", "?"): + path = path.split(separator, 1)[0] + return path.rstrip(".") + + +def _is_within(path: str, root: str) -> bool: + return path == root or path.startswith(f"{root}/") + + +def _display_path(path: Path, repo_root: Path) -> str: + try: + return str(path.relative_to(repo_root)) + except ValueError: + return str(path) + + +def check_links(args: argparse.Namespace) -> int: + repo_root = args.repo_root.resolve() + source_dir = args.source_dir.resolve() + examples_root = args.examples_root.strip("/") + placeholder_ref = f"|{args.placeholder}|" if args.placeholder else None + checked = 0 + failures: list[str] = [] + + for source_path in _source_files(source_dir): + text = source_path.read_text(encoding="utf-8") + for match in CUDA_PYTHON_URL_RE.finditer(text): + url_path = _normalize_url_path(match.group("path")) + if not _is_within(url_path, examples_root): + continue + + checked += 1 + ref = match.group("ref") + kind = match.group("kind") + location = _display_path(source_path, repo_root) + target_path = Path(url_path) + target = repo_root / target_path + + if target_path.is_absolute() or ".." in target_path.parts: + failures.append(f"{location}: invalid repository path in {match.group(0)}") + continue + + if placeholder_ref and ref == placeholder_ref: + rendered_ref = args.expected_ref + elif ref == args.expected_ref: + rendered_ref = ref + else: + expected = placeholder_ref or args.expected_ref + failures.append(f"{location}: {match.group(0)} uses ref {ref!r}; expected {expected!r}") + rendered_ref = ref + + if kind == "blob" and not target.is_file(): + failures.append( + f"{location}: {match.group(0)} resolves to missing file " + f"{target.relative_to(repo_root)} at ref {rendered_ref}" + ) + elif kind == "tree" and not target.is_dir(): + failures.append( + f"{location}: {match.group(0)} resolves to missing directory " + f"{target.relative_to(repo_root)} at ref {rendered_ref}" + ) + + if checked == 0 and not args.allow_empty: + failures.append(f"No example links under {examples_root!r} found in {source_dir}") + + if failures: + sys.stderr.write("Example link check failed:\n") + for failure in failures: + sys.stderr.write(f" - {failure}\n") + return 1 + + sys.stdout.write(f"Checked {checked} example link(s) under {examples_root} against ref {args.expected_ref}\n") + return 0 + + +def parse_args(argv: list[str]) -> argparse.Namespace: + repo_root = Path(__file__).resolve().parents[2] + + parser = argparse.ArgumentParser(description="Validate cuda-python example links without probing GitHub.") + parser.add_argument("--source-dir", type=Path, required=True) + parser.add_argument("--examples-root", required=True) + parser.add_argument("--expected-ref", required=True) + parser.add_argument("--placeholder") + parser.add_argument("--repo-root", type=Path, default=repo_root) + parser.add_argument("--allow-empty", action="store_true") + return parser.parse_args(argv) + + +def main(argv: list[str] | None = None) -> int: + args = parse_args(sys.argv[1:] if argv is None else argv) + return check_links(args) + + +if __name__ == "__main__": + raise SystemExit(main()) From 3c880e665ca02f3866ee6af2683bb0775b6662e1 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 11:03:23 -0400 Subject: [PATCH 04/22] Add lychee docs link checking --- .gitignore | 1 + .pre-commit-config.yaml | 12 ++++++++++++ cuda_bindings/docs/source/conduct.rst | 4 ++-- cuda_bindings/docs/source/motivation.rst | 4 ++-- cuda_bindings/docs/source/overview.rst | 8 +++++--- cuda_bindings/docs/source/release/11.7.1-notes.rst | 4 +++- cuda_bindings/docs/source/release/11.8.0-notes.rst | 4 ++-- cuda_bindings/docs/source/release/12.9.6-notes.rst | 2 +- cuda_bindings/docs/source/release/13.1.1-notes.rst | 4 ++-- cuda_bindings/docs/source/release/13.2.0-notes.rst | 2 +- cuda_bindings/docs/source/support.rst | 4 ++-- cuda_core/docs/source/conduct.rst | 4 ++-- cuda_python/docs/source/release/12.9.5-notes.rst | 4 ++-- cuda_python/docs/source/release/12.9.6-notes.rst | 2 +- 14 files changed, 38 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 26f13b1d174..e15f36ccc46 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ __pycache__/ # CUDA Python specific .cache/ +.lycheecache .pytest_cache/ .benchmarks/ *.cpp diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 25fb48eca34..2fd4e8d8365 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -53,6 +53,18 @@ repos: - stubgen-pyx==0.2.6 - Cython==3.2.4 + # Link checking for authored documentation files + - repo: https://github.com/lycheeverse/lychee + rev: 2bba271688c1abb1503097a064e6c3bc1d1b6a9b # frozen: lychee-v0.24.2 + hooks: + - id: lychee + args: + - --cache + - --max-concurrency=4 + - --max-retries=3 + - --no-progress + files: '\.(md|rst)$' + # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks rev: "3e8a8703264a2f4a69428a0aa4dcb512790b2c8c" # frozen: v6.0.0 diff --git a/cuda_bindings/docs/source/conduct.rst b/cuda_bindings/docs/source/conduct.rst index b70d9dd7ce3..26d3f1e59f9 100644 --- a/cuda_bindings/docs/source/conduct.rst +++ b/cuda_bindings/docs/source/conduct.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE Code of Conduct @@ -85,7 +85,7 @@ Attribution ----------- This Code of Conduct is adapted from the `Contributor Covenant `_, version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct/ For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq diff --git a/cuda_bindings/docs/source/motivation.rst b/cuda_bindings/docs/source/motivation.rst index 433cc166193..16bfd9745af 100644 --- a/cuda_bindings/docs/source/motivation.rst +++ b/cuda_bindings/docs/source/motivation.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE Motivation @@ -31,7 +31,7 @@ you get the best of both worlds: rapid iterative development with Python and the speed of a compiled language targeting both CPUs and NVIDIA GPUs. `CuPy `_ is a -`NumPy `_/`SciPy `_ compatible Array +`NumPy `_/`SciPy `_ compatible Array library, from `Preferred Networks `_, for GPU-accelerated computing with Python. CUDA Python simplifies the CuPy build and allows for a faster and smaller memory footprint when importing the CuPy diff --git a/cuda_bindings/docs/source/overview.rst b/cuda_bindings/docs/source/overview.rst index e0d269cb6b6..8ada38bfd22 100644 --- a/cuda_bindings/docs/source/overview.rst +++ b/cuda_bindings/docs/source/overview.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE Overview @@ -38,8 +38,8 @@ The first thing to do is import the `Driver API `_ and `NVRTC `_ modules from the ``cuda.bindings`` package. Next, we consider how to store host data and pass it to the device. Different -approaches can be used to accomplish this and are described in `Preparing kernel -arguments `_. +approaches can be used to accomplish this and are described in +:ref:`Preparing kernel arguments `. In this example, we will use NumPy to store host data and pass it to the device, so let's import this dependency as well. @@ -308,6 +308,8 @@ maximize performance ({numref}``Figure 1``). Screenshot of Nsight Compute CLI output of ``cuda.bindings`` example. +.. _preparing-kernel-arguments: + Preparing kernel arguments -------------------------- diff --git a/cuda_bindings/docs/source/release/11.7.1-notes.rst b/cuda_bindings/docs/source/release/11.7.1-notes.rst index 0fbea248e36..385cfb6e233 100644 --- a/cuda_bindings/docs/source/release/11.7.1-notes.rst +++ b/cuda_bindings/docs/source/release/11.7.1-notes.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE CUDA Python 11.7.1 Release notes @@ -14,6 +14,8 @@ Highlights Limitations ----------- +.. _cuda-bindings-11-7-1-source-builds: + Source builds ^^^^^^^^^^^^^ diff --git a/cuda_bindings/docs/source/release/11.8.0-notes.rst b/cuda_bindings/docs/source/release/11.8.0-notes.rst index e24022142df..68e40bc325d 100644 --- a/cuda_bindings/docs/source/release/11.8.0-notes.rst +++ b/cuda_bindings/docs/source/release/11.8.0-notes.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE CUDA Python 11.8.0 Release notes @@ -16,7 +16,7 @@ Highlights Source Builds ^^^^^^^^^^^^^ -CUDA Python source builds now parse CUDA headers located in $CUDA_HOME directory, enabling/disabling types and APIs if defined. Therefore this removes the need for CTK headers to have all types defined. By allowing minor variations, previous `11.7.1 mobile platform workaround `_ is no longer needed. +CUDA Python source builds now parse CUDA headers located in $CUDA_HOME directory, enabling/disabling types and APIs if defined. Therefore this removes the need for CTK headers to have all types defined. By allowing minor variations, previous :ref:`11.7.1 mobile platform workaround ` is no longer needed. It's still required that source builds use the latest CTK headers (i.e. “$CUDA_HOME/include” has latest CTK headers). diff --git a/cuda_bindings/docs/source/release/12.9.6-notes.rst b/cuda_bindings/docs/source/release/12.9.6-notes.rst index dd508ff1478..2ba5f3d96f8 100644 --- a/cuda_bindings/docs/source/release/12.9.6-notes.rst +++ b/cuda_bindings/docs/source/release/12.9.6-notes.rst @@ -31,7 +31,7 @@ Bugfixes * Fixed an issue where the ``CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL`` attribute was retrieved as an unsigned int, rather than a signed int. - (`PR #1336 `_) + (`PR #1336 `_) * Fixed a use-after-free in ``_HelperInputVoidPtr`` properties when backed by Python buffer objects. (`PR #1629 `_) diff --git a/cuda_bindings/docs/source/release/13.1.1-notes.rst b/cuda_bindings/docs/source/release/13.1.1-notes.rst index 37353cbe145..d4ef6af2d98 100644 --- a/cuda_bindings/docs/source/release/13.1.1-notes.rst +++ b/cuda_bindings/docs/source/release/13.1.1-notes.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE .. module:: cuda.bindings @@ -12,7 +12,7 @@ Highlights ---------- * Add missing driver & runtime bindings for functions new in CTK 13.1.0 - (`PR #1321 `_) + (`PR #1321 `_) Experimental ------------ diff --git a/cuda_bindings/docs/source/release/13.2.0-notes.rst b/cuda_bindings/docs/source/release/13.2.0-notes.rst index 4ea580c9c53..e470b896d52 100644 --- a/cuda_bindings/docs/source/release/13.2.0-notes.rst +++ b/cuda_bindings/docs/source/release/13.2.0-notes.rst @@ -39,7 +39,7 @@ Bugfixes * Fixed an issue where the ``CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL`` attribute was retrieved as an unsigned int, rather than a signed int. - (`PR #1336 `_) + (`PR #1336 `_) * Fixed ABI incompatibility bugs in cuFILE bindings introduced in v13.1.0. (`PR #1468 `_) * Fixed a use-after-free in ``_HelperInputVoidPtr`` properties when backed by diff --git a/cuda_bindings/docs/source/support.rst b/cuda_bindings/docs/source/support.rst index 4439d963c0e..0ed4d023efa 100644 --- a/cuda_bindings/docs/source/support.rst +++ b/cuda_bindings/docs/source/support.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE .. _support: @@ -38,7 +38,7 @@ The NVIDIA CUDA Python team reserves rights to amend the above support policy. A however, will be announced to the users in advance. -.. _CUDA minor version compatibility: https://docs.nvidia.com/deploy/cuda-compatibility/#minor-version-compatibility +.. _CUDA minor version compatibility: https://docs.nvidia.com/deploy/cuda-compatibility/minor-version-compatibility.html .. _CPython EOL schedule: https://devguide.python.org/versions/ .. _built-in modules that are known to be thread-unsafe: https://github.com/python/cpython/issues/116738 .. _free-threaded interpreter: https://docs.python.org/3/howto/free-threading-python.html diff --git a/cuda_core/docs/source/conduct.rst b/cuda_core/docs/source/conduct.rst index 1c00f5c3430..d6df40945a1 100644 --- a/cuda_core/docs/source/conduct.rst +++ b/cuda_core/docs/source/conduct.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: Apache-2.0 Code of Conduct @@ -85,7 +85,7 @@ Attribution ----------- This Code of Conduct is adapted from the `Contributor Covenant `_, version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct/ For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq diff --git a/cuda_python/docs/source/release/12.9.5-notes.rst b/cuda_python/docs/source/release/12.9.5-notes.rst index a134a36f00e..aac1dfa7929 100644 --- a/cuda_python/docs/source/release/12.9.5-notes.rst +++ b/cuda_python/docs/source/release/12.9.5-notes.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE CUDA Python 12.9.5 Release notes @@ -8,7 +8,7 @@ CUDA Python 12.9.5 Release notes Included components ------------------- -* `cuda.bindings 12.9.5 `_ +* `cuda.bindings 12.9.5 `_ * `cuda.pathfinder 1.3.3 `_ diff --git a/cuda_python/docs/source/release/12.9.6-notes.rst b/cuda_python/docs/source/release/12.9.6-notes.rst index 86ed747cfc7..b66e1e9ad50 100644 --- a/cuda_python/docs/source/release/12.9.6-notes.rst +++ b/cuda_python/docs/source/release/12.9.6-notes.rst @@ -7,7 +7,7 @@ CUDA Python 12.9.6 Release notes Included components ------------------- -* `cuda.bindings 12.9.6 `_ +* `cuda.bindings 12.9.6 `_ * `cuda.pathfinder 1.4.2 `_ Known issues From d6466e94800127f6b0cd2f4e521f6228945959b6 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 11:06:53 -0400 Subject: [PATCH 05/22] Skip lychee on pre-commit.ci --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2fd4e8d8365..40121b6f0fe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,6 +9,7 @@ ci: autoupdate_branch: '' autoupdate_commit_msg: '[pre-commit.ci] pre-commit autoupdate' autoupdate_schedule: quarterly + skip: [lychee] submodules: false # Please update the rev: SHAs below with this command: From ed504843b20f8ce88ebee058ffcecc7e77a68dc3 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 11:27:52 -0400 Subject: [PATCH 06/22] Check rendered doc preview links with lychee --- .github/workflows/build-docs.yml | 76 +++++++++++++- cuda_bindings/docs/build_docs.sh | 15 --- cuda_core/docs/build_docs.sh | 15 --- cuda_pathfinder/docs/build_docs.sh | 15 --- cuda_python/docs/check_example_links.py | 125 ------------------------ 5 files changed, 72 insertions(+), 174 deletions(-) delete mode 100644 cuda_python/docs/check_example_links.py diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 62895ff2a9b..eb7197ccc90 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -216,9 +216,9 @@ jobs: run: | pushd cuda_python/docs/ if [[ "${{ inputs.is-release }}" == "false" ]]; then - DOCS_LINKCHECK=1 ./build_all_docs.sh latest-only + ./build_all_docs.sh latest-only else - DOCS_LINKCHECK=1 ./build_all_docs.sh + ./build_all_docs.sh # At release time, we don't want to update the latest docs rm -rf build/html/latest fi @@ -232,9 +232,9 @@ jobs: COMPONENT=$(echo "${{ inputs.component }}" | tr '-' '_') pushd ${COMPONENT}/docs/ if [[ "${{ inputs.is-release }}" == "false" ]]; then - DOCS_LINKCHECK=1 ./build_docs.sh latest-only + ./build_docs.sh latest-only else - DOCS_LINKCHECK=1 ./build_docs.sh + ./build_docs.sh # At release time, we don't want to update the latest docs rm -rf build/html/latest fi @@ -248,6 +248,11 @@ jobs: fi mv ${COMPONENT}/docs/build/html/* artifacts/docs/${TARGET} + - name: Write doc preview marker + if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} + run: | + echo "${{ github.sha }}" > artifacts/docs/.preview-commit + # TODO: Consider removing this step? - name: Upload doc artifacts uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 @@ -263,6 +268,69 @@ jobs: 'artifacts/empty_docs' }} pr-number: ${{ env.PR_NUMBER }} + - name: Wait for doc preview deployment + if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} + env: + PREVIEW_URL: https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }} + run: | + marker_url="${PREVIEW_URL}/.preview-commit" + for attempt in {1..60}; do + marker=$(curl -fsSL "${marker_url}" || true) + if [[ "${marker}" == "${{ github.sha }}" ]]; then + echo "Doc preview is available at ${PREVIEW_URL}" + exit 0 + fi + echo "Waiting for doc preview marker ${marker_url} (${attempt}/60)" + sleep 10 + done + echo "error: doc preview marker did not update to ${{ github.sha }}" >&2 + exit 1 + + - name: Restore lychee cache + id: restore-lychee-cache + if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .lycheecache + key: docs-preview-lychee-${{ env.PR_NUMBER }}-${{ github.sha }} + restore-keys: | + docs-preview-lychee-${{ env.PR_NUMBER }}- + + - name: Check doc preview links + if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} + uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2 + with: + args: >- + --base-url https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }}/ + --root-dir ${{ github.workspace }}/artifacts/docs + --index-files index.html + --fallback-extensions html,htm + --include-fragments full + --cache + --max-cache-age 1d + --max-concurrency 16 + --host-concurrency 2 + --host-request-interval 250ms + --max-retries 3 + --retry-wait-time 5 + --timeout 30 + --no-progress + '${{ github.workspace }}/artifacts/docs/**/*.html' + fail: true + failIfEmpty: true + format: markdown + jobSummary: true + lycheeVersion: v0.24.2 + output: lychee-preview.md + token: ${{ github.token }} + + - name: Save lychee cache + if: ${{ always() && !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') && steps.restore-lychee-cache.outputs.cache-hit != 'true' && steps.restore-lychee-cache.outputs.cache-primary-key != '' }} + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .lycheecache + key: ${{ steps.restore-lychee-cache.outputs.cache-primary-key }} + - name: Deploy doc update if: ${{ github.ref_name == 'main' || inputs.is-release }} uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4.8.0 diff --git a/cuda_bindings/docs/build_docs.sh b/cuda_bindings/docs/build_docs.sh index ca2f49b1036..2ab1f086018 100755 --- a/cuda_bindings/docs/build_docs.sh +++ b/cuda_bindings/docs/build_docs.sh @@ -37,21 +37,6 @@ else fi SPHINXOPTS="${HTML_SPHINXOPTS}" make html -if [[ "${DOCS_LINKCHECK:-0}" == "1" ]]; then - if [[ -n "${CUDA_PYTHON_DOCS_GITHUB_REF:-}" ]]; then - DOCS_EXAMPLES_REF="${CUDA_PYTHON_DOCS_GITHUB_REF}" - elif [[ "${BUILD_PREVIEW:-0}" == "1" || "${BUILD_LATEST:-0}" == "1" ]]; then - DOCS_EXAMPLES_REF="main" - else - DOCS_EXAMPLES_REF="v${SPHINX_CUDA_BINDINGS_VER}" - fi - python ../../cuda_python/docs/check_example_links.py \ - --source-dir source \ - --examples-root cuda_bindings/examples \ - --expected-ref "${DOCS_EXAMPLES_REF}" \ - --placeholder cuda_bindings_github_ref -fi - # for debugging/developing (conf.py), please comment out the above line and # use the line below instead, as we must build in serial to avoid getting # obsecure Sphinx errors diff --git a/cuda_core/docs/build_docs.sh b/cuda_core/docs/build_docs.sh index 0b14c3f4369..28ae6dd07fd 100755 --- a/cuda_core/docs/build_docs.sh +++ b/cuda_core/docs/build_docs.sh @@ -37,21 +37,6 @@ fi SPHINXOPTS="${HTML_SPHINXOPTS}" make html -if [[ "${DOCS_LINKCHECK:-0}" == "1" ]]; then - if [[ -n "${CUDA_PYTHON_DOCS_GITHUB_REF:-}" ]]; then - DOCS_EXAMPLES_REF="${CUDA_PYTHON_DOCS_GITHUB_REF}" - elif [[ "${BUILD_PREVIEW:-0}" == "1" || "${BUILD_LATEST:-0}" == "1" ]]; then - DOCS_EXAMPLES_REF="main" - else - DOCS_EXAMPLES_REF="cuda-core-v${SPHINX_CUDA_CORE_VER}" - fi - python ../../cuda_python/docs/check_example_links.py \ - --source-dir source \ - --examples-root cuda_core/examples \ - --expected-ref "${DOCS_EXAMPLES_REF}" \ - --placeholder cuda_core_github_ref -fi - # to support version dropdown menu cp ./versions.json build/html cp ./nv-versions.json build/html diff --git a/cuda_pathfinder/docs/build_docs.sh b/cuda_pathfinder/docs/build_docs.sh index 598a51249b4..4720cd458f6 100755 --- a/cuda_pathfinder/docs/build_docs.sh +++ b/cuda_pathfinder/docs/build_docs.sh @@ -37,21 +37,6 @@ else fi SPHINXOPTS="${HTML_SPHINXOPTS}" make html -if [[ "${DOCS_LINKCHECK:-0}" == "1" ]]; then - if [[ -n "${CUDA_PYTHON_DOCS_GITHUB_REF:-}" ]]; then - DOCS_EXAMPLES_REF="${CUDA_PYTHON_DOCS_GITHUB_REF}" - elif [[ "${BUILD_PREVIEW:-0}" == "1" || "${BUILD_LATEST:-0}" == "1" ]]; then - DOCS_EXAMPLES_REF="main" - else - DOCS_EXAMPLES_REF="cuda-pathfinder-v${SPHINX_CUDA_PATHFINDER_VER}" - fi - python ../../cuda_python/docs/check_example_links.py \ - --source-dir source \ - --examples-root cuda_pathfinder/examples \ - --expected-ref "${DOCS_EXAMPLES_REF}" \ - --allow-empty -fi - # for debugging/developing (conf.py), please comment out the above line and # use the line below instead, as we must build in serial to avoid getting # obsecure Sphinx errors diff --git a/cuda_python/docs/check_example_links.py b/cuda_python/docs/check_example_links.py deleted file mode 100644 index 5f76c412ea7..00000000000 --- a/cuda_python/docs/check_example_links.py +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env python3 - -# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE - -from __future__ import annotations - -import argparse -import re -import sys -from pathlib import Path -from urllib.parse import unquote - -CUDA_PYTHON_URL_RE = re.compile( - r"https://github\.com/NVIDIA/cuda-python/" - r"(?Pblob|tree)/" - r"(?P[^/\s<>`]+)/" - r"(?P[^\s<>`)]+)" -) -SOURCE_SUFFIXES = {".md", ".rst"} - - -def _source_files(source_dir: Path): - for path in sorted(source_dir.rglob("*")): - if path.suffix in SOURCE_SUFFIXES and path.is_file(): - yield path - - -def _normalize_url_path(url_path: str) -> str: - path = unquote(url_path) - for separator in ("#", "?"): - path = path.split(separator, 1)[0] - return path.rstrip(".") - - -def _is_within(path: str, root: str) -> bool: - return path == root or path.startswith(f"{root}/") - - -def _display_path(path: Path, repo_root: Path) -> str: - try: - return str(path.relative_to(repo_root)) - except ValueError: - return str(path) - - -def check_links(args: argparse.Namespace) -> int: - repo_root = args.repo_root.resolve() - source_dir = args.source_dir.resolve() - examples_root = args.examples_root.strip("/") - placeholder_ref = f"|{args.placeholder}|" if args.placeholder else None - checked = 0 - failures: list[str] = [] - - for source_path in _source_files(source_dir): - text = source_path.read_text(encoding="utf-8") - for match in CUDA_PYTHON_URL_RE.finditer(text): - url_path = _normalize_url_path(match.group("path")) - if not _is_within(url_path, examples_root): - continue - - checked += 1 - ref = match.group("ref") - kind = match.group("kind") - location = _display_path(source_path, repo_root) - target_path = Path(url_path) - target = repo_root / target_path - - if target_path.is_absolute() or ".." in target_path.parts: - failures.append(f"{location}: invalid repository path in {match.group(0)}") - continue - - if placeholder_ref and ref == placeholder_ref: - rendered_ref = args.expected_ref - elif ref == args.expected_ref: - rendered_ref = ref - else: - expected = placeholder_ref or args.expected_ref - failures.append(f"{location}: {match.group(0)} uses ref {ref!r}; expected {expected!r}") - rendered_ref = ref - - if kind == "blob" and not target.is_file(): - failures.append( - f"{location}: {match.group(0)} resolves to missing file " - f"{target.relative_to(repo_root)} at ref {rendered_ref}" - ) - elif kind == "tree" and not target.is_dir(): - failures.append( - f"{location}: {match.group(0)} resolves to missing directory " - f"{target.relative_to(repo_root)} at ref {rendered_ref}" - ) - - if checked == 0 and not args.allow_empty: - failures.append(f"No example links under {examples_root!r} found in {source_dir}") - - if failures: - sys.stderr.write("Example link check failed:\n") - for failure in failures: - sys.stderr.write(f" - {failure}\n") - return 1 - - sys.stdout.write(f"Checked {checked} example link(s) under {examples_root} against ref {args.expected_ref}\n") - return 0 - - -def parse_args(argv: list[str]) -> argparse.Namespace: - repo_root = Path(__file__).resolve().parents[2] - - parser = argparse.ArgumentParser(description="Validate cuda-python example links without probing GitHub.") - parser.add_argument("--source-dir", type=Path, required=True) - parser.add_argument("--examples-root", required=True) - parser.add_argument("--expected-ref", required=True) - parser.add_argument("--placeholder") - parser.add_argument("--repo-root", type=Path, default=repo_root) - parser.add_argument("--allow-empty", action="store_true") - return parser.parse_args(argv) - - -def main(argv: list[str] | None = None) -> int: - args = parse_args(sys.argv[1:] if argv is None else argv) - return check_links(args) - - -if __name__ == "__main__": - raise SystemExit(main()) From 4a90b21636b0c8bfa0b1bd66e8cb3b45ee89cb2f Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 12:00:24 -0400 Subject: [PATCH 07/22] Fix doc preview wait step --- .github/workflows/build-docs.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index eb7197ccc90..493b6c10158 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -272,19 +272,24 @@ jobs: if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} env: PREVIEW_URL: https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }} + EXPECTED_SHA: ${{ github.sha }} run: | + preview_ready=0 marker_url="${PREVIEW_URL}/.preview-commit" for attempt in {1..60}; do marker=$(curl -fsSL "${marker_url}" || true) - if [[ "${marker}" == "${{ github.sha }}" ]]; then - echo "Doc preview is available at ${PREVIEW_URL}" - exit 0 + if [[ "${marker}" == "${EXPECTED_SHA}" ]]; then + preview_ready=1 + break fi echo "Waiting for doc preview marker ${marker_url} (${attempt}/60)" sleep 10 done - echo "error: doc preview marker did not update to ${{ github.sha }}" >&2 - exit 1 + if [[ "${preview_ready}" != "1" ]]; then + echo "error: doc preview marker did not update to ${EXPECTED_SHA}" >&2 + exit 1 + fi + echo "Doc preview is available at ${PREVIEW_URL}" - name: Restore lychee cache id: restore-lychee-cache From 8833364aece48cf2f9fb77a97933285deb73e43d Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 12:30:30 -0400 Subject: [PATCH 08/22] Use lychee-action default binary --- .github/workflows/build-docs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 493b6c10158..97900262e3a 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -325,7 +325,6 @@ jobs: failIfEmpty: true format: markdown jobSummary: true - lycheeVersion: v0.24.2 output: lychee-preview.md token: ${{ github.token }} From 451cdb1120f4e1b5e0b0c2ce732a83cf5e27879a Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 12:42:07 -0400 Subject: [PATCH 09/22] Address docs review comments --- cuda_bindings/docs/source/conf.py | 7 +------ cuda_bindings/docs/source/release/12.9.6-notes.rst | 2 +- cuda_bindings/docs/source/release/13.1.1-notes.rst | 2 +- cuda_bindings/docs/source/release/13.2.0-notes.rst | 2 +- cuda_core/docs/source/conf.py | 5 ----- 5 files changed, 4 insertions(+), 14 deletions(-) diff --git a/cuda_bindings/docs/source/conf.py b/cuda_bindings/docs/source/conf.py index 297815a2956..1e27205feeb 100644 --- a/cuda_bindings/docs/source/conf.py +++ b/cuda_bindings/docs/source/conf.py @@ -132,13 +132,8 @@ def _github_examples_ref(): def rewrite_source(app, docname, source): - text = source[0] - text = text.replace("|cuda_bindings_github_ref|", GITHUB_EXAMPLES_REF) - if docname.startswith("release/"): - text = text.replace(".. module:: cuda.bindings\n\n", "", 1) - - source[0] = text + source[0] = source[0].replace(".. module:: cuda.bindings\n\n", "", 1) suppress_warnings = [ diff --git a/cuda_bindings/docs/source/release/12.9.6-notes.rst b/cuda_bindings/docs/source/release/12.9.6-notes.rst index 2ba5f3d96f8..d24671700bf 100644 --- a/cuda_bindings/docs/source/release/12.9.6-notes.rst +++ b/cuda_bindings/docs/source/release/12.9.6-notes.rst @@ -31,7 +31,7 @@ Bugfixes * Fixed an issue where the ``CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL`` attribute was retrieved as an unsigned int, rather than a signed int. - (`PR #1336 `_) + (`PR #1451 `_) * Fixed a use-after-free in ``_HelperInputVoidPtr`` properties when backed by Python buffer objects. (`PR #1629 `_) diff --git a/cuda_bindings/docs/source/release/13.1.1-notes.rst b/cuda_bindings/docs/source/release/13.1.1-notes.rst index d4ef6af2d98..4725fe570c6 100644 --- a/cuda_bindings/docs/source/release/13.1.1-notes.rst +++ b/cuda_bindings/docs/source/release/13.1.1-notes.rst @@ -12,7 +12,7 @@ Highlights ---------- * Add missing driver & runtime bindings for functions new in CTK 13.1.0 - (`PR #1321 `_) + (`PR #1337 `_) Experimental ------------ diff --git a/cuda_bindings/docs/source/release/13.2.0-notes.rst b/cuda_bindings/docs/source/release/13.2.0-notes.rst index e470b896d52..71d2e13e562 100644 --- a/cuda_bindings/docs/source/release/13.2.0-notes.rst +++ b/cuda_bindings/docs/source/release/13.2.0-notes.rst @@ -39,7 +39,7 @@ Bugfixes * Fixed an issue where the ``CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL`` attribute was retrieved as an unsigned int, rather than a signed int. - (`PR #1336 `_) + (`PR #1451 `_) * Fixed ABI incompatibility bugs in cuFILE bindings introduced in v13.1.0. (`PR #1468 `_) * Fixed a use-after-free in ``_HelperInputVoidPtr`` properties when backed by diff --git a/cuda_core/docs/source/conf.py b/cuda_core/docs/source/conf.py index 28d0f6add6a..0549d3f0dcf 100644 --- a/cuda_core/docs/source/conf.py +++ b/cuda_core/docs/source/conf.py @@ -200,11 +200,6 @@ def skip_member(app, what, name, obj, skip, options): return None -def rewrite_source(app, docname, source): - source[0] = source[0].replace("|cuda_core_github_ref|", GITHUB_EXAMPLES_REF) - - def setup(app): app.connect("autodoc-process-docstring", autodoc_process_docstring) app.connect("autodoc-skip-member", skip_member) - app.connect("source-read", rewrite_source) From fbc91e29f9beb7a436008017561fb03107f2a2f1 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 13:26:39 -0400 Subject: [PATCH 10/22] Use fixed lychee-action revision --- .github/workflows/build-docs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 97900262e3a..4d36691783a 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -303,7 +303,7 @@ jobs: - name: Check doc preview links if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} - uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2 + uses: lycheeverse/lychee-action@6da1d14f3a43098a294b7696d93d938aa8d20fc0 # unreleased: supports v0.24.x archive layout with: args: >- --base-url https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }}/ @@ -325,6 +325,7 @@ jobs: failIfEmpty: true format: markdown jobSummary: true + lycheeVersion: v0.24.2 output: lychee-preview.md token: ${{ github.token }} From a1ff9845ea50877323fdf2507422f917d0faf495 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 13:56:47 -0400 Subject: [PATCH 11/22] Fix lychee fragment option syntax --- .github/workflows/build-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 4d36691783a..d013b3536cf 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -310,7 +310,7 @@ jobs: --root-dir ${{ github.workspace }}/artifacts/docs --index-files index.html --fallback-extensions html,htm - --include-fragments full + --include-fragments=full --cache --max-cache-age 1d --max-concurrency 16 From 1bbd30a7d7ab2572224f9535cd8ff8a038995296 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 16:07:41 -0400 Subject: [PATCH 12/22] Check deployed docs preview links --- .github/workflows/build-docs.yml | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index d013b3536cf..a43de8b7047 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -301,15 +301,26 @@ jobs: restore-keys: | docs-preview-lychee-${{ env.PR_NUMBER }}- + - name: Write lychee doc preview URL list + if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} + env: + PREVIEW_URL: https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }} + run: | + find "${GITHUB_WORKSPACE}/artifacts/docs" -type f -name '*.html' -printf '%P\n' \ + | LC_ALL=C sort \ + | sed "s#^#${PREVIEW_URL}/#" > lychee-preview-urls.txt + if [[ ! -s lychee-preview-urls.txt ]]; then + echo "error: no rendered HTML pages found for lychee" >&2 + exit 1 + fi + wc -l lychee-preview-urls.txt + - name: Check doc preview links if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} uses: lycheeverse/lychee-action@6da1d14f3a43098a294b7696d93d938aa8d20fc0 # unreleased: supports v0.24.x archive layout with: args: >- - --base-url https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }}/ - --root-dir ${{ github.workspace }}/artifacts/docs - --index-files index.html - --fallback-extensions html,htm + --files-from ${{ github.workspace }}/lychee-preview-urls.txt --include-fragments=full --cache --max-cache-age 1d @@ -320,11 +331,10 @@ jobs: --retry-wait-time 5 --timeout 30 --no-progress - '${{ github.workspace }}/artifacts/docs/**/*.html' fail: true failIfEmpty: true format: markdown - jobSummary: true + jobSummary: false lycheeVersion: v0.24.2 output: lychee-preview.md token: ${{ github.token }} From 14c70d0ec19abb70f74cbe6c5be3c11b96fb826d Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 2 Jun 2026 17:03:19 -0400 Subject: [PATCH 13/22] Fix rendered docs linkcheck failures --- .github/workflows/build-docs.yml | 2 +- cuda_bindings/docs/source/conf.py | 11 +++++++- cuda_bindings/docs/source/install.rst | 4 +-- cuda_bindings/docs/source/module/driver.rst | 14 +++++----- cuda_bindings/docs/source/module/runtime.rst | 10 +++---- cuda_core/docs/source/conf.py | 12 ++++++++- cuda_core/docs/source/examples.rst | 26 +++++++++---------- cuda_core/docs/source/getting-started.rst | 4 +-- cuda_core/docs/source/interoperability.rst | 6 ++--- cuda_core/docs/source/release/0.3.1-notes.rst | 4 +-- cuda_pathfinder/docs/source/conf.py | 13 ++++++++-- cuda_python/docs/build_docs.sh | 6 ++++- cuda_python/docs/source/conf.py | 13 ++++++++-- 13 files changed, 83 insertions(+), 42 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index a43de8b7047..4f030206398 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -306,7 +306,7 @@ jobs: env: PREVIEW_URL: https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }} run: | - find "${GITHUB_WORKSPACE}/artifacts/docs" -type f -name '*.html' -printf '%P\n' \ + find "${GITHUB_WORKSPACE}/artifacts/docs" -type f -name '*.html' ! -path '*/_static/*' -printf '%P\n' \ | LC_ALL=C sort \ | sed "s#^#${PREVIEW_URL}/#" > lychee-preview-urls.txt if [[ ! -s lychee-preview-urls.txt ]]; then diff --git a/cuda_bindings/docs/source/conf.py b/cuda_bindings/docs/source/conf.py index 1e27205feeb..64f28ace24d 100644 --- a/cuda_bindings/docs/source/conf.py +++ b/cuda_bindings/docs/source/conf.py @@ -37,6 +37,15 @@ def _github_examples_ref(): GITHUB_EXAMPLES_REF = _github_examples_ref() +def _html_baseurl(): + docs_domain = os.environ.get("CUDA_PYTHON_DOCS_DOMAIN", "https://nvidia.github.io/cuda-python") + if int(os.environ.get("BUILD_PREVIEW", 0)): + return f"{docs_domain}/pr-preview/pr-{os.environ['PR_NUMBER']}/cuda-bindings/latest/" + if int(os.environ.get("BUILD_LATEST", 0)): + return f"{docs_domain}/cuda-bindings/latest/" + return f"{docs_domain}/cuda-bindings/{release}/" + + # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be @@ -76,7 +85,7 @@ def _github_examples_ref(): # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_baseurl = "docs" +html_baseurl = _html_baseurl() html_theme = "nvidia_sphinx_theme" html_theme_options = { "switcher": { diff --git a/cuda_bindings/docs/source/install.rst b/cuda_bindings/docs/source/install.rst index bb5a8585257..ce99255c133 100644 --- a/cuda_bindings/docs/source/install.rst +++ b/cuda_bindings/docs/source/install.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE Installation @@ -99,7 +99,7 @@ Source builds require that the provided CUDA headers are of the same major.minor $ export CUDA_PATH=/usr/local/cuda -See `Environment Variables `_ for a description of other build-time environment variables. +See :doc:`Environment Variables ` for a description of other build-time environment variables. .. note:: diff --git a/cuda_bindings/docs/source/module/driver.rst b/cuda_bindings/docs/source/module/driver.rst index 49c633aa074..020633665bf 100644 --- a/cuda_bindings/docs/source/module/driver.rst +++ b/cuda_bindings/docs/source/module/driver.rst @@ -406,25 +406,25 @@ Data types used by CUDA driver .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_GEQ - Wait until (int32_t)(*addr - value) >= 0 (or int64_t for 64 bit values). Note this is a cyclic comparison which ignores wraparound. (Default behavior.) + Wait until (int32_t)(\*addr - value) >= 0 (or int64_t for 64 bit values). Note this is a cyclic comparison which ignores wraparound. (Default behavior.) .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_EQ - Wait until *addr == value. + Wait until \*addr == value. .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_AND - Wait until (*addr & value) != 0. + Wait until (\*addr & value) != 0. .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_NOR - Wait until ~(*addr | value) != 0. Support for this operation can be queried with :py:obj:`~.cuDeviceGetAttribute()` and :py:obj:`~.CU_DEVICE_ATTRIBUTE_CAN_USE_STREAM_WAIT_VALUE_NOR`. + Wait until ~(\*addr | value) != 0. Support for this operation can be queried with :py:obj:`~.cuDeviceGetAttribute()` and :py:obj:`~.CU_DEVICE_ATTRIBUTE_CAN_USE_STREAM_WAIT_VALUE_NOR`. .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_FLUSH @@ -506,19 +506,19 @@ Data types used by CUDA driver .. autoattribute:: cuda.bindings.driver.CUstreamAtomicReductionOpType.CU_STREAM_ATOMIC_REDUCTION_OP_OR - Performs an atomic OR: *(address) = *(address) | value + Performs an atomic OR: \*(address) = \*(address) | value .. autoattribute:: cuda.bindings.driver.CUstreamAtomicReductionOpType.CU_STREAM_ATOMIC_REDUCTION_OP_AND - Performs an atomic AND: *(address) = *(address) & value + Performs an atomic AND: \*(address) = \*(address) & value .. autoattribute:: cuda.bindings.driver.CUstreamAtomicReductionOpType.CU_STREAM_ATOMIC_REDUCTION_OP_ADD - Performs an atomic ADD: *(address) = *(address) + value + Performs an atomic ADD: \*(address) = \*(address) + value .. autoclass:: cuda.bindings.driver.CUstreamAtomicReductionDataType diff --git a/cuda_bindings/docs/source/module/runtime.rst b/cuda_bindings/docs/source/module/runtime.rst index 5f7b5177560..4714cf8f13b 100644 --- a/cuda_bindings/docs/source/module/runtime.rst +++ b/cuda_bindings/docs/source/module/runtime.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +.. SPDX-FileCopyrightText: Copyright (c) 2021-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. .. SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE ------- @@ -299,7 +299,7 @@ Data types used by CUDA Runtime .. autoattribute:: cuda.bindings.runtime.cudaError_t.cudaErrorIncompatibleDriverContext - This indicates that the current context is not compatible with this the CUDA Runtime. This can only occur if you are using CUDA Runtime/Driver interoperability and have created an existing Driver context using the driver API. The Driver context may be incompatible either because the Driver context was created using an older version of the API, because the Runtime API call expects a primary driver context and the Driver context is not primary, or because the Driver context has been destroyed. Please see :py:obj:`~.Interactions`with the CUDA Driver API" for more information. + This indicates that the current context is not compatible with this the CUDA Runtime. This can only occur if you are using CUDA Runtime/Driver interoperability and have created an existing Driver context using the driver API. The Driver context may be incompatible either because the Driver context was created using an older version of the API, because the Runtime API call expects a primary driver context and the Driver context is not primary, or because the Driver context has been destroyed. Please see `Interactions with the CUDA Driver API`_ for more information. .. autoattribute:: cuda.bindings.runtime.cudaError_t.cudaErrorMissingConfiguration @@ -6403,11 +6403,11 @@ The types ::CUevent and cudaEvent_t are identical and may be used interchangeabl -The types ::CUarray and struct ::cudaArray * represent the same data type and may be used interchangeably by casting the two types between each other. +The types ``CUarray`` and ``struct cudaArray *`` represent the same data type and may be used interchangeably by casting the two types between each other. -In order to use a ::CUarray in a CUDA Runtime API function which takes a struct ::cudaArray *, it is necessary to explicitly cast the ::CUarray to a struct ::cudaArray *. +In order to use a ``CUarray`` in a CUDA Runtime API function which takes a ``struct cudaArray *``, it is necessary to explicitly cast the ``CUarray`` to a ``struct cudaArray *``. -In order to use a struct ::cudaArray * in a CUDA Driver API function which takes a ::CUarray, it is necessary to explicitly cast the struct ::cudaArray * to a ::CUarray . +In order to use a ``struct cudaArray *`` in a CUDA Driver API function which takes a ``CUarray``, it is necessary to explicitly cast the ``struct cudaArray *`` to a ``CUarray``. diff --git a/cuda_core/docs/source/conf.py b/cuda_core/docs/source/conf.py index 0549d3f0dcf..451eb8b4453 100644 --- a/cuda_core/docs/source/conf.py +++ b/cuda_core/docs/source/conf.py @@ -38,6 +38,15 @@ def _github_examples_ref(): GITHUB_EXAMPLES_REF = _github_examples_ref() +def _html_baseurl(): + docs_domain = os.environ.get("CUDA_PYTHON_DOCS_DOMAIN", "https://nvidia.github.io/cuda-python") + if int(os.environ.get("BUILD_PREVIEW", 0)): + return f"{docs_domain}/pr-preview/pr-{os.environ['PR_NUMBER']}/cuda-core/latest/" + if int(os.environ.get("BUILD_LATEST", 0)): + return f"{docs_domain}/cuda-core/latest/" + return f"{docs_domain}/cuda-core/{release}/" + + # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be @@ -46,6 +55,7 @@ def _github_examples_ref(): extensions = [ "sphinx.ext.autodoc", "sphinx.ext.autosummary", + "sphinx.ext.extlinks", "sphinx.ext.napoleon", "sphinx.ext.intersphinx", "sphinx.ext.extlinks", @@ -75,7 +85,7 @@ def _github_examples_ref(): # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_baseurl = "docs" +html_baseurl = _html_baseurl() html_theme = "nvidia_sphinx_theme" html_theme_options = { "switcher": { diff --git a/cuda_core/docs/source/examples.rst b/cuda_core/docs/source/examples.rst index e3b2ef8f3f5..cf13961c6dc 100644 --- a/cuda_core/docs/source/examples.rst +++ b/cuda_core/docs/source/examples.rst @@ -12,48 +12,48 @@ workflow. Compilation and kernel launch ----------------------------- -- :cuda-core-example:`vector_add.py` +- :cuda-core-example:`vector_add.py ` compiles and launches a simple vector-add kernel with CuPy arrays. -- :cuda-core-example:`saxpy.py` +- :cuda-core-example:`saxpy.py ` JIT-compiles a templated SAXPY kernel and launches both float and double instantiations. -- :cuda-core-example:`pytorch_example.py` +- :cuda-core-example:`pytorch_example.py ` launches a CUDA kernel with PyTorch tensors and a wrapped PyTorch stream. Multi-device and advanced launch configuration ---------------------------------------------- -- :cuda-core-example:`simple_multi_gpu_example.py` +- :cuda-core-example:`simple_multi_gpu_example.py ` compiles and launches kernels across multiple GPUs. -- :cuda-core-example:`thread_block_cluster.py` +- :cuda-core-example:`thread_block_cluster.py ` demonstrates thread block cluster launch configuration on Hopper-class GPUs. -- :cuda-core-example:`tma_tensor_map.py` +- :cuda-core-example:`tma_tensor_map.py ` demonstrates Tensor Memory Accelerator descriptors and TMA-based bulk copies. Linking and graphs ------------------ -- :cuda-core-example:`jit_lto_fractal.py` +- :cuda-core-example:`jit_lto_fractal.py ` uses JIT link-time optimization to link user-provided device code into a fractal workflow at runtime. -- :cuda-core-example:`cuda_graphs.py` +- :cuda-core-example:`cuda_graphs.py ` captures and replays a multi-kernel CUDA graph to reduce launch overhead. Interoperability and memory access ---------------------------------- -- :cuda-core-example:`memory_ops.py` +- :cuda-core-example:`memory_ops.py ` covers memory resources, pinned memory, device transfers, and DLPack interop. -- :cuda-core-example:`strided_memory_view_cpu.py` +- :cuda-core-example:`strided_memory_view_cpu.py ` uses ``StridedMemoryView`` with JIT-compiled CPU code via ``cffi``. -- :cuda-core-example:`strided_memory_view_gpu.py` +- :cuda-core-example:`strided_memory_view_gpu.py ` uses ``StridedMemoryView`` with JIT-compiled GPU code and foreign GPU buffers. -- :cuda-core-example:`gl_interop_plasma.py` +- :cuda-core-example:`gl_interop_plasma.py ` renders a CUDA-generated plasma effect through OpenGL interop without CPU copies. System inspection ----------------- -- :cuda-core-example:`show_device_properties.py` +- :cuda-core-example:`show_device_properties.py ` prints a detailed report of the CUDA devices available on the system. diff --git a/cuda_core/docs/source/getting-started.rst b/cuda_core/docs/source/getting-started.rst index fb2f0b22fcf..e03ce23782f 100644 --- a/cuda_core/docs/source/getting-started.rst +++ b/cuda_core/docs/source/getting-started.rst @@ -32,7 +32,7 @@ Example: Compiling and Launching a CUDA kernel ---------------------------------------------- To get a taste for ``cuda.core``, let's walk through a simple example that compiles and launches a vector addition kernel. -You can find the complete example in :cuda-core-example:`vector_add.py` +You can find the complete example in :cuda-core-example:`vector_add.py ` and browse the :doc:`examples page ` for the rest of the shipped workflows. @@ -80,7 +80,7 @@ Note the use of the ``name_expressions`` parameter to the :meth:`Program.compile Next, we retrieve the compiled kernel from the CUBIN and prepare the arguments and kernel configuration. We're using `CuPy `_ arrays as inputs for this example, but you can use PyTorch tensors too (see -:cuda-core-example:`pytorch_example.py` +:cuda-core-example:`pytorch_example.py ` and the :doc:`examples page `). .. code-block:: python diff --git a/cuda_core/docs/source/interoperability.rst b/cuda_core/docs/source/interoperability.rst index 4aa155ce5f9..87347eb9d25 100644 --- a/cuda_core/docs/source/interoperability.rst +++ b/cuda_core/docs/source/interoperability.rst @@ -70,11 +70,11 @@ a few iterations to ensure correctness. for extracting the metadata (such as pointer address, shape, strides, and dtype) from any Python objects supporting either CAI or DLPack and returning a :class:`~utils.StridedMemoryView` object. See the -:cuda-core-example:`strided_memory_view_constructors.py` +:cuda-core-example:`strided_memory_view_constructors.py ` example for the explicit constructors, or -:cuda-core-example:`strided_memory_view_cpu.py` +:cuda-core-example:`strided_memory_view_cpu.py ` and -:cuda-core-example:`strided_memory_view_gpu.py` +:cuda-core-example:`strided_memory_view_gpu.py ` for decorator-based workflows. This provides a *concrete implementation* to both protocols that is **array-library-agnostic**, so that all Python projects can just rely on this without either re-implementing (the consumer-side of) diff --git a/cuda_core/docs/source/release/0.3.1-notes.rst b/cuda_core/docs/source/release/0.3.1-notes.rst index 6783011d731..8360d1b9eb7 100644 --- a/cuda_core/docs/source/release/0.3.1-notes.rst +++ b/cuda_core/docs/source/release/0.3.1-notes.rst @@ -31,8 +31,8 @@ None. New examples ------------ -- Add a `CUDA graph `_ example. -- Add a `memory resource `_ example. +- Add a :cuda-core-example:`CUDA graph ` example. +- Add a :cuda-core-example:`memory resource ` example. Fixes and enhancements diff --git a/cuda_pathfinder/docs/source/conf.py b/cuda_pathfinder/docs/source/conf.py index f794eb9ee2b..aa6cd964b54 100644 --- a/cuda_pathfinder/docs/source/conf.py +++ b/cuda_pathfinder/docs/source/conf.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2012-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2012-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # Configuration file for the Sphinx documentation builder. @@ -26,6 +26,15 @@ release = os.environ["SPHINX_CUDA_PATHFINDER_VER"] +def _html_baseurl(): + docs_domain = os.environ.get("CUDA_PYTHON_DOCS_DOMAIN", "https://nvidia.github.io/cuda-python") + if int(os.environ.get("BUILD_PREVIEW", 0)): + return f"{docs_domain}/pr-preview/pr-{os.environ['PR_NUMBER']}/cuda-pathfinder/latest/" + if int(os.environ.get("BUILD_LATEST", 0)): + return f"{docs_domain}/cuda-pathfinder/latest/" + return f"{docs_domain}/cuda-pathfinder/{release}/" + + # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be @@ -65,7 +74,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_baseurl = "docs" +html_baseurl = _html_baseurl() html_theme = "nvidia_sphinx_theme" html_theme_options = { "switcher": { diff --git a/cuda_python/docs/build_docs.sh b/cuda_python/docs/build_docs.sh index 97be962a1a9..528b1c15c3a 100755 --- a/cuda_python/docs/build_docs.sh +++ b/cuda_python/docs/build_docs.sh @@ -1,6 +1,6 @@ #!/bin/bash -# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE set -ex @@ -25,6 +25,10 @@ if [[ -z "${SPHINX_CUDA_PYTHON_VER}" ]]; then | awk -F'+' '{print $1}') fi +if [[ "${LATEST_ONLY}" == "1" && -z "${BUILD_PREVIEW:-}" && -z "${BUILD_LATEST:-}" ]]; then + export BUILD_LATEST=1 +fi + # build the docs (in parallel) SPHINXOPTS="-j 4 -d build/.doctrees" make html diff --git a/cuda_python/docs/source/conf.py b/cuda_python/docs/source/conf.py index 454cec49732..1b1932be711 100644 --- a/cuda_python/docs/source/conf.py +++ b/cuda_python/docs/source/conf.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright (c) 2021-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-FileCopyrightText: Copyright (c) 2021-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE # Configuration file for the Sphinx documentation builder. @@ -26,6 +26,15 @@ release = os.environ["SPHINX_CUDA_PYTHON_VER"] +def _html_baseurl(): + docs_domain = os.environ.get("CUDA_PYTHON_DOCS_DOMAIN", "https://nvidia.github.io/cuda-python") + if int(os.environ.get("BUILD_PREVIEW", 0)): + return f"{docs_domain}/pr-preview/pr-{os.environ['PR_NUMBER']}/latest/" + if int(os.environ.get("BUILD_LATEST", 0)): + return f"{docs_domain}/latest/" + return f"{docs_domain}/{release}/" + + # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be @@ -58,7 +67,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_baseurl = "docs" +html_baseurl = _html_baseurl() html_theme = "nvidia_sphinx_theme" html_theme_options = { "switcher": { From e7c5bac296eb2a4b7268ccc0abe5ecd66a5c317a Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Thu, 4 Jun 2026 12:50:32 -0400 Subject: [PATCH 14/22] Split rendered docs link check workflow --- .github/workflows/build-docs.yml | 97 ++++++------------------- .github/workflows/check-doc-links.yml | 100 ++++++++++++++++++++++++++ .github/workflows/ci.yml | 16 +++++ 3 files changed, 137 insertions(+), 76 deletions(-) create mode 100644 .github/workflows/check-doc-links.yml diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 4f030206398..0fa08246eb0 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -253,55 +253,7 @@ jobs: run: | echo "${{ github.sha }}" > artifacts/docs/.preview-commit - # TODO: Consider removing this step? - - name: Upload doc artifacts - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 - with: - path: artifacts/ - retention-days: 3 - - - name: Deploy or clean up doc preview - if: ${{ !inputs.is-release }} - uses: ./.github/actions/doc_preview - with: - source-folder: ${{ (github.ref_name != 'main' && 'artifacts/docs') || - 'artifacts/empty_docs' }} - pr-number: ${{ env.PR_NUMBER }} - - - name: Wait for doc preview deployment - if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} - env: - PREVIEW_URL: https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }} - EXPECTED_SHA: ${{ github.sha }} - run: | - preview_ready=0 - marker_url="${PREVIEW_URL}/.preview-commit" - for attempt in {1..60}; do - marker=$(curl -fsSL "${marker_url}" || true) - if [[ "${marker}" == "${EXPECTED_SHA}" ]]; then - preview_ready=1 - break - fi - echo "Waiting for doc preview marker ${marker_url} (${attempt}/60)" - sleep 10 - done - if [[ "${preview_ready}" != "1" ]]; then - echo "error: doc preview marker did not update to ${EXPECTED_SHA}" >&2 - exit 1 - fi - echo "Doc preview is available at ${PREVIEW_URL}" - - - name: Restore lychee cache - id: restore-lychee-cache - if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} - uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 - with: - path: .lycheecache - key: docs-preview-lychee-${{ env.PR_NUMBER }}-${{ github.sha }} - restore-keys: | - docs-preview-lychee-${{ env.PR_NUMBER }}- - - - name: Write lychee doc preview URL list + - name: Write doc preview link-check URL list if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} env: PREVIEW_URL: https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }} @@ -315,36 +267,29 @@ jobs: fi wc -l lychee-preview-urls.txt - - name: Check doc preview links + - name: Upload doc preview link-check URL list if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} - uses: lycheeverse/lychee-action@6da1d14f3a43098a294b7696d93d938aa8d20fc0 # unreleased: supports v0.24.x archive layout + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: docs-preview-linkcheck-urls + path: lychee-preview-urls.txt + if-no-files-found: error + retention-days: 3 + + # TODO: Consider removing this step? + - name: Upload doc artifacts + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: - args: >- - --files-from ${{ github.workspace }}/lychee-preview-urls.txt - --include-fragments=full - --cache - --max-cache-age 1d - --max-concurrency 16 - --host-concurrency 2 - --host-request-interval 250ms - --max-retries 3 - --retry-wait-time 5 - --timeout 30 - --no-progress - fail: true - failIfEmpty: true - format: markdown - jobSummary: false - lycheeVersion: v0.24.2 - output: lychee-preview.md - token: ${{ github.token }} - - - name: Save lychee cache - if: ${{ always() && !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') && steps.restore-lychee-cache.outputs.cache-hit != 'true' && steps.restore-lychee-cache.outputs.cache-primary-key != '' }} - uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + path: artifacts/ + retention-days: 3 + + - name: Deploy or clean up doc preview + if: ${{ !inputs.is-release }} + uses: ./.github/actions/doc_preview with: - path: .lycheecache - key: ${{ steps.restore-lychee-cache.outputs.cache-primary-key }} + source-folder: ${{ (github.ref_name != 'main' && 'artifacts/docs') || + 'artifacts/empty_docs' }} + pr-number: ${{ env.PR_NUMBER }} - name: Deploy doc update if: ${{ github.ref_name == 'main' || inputs.is-release }} diff --git a/.github/workflows/check-doc-links.yml b/.github/workflows/check-doc-links.yml new file mode 100644 index 00000000000..b7a12ee08ee --- /dev/null +++ b/.github/workflows/check-doc-links.yml @@ -0,0 +1,100 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +name: "CI: Check rendered docs links" + +on: + workflow_call: + inputs: + url-artifact: + description: "Artifact containing the rendered doc preview URL list" + required: false + default: docs-preview-linkcheck-urls + type: string + +jobs: + check: + name: Check rendered docs links + if: ${{ github.repository_owner == 'nvidia' && startsWith(github.ref_name, 'pull-request/') }} + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + pull-requests: read + defaults: + run: + shell: bash -el {0} + steps: + - name: Checkout ${{ github.event.repository.name }} + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Get PR number + uses: ./.github/actions/get_pr_number + + - name: Download doc preview link-check URL list + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: ${{ inputs.url-artifact }} + path: linkcheck-input + + - name: Wait for doc preview deployment + env: + PREVIEW_URL: https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }} + EXPECTED_SHA: ${{ github.sha }} + run: | + preview_ready=0 + marker_url="${PREVIEW_URL}/.preview-commit" + for attempt in {1..60}; do + marker=$(curl -fsSL "${marker_url}" || true) + if [[ "${marker}" == "${EXPECTED_SHA}" ]]; then + preview_ready=1 + break + fi + echo "Waiting for doc preview marker ${marker_url} (${attempt}/60)" + sleep 10 + done + if [[ "${preview_ready}" != "1" ]]; then + echo "error: doc preview marker did not update to ${EXPECTED_SHA}" >&2 + exit 1 + fi + echo "Doc preview is available at ${PREVIEW_URL}" + + - name: Restore lychee cache + id: restore-lychee-cache + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .lycheecache + key: docs-preview-lychee-${{ env.PR_NUMBER }}-${{ github.sha }} + restore-keys: | + docs-preview-lychee-${{ env.PR_NUMBER }}- + + - name: Check doc preview links + uses: lycheeverse/lychee-action@6da1d14f3a43098a294b7696d93d938aa8d20fc0 # unreleased: supports v0.24.x archive layout + with: + args: >- + --files-from ${{ github.workspace }}/linkcheck-input/lychee-preview-urls.txt + --include-fragments=full + --cache + --max-cache-age 1d + --max-concurrency 16 + --host-concurrency 2 + --host-request-interval 250ms + --max-retries 3 + --retry-wait-time 5 + --timeout 30 + --no-progress + fail: true + failIfEmpty: true + format: markdown + jobSummary: false + lycheeVersion: v0.24.2 + output: lychee-preview.md + token: ${{ github.token }} + + - name: Save lychee cache + if: ${{ always() && steps.restore-lychee-cache.outputs.cache-hit != 'true' && steps.restore-lychee-cache.outputs.cache-primary-key != '' }} + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .lycheecache + key: ${{ steps.restore-lychee-cache.outputs.cache-primary-key }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b510ecffc8..0d52821c847 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -415,6 +415,18 @@ jobs: with: is-release: ${{ github.ref_type == 'tag' }} + doc-linkcheck: + name: Docs link check + if: ${{ github.repository_owner == 'nvidia' && startsWith(github.ref_name, 'pull-request/') && needs.doc.result == 'success' }} + permissions: + actions: read + contents: read + pull-requests: read + needs: + - doc + secrets: inherit + uses: ./.github/workflows/check-doc-links.yml + checks: name: Check job status if: always() @@ -428,6 +440,7 @@ jobs: - test-linux-aarch64 - test-windows - doc + - doc-linkcheck steps: - name: Exit run: | @@ -463,6 +476,9 @@ jobs: if ${{ needs.doc.result == 'cancelled' || needs.doc.result == 'failure' }}; then exit 1 fi + if ${{ needs.doc-linkcheck.result == 'cancelled' || needs.doc-linkcheck.result == 'failure' }}; then + exit 1 + fi if ${{ needs.test-sdist-linux.result == 'cancelled' || needs.test-sdist-linux.result == 'failure' || needs.test-sdist-windows.result == 'cancelled' || From 7f7bfa6116443a6b47d31aed7f0987b750fa2f92 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Thu, 4 Jun 2026 12:57:08 -0400 Subject: [PATCH 15/22] Check rendered docs links locally --- .github/workflows/build-docs.yml | 20 ++------- .github/workflows/check-doc-links.yml | 59 ++++++++++++--------------- 2 files changed, 28 insertions(+), 51 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 0fa08246eb0..63eb04b898a 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -253,26 +253,12 @@ jobs: run: | echo "${{ github.sha }}" > artifacts/docs/.preview-commit - - name: Write doc preview link-check URL list - if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} - env: - PREVIEW_URL: https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }} - run: | - find "${GITHUB_WORKSPACE}/artifacts/docs" -type f -name '*.html' ! -path '*/_static/*' -printf '%P\n' \ - | LC_ALL=C sort \ - | sed "s#^#${PREVIEW_URL}/#" > lychee-preview-urls.txt - if [[ ! -s lychee-preview-urls.txt ]]; then - echo "error: no rendered HTML pages found for lychee" >&2 - exit 1 - fi - wc -l lychee-preview-urls.txt - - - name: Upload doc preview link-check URL list + - name: Upload rendered docs for link checking if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: docs-preview-linkcheck-urls - path: lychee-preview-urls.txt + name: docs-rendered-html + path: artifacts/docs/ if-no-files-found: error retention-days: 3 diff --git a/.github/workflows/check-doc-links.yml b/.github/workflows/check-doc-links.yml index b7a12ee08ee..89366422c35 100644 --- a/.github/workflows/check-doc-links.yml +++ b/.github/workflows/check-doc-links.yml @@ -7,10 +7,10 @@ name: "CI: Check rendered docs links" on: workflow_call: inputs: - url-artifact: - description: "Artifact containing the rendered doc preview URL list" + docs-artifact: + description: "Artifact containing the rendered docs HTML tree" required: false - default: docs-preview-linkcheck-urls + default: docs-rendered-html type: string jobs: @@ -26,54 +26,45 @@ jobs: run: shell: bash -el {0} steps: - - name: Checkout ${{ github.event.repository.name }} - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - - name: Get PR number - uses: ./.github/actions/get_pr_number + - name: Extract PR number + run: | + PR_NUMBER="${GITHUB_REF_NAME#pull-request/}" + if [[ ! "${PR_NUMBER}" =~ ^[0-9]+$ ]]; then + echo "error: cannot extract PR number from ref ${GITHUB_REF_NAME}" >&2 + exit 1 + fi + echo "PR_NUMBER=${PR_NUMBER}" >> "${GITHUB_ENV}" - - name: Download doc preview link-check URL list + - name: Download rendered docs uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: ${{ inputs.url-artifact }} - path: linkcheck-input + name: ${{ inputs.docs-artifact }} + path: rendered-docs - - name: Wait for doc preview deployment - env: - PREVIEW_URL: https://nvidia.github.io/cuda-python/pr-preview/pr-${{ env.PR_NUMBER }} - EXPECTED_SHA: ${{ github.sha }} + - name: Write rendered docs file list run: | - preview_ready=0 - marker_url="${PREVIEW_URL}/.preview-commit" - for attempt in {1..60}; do - marker=$(curl -fsSL "${marker_url}" || true) - if [[ "${marker}" == "${EXPECTED_SHA}" ]]; then - preview_ready=1 - break - fi - echo "Waiting for doc preview marker ${marker_url} (${attempt}/60)" - sleep 10 - done - if [[ "${preview_ready}" != "1" ]]; then - echo "error: doc preview marker did not update to ${EXPECTED_SHA}" >&2 + find "${GITHUB_WORKSPACE}/rendered-docs" -type f -name '*.html' ! -path '*/_static/*' \ + | LC_ALL=C sort > lychee-rendered-html-files.txt + if [[ ! -s lychee-rendered-html-files.txt ]]; then + echo "error: no rendered HTML pages found for lychee" >&2 exit 1 fi - echo "Doc preview is available at ${PREVIEW_URL}" + wc -l lychee-rendered-html-files.txt - name: Restore lychee cache id: restore-lychee-cache uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: .lycheecache - key: docs-preview-lychee-${{ env.PR_NUMBER }}-${{ github.sha }} + key: docs-rendered-lychee-${{ env.PR_NUMBER }}-${{ github.sha }} restore-keys: | - docs-preview-lychee-${{ env.PR_NUMBER }}- + docs-rendered-lychee-${{ env.PR_NUMBER }}- - - name: Check doc preview links + - name: Check rendered docs links uses: lycheeverse/lychee-action@6da1d14f3a43098a294b7696d93d938aa8d20fc0 # unreleased: supports v0.24.x archive layout with: args: >- - --files-from ${{ github.workspace }}/linkcheck-input/lychee-preview-urls.txt + --files-from ${{ github.workspace }}/lychee-rendered-html-files.txt --include-fragments=full --cache --max-cache-age 1d @@ -89,7 +80,7 @@ jobs: format: markdown jobSummary: false lycheeVersion: v0.24.2 - output: lychee-preview.md + output: lychee-rendered-html.md token: ${{ github.token }} - name: Save lychee cache From d16f283a26c18ec1482c4aabc8b7c128affb1880 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Thu, 4 Jun 2026 13:09:58 -0400 Subject: [PATCH 16/22] Clarify rendered docs artifact uploads --- .github/workflows/build-docs.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 63eb04b898a..1b79ea80ae2 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -248,11 +248,6 @@ jobs: fi mv ${COMPONENT}/docs/build/html/* artifacts/docs/${TARGET} - - name: Write doc preview marker - if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} - run: | - echo "${{ github.sha }}" > artifacts/docs/.preview-commit - - name: Upload rendered docs for link checking if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 @@ -262,8 +257,9 @@ jobs: if-no-files-found: error retention-days: 3 - # TODO: Consider removing this step? - - name: Upload doc artifacts + # This is the GitHub Pages artifact format; the link checker needs a + # normal workflow artifact with the rendered HTML tree above. + - name: Upload docs GitHub Pages artifact uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: path: artifacts/ From 1ace33e60de4ef8a7c33aee99e724960af2bed78 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Thu, 4 Jun 2026 13:56:40 -0400 Subject: [PATCH 17/22] Handle rendered docs linkcheck exclusions --- .github/workflows/check-doc-links.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/check-doc-links.yml b/.github/workflows/check-doc-links.yml index 89366422c35..c00730b6605 100644 --- a/.github/workflows/check-doc-links.yml +++ b/.github/workflows/check-doc-links.yml @@ -63,6 +63,9 @@ jobs: - name: Check rendered docs links uses: lycheeverse/lychee-action@6da1d14f3a43098a294b7696d93d938aa8d20fc0 # unreleased: supports v0.24.x archive layout with: + # PR-preview canonical URLs are checked by the preview deployment workflow. + # The cuda-bindings #id links are docutils "problematic" anchors from generated API docs. + # Preferred Networks rejects hosted-runner GETs, but the URL is browser reachable. args: >- --files-from ${{ github.workspace }}/lychee-rendered-html-files.txt --include-fragments=full @@ -75,6 +78,9 @@ jobs: --retry-wait-time 5 --timeout 30 --no-progress + --exclude '^https://nvidia\.github\.io/cuda-python/pr-preview/pr-[0-9]+/' + --exclude '^file://.*/cuda-bindings/latest/module/(driver|runtime)\.html#id[0-9]+$' + --exclude '^https://www\.preferred\.jp/en/?$' fail: true failIfEmpty: true format: markdown From d1af8874fb43dfcd3305550a13be2fc10c38b138 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Fri, 5 Jun 2026 22:26:12 -0400 Subject: [PATCH 18/22] Defer generated pointer docs cleanup --- cuda_bindings/docs/source/module/driver.rst | 14 +++++++------- cuda_bindings/docs/source/module/runtime.rst | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cuda_bindings/docs/source/module/driver.rst b/cuda_bindings/docs/source/module/driver.rst index 020633665bf..49c633aa074 100644 --- a/cuda_bindings/docs/source/module/driver.rst +++ b/cuda_bindings/docs/source/module/driver.rst @@ -406,25 +406,25 @@ Data types used by CUDA driver .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_GEQ - Wait until (int32_t)(\*addr - value) >= 0 (or int64_t for 64 bit values). Note this is a cyclic comparison which ignores wraparound. (Default behavior.) + Wait until (int32_t)(*addr - value) >= 0 (or int64_t for 64 bit values). Note this is a cyclic comparison which ignores wraparound. (Default behavior.) .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_EQ - Wait until \*addr == value. + Wait until *addr == value. .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_AND - Wait until (\*addr & value) != 0. + Wait until (*addr & value) != 0. .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_NOR - Wait until ~(\*addr | value) != 0. Support for this operation can be queried with :py:obj:`~.cuDeviceGetAttribute()` and :py:obj:`~.CU_DEVICE_ATTRIBUTE_CAN_USE_STREAM_WAIT_VALUE_NOR`. + Wait until ~(*addr | value) != 0. Support for this operation can be queried with :py:obj:`~.cuDeviceGetAttribute()` and :py:obj:`~.CU_DEVICE_ATTRIBUTE_CAN_USE_STREAM_WAIT_VALUE_NOR`. .. autoattribute:: cuda.bindings.driver.CUstreamWaitValue_flags.CU_STREAM_WAIT_VALUE_FLUSH @@ -506,19 +506,19 @@ Data types used by CUDA driver .. autoattribute:: cuda.bindings.driver.CUstreamAtomicReductionOpType.CU_STREAM_ATOMIC_REDUCTION_OP_OR - Performs an atomic OR: \*(address) = \*(address) | value + Performs an atomic OR: *(address) = *(address) | value .. autoattribute:: cuda.bindings.driver.CUstreamAtomicReductionOpType.CU_STREAM_ATOMIC_REDUCTION_OP_AND - Performs an atomic AND: \*(address) = \*(address) & value + Performs an atomic AND: *(address) = *(address) & value .. autoattribute:: cuda.bindings.driver.CUstreamAtomicReductionOpType.CU_STREAM_ATOMIC_REDUCTION_OP_ADD - Performs an atomic ADD: \*(address) = \*(address) + value + Performs an atomic ADD: *(address) = *(address) + value .. autoclass:: cuda.bindings.driver.CUstreamAtomicReductionDataType diff --git a/cuda_bindings/docs/source/module/runtime.rst b/cuda_bindings/docs/source/module/runtime.rst index 4714cf8f13b..29da14b40de 100644 --- a/cuda_bindings/docs/source/module/runtime.rst +++ b/cuda_bindings/docs/source/module/runtime.rst @@ -6403,11 +6403,11 @@ The types ::CUevent and cudaEvent_t are identical and may be used interchangeabl -The types ``CUarray`` and ``struct cudaArray *`` represent the same data type and may be used interchangeably by casting the two types between each other. +The types ::CUarray and struct ::cudaArray * represent the same data type and may be used interchangeably by casting the two types between each other. -In order to use a ``CUarray`` in a CUDA Runtime API function which takes a ``struct cudaArray *``, it is necessary to explicitly cast the ``CUarray`` to a ``struct cudaArray *``. +In order to use a ::CUarray in a CUDA Runtime API function which takes a struct ::cudaArray *, it is necessary to explicitly cast the ::CUarray to a struct ::cudaArray *. -In order to use a ``struct cudaArray *`` in a CUDA Driver API function which takes a ``CUarray``, it is necessary to explicitly cast the ``struct cudaArray *`` to a ``CUarray``. +In order to use a struct ::cudaArray * in a CUDA Driver API function which takes a ::CUarray, it is necessary to explicitly cast the struct ::cudaArray * to a ::CUarray . From 809534b20afc431bb76c35b1da920463212a7da4 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Sat, 6 Jun 2026 00:33:50 -0400 Subject: [PATCH 19/22] Remove redundant docs commit hash env --- .github/workflows/build-docs.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 1b79ea80ae2..167fd7062e5 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -95,17 +95,14 @@ jobs: if [[ -z "${DOCS_GITHUB_REF}" ]]; then DOCS_GITHUB_REF="${GITHUB_REF_NAME}" fi - COMMIT_HASH="${DOCS_GITHUB_REF}" else FILE_HASH="${{ github.sha }}" DOCS_GITHUB_REF="${{ github.sha }}" - COMMIT_HASH="${DOCS_GITHUB_REF}" fi # 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 - echo "COMMIT_HASH=${COMMIT_HASH}" >> $GITHUB_ENV echo "CUDA_CORE_ARTIFACT_BASENAME=${CUDA_CORE_ARTIFACT_BASENAME}" >> $GITHUB_ENV echo "CUDA_CORE_ARTIFACT_NAME=${CUDA_CORE_ARTIFACT_BASENAME}-${FILE_HASH}" >> $GITHUB_ENV echo "CUDA_CORE_ARTIFACTS_DIR=$(realpath "$REPO_DIR/cuda_core/dist")" >> $GITHUB_ENV @@ -281,5 +278,5 @@ jobs: git-config-email: cuda-python-bot@users.noreply.github.com folder: artifacts/docs/ target-folder: docs/ - commit-message: "Deploy ${{ (inputs.is-release && 'release') || 'latest' }} docs: ${{ env.COMMIT_HASH }}" + commit-message: "Deploy ${{ (inputs.is-release && 'release') || 'latest' }} docs: ${{ env.CUDA_PYTHON_DOCS_GITHUB_REF }}" clean: false From f6adcfbe6a39375453dc83aa7c2afcc1fbf285ec Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 9 Jun 2026 12:29:44 -0400 Subject: [PATCH 20/22] Note temporary rendered docs link exclusion --- .github/workflows/check-doc-links.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-doc-links.yml b/.github/workflows/check-doc-links.yml index c00730b6605..3d45231dea4 100644 --- a/.github/workflows/check-doc-links.yml +++ b/.github/workflows/check-doc-links.yml @@ -65,6 +65,7 @@ jobs: with: # PR-preview canonical URLs are checked by the preview deployment workflow. # The cuda-bindings #id links are docutils "problematic" anchors from generated API docs. + # TODO: Remove this exclusion after cybind stops emitting those problematic anchors. # Preferred Networks rejects hosted-runner GETs, but the URL is browser reachable. args: >- --files-from ${{ github.workspace }}/lychee-rendered-html-files.txt From 22dde0aabe45f3d6be62012fba955294ac2a6b8d Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 9 Jun 2026 13:29:25 -0400 Subject: [PATCH 21/22] Use lychee release tag for pre-commit hook --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 40121b6f0fe..f9a79df944e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -56,7 +56,7 @@ repos: # Link checking for authored documentation files - repo: https://github.com/lycheeverse/lychee - rev: 2bba271688c1abb1503097a064e6c3bc1d1b6a9b # frozen: lychee-v0.24.2 + rev: lychee-v0.24.2 hooks: - id: lychee args: From 0a319ad1ffc67fa9ac538aa855d9bf3919c73f36 Mon Sep 17 00:00:00 2001 From: Keith Kraus Date: Tue, 9 Jun 2026 13:38:32 -0400 Subject: [PATCH 22/22] Inline rendered docs link check --- .github/workflows/build-docs.yml | 64 ++++++++++++++--- .github/workflows/check-doc-links.yml | 98 --------------------------- .github/workflows/ci.yml | 16 ----- .pre-commit-config.yaml | 2 +- 4 files changed, 57 insertions(+), 123 deletions(-) delete mode 100644 .github/workflows/check-doc-links.yml diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 167fd7062e5..45fa53ab1b1 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -245,17 +245,65 @@ jobs: fi mv ${COMPONENT}/docs/build/html/* artifacts/docs/${TARGET} - - name: Upload rendered docs for link checking + - name: Write rendered docs file list if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + run: | + find "${GITHUB_WORKSPACE}/artifacts/docs" -type f -name '*.html' ! -path '*/_static/*' \ + | LC_ALL=C sort > lychee-rendered-html-files.txt + if [[ ! -s lychee-rendered-html-files.txt ]]; then + echo "error: no rendered HTML pages found for lychee" >&2 + exit 1 + fi + wc -l lychee-rendered-html-files.txt + + - name: Restore lychee cache + if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} + id: restore-lychee-cache + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: - name: docs-rendered-html - path: artifacts/docs/ - if-no-files-found: error - retention-days: 3 + path: .lycheecache + key: docs-rendered-lychee-${{ env.PR_NUMBER }}-${{ github.sha }} + restore-keys: | + docs-rendered-lychee-${{ env.PR_NUMBER }}- + + - name: Check rendered docs links + if: ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }} + uses: lycheeverse/lychee-action@6da1d14f3a43098a294b7696d93d938aa8d20fc0 # unreleased: supports v0.24.x archive layout + with: + # PR-preview canonical URLs are checked by the preview deployment workflow. + # The cuda-bindings #id links are docutils "problematic" anchors from generated API docs. + # TODO: Remove this exclusion after cybind stops emitting those problematic anchors. + # Preferred Networks rejects hosted-runner GETs, but the URL is browser reachable. + args: >- + --files-from ${{ github.workspace }}/lychee-rendered-html-files.txt + --include-fragments=full + --cache + --max-cache-age 1d + --max-concurrency 16 + --host-concurrency 2 + --host-request-interval 250ms + --max-retries 3 + --retry-wait-time 5 + --timeout 30 + --no-progress + --exclude '^https://nvidia\.github\.io/cuda-python/pr-preview/pr-[0-9]+/' + --exclude '^file://.*/cuda-bindings/latest/module/(driver|runtime)\.html#id[0-9]+$' + --exclude '^https://www\.preferred\.jp/en/?$' + fail: true + failIfEmpty: true + format: markdown + jobSummary: false + lycheeVersion: v0.24.2 + output: lychee-rendered-html.md + token: ${{ github.token }} + + - name: Save lychee cache + if: ${{ always() && !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') && steps.restore-lychee-cache.outputs.cache-hit != 'true' && steps.restore-lychee-cache.outputs.cache-primary-key != '' }} + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 + with: + path: .lycheecache + key: ${{ steps.restore-lychee-cache.outputs.cache-primary-key }} - # This is the GitHub Pages artifact format; the link checker needs a - # normal workflow artifact with the rendered HTML tree above. - name: Upload docs GitHub Pages artifact uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: diff --git a/.github/workflows/check-doc-links.yml b/.github/workflows/check-doc-links.yml deleted file mode 100644 index 3d45231dea4..00000000000 --- a/.github/workflows/check-doc-links.yml +++ /dev/null @@ -1,98 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# SPDX-License-Identifier: Apache-2.0 - -name: "CI: Check rendered docs links" - -on: - workflow_call: - inputs: - docs-artifact: - description: "Artifact containing the rendered docs HTML tree" - required: false - default: docs-rendered-html - type: string - -jobs: - check: - name: Check rendered docs links - if: ${{ github.repository_owner == 'nvidia' && startsWith(github.ref_name, 'pull-request/') }} - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - pull-requests: read - defaults: - run: - shell: bash -el {0} - steps: - - name: Extract PR number - run: | - PR_NUMBER="${GITHUB_REF_NAME#pull-request/}" - if [[ ! "${PR_NUMBER}" =~ ^[0-9]+$ ]]; then - echo "error: cannot extract PR number from ref ${GITHUB_REF_NAME}" >&2 - exit 1 - fi - echo "PR_NUMBER=${PR_NUMBER}" >> "${GITHUB_ENV}" - - - name: Download rendered docs - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: ${{ inputs.docs-artifact }} - path: rendered-docs - - - name: Write rendered docs file list - run: | - find "${GITHUB_WORKSPACE}/rendered-docs" -type f -name '*.html' ! -path '*/_static/*' \ - | LC_ALL=C sort > lychee-rendered-html-files.txt - if [[ ! -s lychee-rendered-html-files.txt ]]; then - echo "error: no rendered HTML pages found for lychee" >&2 - exit 1 - fi - wc -l lychee-rendered-html-files.txt - - - name: Restore lychee cache - id: restore-lychee-cache - uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 - with: - path: .lycheecache - key: docs-rendered-lychee-${{ env.PR_NUMBER }}-${{ github.sha }} - restore-keys: | - docs-rendered-lychee-${{ env.PR_NUMBER }}- - - - name: Check rendered docs links - uses: lycheeverse/lychee-action@6da1d14f3a43098a294b7696d93d938aa8d20fc0 # unreleased: supports v0.24.x archive layout - with: - # PR-preview canonical URLs are checked by the preview deployment workflow. - # The cuda-bindings #id links are docutils "problematic" anchors from generated API docs. - # TODO: Remove this exclusion after cybind stops emitting those problematic anchors. - # Preferred Networks rejects hosted-runner GETs, but the URL is browser reachable. - args: >- - --files-from ${{ github.workspace }}/lychee-rendered-html-files.txt - --include-fragments=full - --cache - --max-cache-age 1d - --max-concurrency 16 - --host-concurrency 2 - --host-request-interval 250ms - --max-retries 3 - --retry-wait-time 5 - --timeout 30 - --no-progress - --exclude '^https://nvidia\.github\.io/cuda-python/pr-preview/pr-[0-9]+/' - --exclude '^file://.*/cuda-bindings/latest/module/(driver|runtime)\.html#id[0-9]+$' - --exclude '^https://www\.preferred\.jp/en/?$' - fail: true - failIfEmpty: true - format: markdown - jobSummary: false - lycheeVersion: v0.24.2 - output: lychee-rendered-html.md - token: ${{ github.token }} - - - name: Save lychee cache - if: ${{ always() && steps.restore-lychee-cache.outputs.cache-hit != 'true' && steps.restore-lychee-cache.outputs.cache-primary-key != '' }} - uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 - with: - path: .lycheecache - key: ${{ steps.restore-lychee-cache.outputs.cache-primary-key }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d52821c847..6b510ecffc8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -415,18 +415,6 @@ jobs: with: is-release: ${{ github.ref_type == 'tag' }} - doc-linkcheck: - name: Docs link check - if: ${{ github.repository_owner == 'nvidia' && startsWith(github.ref_name, 'pull-request/') && needs.doc.result == 'success' }} - permissions: - actions: read - contents: read - pull-requests: read - needs: - - doc - secrets: inherit - uses: ./.github/workflows/check-doc-links.yml - checks: name: Check job status if: always() @@ -440,7 +428,6 @@ jobs: - test-linux-aarch64 - test-windows - doc - - doc-linkcheck steps: - name: Exit run: | @@ -476,9 +463,6 @@ jobs: if ${{ needs.doc.result == 'cancelled' || needs.doc.result == 'failure' }}; then exit 1 fi - if ${{ needs.doc-linkcheck.result == 'cancelled' || needs.doc-linkcheck.result == 'failure' }}; then - exit 1 - fi if ${{ needs.test-sdist-linux.result == 'cancelled' || needs.test-sdist-linux.result == 'failure' || needs.test-sdist-windows.result == 'cancelled' || diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f9a79df944e..40121b6f0fe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -56,7 +56,7 @@ repos: # Link checking for authored documentation files - repo: https://github.com/lycheeverse/lychee - rev: lychee-v0.24.2 + rev: 2bba271688c1abb1503097a064e6c3bc1d1b6a9b # frozen: lychee-v0.24.2 hooks: - id: lychee args: