[doc-only] cuda.core: document how to install nightly (top-of-tree) builds #1274
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| # SPDX-License-Identifier: Apache-2.0 | |
| name: "CI: Restricted Paths Guard" | |
| on: | |
| # Run on drafts too so maintainers get early awareness on WIP PRs. | |
| # Label updates on fork PRs require pull_request_target permissions. | |
| pull_request_target: | |
| types: | |
| - opened | |
| - synchronize | |
| - reopened | |
| - ready_for_review | |
| jobs: | |
| restricted-paths-guard: | |
| name: Apply review label if needed | |
| if: github.repository_owner == 'NVIDIA' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write # needed for collaborator permission check | |
| pull-requests: write | |
| steps: | |
| - name: Inspect PR author signals for restricted paths | |
| env: | |
| # PR metadata inputs (the event payload's author_association can be | |
| # stale for fork PRs, so restricted-path PRs query the live PR API). | |
| PR_AUTHOR: ${{ github.event.pull_request.user.login }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| PR_URL: ${{ github.event.pull_request.html_url }} | |
| RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| # Workflow policy inputs | |
| REVIEW_LABEL: Needs-Restricted-Paths-Review | |
| # Temporary testing recipe for agents: | |
| # 1. Change pull_request_target to pull_request. | |
| # 2. Set DRY_RUN_REVIEW_LABEL_WRITES to true. | |
| # 3. Add a dummy comment or whitespace-only change in | |
| # cuda_bindings/README.md to trigger restricted-path detection | |
| # without affecting build/package behavior. | |
| # 4. Replace both trusted case patterns below with DRY_RUN_NEVER_MATCH | |
| # so the test does not depend on the tester's GitHub identity: | |
| # MEMBER|OWNER and admin|maintain|write|triage. | |
| # 5. Commit these changes as a temporary dry-run test commit and revert | |
| # that commit before merge. | |
| DRY_RUN_REVIEW_LABEL_WRITES: false | |
| # API request context/auth | |
| GH_TOKEN: ${{ github.token }} | |
| REPO: ${{ github.repository }} | |
| run: | | |
| set -euo pipefail | |
| COLLABORATOR_PERMISSION="not checked" | |
| COLLABORATOR_PERMISSION_API_ERROR="" | |
| AUTHOR_ASSOCIATION="not checked" | |
| AUTHOR_ASSOCIATION_API_ERROR="" | |
| if ! MATCHING_RESTRICTED_PATHS=$( | |
| gh api \ | |
| --paginate \ | |
| --jq ' | |
| .[] | |
| | select( | |
| (.filename | startswith("cuda_bindings/")) | |
| or ((.previous_filename // "") | startswith("cuda_bindings/")) | |
| or (.filename | startswith("cuda_python/")) | |
| or ((.previous_filename // "") | startswith("cuda_python/")) | |
| ) | |
| | if (.previous_filename // "") != "" then | |
| "\(.previous_filename) -> \(.filename)" | |
| else | |
| .filename | |
| end | |
| ' \ | |
| "repos/$REPO/pulls/$PR_NUMBER/files" | |
| ); then | |
| echo "::error::Failed to inspect the PR file list." | |
| { | |
| echo "## Restricted Paths Guard Failed" | |
| echo "" | |
| echo "- **Error**: Failed to inspect the PR file list." | |
| echo "- **Author**: $PR_AUTHOR" | |
| echo "- **Author association**: $AUTHOR_ASSOCIATION" | |
| echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION" | |
| echo "" | |
| echo "Please update the PR at: $PR_URL" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| exit 1 | |
| fi | |
| # Fetch live PR labels to avoid stale event payload (race condition | |
| # when labels are changed shortly before the workflow runs). | |
| if ! LIVE_LABELS=$( | |
| gh pr view "${PR_NUMBER}" --repo "${REPO}" \ | |
| --json labels \ | |
| --jq '[.labels[].name]' | |
| ); then | |
| echo "::error::Failed to inspect the current PR labels." | |
| { | |
| echo "## Restricted Paths Guard Failed" | |
| echo "" | |
| echo "- **Error**: Failed to inspect the current PR labels." | |
| echo "- **Author**: $PR_AUTHOR" | |
| echo "- **Author association**: $AUTHOR_ASSOCIATION" | |
| echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION" | |
| echo "" | |
| echo "Please update the PR at: $PR_URL" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| exit 1 | |
| fi | |
| TOUCHES_RESTRICTED_PATHS=false | |
| if [ -n "$MATCHING_RESTRICTED_PATHS" ]; then | |
| TOUCHES_RESTRICTED_PATHS=true | |
| fi | |
| write_matching_restricted_paths() { | |
| echo "- **Matched restricted paths**:" | |
| echo '```text' | |
| printf '%s\n' "$MATCHING_RESTRICTED_PATHS" | |
| echo '```' | |
| } | |
| write_collaborator_permission_api_error() { | |
| echo "- **Collaborator permission API error**:" | |
| echo '```text' | |
| printf '%s\n' "$COLLABORATOR_PERMISSION_API_ERROR" | |
| echo '```' | |
| } | |
| write_author_association_api_error() { | |
| echo "- **Author association API error**:" | |
| echo '```text' | |
| printf '%s\n' "$AUTHOR_ASSOCIATION_API_ERROR" | |
| echo '```' | |
| } | |
| build_review_label_comment() { | |
| printf '%s\n\n%s\n\n%s\n\n%s\n\n%s\n' \ | |
| "\`$REVIEW_LABEL\` was assigned by \`CI: Restricted Paths Guard\`." \ | |
| "For details, open [this workflow run]($RUN_URL) and click **Summary**." \ | |
| "For external contributors: thank you for your interest in improving CUDA Python. The \`cuda_bindings/\` package is distributed under the [NVIDIA Software License](https://github.com/NVIDIA/cuda-python/blob/main/cuda_bindings/LICENSE), which does not allow us to accept external contributions to files under \`cuda_bindings/\` in this repository." \ | |
| "Please close this PR. If your changes also include updates outside \`cuda_bindings/\`, please open a new PR containing only those changes so we can review them separately under the applicable license." \ | |
| "If you are an NVIDIA employee and believe this label was applied in error, no action is needed; a maintainer will review and remove the label if appropriate." | |
| } | |
| write_review_label_comment_dry_run() { | |
| echo "- **Dry-run comment body**:" | |
| echo '```markdown' | |
| build_review_label_comment | |
| echo '```' | |
| } | |
| post_review_label_comment() { | |
| local comment_body | |
| comment_body=$(build_review_label_comment) | |
| if gh api "repos/$REPO/issues/$PR_NUMBER/comments" \ | |
| -f body="$comment_body" >/dev/null; then | |
| COMMENT_ACTION="posted" | |
| else | |
| COMMENT_ACTION="failed (non-fatal)" | |
| echo "::warning::Failed to post PR comment about newly added $REVIEW_LABEL." | |
| fi | |
| } | |
| HAS_TRUSTED_SIGNAL=false | |
| LABEL_ACTION="not needed (no restricted paths)" | |
| TRUSTED_SIGNALS="(none)" | |
| COMMENT_ACTION="not needed" | |
| if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then | |
| if AUTHOR_ASSOCIATION_RESPONSE=$( | |
| gh api "repos/$REPO/pulls/$PR_NUMBER" \ | |
| --jq '.author_association // "NONE"' 2>&1 | |
| ); then | |
| AUTHOR_ASSOCIATION="$AUTHOR_ASSOCIATION_RESPONSE" | |
| else | |
| AUTHOR_ASSOCIATION="unknown" | |
| AUTHOR_ASSOCIATION_API_ERROR="$AUTHOR_ASSOCIATION_RESPONSE" | |
| echo "::error::Failed to inspect live author association for PR #$PR_NUMBER." | |
| { | |
| echo "## Restricted Paths Guard Failed" | |
| echo "" | |
| echo "- **Error**: Failed to inspect live author association." | |
| echo "- **Author**: $PR_AUTHOR" | |
| echo "- **Author association**: $AUTHOR_ASSOCIATION" | |
| echo "" | |
| write_matching_restricted_paths | |
| echo "" | |
| write_author_association_api_error | |
| echo "" | |
| echo "Please retry this workflow. If the failure persists, inspect the author association API error above." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| exit 1 | |
| fi | |
| case "$AUTHOR_ASSOCIATION" in | |
| MEMBER|OWNER) | |
| HAS_TRUSTED_SIGNAL=true | |
| LABEL_ACTION="not needed (live author association is a trusted signal)" | |
| TRUSTED_SIGNALS="author_association:$AUTHOR_ASSOCIATION" | |
| ;; | |
| *) | |
| # COLLABORATOR can still be too broad for this policy; use the | |
| # collaborator permission API below for repo-level trust. | |
| ;; | |
| esac | |
| # Distinguish a legitimate 404 "not a collaborator" response from | |
| # actual API failures. The former is an expected untrusted case; | |
| # the latter fails the workflow so it can be rerun later. | |
| if [ "$HAS_TRUSTED_SIGNAL" = "false" ]; then | |
| if COLLABORATOR_PERMISSION_RESPONSE=$( | |
| gh api "repos/$REPO/collaborators/$PR_AUTHOR/permission" \ | |
| --jq '.permission' 2>&1 | |
| ); then | |
| COLLABORATOR_PERMISSION="$COLLABORATOR_PERMISSION_RESPONSE" | |
| elif [[ "$COLLABORATOR_PERMISSION_RESPONSE" == *"(HTTP 404)"* ]]; then | |
| COLLABORATOR_PERMISSION="none" | |
| else | |
| COLLABORATOR_PERMISSION="unknown" | |
| COLLABORATOR_PERMISSION_API_ERROR="$COLLABORATOR_PERMISSION_RESPONSE" | |
| echo "::error::Failed to inspect collaborator permission for $PR_AUTHOR." | |
| { | |
| echo "## Restricted Paths Guard Failed" | |
| echo "" | |
| echo "- **Error**: Failed to inspect collaborator permission." | |
| echo "- **Author**: $PR_AUTHOR" | |
| echo "- **Author association**: $AUTHOR_ASSOCIATION" | |
| echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION" | |
| echo "" | |
| write_matching_restricted_paths | |
| echo "" | |
| write_collaborator_permission_api_error | |
| echo "" | |
| echo "Please retry this workflow. If the failure persists, inspect the collaborator permission API error above." | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| exit 1 | |
| fi | |
| case "$COLLABORATOR_PERMISSION" in | |
| admin|maintain|write|triage) | |
| HAS_TRUSTED_SIGNAL=true | |
| LABEL_ACTION="not needed (collaborator permission is a trusted signal)" | |
| TRUSTED_SIGNALS="collaborator_permission:$COLLABORATOR_PERMISSION" | |
| ;; | |
| *) | |
| # read or none: not a trusted signal. In a public repo, read | |
| # can be the effective permission for any GitHub user. | |
| ;; | |
| esac | |
| fi | |
| fi | |
| NEEDS_REVIEW_LABEL=false | |
| if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUSTED_SIGNAL" = "false" ]; then | |
| NEEDS_REVIEW_LABEL=true | |
| fi | |
| LABEL_ALREADY_PRESENT=false | |
| if jq -e --arg label "$REVIEW_LABEL" '.[] == $label' <<<"$LIVE_LABELS" >/dev/null; then | |
| LABEL_ALREADY_PRESENT=true | |
| fi | |
| if [ "$NEEDS_REVIEW_LABEL" = "true" ]; then | |
| if [ "$LABEL_ALREADY_PRESENT" = "true" ]; then | |
| LABEL_ACTION="already present" | |
| elif [ "$DRY_RUN_REVIEW_LABEL_WRITES" = "true" ]; then | |
| LABEL_ACTION="would add (dry run)" | |
| COMMENT_ACTION="would post (dry run)" | |
| { | |
| echo "## Restricted Paths Guard Dry Run" | |
| echo "" | |
| echo "- **Would add label**: \`$REVIEW_LABEL\`" | |
| echo "" | |
| write_review_label_comment_dry_run | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| elif ! gh pr edit "$PR_NUMBER" --repo "$REPO" --add-label "$REVIEW_LABEL"; then | |
| echo "::error::Failed to add the $REVIEW_LABEL label." | |
| { | |
| echo "## Restricted Paths Guard Failed" | |
| echo "" | |
| echo "- **Error**: Failed to add the \`$REVIEW_LABEL\` label." | |
| echo "- **Author**: $PR_AUTHOR" | |
| echo "- **Author association**: $AUTHOR_ASSOCIATION" | |
| echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION" | |
| echo "" | |
| write_matching_restricted_paths | |
| echo "" | |
| echo "Please update the PR at: $PR_URL" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| exit 1 | |
| else | |
| LABEL_ACTION="added" | |
| post_review_label_comment | |
| fi | |
| elif [ "$LABEL_ALREADY_PRESENT" = "true" ]; then | |
| LABEL_ACTION="left in place (manual removal required)" | |
| fi | |
| { | |
| echo "## Restricted Paths Guard Completed" | |
| echo "" | |
| echo "- **Author**: $PR_AUTHOR" | |
| echo "- **Author association**: $AUTHOR_ASSOCIATION" | |
| echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION" | |
| echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" | |
| echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" | |
| echo "- **Trusted signals**: $TRUSTED_SIGNALS" | |
| echo "- **Label action**: $LABEL_ACTION" | |
| echo "- **Comment action**: $COMMENT_ACTION" | |
| if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then | |
| echo "" | |
| write_matching_restricted_paths | |
| fi | |
| if [ "$NEEDS_REVIEW_LABEL" = "true" ]; then | |
| echo "" | |
| echo "- **Manual follow-up**: No trusted signal was found, so \`$REVIEW_LABEL\` is required." | |
| elif [ "$LABEL_ALREADY_PRESENT" = "true" ]; then | |
| echo "" | |
| echo "- **Manual follow-up**: Existing \`$REVIEW_LABEL\` was left in place intentionally because this workflow does not inspect every commit. Remove it manually after reviewing the PR for restricted-paths policy compliance." | |
| fi | |
| } >> "$GITHUB_STEP_SUMMARY" |