|
39 | 39 | run: | |
40 | 40 | set -euo pipefail |
41 | 41 |
|
42 | | - # Query the collaborator permission API to get the author's actual |
43 | | - # permission level. This is authoritative regardless of whether the |
44 | | - # PR originates from a fork or a branch in the main repo. |
45 | | - # Returns: admin, maintain, write, triage, read, or none. |
46 | | - COLLABORATOR_PERMISSION=$( |
47 | | - gh api "repos/$REPO/collaborators/$PR_AUTHOR/permission" \ |
48 | | - --jq '.permission' 2>/dev/null || echo "none" |
49 | | - ) |
| 42 | + COLLABORATOR_PERMISSION="not checked" |
| 43 | + COLLABORATOR_PERMISSION_API_ERROR="" |
50 | 44 |
|
51 | 45 | if ! MATCHING_RESTRICTED_PATHS=$( |
52 | 46 | gh api \ |
@@ -112,19 +106,56 @@ jobs: |
112 | 106 | echo '```' |
113 | 107 | } |
114 | 108 |
|
| 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 | +
|
115 | 116 | HAS_TRUSTED_SIGNAL=false |
116 | 117 | LABEL_ACTION="not needed (no restricted paths)" |
117 | 118 | TRUSTED_SIGNALS="(none)" |
118 | 119 |
|
119 | 120 | if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then |
| 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 | +
|
120 | 151 | case "$COLLABORATOR_PERMISSION" in |
121 | 152 | admin|maintain|write) |
122 | 153 | HAS_TRUSTED_SIGNAL=true |
123 | 154 | LABEL_ACTION="not needed (collaborator permission is a trusted signal)" |
124 | 155 | TRUSTED_SIGNALS="collaborator_permission:$COLLABORATOR_PERMISSION" |
125 | 156 | ;; |
126 | 157 | *) |
127 | | - # triage, read, none, or API error: not a trusted signal |
| 158 | + # triage, read, or none: not a trusted signal |
128 | 159 | ;; |
129 | 160 | esac |
130 | 161 | fi |
|
0 commit comments