33# SPDX-License-Identifier: Apache-2.0
44
55name : " WoA main CI"
6- run-name : " WoA main CI for ${{ inputs.public_run_id || 'latest successful public main CI run' }}"
6+ run-name : " WoA main CI for ${{ github.sha }}"
77
88on :
9- workflow_call :
10- inputs :
11- public_run_id :
12- required : true
13- type : string
14- secrets :
15- CUDA_PYTHON_WOA_XREPO_CI_PRIVATE_APP_PRIVATE_KEY :
16- required : true
17- schedule :
18- - cron : " 17 * * * *"
19- workflow_dispatch :
20- inputs :
21- public_run_id :
22- description : Eligible public main CI run; leave empty to find the latest successful main CI run
23- required : false
24- type : string
9+ push :
10+ branches : [main]
2511
2612permissions : {}
2713
3319 resolve-public-build :
3420 if : ${{ github.repository == 'NVIDIA/cuda-python' }}
3521 runs-on : ubuntu-latest
36- timeout-minutes : 10
22+ timeout-minutes : 120
3723 permissions :
3824 actions : read
3925 contents : read
@@ -50,56 +36,57 @@ jobs:
5036 ref : ${{ github.sha }}
5137 persist-credentials : false
5238 sparse-checkout : |
53- ci/tools/lookup-run-id
5439 ci/tools/select-woa-batch
40+ ci/versions.yml
5541 sparse-checkout-cone-mode : false
5642
5743 - name : Resolve exact public build
5844 id : resolve
5945 env :
6046 GH_TOKEN : ${{ github.token }}
61- PUBLIC_RUN_ID : ${{ inputs.public_run_id }}
47+ PUBLIC_SHA : ${{ github.sha }}
6248 run : |
6349 set -euo pipefail
64- public_sha=''
50+ PUBLIC_RUN_ID=''
51+ for ((attempt = 0; attempt < 20; attempt++)); do
52+ runs=$(gh api --method GET \
53+ -H 'X-GitHub-Api-Version: 2026-03-10' \
54+ repos/NVIDIA/cuda-python/actions/workflows/ci.yml/runs \
55+ -f event=push -f branch=main -f head_sha="$PUBLIC_SHA" -F per_page=100)
56+ PUBLIC_RUN_ID=$(jq -r --arg sha "$PUBLIC_SHA" '
57+ [.workflow_runs[] | select(.event == "push" and
58+ .head_branch == "main" and .head_sha == $sha)]
59+ | max_by(.id) | .id // empty
60+ ' <<< "$runs")
61+ [[ -z "$PUBLIC_RUN_ID" ]] || break
62+ echo "Waiting for main push CI run at $PUBLIC_SHA (attempt $((attempt + 1))/20)."
63+ sleep 30
64+ done
6565 if [[ -z "$PUBLIC_RUN_ID" ]]; then
66- lookup_output=$(./ci/tools/lookup-run-id --branch main --event push --head-sha NVIDIA/cuda-python CI)
67- mapfile -t lookup_result <<< "$lookup_output"
68- [[ ${#lookup_result[@]} == 2 ]]
69- PUBLIC_RUN_ID=${lookup_result[0]}
70- public_sha=${lookup_result[1]}
71- [[ "$public_sha" =~ ^[0-9a-f]{40}$ ]]
66+ echo "::error::No main push CI run appeared for $PUBLIC_SHA within ten minutes."
67+ exit 1
7268 fi
7369 [[ "$PUBLIC_RUN_ID" =~ ^[1-9][0-9]*$ ]]
7470 run=$(gh api \
7571 -H 'X-GitHub-Api-Version: 2026-03-10' \
7672 "repos/NVIDIA/cuda-python/actions/runs/$PUBLIC_RUN_ID")
77- jq -e --arg sha "$public_sha " '
73+ jq -e --arg sha "$PUBLIC_SHA " '
7874 .repository.full_name == "NVIDIA/cuda-python" and
7975 .workflow_id == 155304118 and
8076 .path == ".github/workflows/ci.yml" and
8177 .event == "push" and
8278 .head_branch == "main" and
83- ((.status == "in_progress " and .conclusion == null) or
79+ ((.status != "completed " and .conclusion == null) or
8480 (.status == "completed" and .conclusion == "success")) and
85- ($sha == "" or .head_sha == $sha) and
81+ .head_sha == $sha and
8682 (.head_sha | test("^[0-9a-f]{40}$"))
8783 ' <<< "$run" >/dev/null
88- if [[ -z "$public_sha" ]]; then
89- public_sha=$(jq -r .head_sha <<< "$run")
90- fi
91-
92- comparison=$(gh api \
93- -H 'X-GitHub-Api-Version: 2026-03-10' \
94- "repos/NVIDIA/cuda-python/compare/$public_sha...main")
95- jq -e '.status == "ahead" or .status == "identical"' <<< "$comparison" >/dev/null
96-
97- correlation_id="v1:NVIDIA/cuda-python:$PUBLIC_RUN_ID:$public_sha"
84+ correlation_id="v1:NVIDIA/cuda-python:$PUBLIC_RUN_ID:$PUBLIC_SHA"
9885 echo "correlation_id=$correlation_id" >> "$GITHUB_OUTPUT"
9986 echo "public_run_id=$PUBLIC_RUN_ID" >> "$GITHUB_OUTPUT"
100- echo "public_sha=$public_sha " >> "$GITHUB_OUTPUT"
87+ echo "public_sha=$PUBLIC_SHA " >> "$GITHUB_OUTPUT"
10188 {
102- echo "Resolved public run \`$PUBLIC_RUN_ID\` at commit \`$public_sha \`."
89+ echo "Resolved public run \`$PUBLIC_RUN_ID\` at commit \`$PUBLIC_SHA \`."
10390 } >> "$GITHUB_STEP_SUMMARY"
10491
10592 - name : Select public batch
@@ -110,6 +97,53 @@ jobs:
11097 PUBLIC_SHA : ${{ steps.resolve.outputs.public_sha }}
11198 run : bash ./ci/tools/select-woa-batch
11299
100+ - name : Wait for public WoA wheel artifacts
101+ if : ${{ steps.select.outputs.dispatch == 'true' }}
102+ timeout-minutes : 100
103+ env :
104+ GH_TOKEN : ${{ github.token }}
105+ PUBLIC_RUN_ID : ${{ steps.resolve.outputs.public_run_id }}
106+ PUBLIC_SHA : ${{ steps.resolve.outputs.public_sha }}
107+ run : |
108+ set -euo pipefail
109+ cuda_version=$(yq -r '.cuda.build.version' ci/versions.yml)
110+ mapfile -t python_versions < <(yq -r '.python.supported[]' ci/versions.yml)
111+ pending=(cuda-pathfinder-wheel)
112+ for version in "${python_versions[@]}"; do
113+ python_tag=${version//./}
114+ pending+=("cuda-bindings-python$python_tag-cuda$cuda_version-win-arm64-$PUBLIC_SHA"
115+ "cuda-core-python$python_tag-win-arm64-$PUBLIC_SHA")
116+ done
117+ while (( ${#pending[@]} > 0 )); do
118+ run=$(gh api \
119+ -H 'X-GitHub-Api-Version: 2026-03-10' \
120+ "repos/NVIDIA/cuda-python/actions/runs/$PUBLIC_RUN_ID")
121+ if jq -e '.status == "completed" and .conclusion != "success"' <<< "$run" >/dev/null; then
122+ echo "::error::Public CI run $PUBLIC_RUN_ID ended with $(jq -r .conclusion <<< "$run")."
123+ exit 1
124+ fi
125+ artifact_name=${pending[0]}
126+ artifacts=$(gh api --method GET \
127+ -H 'X-GitHub-Api-Version: 2026-03-10' \
128+ "repos/NVIDIA/cuda-python/actions/runs/$PUBLIC_RUN_ID/artifacts" \
129+ -f name="$artifact_name")
130+ if jq -e --arg name "$artifact_name" '
131+ .total_count == 1 and (.artifacts | length == 1) and
132+ .artifacts[0].name == $name and .artifacts[0].expired == false
133+ ' <<< "$artifacts" >/dev/null; then
134+ echo "Ready: $artifact_name"
135+ pending=("${pending[@]:1}")
136+ elif [[ $(jq -r .status <<< "$run") == completed ]]; then
137+ echo "::error::Successful public CI run $PUBLIC_RUN_ID is missing usable artifact $artifact_name."
138+ jq . <<< "$artifacts"
139+ exit 1
140+ else
141+ echo "Waiting for $artifact_name (${#pending[@]} artifacts remaining)."
142+ sleep 60
143+ fi
144+ done
145+ echo "All public WoA wheel artifacts are ready; remaining public CI jobs need not finish." >> "$GITHUB_STEP_SUMMARY"
146+
113147 dispatch-private-validation :
114148 needs : resolve-public-build
115149 if : ${{ needs.resolve-public-build.outputs.dispatch == 'true' }}
0 commit comments