-
Notifications
You must be signed in to change notification settings - Fork 268
[no-ci] CI: Add restricted-paths-guard.yml #1878
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
5c15180
4b650ce
ead62e7
f56a8d1
42ba3f8
a4aa6f0
6f58858
9dcf7b1
c09bb82
bc16d97
539461f
c6753f7
4d4cb84
4563db8
02eacfa
3141d89
16c3faa
71b76d7
02edff4
d452d73
66bd22e
9100985
5a4c8e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2024-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: | ||
| pull-requests: write | ||
| steps: | ||
| - name: Inspect PR author signals for restricted paths | ||
| env: | ||
| # PR metadata inputs | ||
| AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }} | ||
| PR_AUTHOR: ${{ github.event.pull_request.user.login }} | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| PR_URL: ${{ github.event.pull_request.html_url }} | ||
|
|
||
| # Workflow policy inputs | ||
| REVIEW_LABEL: Needs-Restricted-Paths-Review | ||
|
|
||
| # API request context/auth | ||
| GH_TOKEN: ${{ github.token }} | ||
| REPO: ${{ github.repository }} | ||
| run: | | ||
| set -euo pipefail | ||
|
|
||
| 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 "" | ||
| 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 "" | ||
| 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 '```' | ||
| } | ||
|
|
||
| HAS_TRUSTED_SIGNAL=false | ||
| LABEL_ACTION="not needed (no restricted paths)" | ||
| TRUSTED_SIGNALS="(none)" | ||
|
|
||
| if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then | ||
| case "$AUTHOR_ASSOCIATION" in | ||
| COLLABORATOR|MEMBER|OWNER) | ||
| HAS_TRUSTED_SIGNAL=true | ||
| LABEL_ACTION="not needed (author association is a trusted signal)" | ||
| TRUSTED_SIGNALS="author_association:$AUTHOR_ASSOCIATION" | ||
| ;; | ||
| esac | ||
| 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 | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done: commit 66bd22e There is a message in the summary now: + 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."When I gave your feedback to Cursor, it actually added code to remove the label, but I requested to back it out again: I expect this situation to be very rare, and because we're not inspecting individual commits, it's safer to require manual removal. In such cases, we might also want to manually clean up the squash-merge commit message. |
||
| if [ "$NEEDS_REVIEW_LABEL" = "true" ]; then | ||
| if [ "$LABEL_ALREADY_PRESENT" = "true" ]; then | ||
| LABEL_ACTION="already present" | ||
| 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 "" | ||
| write_matching_restricted_paths | ||
| echo "" | ||
| echo "Please update the PR at: $PR_URL" | ||
| } >> "$GITHUB_STEP_SUMMARY" | ||
| exit 1 | ||
| else | ||
| LABEL_ACTION="added" | ||
| 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 "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" | ||
| echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" | ||
| echo "- **Trusted signals**: $TRUSTED_SIGNALS" | ||
| echo "- **Label action**: $LABEL_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" | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlike
pr-metadata-check.ymlwhich skips drafts, this workflow runs on draft PRs too. That's probably fine for early awareness, but worth noting if intentional — especially since the label could be confusing on a WIP draft.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: commit 66bd22e
The label is also for external PR authors, to alert them early.