@@ -19,12 +19,13 @@ jobs:
1919 if : github.repository_owner == 'NVIDIA'
2020 runs-on : ubuntu-latest
2121 permissions :
22+ contents : write # needed for collaborator permission check
2223 pull-requests : write
2324 steps :
2425 - name : Inspect PR author signals for restricted paths
2526 env :
26- # PR metadata inputs
27- AUTHOR_ASSOCIATION : ${{ github.event.pull_request.author_association || 'NONE' }}
27+ # PR metadata inputs (author_association from event payload is
28+ # unreliable for fork PRs, so we query the collaborator API directly)
2829 PR_AUTHOR : ${{ github.event.pull_request.user.login }}
2930 PR_NUMBER : ${{ github.event.pull_request.number }}
3031 PR_URL : ${{ github.event.pull_request.html_url }}
3839 run : |
3940 set -euo pipefail
4041
42+ COLLABORATOR_PERMISSION="not checked"
43+ COLLABORATOR_PERMISSION_API_ERROR=""
44+
4145 if ! MATCHING_RESTRICTED_PATHS=$(
4246 gh api \
4347 --paginate \
6367 echo ""
6468 echo "- **Error**: Failed to inspect the PR file list."
6569 echo "- **Author**: $PR_AUTHOR"
66- echo "- **Author association **: $AUTHOR_ASSOCIATION "
70+ echo "- **Collaborator permission **: $COLLABORATOR_PERMISSION "
6771 echo ""
6872 echo "Please update the PR at: $PR_URL"
6973 } >> "$GITHUB_STEP_SUMMARY"
8387 echo ""
8488 echo "- **Error**: Failed to inspect the current PR labels."
8589 echo "- **Author**: $PR_AUTHOR"
86- echo "- **Author association **: $AUTHOR_ASSOCIATION "
90+ echo "- **Collaborator permission **: $COLLABORATOR_PERMISSION "
8791 echo ""
8892 echo "Please update the PR at: $PR_URL"
8993 } >> "$GITHUB_STEP_SUMMARY"
@@ -102,16 +106,56 @@ jobs:
102106 echo '```'
103107 }
104108
109+ write_collaborator_permission_api_error() {
110+ echo "- **Collaborator permission API error**:"
111+ echo '```text'
112+ printf '%s\n' "$COLLABORATOR_PERMISSION_API_ERROR"
113+ echo '```'
114+ }
115+
105116 HAS_TRUSTED_SIGNAL=false
106117 LABEL_ACTION="not needed (no restricted paths)"
107118 TRUSTED_SIGNALS="(none)"
108119
109120 if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then
110- case "$AUTHOR_ASSOCIATION" in
111- COLLABORATOR|MEMBER|OWNER)
121+ # Distinguish a legitimate 404 "not a collaborator" response from
122+ # actual API failures. The former is an expected untrusted case;
123+ # the latter fails the workflow so it can be rerun later.
124+ if COLLABORATOR_PERMISSION_RESPONSE=$(
125+ gh api "repos/$REPO/collaborators/$PR_AUTHOR/permission" \
126+ --jq '.permission' 2>&1
127+ ); then
128+ COLLABORATOR_PERMISSION="$COLLABORATOR_PERMISSION_RESPONSE"
129+ elif [[ "$COLLABORATOR_PERMISSION_RESPONSE" == *"(HTTP 404)"* ]]; then
130+ COLLABORATOR_PERMISSION="none"
131+ else
132+ COLLABORATOR_PERMISSION="unknown"
133+ COLLABORATOR_PERMISSION_API_ERROR="$COLLABORATOR_PERMISSION_RESPONSE"
134+ echo "::error::Failed to inspect collaborator permission for $PR_AUTHOR."
135+ {
136+ echo "## Restricted Paths Guard Failed"
137+ echo ""
138+ echo "- **Error**: Failed to inspect collaborator permission."
139+ echo "- **Author**: $PR_AUTHOR"
140+ echo "- **Collaborator permission**: $COLLABORATOR_PERMISSION"
141+ echo ""
142+ write_matching_restricted_paths
143+ echo ""
144+ write_collaborator_permission_api_error
145+ echo ""
146+ echo "Please retry this workflow. If the failure persists, inspect the collaborator permission API error above."
147+ } >> "$GITHUB_STEP_SUMMARY"
148+ exit 1
149+ fi
150+
151+ case "$COLLABORATOR_PERMISSION" in
152+ admin|maintain|write)
112153 HAS_TRUSTED_SIGNAL=true
113- LABEL_ACTION="not needed (author association is a trusted signal)"
114- TRUSTED_SIGNALS="author_association:$AUTHOR_ASSOCIATION"
154+ LABEL_ACTION="not needed (collaborator permission is a trusted signal)"
155+ TRUSTED_SIGNALS="collaborator_permission:$COLLABORATOR_PERMISSION"
156+ ;;
157+ *)
158+ # triage, read, or none: not a trusted signal
115159 ;;
116160 esac
117161 fi
@@ -136,7 +180,7 @@ jobs:
136180 echo ""
137181 echo "- **Error**: Failed to add the \`$REVIEW_LABEL\` label."
138182 echo "- **Author**: $PR_AUTHOR"
139- echo "- **Author association **: $AUTHOR_ASSOCIATION "
183+ echo "- **Collaborator permission **: $COLLABORATOR_PERMISSION "
140184 echo ""
141185 write_matching_restricted_paths
142186 echo ""
@@ -154,7 +198,7 @@ jobs:
154198 echo "## Restricted Paths Guard Completed"
155199 echo ""
156200 echo "- **Author**: $PR_AUTHOR"
157- echo "- **Author association **: $AUTHOR_ASSOCIATION "
201+ echo "- **Collaborator permission **: $COLLABORATOR_PERMISSION "
158202 echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS"
159203 echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`"
160204 echo "- **Trusted signals**: $TRUSTED_SIGNALS"
0 commit comments