@@ -19,39 +19,116 @@ inputs:
1919 description : " where the CTK components will be installed to, relative to $PWD"
2020 required : false
2121 default : " ./cuda_toolkit"
22+ install-mode :
23+ description : >
24+ "replace" (default) empties cuda-path before installing.
25+ "add" installs the components on top of the mini CTK that an earlier
26+ fetch_ctk call installed at the same cuda-path, and leaves the
27+ environment that call exported unchanged.
28+ required : false
29+ default : " replace"
30+ redist-base-url :
31+ description : >
32+ Base URL of a redistrib server (manifest and component archives).
33+ Defaults to the public NVIDIA developer server.
34+ Override to install from an alternate redistrib server.
35+ required : false
36+ default : " https://developer.download.nvidia.com/compute/cuda/redist"
2237
2338runs :
2439 using : composite
2540 steps :
41+ - name : Install Unix dependencies
42+ if : ${{ runner.os == 'Linux' }}
43+ uses : ./.github/actions/install_unix_deps
44+ with :
45+ dependencies : " zstd curl xz-utils"
46+ dependent_exes : " zstd curl xz"
47+
48+ - name : Install Windows dependencies
49+ if : ${{ runner.os == 'Windows' }}
50+ uses : ./.github/actions/install_windows_deps
51+ with :
52+ dependent_exes : " curl unzip tar sha256sum cygpath"
53+
54+ - name : Check install mode
55+ shell : bash --noprofile --norc -xeuo pipefail {0}
56+ run : |
57+ case "${{ inputs.install-mode }}" in
58+ replace)
59+ ;;
60+ add)
61+ # The environment exports are skipped in this mode, so the target
62+ # must be the CUDA_PATH an earlier fetch_ctk call exported.
63+ if [[ -z "${CUDA_PATH:-}" ]]; then
64+ echo "::error::install-mode 'add' requires CUDA_PATH from an earlier fetch_ctk call"
65+ exit 1
66+ fi
67+ EXISTING_PATH="$CUDA_PATH"
68+ if [[ "${{ inputs.host-platform }}" == win* ]]; then
69+ EXISTING_PATH="$(cygpath -u "$EXISTING_PATH")"
70+ fi
71+ if [[ "$(realpath -e "${{ inputs.cuda-path }}")" != "$(realpath -e "$EXISTING_PATH")" ]]; then
72+ echo "::error::install-mode 'add' requires cuda-path to be the existing CUDA_PATH ($CUDA_PATH)"
73+ exit 1
74+ fi
75+ ;;
76+ *)
77+ echo "::error::install-mode must be 'replace' or 'add', got '${{ inputs.install-mode }}'"
78+ exit 1
79+ ;;
80+ esac
81+
2682 - name : Set up CTK cache variable
2783 shell : bash --noprofile --norc -xeuo pipefail {0}
2884 run : |
29- # Pre-process the component list to ensure hash uniqueness
3085 # Use the runtime workspace mount so this also works inside container jobs.
3186 CTK_REDIST_TOOL="${GITHUB_WORKSPACE}/ci/tools/fetch_ctk_redistrib.py"
32- CTK_CACHE_COMPONENTS=${{ inputs.cuda-components }}
33- CTK_JSON_URL="https://developer.download.nvidia.com/compute/cuda/redist/redistrib_${{ inputs.cuda-version }}.json"
87+ CTK_BASE_URL="${{ inputs.redist-base-url }}"
88+ # A trailing slash would defeat the public-server comparison below and double up in URLs.
89+ CTK_BASE_URL="${CTK_BASE_URL%/}"
90+ # RUNNER_TEMP persists across steps, so "Get CUDA components" reuses this file.
91+ CTK_JSON_FILE="$RUNNER_TEMP/redistrib-${{ inputs.cuda-version }}.json"
92+ curl -LSs --fail --retry 3 --retry-delay 2 "${CTK_BASE_URL}/redistrib_${{ inputs.cuda-version }}.json" -o "$CTK_JSON_FILE"
93+
94+ # Pin the metadata JSON: the per-archive sha256 checks below are only
95+ # trustworthy if the JSON that carries those hashes is itself trusted.
96+ # The pins describe the public server; alternate servers only warn.
97+ if [[ "$CTK_BASE_URL" == "https://developer.download.nvidia.com/compute/cuda/redist" ]]; then
98+ METADATA_SOURCE=public
99+ else
100+ METADATA_SOURCE=custom
101+ fi
102+ python "$CTK_REDIST_TOOL" verify-metadata \
103+ --cuda-version "${{ inputs.cuda-version }}" \
104+ --metadata-path "$CTK_JSON_FILE" \
105+ --metadata-source "$METADATA_SOURCE"
106+
107+ # Pre-process the component list to ensure hash uniqueness
34108 CTK_CACHE_COMPONENTS="$(python "$CTK_REDIST_TOOL" filter-components \
35109 --host-platform "${{ inputs.host-platform }}" \
36110 --cuda-version "${{ inputs.cuda-version }}" \
37- --components "$CTK_CACHE_COMPONENTS " \
38- --metadata-url "$CTK_JSON_URL ")"
111+ --components "${{ inputs.cuda-components }} " \
112+ --metadata-path "$CTK_JSON_FILE ")"
39113
114+ # Alternate redist servers (non-default) publish different manifests for the
115+ # same CUDA version; keying on the full manifest hash keeps them from restoring
116+ # each other's toolkit (a truncated hash could be collided on purpose).
117+ # Hash via stdin: with a backslash in the path (Windows RUNNER_TEMP), sha256sum
118+ # prefixes its output line with "\", which would end up in the cache key.
119+ MANIFEST_SHA256="$(sha256sum < "$CTK_JSON_FILE" | awk '{print $1}')"
40120 HASH=$(echo -n "${CTK_CACHE_COMPONENTS}" | sha256sum | awk '{print $1}')
41- echo "CTK_CACHE_KEY=mini-ctk-${{ inputs.cuda-version }}-${{ inputs.host-platform }}-$HASH" >> $GITHUB_ENV
42- echo "CTK_CACHE_FILENAME=mini-ctk-${{ inputs.cuda-version }}-${{ inputs.host-platform }}-$HASH.tar.gz" >> $GITHUB_ENV
43- echo "CTK_CACHE_COMPONENTS=${CTK_CACHE_COMPONENTS}" >> $GITHUB_ENV
44-
45- - name : Install dependencies
46- uses : ./.github/actions/install_unix_deps
47- continue-on-error : false
48- with :
49- dependencies : " zstd curl xz-utils"
50- dependent_exes : " zstd curl xz"
121+ {
122+ echo "CTK_CACHE_KEY=mini-ctk-${{ inputs.cuda-version }}-${{ inputs.host-platform }}-$HASH-m$MANIFEST_SHA256"
123+ echo "CTK_CACHE_FILENAME=mini-ctk-${{ inputs.cuda-version }}-${{ inputs.host-platform }}-$HASH-m$MANIFEST_SHA256.tar.gz"
124+ echo "CTK_CACHE_COMPONENTS=${CTK_CACHE_COMPONENTS}"
125+ echo "CTK_BASE_URL=${CTK_BASE_URL}"
126+ echo "CTK_JSON_FILE=${CTK_JSON_FILE}"
127+ } >> "$GITHUB_ENV"
51128
52129 - name : Download CTK cache
53130 id : ctk-get-cache
54- uses : actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
131+ uses : actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
55132 continue-on-error : true
56133 with :
57134 key : ${{ env.CTK_CACHE_KEY }}
@@ -68,13 +145,10 @@ runs:
68145 rm -rf $CACHE_TMP_DIR
69146 mkdir $CACHE_TMP_DIR
70147
71- # The binary archives (redist) are guaranteed to be updated as part of the release posting.
72148 # Use the runtime workspace mount so this also works inside container jobs.
73149 CTK_REDIST_TOOL="${GITHUB_WORKSPACE}/ci/tools/fetch_ctk_redistrib.py"
74- CTK_BASE_URL="https://developer.download.nvidia.com/compute/cuda/redist/"
75- CTK_JSON_URL="$CTK_BASE_URL/redistrib_${{ inputs.cuda-version }}.json"
76- CTK_JSON_FILE="$CACHE_TMP_DIR/redistrib.json"
77- curl -LSs "$CTK_JSON_URL" -o "$CTK_JSON_FILE"
150+ # CTK_BASE_URL and the verified manifest at CTK_JSON_FILE come from
151+ # "Set up CTK cache variable".
78152 if [[ "${{ inputs.host-platform }}" == linux* ]]; then
79153 function extract() {
80154 tar -xvf $1 -C $CACHE_TMP_DIR --strip-components=1
@@ -102,6 +176,13 @@ runs:
102176 CTK_COMPONENT_URL="${CTK_BASE_URL}/${CTK_COMPONENT_REL_PATH}"
103177 CTK_COMPONENT_COMPONENT_FILENAME="$(basename $CTK_COMPONENT_REL_PATH)"
104178 download $CTK_COMPONENT_URL $CTK_COMPONENT_COMPONENT_FILENAME
179+ # Verify the downloaded archive against the sha256 in the (pinned)
180+ # metadata before extracting; fail closed on any mismatch.
181+ CTK_COMPONENT_SHA256="$(python "$CTK_REDIST_TOOL" component-sha256 \
182+ --host-platform "${{ inputs.host-platform }}" \
183+ --component "$CTK_COMPONENT" \
184+ --metadata-path "$CTK_JSON_FILE")"
185+ echo "${CTK_COMPONENT_SHA256} ${CTK_COMPONENT_COMPONENT_FILENAME}" | sha256sum --check --strict -
105186 extract $CTK_COMPONENT_COMPONENT_FILENAME
106187 rm $CTK_COMPONENT_COMPONENT_FILENAME
107188 }
@@ -125,7 +206,9 @@ runs:
125206 # symlinks from a prerelease CTK at ./cuda_toolkit/include etc., causing
126207 # "cp: cannot overwrite non-directory" failures on the next restore).
127208 CUDA_PATH="${{ inputs.cuda-path }}"
128- rm -rf $CUDA_PATH
209+ if [[ "${{ inputs.install-mode }}" == replace ]]; then
210+ rm -rf $CUDA_PATH
211+ fi
129212 mkdir -p $CUDA_PATH
130213 # Unfortunately we cannot use "rsync -av $CACHE_TMP_DIR/ $CUDA_PATH" because
131214 # not all runners have rsync pre-installed (or even installable, such as
@@ -137,7 +220,7 @@ runs:
137220 - name : Upload CTK cache
138221 if : ${{ !cancelled() &&
139222 steps.ctk-get-cache.outputs.cache-hit != 'true' }}
140- uses : actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
223+ uses : actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
141224 with :
142225 key : ${{ env.CTK_CACHE_KEY }}
143226 path : ./${{ env.CTK_CACHE_FILENAME }}
@@ -149,7 +232,9 @@ runs:
149232 ls -l
150233 CACHE_TMP_DIR="./cache_tmp_dir"
151234 CUDA_PATH="${{ inputs.cuda-path }}"
152- rm -rf $CUDA_PATH
235+ if [[ "${{ inputs.install-mode }}" == replace ]]; then
236+ rm -rf $CUDA_PATH
237+ fi
153238 mkdir -p $CUDA_PATH
154239 tar -xzvf $CTK_CACHE_FILENAME
155240 # Can't use rsync here, see above
@@ -158,6 +243,7 @@ runs:
158243 ls -l $CUDA_PATH
159244
160245 - name : Set output environment variables
246+ if : ${{ inputs.install-mode == 'replace' }}
161247 shell : bash --noprofile --norc -xeuo pipefail {0}
162248 run : |
163249 # mimics actual CTK installation
0 commit comments