Skip to content

Commit fd31eb2

Browse files
committed
fix(ci): harden backport run lookup for artifact downloads
Backport artifact downloads were relying on `gh run list -w ci.yml -s success`, which can fail to return runs even when the branch has successful CI artifacts. Move the lookup into a shared helper that queries completed `CI` runs and filters for successful results explicitly, so Linux and Windows workflows resolve prior-branch bindings artifacts reliably. Made-with: Cursor
1 parent 7b8c46c commit fd31eb2

4 files changed

Lines changed: 99 additions & 41 deletions

File tree

‎.github/workflows/build-wheel.yml‎

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -401,18 +401,14 @@ jobs:
401401
402402
OLD_BRANCH=$(yq '.backport_branch' ci/versions.yml)
403403
OLD_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda*-${{ inputs.host-platform }}*"
404-
LATEST_PRIOR_RUN_ID=$(gh run list -b ${OLD_BRANCH} -L 1 -w "ci.yml" -s success -R NVIDIA/cuda-python --json databaseId | jq '.[]| .databaseId')
405-
if [[ "$LATEST_PRIOR_RUN_ID" == "" ]]; then
406-
echo "LATEST_PRIOR_RUN_ID not found!"
407-
exit 1
408-
fi
404+
LATEST_PRIOR_RUN_ID=$(bash ./ci/tools/lookup-run-id-by-branch "${OLD_BRANCH}" "${{ github.repository }}")
409405
410-
gh run download $LATEST_PRIOR_RUN_ID -p ${OLD_BASENAME} -R NVIDIA/cuda-python
411-
rm -rf ${OLD_BASENAME}-tests # exclude cython test artifacts
412-
ls -al $OLD_BASENAME
406+
gh run download "${LATEST_PRIOR_RUN_ID}" -p "${OLD_BASENAME}" -R "${{ github.repository }}"
407+
rm -rf "${OLD_BASENAME}-tests" # exclude cython test artifacts
408+
ls -al "${OLD_BASENAME}"
413409
mkdir -p "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
414-
mv $OLD_BASENAME/*.whl "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
415-
rmdir $OLD_BASENAME
410+
mv "${OLD_BASENAME}"/*.whl "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
411+
rmdir "${OLD_BASENAME}"
416412
417413
- name: Build cuda.core wheel
418414
uses: pypa/cibuildwheel@ee02a1537ce3071a004a6b08c41e72f0fdc42d9a # v3.4.0

‎.github/workflows/test-wheel-linux.yml‎

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -160,20 +160,16 @@ jobs:
160160
161161
OLD_BRANCH=${{ needs.compute-matrix.outputs.OLD_BRANCH }}
162162
OLD_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda*-${{ inputs.host-platform }}*"
163-
LATEST_PRIOR_RUN_ID=$(gh run list -b ${OLD_BRANCH} -L 1 -w "ci.yml" -s success -R NVIDIA/cuda-python --json databaseId | jq '.[]| .databaseId')
164-
if [[ "$LATEST_PRIOR_RUN_ID" == "" ]]; then
165-
echo "LATEST_PRIOR_RUN_ID not found!"
166-
exit 1
167-
fi
163+
LATEST_PRIOR_RUN_ID=$(bash ./ci/tools/lookup-run-id-by-branch "${OLD_BRANCH}" "${{ github.repository }}")
168164
169-
gh run download $LATEST_PRIOR_RUN_ID -p ${OLD_BASENAME} -R NVIDIA/cuda-python
170-
rm -rf ${OLD_BASENAME}-tests # exclude cython test artifacts
171-
ls -al $OLD_BASENAME
165+
gh run download "${LATEST_PRIOR_RUN_ID}" -p "${OLD_BASENAME}" -R "${{ github.repository }}"
166+
rm -rf "${OLD_BASENAME}-tests" # exclude cython test artifacts
167+
ls -al "${OLD_BASENAME}"
172168
mkdir -p "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
173-
mv $OLD_BASENAME/*.whl "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"/
174-
rmdir $OLD_BASENAME
169+
mv "${OLD_BASENAME}"/*.whl "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"/
170+
rmdir "${OLD_BASENAME}"
175171
176-
gh run download $LATEST_PRIOR_RUN_ID -p cuda-python-wheel -R NVIDIA/cuda-python
172+
gh run download "${LATEST_PRIOR_RUN_ID}" -p cuda-python-wheel -R "${{ github.repository }}"
177173
ls -al cuda-python-wheel
178174
mv cuda-python-wheel/*.whl .
179175
rmdir cuda-python-wheel

‎.github/workflows/test-wheel-windows.yml‎

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -142,27 +142,23 @@ jobs:
142142
if: ${{ env.USE_BACKPORT_BINDINGS == '1' }}
143143
env:
144144
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
145+
shell: bash --noprofile --norc -xeuo pipefail {0}
145146
run: |
146-
$OLD_BRANCH = yq '.backport_branch' ci/versions.yml
147-
$OLD_BASENAME = "cuda-bindings-python${env:PYTHON_VERSION_FORMATTED}-cuda*-${{ inputs.host-platform }}*"
148-
$runData = gh run list -b $OLD_BRANCH -L 1 -w "ci.yml" -s success -R NVIDIA/cuda-python --json databaseId | ConvertFrom-Json
149-
if (-not $runData -or $runData.Length -eq 0 -or -not $runData[0].databaseId -or [string]::IsNullOrEmpty($runData[0].databaseId)) {
150-
Write-Host "LATEST_PRIOR_RUN_ID not found!"
151-
exit 1
152-
}
153-
$LATEST_PRIOR_RUN_ID = $runData[0].databaseId
154-
155-
gh run download $LATEST_PRIOR_RUN_ID -p $OLD_BASENAME -R NVIDIA/cuda-python
156-
Remove-Item -Recurse -Force "${OLD_BASENAME}-tests" # exclude cython test artifacts
157-
Get-ChildItem -Path $OLD_BASENAME
158-
New-Item -Path "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}" -ItemType Directory -Force
159-
Move-Item -Path "$OLD_BASENAME/*.whl" -Destination "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
160-
Remove-Item -Path $OLD_BASENAME -Force
161-
162-
gh run download $LATEST_PRIOR_RUN_ID -p cuda-python-wheel -R NVIDIA/cuda-python
163-
Get-ChildItem -Path cuda-python-wheel
164-
Move-Item -Path "cuda-python-wheel/*.whl" -Destination .
165-
Remove-Item -Path cuda-python-wheel -Force
147+
OLD_BRANCH=$(yq '.backport_branch' ci/versions.yml)
148+
OLD_BASENAME="cuda-bindings-python${PYTHON_VERSION_FORMATTED}-cuda*-${{ inputs.host-platform }}*"
149+
LATEST_PRIOR_RUN_ID=$(bash ./ci/tools/lookup-run-id-by-branch "${OLD_BRANCH}" "${{ github.repository }}")
150+
151+
gh run download "${LATEST_PRIOR_RUN_ID}" -p "${OLD_BASENAME}" -R "${{ github.repository }}"
152+
rm -rf "${OLD_BASENAME}-tests" # exclude cython test artifacts
153+
ls -al "${OLD_BASENAME}"
154+
mkdir -p "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
155+
mv "${OLD_BASENAME}"/*.whl "${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}"
156+
rmdir "${OLD_BASENAME}"
157+
158+
gh run download "${LATEST_PRIOR_RUN_ID}" -p cuda-python-wheel -R "${{ github.repository }}"
159+
ls -al cuda-python-wheel
160+
mv cuda-python-wheel/*.whl .
161+
rmdir cuda-python-wheel
166162
167163
- name: Display structure of downloaded cuda-python artifacts
168164
run: |

‎ci/tools/lookup-run-id-by-branch‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env bash
2+
3+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
4+
#
5+
# SPDX-License-Identifier: Apache-2.0
6+
7+
# Find the latest successful workflow run for a branch.
8+
#
9+
# This intentionally queries completed runs for the workflow name and filters
10+
# for success in jq. In CI, `gh run list --status success` and workflow file
11+
# selectors such as `ci.yml` have proven brittle for this lookup (see PR #1981).
12+
13+
set -euo pipefail
14+
15+
if [[ $# -lt 2 || $# -gt 3 ]]; then
16+
echo "Usage: $0 <branch> <repository> [workflow-name]" >&2
17+
echo " branch: The git branch to find the latest successful run for" >&2
18+
echo " repository: The GitHub repository (e.g., NVIDIA/cuda-python)" >&2
19+
echo " workflow-name: Optional workflow name to filter by (default: CI)" >&2
20+
exit 1
21+
fi
22+
23+
BRANCH="${1}"
24+
REPOSITORY="${2}"
25+
WORKFLOW_NAME="${3:-CI}"
26+
27+
if ! command -v jq >/dev/null 2>&1; then
28+
echo "Error: jq is required but not installed" >&2
29+
exit 1
30+
fi
31+
32+
if ! command -v gh >/dev/null 2>&1; then
33+
echo "Error: GitHub CLI (gh) is required but not installed" >&2
34+
exit 1
35+
fi
36+
37+
echo "Looking up latest successful '${WORKFLOW_NAME}' run on branch '${BRANCH}' in repository '${REPOSITORY}'" >&2
38+
39+
RUN_DATA=$(gh run list \
40+
--repo "${REPOSITORY}" \
41+
--branch "${BRANCH}" \
42+
--workflow "${WORKFLOW_NAME}" \
43+
--status completed \
44+
--json databaseId,workflowName,status,conclusion,headBranch,createdAt,url \
45+
--limit 50)
46+
47+
if [[ -z "${RUN_DATA}" || "${RUN_DATA}" == "[]" ]]; then
48+
echo "Error: No completed '${WORKFLOW_NAME}' workflow runs found for branch '${BRANCH}'." >&2
49+
exit 1
50+
fi
51+
52+
RUN_ID=$(echo "${RUN_DATA}" | jq -r --arg branch "${BRANCH}" --arg workflow "${WORKFLOW_NAME}" '
53+
map(select(
54+
.headBranch == $branch and
55+
.workflowName == $workflow and
56+
.conclusion == "success"
57+
))
58+
| sort_by(.createdAt)
59+
| reverse
60+
| .[0].databaseId // empty
61+
')
62+
63+
if [[ -z "${RUN_ID}" ]]; then
64+
echo "Error: No successful completed '${WORKFLOW_NAME}' workflow runs found for branch '${BRANCH}'." >&2
65+
echo "Completed runs returned by gh:" >&2
66+
echo "${RUN_DATA}" | jq -r '.[] | "\(.databaseId): branch=\(.headBranch // "null"), conclusion=\(.conclusion // "null"), status=\(.status // "null"), createdAt=\(.createdAt // "null"), url=\(.url // "null")"' >&2
67+
exit 1
68+
fi
69+
70+
echo "${RUN_ID}"

0 commit comments

Comments
 (0)