Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.

Check failure on line 1 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

1:81 [line-length] line too long (103 > 80 characters)
#
# SPDX-License-Identifier: Apache-2.0

name: "CI: Release"

Check warning on line 5 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

5:1 [document-start] missing document start "---"

description: Manually-triggered release workflow. Creates a release draft if one doesn't exist for the given tag, or uses existing draft.

Check failure on line 7 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

7:81 [line-length] line too long (137 > 80 characters)

on:

Check warning on line 9 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

9:1 [truthy] truthy value should be one of [false, true]
workflow_dispatch:
inputs:
component:
Expand All @@ -24,8 +24,8 @@
required: true
type: string
run-id:
description: "The GHA run ID that generated validated artifacts"
required: true
description: "The GHA run ID that generated validated artifacts (optional - will be auto-detected from git tag if not provided)"

Check failure on line 27 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

27:81 [line-length] line too long (136 > 80 characters)
required: false
Comment thread
leofang marked this conversation as resolved.
type: string
build-ctk-ver:
type: string
Expand All @@ -43,12 +43,37 @@
shell: bash --noprofile --norc -xeuo pipefail {0}

jobs:
determine-run-id:
runs-on: ubuntu-latest
outputs:
run-id: ${{ steps.lookup-run-id.outputs.run-id }}
steps:
- name: Checkout Source
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:

Check failure on line 53 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

53:81 [line-length] line too long (81 > 80 characters)
fetch-depth: 0
Comment thread
leofang marked this conversation as resolved.

- name: Determine Run ID
id: lookup-run-id
env:
GH_TOKEN: ${{ github.token }}
run: |
if [[ -n "${{ inputs.run-id }}" ]]; then
echo "Using provided run ID: ${{ inputs.run-id }}"
echo "run-id=${{ inputs.run-id }}" >> $GITHUB_OUTPUT
else
echo "Auto-detecting run ID for tag: ${{ inputs.git-tag }}"
RUN_ID=$(./ci/tools/lookup-run-id "${{ inputs.git-tag }}" "${{ github.repository }}")
echo "Auto-detected run ID: $RUN_ID"

Check failure on line 67 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

67:81 [line-length] line too long (97 > 80 characters)
echo "run-id=$RUN_ID" >> $GITHUB_OUTPUT
fi

check-tag:
runs-on: ubuntu-latest
steps:
- name: Checkout Source
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
with:

Check failure on line 76 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

76:81 [line-length] line too long (81 > 80 characters)
fetch-depth: 0

- name: Check or create draft release for the tag
Expand All @@ -57,11 +82,11 @@
run: |
tags=
for i in $(gh release list -R ${{ github.repository }} --json tagName --jq '.[]| .tagName'); do
tags+=( $i )

Check failure on line 85 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

85:81 [line-length] line too long (105 > 80 characters)
done
is_draft=
for i in $(gh release list -R ${{ github.repository }} --json isDraft --jq '.[]| .isDraft'); do
is_draft+=( $i )

Check failure on line 89 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

89:81 [line-length] line too long (105 > 80 characters)
done

found=0
Expand All @@ -78,8 +103,8 @@
done
if [[ "$found" == 0 ]]; then
echo "no release found for ${{ inputs.git-tag }}, creating draft release"
gh release create "${{ inputs.git-tag }}" --draft --repo "${{ github.repository }}" --title "Release ${{ inputs.git-tag }}" --notes "Release ${{ inputs.git-tag }}"

Check failure on line 106 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

106:81 [line-length] line too long (85 > 80 characters)
fi

Check failure on line 107 in .github/workflows/release.yml

View workflow job for this annotation

GitHub Actions / copilot

107:81 [line-length] line too long (175 > 80 characters)

doc:
name: Build release docs
Expand All @@ -91,13 +116,14 @@
pull-requests: write
needs:
- check-tag
- determine-run-id
secrets: inherit
uses: ./.github/workflows/build-docs.yml
with:
build-ctk-ver: ${{ inputs.build-ctk-ver }}
component: ${{ inputs.component }}
git-tag: ${{ inputs.git-tag }}
run-id: ${{ inputs.run-id }}
run-id: ${{ needs.determine-run-id.outputs.run-id }}
is-release: true

upload-archive:
Expand All @@ -106,18 +132,20 @@
contents: write
needs:
- check-tag
- determine-run-id
secrets: inherit
uses: ./.github/workflows/release-upload.yml
with:
git-tag: ${{ inputs.git-tag }}
run-id: ${{ inputs.run-id }}
run-id: ${{ needs.determine-run-id.outputs.run-id }}
component: ${{ inputs.component }}

publish-wheels:
name: Publish wheels
runs-on: ubuntu-latest
needs:
- check-tag
- determine-run-id
environment:
name: ${{ inputs.wheel-dst }}
url: https://${{ (inputs.wheel-dst == 'testpypi' && 'test.') || '' }}pypi.org/p/${{ inputs.component }}/
Expand All @@ -131,7 +159,7 @@
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./ci/tools/download-wheels "${{ inputs.run-id }}" "${{ inputs.component }}" "${{ github.repository }}" "dist"
./ci/tools/download-wheels "${{ needs.determine-run-id.outputs.run-id }}" "${{ inputs.component }}" "${{ github.repository }}" "dist"

