Skip to content

Commit 90625f6

Browse files
committed
CI: restrict cuda_bindings changes to NVIDIA members
Keep the PR policy workflow self-contained by using the pull request payload and files API to block non-members from modifying low-level bindings. Made-with: Cursor
1 parent 4d8ee87 commit 90625f6

File tree

1 file changed

+56
-6
lines changed

1 file changed

+56
-6
lines changed

.github/workflows/pr-metadata-check.yml

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5-
name: "CI: Enforce assignee/label/milestone on PRs"
5+
name: "CI: Enforce PR metadata and cuda_bindings policy"
66

77
on:
88
pull_request_target:
@@ -19,18 +19,32 @@ on:
1919

2020
jobs:
2121
check-metadata:
22-
name: PR has assignee, labels, and milestone
22+
name: PR has required metadata and valid cuda_bindings author
2323
if: github.repository_owner == 'NVIDIA'
2424
runs-on: ubuntu-latest
25+
permissions:
26+
contents: read
27+
pull-requests: read
2528
steps:
26-
- name: Check for assignee, labels, and milestone
29+
- name: Check PR metadata and cuda_bindings policy
2730
env:
31+
# PR metadata inputs
2832
ASSIGNEES: ${{ toJson(github.event.pull_request.assignees) }}
33+
AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }}
2934
LABELS: ${{ toJson(github.event.pull_request.labels) }}
3035
MILESTONE: ${{ github.event.pull_request.milestone && github.event.pull_request.milestone.title || '' }}
36+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
37+
PR_NUMBER: ${{ github.event.pull_request.number }}
3138
PR_URL: ${{ github.event.pull_request.html_url }}
39+
40+
# Gating booleans
3241
IS_BOT: ${{ github.actor == 'dependabot[bot]' || github.actor == 'pre-commit-ci[bot]' || github.actor == 'copy-pr-bot[bot]' }}
3342
IS_DRAFT: ${{ github.event.pull_request.draft }}
43+
44+
# API request context/auth
45+
GITHUB_API_URL: ${{ github.api_url }}
46+
GH_TOKEN: ${{ github.token }}
47+
REPO: ${{ github.repository }}
3448
run: |
3549
if [ "$IS_BOT" = "true" ] || [ "$IS_DRAFT" = "true" ]; then
3650
echo "Skipping check for bot or draft PR."
@@ -103,10 +117,45 @@ jobs:
103117
ERRORS="${ERRORS}- **Blocked label detected**: label \`$label\` prevents merging. Remove it when the PR is ready.\n"
104118
done <<<"$BLOCKED_LABELS"
105119
120+
# Only NVIDIA organization members may change code under cuda_bindings.
121+
if [ "$AUTHOR_ASSOCIATION" != "MEMBER" ] && [ "$AUTHOR_ASSOCIATION" != "OWNER" ]; then
122+
page=1
123+
TOUCHES_CUDA_BINDINGS=false
124+
while true; do
125+
FILES_JSON=$(curl --silent --show-error --fail \
126+
-H "Authorization: Bearer $GH_TOKEN" \
127+
-H "Accept: application/vnd.github+json" \
128+
-H "X-GitHub-Api-Version: 2022-11-28" \
129+
"$GITHUB_API_URL/repos/$REPO/pulls/$PR_NUMBER/files?per_page=100&page=$page")
130+
131+
if jq -e '
132+
.[]
133+
| select(
134+
(.filename | startswith("cuda_bindings/"))
135+
or ((.previous_filename // "") | startswith("cuda_bindings/"))
136+
)
137+
' <<<"$FILES_JSON" >/dev/null; then
138+
TOUCHES_CUDA_BINDINGS=true
139+
break
140+
fi
141+
142+
FILE_COUNT=$(jq 'length' <<<"$FILES_JSON")
143+
if [ "$FILE_COUNT" -lt 100 ]; then
144+
break
145+
fi
146+
147+
page=$((page + 1))
148+
done
149+
150+
if [ "$TOUCHES_CUDA_BINDINGS" = "true" ]; then
151+
ERRORS="${ERRORS}- **cuda_bindings policy**: See \`cuda_bindings/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` (PR author \`$PR_AUTHOR\` has association \`$AUTHOR_ASSOCIATION\`).\n"
152+
fi
153+
fi
154+
106155
if [ -n "$ERRORS" ]; then
107-
echo "::error::This PR is missing required metadata. See the job summary for details."
156+
echo "::error::This PR failed the required metadata/policy checks. See the job summary for details."
108157
{
109-
echo "## PR Metadata Check Failed"
158+
echo "## PR Requirements Check Failed"
110159
echo ""
111160
printf '%b' "$ERRORS"
112161
echo ""
@@ -118,9 +167,10 @@ jobs:
118167
ASSIGNEE_LIST=$(echo "$ASSIGNEES" | jq -r '.[].login' | paste -sd ', ' -)
119168
LABEL_LIST=$(echo "$LABELS" | jq -r '.[].name' | paste -sd ', ' -)
120169
{
121-
echo "## PR Metadata Check Passed"
170+
echo "## PR Requirements Check Passed"
122171
echo ""
123172
echo "- **Assignees**: $ASSIGNEE_LIST"
124173
echo "- **Labels**: $LABEL_LIST"
125174
echo "- **Milestone**: $MILESTONE"
175+
echo "- **Author association**: $AUTHOR_ASSOCIATION"
126176
} >> "$GITHUB_STEP_SUMMARY"

0 commit comments

Comments
 (0)