|
1 | 1 | # SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. |
2 | 2 | # SPDX-License-Identifier: Apache-2.0 |
3 | 3 |
|
4 | | -name: "CI: Check PR author signals for restricted paths" |
| 4 | +name: "CI: Check PR author organization for restricted paths" |
5 | 5 |
|
6 | 6 | on: |
7 | | - # Label updates on fork PRs require pull_request_target permissions. |
8 | | - # TODO BEFORE MERGING: change to pull_request_target |
9 | 7 | pull_request: |
10 | 8 | types: |
11 | 9 | - opened |
|
15 | 13 |
|
16 | 14 | jobs: |
17 | 15 | check-author-org: |
18 | | - name: PR author signals recorded for restricted paths |
| 16 | + name: PR author may modify restricted paths |
19 | 17 | if: github.repository_owner == 'NVIDIA' |
20 | 18 | runs-on: ubuntu-latest |
21 | 19 | permissions: |
22 | | - issues: write |
23 | 20 | pull-requests: read |
24 | 21 | steps: |
25 | | - - name: Inspect PR author signals for restricted paths |
| 22 | + - name: Check PR author organization for restricted paths |
26 | 23 | env: |
27 | 24 | # PR metadata inputs |
28 | 25 | AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }} |
29 | | - EXISTING_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} |
30 | 26 | PR_AUTHOR: ${{ github.event.pull_request.user.login }} |
31 | 27 | PR_NUMBER: ${{ github.event.pull_request.number }} |
32 | 28 | PR_URL: ${{ github.event.pull_request.html_url }} |
33 | 29 |
|
34 | | - # Workflow policy inputs |
35 | | - PUBLIC_MEMBER_ORG: NVIDIA |
36 | | - REVIEW_LABEL: Check-PR-author-ORG |
37 | | - |
38 | 30 | # API request context/auth |
39 | 31 | GH_TOKEN: ${{ github.token }} |
40 | | - GITHUB_API_URL: ${{ github.api_url }} |
41 | 32 | REPO: ${{ github.repository }} |
42 | 33 | run: | |
43 | | - set -euo pipefail |
44 | | -
|
45 | 34 | if ! MATCHING_RESTRICTED_PATHS=$( |
46 | 35 | gh api \ |
47 | 36 | --paginate \ |
@@ -82,104 +71,40 @@ jobs: |
82 | 71 | echo '```' |
83 | 72 | } |
84 | 73 |
|
85 | | - HAS_TRUE_POSITIVE_SIGNAL=false |
86 | | - LABEL_ACTION="not needed (no restricted paths)" |
87 | | - PUBLIC_MEMBER_CHECK="not needed (no restricted paths)" |
88 | | - TRUE_POSITIVE_SIGNALS="(none)" |
89 | | -
|
| 74 | + IS_ALLOWED=false |
90 | 75 | case "$AUTHOR_ASSOCIATION" in |
91 | | - MEMBER|OWNER) |
92 | | - HAS_TRUE_POSITIVE_SIGNAL=true |
93 | | - LABEL_ACTION="not needed (author association is a true positive)" |
94 | | - PUBLIC_MEMBER_CHECK="skipped (author association is a true positive)" |
95 | | - TRUE_POSITIVE_SIGNALS="author_association:$AUTHOR_ASSOCIATION" |
| 76 | + COLLABORATOR|MEMBER|OWNER) |
| 77 | + IS_ALLOWED=true |
96 | 78 | ;; |
97 | 79 | esac |
98 | 80 |
|
99 | | - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then |
100 | | - PUBLIC_MEMBER_STATUS=$(curl \ |
101 | | - --silent \ |
102 | | - --show-error \ |
103 | | - --output /dev/null \ |
104 | | - --write-out '%{http_code}' \ |
105 | | - -H "Authorization: Bearer $GH_TOKEN" \ |
106 | | - -H "Accept: application/vnd.github+json" \ |
107 | | - -H "X-GitHub-Api-Version: 2022-11-28" \ |
108 | | - "$GITHUB_API_URL/orgs/$PUBLIC_MEMBER_ORG/public_members/$PR_AUTHOR") |
109 | | -
|
110 | | - case "$PUBLIC_MEMBER_STATUS" in |
111 | | - 204) |
112 | | - HAS_TRUE_POSITIVE_SIGNAL=true |
113 | | - LABEL_ACTION="not needed (public org membership is a true positive)" |
114 | | - PUBLIC_MEMBER_CHECK="204 (public member)" |
115 | | - TRUE_POSITIVE_SIGNALS="public_org_membership:$PUBLIC_MEMBER_ORG" |
116 | | - ;; |
117 | | - 404) |
118 | | - PUBLIC_MEMBER_CHECK="404 (not a public member)" |
119 | | - ;; |
120 | | - *) |
121 | | - echo "::error::Failed to determine whether the PR author is a public $PUBLIC_MEMBER_ORG member." |
122 | | - { |
123 | | - echo "## PR Author Organization Check Failed" |
124 | | - echo "" |
125 | | - echo "- **Error**: Unexpected HTTP status from \`/orgs/$PUBLIC_MEMBER_ORG/public_members/$PR_AUTHOR\`: \`$PUBLIC_MEMBER_STATUS\`." |
126 | | - echo "- **Author**: $PR_AUTHOR" |
127 | | - echo "- **Author association**: $AUTHOR_ASSOCIATION" |
128 | | - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" |
129 | | - echo "" |
130 | | - write_matching_restricted_paths |
131 | | - echo "" |
132 | | - echo "Please update the PR at: $PR_URL" |
133 | | - } >> "$GITHUB_STEP_SUMMARY" |
134 | | - exit 1 |
135 | | - ;; |
136 | | - esac |
137 | | - fi |
138 | | -
|
139 | | - LABEL_ALREADY_PRESENT=false |
140 | | - if jq -e --arg label "$REVIEW_LABEL" '.[] == $label' <<<"$EXISTING_LABELS" >/dev/null; then |
141 | | - LABEL_ALREADY_PRESENT=true |
142 | | - fi |
143 | | -
|
144 | | - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then |
145 | | - if [ "$LABEL_ALREADY_PRESENT" = "true" ]; then |
146 | | - LABEL_ACTION="already present" |
147 | | - elif ! gh issue edit "$PR_NUMBER" --repo "$REPO" --add-label "$REVIEW_LABEL"; then |
148 | | - echo "::error::Failed to add the $REVIEW_LABEL label." |
149 | | - { |
150 | | - echo "## PR Author Organization Check Failed" |
151 | | - echo "" |
152 | | - echo "- **Error**: Failed to add the \`$REVIEW_LABEL\` label." |
153 | | - echo "- **Author**: $PR_AUTHOR" |
154 | | - echo "- **Author association**: $AUTHOR_ASSOCIATION" |
155 | | - echo "- **Public $PUBLIC_MEMBER_ORG membership check**: $PUBLIC_MEMBER_CHECK" |
156 | | - echo "" |
157 | | - write_matching_restricted_paths |
158 | | - echo "" |
159 | | - echo "Please update the PR at: $PR_URL" |
160 | | - } >> "$GITHUB_STEP_SUMMARY" |
161 | | - exit 1 |
162 | | - else |
163 | | - LABEL_ACTION="added" |
164 | | - fi |
| 81 | + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$IS_ALLOWED" = "false" ]; then |
| 82 | + echo "::error::This PR failed the author organization check. See the job summary for details." |
| 83 | + { |
| 84 | + echo "## PR Author Organization Check Failed" |
| 85 | + echo "" |
| 86 | + echo "- **Author**: $PR_AUTHOR" |
| 87 | + echo "- **Author association**: $AUTHOR_ASSOCIATION" |
| 88 | + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" |
| 89 | + echo "" |
| 90 | + write_matching_restricted_paths |
| 91 | + echo "" |
| 92 | + echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." |
| 93 | + echo "" |
| 94 | + echo "Please update the PR at: $PR_URL" |
| 95 | + } >> "$GITHUB_STEP_SUMMARY" |
| 96 | + exit 1 |
165 | 97 | fi |
166 | 98 |
|
167 | 99 | { |
168 | | - echo "## PR Author Organization Check Completed" |
| 100 | + echo "## PR Author Organization Check Passed" |
169 | 101 | echo "" |
170 | 102 | echo "- **Author**: $PR_AUTHOR" |
171 | 103 | echo "- **Author association**: $AUTHOR_ASSOCIATION" |
172 | 104 | echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" |
173 | 105 | echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" |
174 | | - echo "- **Public $PUBLIC_MEMBER_ORG membership check**: $PUBLIC_MEMBER_CHECK" |
175 | | - echo "- **True positive signals**: $TRUE_POSITIVE_SIGNALS" |
176 | | - echo "- **Label action**: $LABEL_ACTION" |
177 | 106 | if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then |
178 | 107 | echo "" |
179 | 108 | write_matching_restricted_paths |
180 | 109 | fi |
181 | | - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then |
182 | | - echo "" |
183 | | - echo "- **Manual follow-up**: No true positive signal was found, so \`$REVIEW_LABEL\` is required." |
184 | | - fi |
185 | 110 | } >> "$GITHUB_STEP_SUMMARY" |
0 commit comments