Skip to content

Commit 9dcf7b1

Browse files
committed
CI: label PRs without trusted author signals
Use OWNER and MEMBER associations plus public NVIDIA membership as true-positive signals, and add a review label instead of failing when the workflow cannot confirm the author automatically. Made-with: Cursor
1 parent 6f58858 commit 9dcf7b1

1 file changed

Lines changed: 98 additions & 23 deletions

File tree

.github/workflows/pr-author-org-check.yml

Lines changed: 98 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4-
name: "CI: Check PR author organization for restricted paths"
4+
name: "CI: Check PR author signals for restricted paths"
55

66
on:
7+
# Label updates on fork PRs require pull_request_target permissions.
8+
# TODO BEFORE MERGING: change to pull_request_target
79
pull_request:
810
types:
911
- opened
@@ -13,24 +15,33 @@ on:
1315

1416
jobs:
1517
check-author-org:
16-
name: PR author may modify restricted paths
18+
name: PR author signals recorded for restricted paths
1719
if: github.repository_owner == 'NVIDIA'
1820
runs-on: ubuntu-latest
1921
permissions:
22+
issues: write
2023
pull-requests: read
2124
steps:
22-
- name: Check PR author organization for restricted paths
25+
- name: Inspect PR author signals for restricted paths
2326
env:
2427
# PR metadata inputs
2528
AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }}
29+
EXISTING_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }}
2630
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
2731
PR_NUMBER: ${{ github.event.pull_request.number }}
2832
PR_URL: ${{ github.event.pull_request.html_url }}
2933

34+
# Workflow policy inputs
35+
PUBLIC_MEMBER_ORG: NVIDIA
36+
REVIEW_LABEL: Check-PR-author-ORG
37+
3038
# API request context/auth
3139
GH_TOKEN: ${{ github.token }}
40+
GITHUB_API_URL: ${{ github.api_url }}
3241
REPO: ${{ github.repository }}
3342
run: |
43+
set -euo pipefail
44+
3445
if ! MATCHING_RESTRICTED_PATHS=$(
3546
gh api \
3647
--paginate \
@@ -71,40 +82,104 @@ jobs:
7182
echo '```'
7283
}
7384
74-
IS_ALLOWED=false
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+
7590
case "$AUTHOR_ASSOCIATION" in
76-
COLLABORATOR|MEMBER|OWNER)
77-
IS_ALLOWED=true
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"
7896
;;
7997
esac
8098
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
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
97165
fi
98166
99167
{
100-
echo "## PR Author Organization Check Passed"
168+
echo "## PR Author Organization Check Completed"
101169
echo ""
102170
echo "- **Author**: $PR_AUTHOR"
103171
echo "- **Author association**: $AUTHOR_ASSOCIATION"
104172
echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS"
105173
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"
106177
if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then
107178
echo ""
108179
write_matching_restricted_paths
109180
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
110185
} >> "$GITHUB_STEP_SUMMARY"

0 commit comments

Comments
 (0)