- name: Publish package distributions to PyPI
if: ${{ inputs.wheel-dst == 'pypi' }}
Expand All @@ -144,3 +172,3 @@
repository-url: https://test.pypi.org/legacy/

# TODO: add another job to make the release leave the draft state?
99 changes: 99 additions & 0 deletions ci/tools/lookup-run-id
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env bash

# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
Comment thread
leofang marked this conversation as resolved.

# A utility script to find the GitHub Actions workflow run ID for a given git tag.
# This script looks for the CI workflow run that corresponds to the commit of the given tag.

set -euo pipefail

# Check required arguments
if [[ $# -lt 2 ]]; then
echo "Usage: $0 <git-tag> <repository> [workflow-name]" >&2
Comment thread
leofang marked this conversation as resolved.
echo " git-tag: The git tag to find the corresponding workflow run for" >&2
echo " repository: The GitHub repository (e.g., NVIDIA/cuda-python)" >&2
echo " workflow-name: Optional workflow name to filter by (default: CI)" >&2
echo "" >&2
echo "Examples:" >&2
echo " $0 v13.0.1 NVIDIA/cuda-python" >&2
echo " $0 v13.0.1 NVIDIA/cuda-python \"CI\"" >&2
exit 1
fi

GIT_TAG="$1"
Comment thread
leofang marked this conversation as resolved.
Outdated
REPOSITORY="$2"
WORKFLOW_NAME="${3:-CI}"

# Ensure we have required tools
if [[ -z "${GH_TOKEN:-}" ]]; then
echo "Error: GH_TOKEN environment variable is required" >&2
exit 1
fi

if ! command -v jq >/dev/null 2>&1; then
echo "Error: jq is required but not installed" >&2
exit 1
fi

if ! command -v gh >/dev/null 2>&1; then
echo "Error: GitHub CLI (gh) is required but not installed" >&2
exit 1
fi

echo "Looking up run ID for tag: $GIT_TAG in repository: $REPOSITORY" >&2

# Resolve git tag to commit SHA
if ! COMMIT_SHA=$(git rev-parse "$GIT_TAG" 2>/dev/null); then
Comment thread
leofang marked this conversation as resolved.
Outdated
echo "Error: Could not resolve git tag '$GIT_TAG' to a commit SHA" >&2
echo "Make sure the tag exists and you have fetched it" >&2
exit 1
fi

echo "Resolved tag '$GIT_TAG' to commit: $COMMIT_SHA" >&2

# Find workflow runs for this commit
echo "Searching for '$WORKFLOW_NAME' workflow runs for commit: $COMMIT_SHA" >&2

# Get workflow runs for the commit, filter by workflow name and successful status
RUN_DATA=$(gh run list \
--repo "$REPOSITORY" \
--commit "$COMMIT_SHA" \
--workflow "$WORKFLOW_NAME" \
--status completed \
--json databaseId,workflowName,status,conclusion,headSha \
--limit 10)

if [[ -z "$RUN_DATA" || "$RUN_DATA" == "[]" ]]; then
echo "Error: No completed '$WORKFLOW_NAME' workflow runs found for commit $COMMIT_SHA" >&2
echo "Available workflow runs for this commit:" >&2
gh run list --repo "$REPOSITORY" --commit "$COMMIT_SHA" --limit 10 || true
exit 1
fi

# Filter for successful runs (conclusion = success) and extract the run ID from the first one
RUN_ID=$(echo "$RUN_DATA" | jq -r '.[] | select(.conclusion == "success") | .databaseId' | head -1)

if [[ -z "$RUN_ID" || "$RUN_ID" == "null" ]]; then
echo "Error: No successful '$WORKFLOW_NAME' workflow runs found for commit $COMMIT_SHA" >&2
echo "Available workflow runs for this commit:" >&2
gh run list --repo "$REPOSITORY" --commit "$COMMIT_SHA" --limit 10 || true
echo "" >&2
echo "Completed runs with their conclusions:" >&2
echo "$RUN_DATA" | jq -r '.[] | "\(.databaseId): \(.conclusion)"' >&2
exit 1
fi

echo "Found workflow run ID: $RUN_ID for tag '$GIT_TAG'" >&2

# Verify the run has the expected artifacts by checking if there are any artifacts
echo "Verifying artifacts exist for run $RUN_ID..." >&2
ARTIFACT_LIST=$(gh run view "$RUN_ID" --repo "$REPOSITORY" --json url 2>/dev/null || echo "")
Comment thread
leofang marked this conversation as resolved.
Outdated

if [[ -z "$ARTIFACT_LIST" ]]; then
echo "Warning: Could not verify artifacts for workflow run $RUN_ID" >&2
fi

# Output the run ID (this is what gets used by calling scripts)
echo "$RUN_ID"