1- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1+ # SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22#
33# SPDX-License-Identifier: Apache-2.0
44
3333 required : false
3434 default : false
3535 type : boolean
36+ deploy-docs :
37+ description : " Deploy generated docs to GitHub Pages or preview branches"
38+ required : false
39+ default : true
40+ type : boolean
41+ docs-branch :
42+ description : " Branch that receives deployed docs"
43+ required : false
44+ default : " gh-pages"
45+ type : string
3646
3747jobs :
3848 build :
@@ -45,14 +55,21 @@ jobs:
4555 shell : bash -el {0}
4656 steps :
4757 - name : Checkout ${{ github.event.repository.name }}
48- uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
58+ uses : actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
4959 with :
50- fetch-depth : 0
60+ fetch-depth : 1
5161 ref : ${{ inputs.git-tag }}
5262
5363 - name : Read build CTK version
5464 run : |
55- BUILD_CTK_VER=$(yq '.cuda.build.version' ci/versions.yml)
65+ if [[ -f ci/versions.yml ]]; then
66+ BUILD_CTK_VER=$(yq '.cuda.build.version' ci/versions.yml)
67+ elif [[ -f ci/versions.json ]]; then
68+ BUILD_CTK_VER=$(jq -r '.cuda.build.version' ci/versions.json)
69+ else
70+ echo "error: cannot find ci/versions.yml or ci/versions.json" >&2
71+ exit 1
72+ fi
5673 if [[ ! "${BUILD_CTK_VER}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
5774 echo "error: derived CTK build version ${BUILD_CTK_VER} does not match MAJOR.MINOR.MICRO" >&2
5875 exit 1
@@ -91,15 +108,18 @@ jobs:
91108
92109 if [[ ${{ inputs.is-release }} == "true" ]]; then
93110 FILE_HASH="*"
94- COMMIT_HASH="${{ inputs.git-tag }}"
111+ DOCS_GITHUB_REF="${{ inputs.git-tag }}"
112+ if [[ -z "${DOCS_GITHUB_REF}" ]]; then
113+ DOCS_GITHUB_REF="${GITHUB_REF_NAME}"
114+ fi
95115 else
96116 FILE_HASH="${{ github.sha }}"
97- COMMIT_HASH ="${{ github.sha }}"
117+ DOCS_GITHUB_REF ="${{ github.sha }}"
98118 fi
99119
100120 # make outputs from the previous job as env vars
101121 CUDA_CORE_ARTIFACT_BASENAME="cuda-core-python${PYTHON_VERSION_FORMATTED}-linux-64"
102- echo "COMMIT_HASH =${COMMIT_HASH }" >> $GITHUB_ENV
122+ echo "CUDA_PYTHON_DOCS_GITHUB_REF =${DOCS_GITHUB_REF }" >> $GITHUB_ENV
103123 echo "CUDA_CORE_ARTIFACT_BASENAME=${CUDA_CORE_ARTIFACT_BASENAME}" >> $GITHUB_ENV
104124 echo "CUDA_CORE_ARTIFACT_NAME=${CUDA_CORE_ARTIFACT_BASENAME}-${FILE_HASH}" >> $GITHUB_ENV
105125 echo "CUDA_CORE_ARTIFACTS_DIR=$(realpath "$REPO_DIR/cuda_core/dist")" >> $GITHUB_ENV
@@ -242,28 +262,96 @@ jobs:
242262 fi
243263 mv ${COMPONENT}/docs/build/html/* artifacts/docs/${TARGET}
244264
245- # TODO: Consider removing this step?
246- - name : Upload doc artifacts
265+ - name : Write rendered docs file list
266+ if : ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }}
267+ run : |
268+ find "${GITHUB_WORKSPACE}/artifacts/docs" -type f -name '*.html' ! -path '*/_static/*' \
269+ | LC_ALL=C sort > lychee-rendered-html-files.txt
270+ if [[ ! -s lychee-rendered-html-files.txt ]]; then
271+ echo "error: no rendered HTML pages found for lychee" >&2
272+ exit 1
273+ fi
274+ wc -l lychee-rendered-html-files.txt
275+
276+ - name : Restore lychee cache
277+ if : ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }}
278+ id : restore-lychee-cache
279+ uses : actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
280+ with :
281+ path : .lycheecache
282+ key : docs-rendered-lychee-${{ env.PR_NUMBER }}-${{ github.sha }}
283+ restore-keys : |
284+ docs-rendered-lychee-${{ env.PR_NUMBER }}-
285+
286+ - name : Check rendered docs links
287+ if : ${{ !inputs.is-release && github.ref_name != 'main' && !startsWith(github.ref_name, 'release/') }}
288+ uses : lycheeverse/lychee-action@6da1d14f3a43098a294b7696d93d938aa8d20fc0 # unreleased: supports v0.24.x archive layout
289+ with :
290+ # PR-preview canonical URLs are checked by the preview deployment workflow.
291+ # The cuda-bindings #id links are docutils "problematic" anchors from generated API docs.
292+ # TODO: Remove this exclusion after cybind stops emitting those problematic anchors.
293+ # Preferred Networks rejects hosted-runner GETs, but the URL is browser reachable.
294+ args : >-
295+ --files-from ${{ github.workspace }}/lychee-rendered-html-files.txt
296+ --include-fragments=full
297+ --cache
298+ --max-cache-age 1d
299+ --max-concurrency 16
300+ --host-concurrency 2
301+ --host-request-interval 250ms
302+ --max-retries 3
303+ --retry-wait-time 5
304+ --timeout 30
305+ --no-progress
306+ --exclude '^https://nvidia\.github\.io/cuda-python/pr-preview/pr-[0-9]+/'
307+ --exclude '^file://.*/cuda-bindings/latest/module/(driver|runtime)\.html#id[0-9]+$'
308+ --exclude '^https://www\.preferred\.jp/en/?$'
309+ fail : true
310+ failIfEmpty : true
311+ format : markdown
312+ jobSummary : false
313+ lycheeVersion : v0.24.2
314+ output : lychee-rendered-html.md
315+ token : ${{ github.token }}
316+
317+ - name : Save lychee cache
318+ 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 != '' }}
319+ uses : actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
320+ with :
321+ path : .lycheecache
322+ key : ${{ steps.restore-lychee-cache.outputs.cache-primary-key }}
323+
324+ - name : Upload docs GitHub Pages artifact
325+ if : ${{ inputs.deploy-docs }}
247326 uses : actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
248327 with :
249328 path : artifacts/
250329 retention-days : 3
251330
331+ - name : Upload dry-run docs artifact
332+ if : ${{ !inputs.deploy-docs || (inputs.is-release && inputs.docs-branch != 'gh-pages') }}
333+ uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
334+ with :
335+ name : release-docs-dry-run-${{ inputs.component }}-${{ inputs.git-tag }}
336+ path : artifacts/docs/
337+ retention-days : 3
338+
252339 - name : Deploy or clean up doc preview
253- if : ${{ !inputs.is-release }}
340+ if : ${{ inputs.deploy-docs && !inputs.is-release }}
254341 uses : ./.github/actions/doc_preview
255342 with :
256343 source-folder : ${{ (github.ref_name != 'main' && 'artifacts/docs') ||
257344 ' artifacts/empty_docs' }}
258345 pr-number : ${{ env.PR_NUMBER }}
259346
260347 - name : Deploy doc update
261- if : ${{ github.ref_name == 'main' || inputs.is-release }}
348+ if : ${{ inputs.deploy-docs && ( github.ref_name == 'main' || inputs.is-release) }}
262349 uses : JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f # v4.8.0
263350 with :
264351 git-config-name : cuda-python-bot
265352 git-config-email : cuda-python-bot@users.noreply.github.com
353+ branch : ${{ inputs.docs-branch }}
266354 folder : artifacts/docs/
267355 target-folder : docs/
268- commit-message : " Deploy ${{ (inputs.is-release && 'release') || 'latest' }} docs: ${{ env.COMMIT_HASH }}"
356+ commit-message : " Deploy ${{ (inputs.is-release && 'release') || 'latest' }} docs: ${{ env.CUDA_PYTHON_DOCS_GITHUB_REF }}"
269357 clean : false
0 commit comments