From 5c1518006b1926f290295baab2e5031f7833c3e4 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 7 Apr 2026 14:52:01 -0700 Subject: [PATCH 01/12] CI: add PR author organization check Report restricted-path author gating as its own workflow so contributors see the organization requirement as soon as a PR touches cuda_bindings/ or cuda_python/. Made-with: Cursor --- .github/workflows/pr-author-org-check.yml | 93 +++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .github/workflows/pr-author-org-check.yml diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml new file mode 100644 index 0000000000..6bd4ca6b48 --- /dev/null +++ b/.github/workflows/pr-author-org-check.yml @@ -0,0 +1,93 @@ +# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +name: "CI: Check PR author organization for restricted paths" + +on: + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + +jobs: + check-author-org: + name: PR author may modify restricted paths + if: github.repository_owner == 'NVIDIA' + runs-on: ubuntu-latest + permissions: + pull-requests: read + steps: + - name: Check PR author organization for restricted paths + env: + # PR metadata inputs + AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }} + PR_AUTHOR: ${{ github.event.pull_request.user.login }} + PR_NUMBER: ${{ github.event.pull_request.number }} + PR_URL: ${{ github.event.pull_request.html_url }} + + # API request context/auth + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + run: | + if ! TOUCHES_RESTRICTED_PATHS=$( + gh api \ + --paginate \ + --slurp \ + --jq ' + flatten + | any( + .[]; + (.filename | startswith("cuda_bindings/")) + or ((.previous_filename // "") | startswith("cuda_bindings/")) + or (.filename | startswith("cuda_python/")) + or ((.previous_filename // "") | startswith("cuda_python/")) + ) + ' \ + "repos/$REPO/pulls/$PR_NUMBER/files" + ); then + echo "::error::Failed to inspect the PR file list." + { + echo "## PR Author Organization Check Failed" + echo "" + echo "- **Error**: Failed to inspect the PR file list." + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "" + echo "Please update the PR at: $PR_URL" + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + + IS_ALLOWED=false + case "$AUTHOR_ASSOCIATION" in + MEMBER|OWNER) + IS_ALLOWED=true + ;; + esac + + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$IS_ALLOWED" = "false" ]; then + echo "::error::This PR failed the author organization check. See the job summary for details." + { + echo "## PR Author Organization Check Failed" + echo "" + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + echo "" + echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." + echo "" + echo "Please update the PR at: $PR_URL" + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + + { + echo "## PR Author Organization Check Passed" + echo "" + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + } >> "$GITHUB_STEP_SUMMARY" From 4b650cec1e09dcec2a09a4341077728c7da25ad6 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 7 Apr 2026 15:27:49 -0700 Subject: [PATCH 02/12] CI: fix PR author org check file lookup Keep the lightweight PR check runnable on GitHub-hosted runners by avoiding the unsupported gh api --slurp --jq combination when scanning changed files. Made-with: Cursor --- .github/workflows/pr-author-org-check.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index 6bd4ca6b48..394cfbc12f 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -31,19 +31,18 @@ jobs: GH_TOKEN: ${{ github.token }} REPO: ${{ github.repository }} run: | - if ! TOUCHES_RESTRICTED_PATHS=$( + if ! MATCHING_RESTRICTED_PATHS=$( gh api \ --paginate \ - --slurp \ --jq ' - flatten - | any( - .[]; + .[] + | select( (.filename | startswith("cuda_bindings/")) or ((.previous_filename // "") | startswith("cuda_bindings/")) or (.filename | startswith("cuda_python/")) or ((.previous_filename // "") | startswith("cuda_python/")) ) + | .filename ' \ "repos/$REPO/pulls/$PR_NUMBER/files" ); then @@ -60,6 +59,11 @@ jobs: exit 1 fi + TOUCHES_RESTRICTED_PATHS=false + if [ -n "$MATCHING_RESTRICTED_PATHS" ]; then + TOUCHES_RESTRICTED_PATHS=true + fi + IS_ALLOWED=false case "$AUTHOR_ASSOCIATION" in MEMBER|OWNER) From ead62e79631daa6b4885a8fea9749f2d34701245 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 7 Apr 2026 15:31:53 -0700 Subject: [PATCH 03/12] XXX DUMMY CHANGE XXX under cuda_bindings/ --- cuda_bindings/pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/cuda_bindings/pyproject.toml b/cuda_bindings/pyproject.toml index f4866fc4f8..b53ed6d075 100644 --- a/cuda_bindings/pyproject.toml +++ b/cuda_bindings/pyproject.toml @@ -1,5 +1,6 @@ # SPDX-FileCopyrightText: Copyright (c) 2023-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE +# XXX DUMMY CHANGE XXX [build-system] requires = [ "setuptools>=80.0.0", From f56a8d10f8483cc84e20e089fa61babb38429420 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 7 Apr 2026 15:36:28 -0700 Subject: [PATCH 04/12] CI: show matched restricted paths in PR check Include the exact restricted-path matches in the job summary so contributors and reviewers can see what triggered the author organization check. Made-with: Cursor --- .github/workflows/pr-author-org-check.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index 394cfbc12f..06d2cb98dc 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -64,6 +64,13 @@ jobs: TOUCHES_RESTRICTED_PATHS=true fi + write_matching_restricted_paths() { + echo "- **Matched restricted paths**:" + echo '```text' + printf '%s\n' "$MATCHING_RESTRICTED_PATHS" + echo '```' + } + IS_ALLOWED=false case "$AUTHOR_ASSOCIATION" in MEMBER|OWNER) @@ -80,6 +87,8 @@ jobs: echo "- **Author association**: $AUTHOR_ASSOCIATION" echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" echo "" + write_matching_restricted_paths + echo "" echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." echo "" echo "Please update the PR at: $PR_URL" @@ -94,4 +103,8 @@ jobs: echo "- **Author association**: $AUTHOR_ASSOCIATION" echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then + echo "" + write_matching_restricted_paths + fi } >> "$GITHUB_STEP_SUMMARY" From 42ba3f846839934eda69178cf7db85ef705c15f5 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 7 Apr 2026 16:40:51 -0700 Subject: [PATCH 05/12] CI: triage inconclusive PR author org checks Query NVIDIA org membership directly for restricted-path PRs so the workflow can distinguish members, non-members, and inconclusive cases, label PRs that need manual review, and show the matched files. Keep the trigger on pull_request temporarily so the new check can be exercised before switching back to pull_request_target. Made-with: Cursor --- .github/workflows/pr-author-org-check.yml | 174 ++++++++++++++++++---- 1 file changed, 147 insertions(+), 27 deletions(-) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index 06d2cb98dc..515c6a3f87 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -4,6 +4,7 @@ name: "CI: Check PR author organization for restricted paths" on: + # TODO BEFORE MERGING: change to pull_request_target pull_request: types: - opened @@ -17,18 +18,22 @@ jobs: if: github.repository_owner == 'NVIDIA' runs-on: ubuntu-latest permissions: + issues: write pull-requests: read steps: - name: Check PR author organization for restricted paths env: # PR metadata inputs AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }} + LABELS: ${{ toJson(github.event.pull_request.labels) }} PR_AUTHOR: ${{ github.event.pull_request.user.login }} PR_NUMBER: ${{ github.event.pull_request.number }} PR_URL: ${{ github.event.pull_request.html_url }} # API request context/auth GH_TOKEN: ${{ github.token }} + ORG_NAME: NVIDIA + ORG_REVIEW_LABEL: Check-PR-Author-ORG REPO: ${{ github.repository }} run: | if ! MATCHING_RESTRICTED_PATHS=$( @@ -36,13 +41,14 @@ jobs: --paginate \ --jq ' .[] - | select( - (.filename | startswith("cuda_bindings/")) - or ((.previous_filename // "") | startswith("cuda_bindings/")) + | if (.filename | startswith("cuda_bindings/")) or (.filename | startswith("cuda_python/")) + then .filename + elif ((.previous_filename // "") | startswith("cuda_bindings/")) or ((.previous_filename // "") | startswith("cuda_python/")) - ) - | .filename + then "\(.previous_filename) -> \(.filename)" + else empty + end ' \ "repos/$REPO/pulls/$PR_NUMBER/files" ); then @@ -64,6 +70,17 @@ jobs: TOUCHES_RESTRICTED_PATHS=true fi + HAS_ORG_REVIEW_LABEL=false + while IFS= read -r label; do + [ -n "$label" ] || continue + if [ "$label" = "$ORG_REVIEW_LABEL" ]; then + HAS_ORG_REVIEW_LABEL=true + break + fi + done < <(echo "$LABELS" | jq -r '.[].name') + + REVIEW_LABEL_ACTION="none" + write_matching_restricted_paths() { echo "- **Matched restricted paths**:" echo '```text' @@ -71,40 +88,143 @@ jobs: echo '```' } - IS_ALLOWED=false - case "$AUTHOR_ASSOCIATION" in - MEMBER|OWNER) - IS_ALLOWED=true - ;; - esac + write_review_label_action() { + [ "$REVIEW_LABEL_ACTION" != "none" ] || return 0 + echo "- **Review label action**: $REVIEW_LABEL_ACTION \`$ORG_REVIEW_LABEL\`" + } + + ensure_org_review_label_present() { + if [ "$HAS_ORG_REVIEW_LABEL" = "false" ]; then + if ! gh issue edit "$PR_NUMBER" --repo "$REPO" --add-label "$ORG_REVIEW_LABEL" >/dev/null; then + echo "::error::Failed to add label $ORG_REVIEW_LABEL." + exit 1 + fi + HAS_ORG_REVIEW_LABEL=true + REVIEW_LABEL_ACTION="added" + fi + } + + ensure_org_review_label_absent() { + if [ "$HAS_ORG_REVIEW_LABEL" = "true" ]; then + if ! gh issue edit "$PR_NUMBER" --repo "$REPO" --remove-label "$ORG_REVIEW_LABEL" >/dev/null; then + echo "::error::Failed to remove label $ORG_REVIEW_LABEL." + exit 1 + fi + HAS_ORG_REVIEW_LABEL=false + REVIEW_LABEL_ACTION="removed" + fi + } + + if [ "$TOUCHES_RESTRICTED_PATHS" = "false" ]; then + ensure_org_review_label_absent + { + echo "## PR Author Organization Check Passed" + echo "" + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Touches restricted paths**: false" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + write_review_label_action + } >> "$GITHUB_STEP_SUMMARY" + exit 0 + fi - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$IS_ALLOWED" = "false" ]; then - echo "::error::This PR failed the author organization check. See the job summary for details." + # Use curl here because the 204/404/302 HTTP status is the signal we + # need. gh api treats 404 as a command failure, but 404 is an expected + # "not a member" outcome for this check. + if ! MEMBERSHIP_STATUS=$( + curl --silent --show-error --output /dev/null --write-out '%{http_code}' \ + -H "Authorization: Bearer $GH_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/orgs/$ORG_NAME/members/$PR_AUTHOR" + ); then + echo "::error::Failed to query organization membership." { echo "## PR Author Organization Check Failed" echo "" + echo "- **Error**: Failed to query organization membership." echo "- **Author**: $PR_AUTHOR" echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Organization membership query**: failed" echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" echo "" write_matching_restricted_paths echo "" - echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." - echo "" echo "Please update the PR at: $PR_URL" } >> "$GITHUB_STEP_SUMMARY" exit 1 fi - { - echo "## PR Author Organization Check Passed" - echo "" - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then - echo "" - write_matching_restricted_paths - fi - } >> "$GITHUB_STEP_SUMMARY" + case "$MEMBERSHIP_STATUS" in + 204) + ensure_org_review_label_absent + { + echo "## PR Author Organization Check Passed" + echo "" + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Organization membership query**: \`204\` (member)" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + echo "" + write_matching_restricted_paths + write_review_label_action + } >> "$GITHUB_STEP_SUMMARY" + ;; + 302) + ensure_org_review_label_present + echo "::warning::Could not determine conclusively whether $PR_AUTHOR is a member of $ORG_NAME. Added label $ORG_REVIEW_LABEL for manual review." + { + echo "## PR Author Organization Check Inconclusive" + echo "" + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Organization membership query**: \`302\` (inconclusive)" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + echo "" + write_matching_restricted_paths + write_review_label_action + echo "" + echo "- **Next step**: Review whether the PR author should be allowed to modify these restricted paths." + echo "" + echo "Please update the PR at: $PR_URL" + } >> "$GITHUB_STEP_SUMMARY" + ;; + 404) + ensure_org_review_label_absent + echo "::error::This PR failed the author organization check. See the job summary for details." + { + echo "## PR Author Organization Check Failed" + echo "" + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Organization membership query**: \`404\` (not a member)" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + echo "" + write_matching_restricted_paths + write_review_label_action + echo "" + echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." + echo "" + echo "Please update the PR at: $PR_URL" + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + ;; + *) + echo "::error::Unexpected response from organization membership query: HTTP $MEMBERSHIP_STATUS." + { + echo "## PR Author Organization Check Failed" + echo "" + echo "- **Error**: Unexpected response from organization membership query." + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Organization membership query**: \`$MEMBERSHIP_STATUS\`" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + echo "" + write_matching_restricted_paths + echo "" + echo "Please update the PR at: $PR_URL" + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + ;; + esac From a4aa6f0316adffb152166ce82f1dce771ea516b6 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 7 Apr 2026 17:01:09 -0700 Subject: [PATCH 06/12] Revert "CI: triage inconclusive PR author org checks" This reverts commit 42ba3f846839934eda69178cf7db85ef705c15f5. --- .github/workflows/pr-author-org-check.yml | 174 ++++------------------ 1 file changed, 27 insertions(+), 147 deletions(-) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index 515c6a3f87..06d2cb98dc 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -4,7 +4,6 @@ name: "CI: Check PR author organization for restricted paths" on: - # TODO BEFORE MERGING: change to pull_request_target pull_request: types: - opened @@ -18,22 +17,18 @@ jobs: if: github.repository_owner == 'NVIDIA' runs-on: ubuntu-latest permissions: - issues: write pull-requests: read steps: - name: Check PR author organization for restricted paths env: # PR metadata inputs AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }} - LABELS: ${{ toJson(github.event.pull_request.labels) }} PR_AUTHOR: ${{ github.event.pull_request.user.login }} PR_NUMBER: ${{ github.event.pull_request.number }} PR_URL: ${{ github.event.pull_request.html_url }} # API request context/auth GH_TOKEN: ${{ github.token }} - ORG_NAME: NVIDIA - ORG_REVIEW_LABEL: Check-PR-Author-ORG REPO: ${{ github.repository }} run: | if ! MATCHING_RESTRICTED_PATHS=$( @@ -41,14 +36,13 @@ jobs: --paginate \ --jq ' .[] - | if (.filename | startswith("cuda_bindings/")) + | select( + (.filename | startswith("cuda_bindings/")) + or ((.previous_filename // "") | startswith("cuda_bindings/")) or (.filename | startswith("cuda_python/")) - then .filename - elif ((.previous_filename // "") | startswith("cuda_bindings/")) or ((.previous_filename // "") | startswith("cuda_python/")) - then "\(.previous_filename) -> \(.filename)" - else empty - end + ) + | .filename ' \ "repos/$REPO/pulls/$PR_NUMBER/files" ); then @@ -70,17 +64,6 @@ jobs: TOUCHES_RESTRICTED_PATHS=true fi - HAS_ORG_REVIEW_LABEL=false - while IFS= read -r label; do - [ -n "$label" ] || continue - if [ "$label" = "$ORG_REVIEW_LABEL" ]; then - HAS_ORG_REVIEW_LABEL=true - break - fi - done < <(echo "$LABELS" | jq -r '.[].name') - - REVIEW_LABEL_ACTION="none" - write_matching_restricted_paths() { echo "- **Matched restricted paths**:" echo '```text' @@ -88,143 +71,40 @@ jobs: echo '```' } - write_review_label_action() { - [ "$REVIEW_LABEL_ACTION" != "none" ] || return 0 - echo "- **Review label action**: $REVIEW_LABEL_ACTION \`$ORG_REVIEW_LABEL\`" - } - - ensure_org_review_label_present() { - if [ "$HAS_ORG_REVIEW_LABEL" = "false" ]; then - if ! gh issue edit "$PR_NUMBER" --repo "$REPO" --add-label "$ORG_REVIEW_LABEL" >/dev/null; then - echo "::error::Failed to add label $ORG_REVIEW_LABEL." - exit 1 - fi - HAS_ORG_REVIEW_LABEL=true - REVIEW_LABEL_ACTION="added" - fi - } - - ensure_org_review_label_absent() { - if [ "$HAS_ORG_REVIEW_LABEL" = "true" ]; then - if ! gh issue edit "$PR_NUMBER" --repo "$REPO" --remove-label "$ORG_REVIEW_LABEL" >/dev/null; then - echo "::error::Failed to remove label $ORG_REVIEW_LABEL." - exit 1 - fi - HAS_ORG_REVIEW_LABEL=false - REVIEW_LABEL_ACTION="removed" - fi - } - - if [ "$TOUCHES_RESTRICTED_PATHS" = "false" ]; then - ensure_org_review_label_absent - { - echo "## PR Author Organization Check Passed" - echo "" - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Touches restricted paths**: false" - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - write_review_label_action - } >> "$GITHUB_STEP_SUMMARY" - exit 0 - fi + IS_ALLOWED=false + case "$AUTHOR_ASSOCIATION" in + MEMBER|OWNER) + IS_ALLOWED=true + ;; + esac - # Use curl here because the 204/404/302 HTTP status is the signal we - # need. gh api treats 404 as a command failure, but 404 is an expected - # "not a member" outcome for this check. - if ! MEMBERSHIP_STATUS=$( - curl --silent --show-error --output /dev/null --write-out '%{http_code}' \ - -H "Authorization: Bearer $GH_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "https://api.github.com/orgs/$ORG_NAME/members/$PR_AUTHOR" - ); then - echo "::error::Failed to query organization membership." + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$IS_ALLOWED" = "false" ]; then + echo "::error::This PR failed the author organization check. See the job summary for details." { echo "## PR Author Organization Check Failed" echo "" - echo "- **Error**: Failed to query organization membership." echo "- **Author**: $PR_AUTHOR" echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Organization membership query**: failed" echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" echo "" write_matching_restricted_paths echo "" + echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." + echo "" echo "Please update the PR at: $PR_URL" } >> "$GITHUB_STEP_SUMMARY" exit 1 fi - case "$MEMBERSHIP_STATUS" in - 204) - ensure_org_review_label_absent - { - echo "## PR Author Organization Check Passed" - echo "" - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Organization membership query**: \`204\` (member)" - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - echo "" - write_matching_restricted_paths - write_review_label_action - } >> "$GITHUB_STEP_SUMMARY" - ;; - 302) - ensure_org_review_label_present - echo "::warning::Could not determine conclusively whether $PR_AUTHOR is a member of $ORG_NAME. Added label $ORG_REVIEW_LABEL for manual review." - { - echo "## PR Author Organization Check Inconclusive" - echo "" - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Organization membership query**: \`302\` (inconclusive)" - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - echo "" - write_matching_restricted_paths - write_review_label_action - echo "" - echo "- **Next step**: Review whether the PR author should be allowed to modify these restricted paths." - echo "" - echo "Please update the PR at: $PR_URL" - } >> "$GITHUB_STEP_SUMMARY" - ;; - 404) - ensure_org_review_label_absent - echo "::error::This PR failed the author organization check. See the job summary for details." - { - echo "## PR Author Organization Check Failed" - echo "" - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Organization membership query**: \`404\` (not a member)" - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - echo "" - write_matching_restricted_paths - write_review_label_action - echo "" - echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." - echo "" - echo "Please update the PR at: $PR_URL" - } >> "$GITHUB_STEP_SUMMARY" - exit 1 - ;; - *) - echo "::error::Unexpected response from organization membership query: HTTP $MEMBERSHIP_STATUS." - { - echo "## PR Author Organization Check Failed" - echo "" - echo "- **Error**: Unexpected response from organization membership query." - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Organization membership query**: \`$MEMBERSHIP_STATUS\`" - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - echo "" - write_matching_restricted_paths - echo "" - echo "Please update the PR at: $PR_URL" - } >> "$GITHUB_STEP_SUMMARY" - exit 1 - ;; - esac + { + echo "## PR Author Organization Check Passed" + echo "" + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then + echo "" + write_matching_restricted_paths + fi + } >> "$GITHUB_STEP_SUMMARY" From 6f588586723ff674e56f39f47ea405e7a909f122 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 7 Apr 2026 17:07:48 -0700 Subject: [PATCH 07/12] CI: allow collaborators in PR author org check Treat repository collaborators as trusted for restricted-path changes so the workflow blocks only authors with no collaborator, member, or owner association. Made-with: Cursor --- .github/workflows/pr-author-org-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index 06d2cb98dc..4af725bc69 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -73,7 +73,7 @@ jobs: IS_ALLOWED=false case "$AUTHOR_ASSOCIATION" in - MEMBER|OWNER) + COLLABORATOR|MEMBER|OWNER) IS_ALLOWED=true ;; esac From 9dcf7b16b0bfc9594bd7a598c039000b5143abf6 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 8 Apr 2026 11:51:11 -0700 Subject: [PATCH 08/12] 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 --- .github/workflows/pr-author-org-check.yml | 121 ++++++++++++++++++---- 1 file changed, 98 insertions(+), 23 deletions(-) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index 4af725bc69..46cbffd476 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -1,9 +1,11 @@ # SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -name: "CI: Check PR author organization for restricted paths" +name: "CI: Check PR author signals for restricted paths" on: + # Label updates on fork PRs require pull_request_target permissions. + # TODO BEFORE MERGING: change to pull_request_target pull_request: types: - opened @@ -13,24 +15,33 @@ on: jobs: check-author-org: - name: PR author may modify restricted paths + name: PR author signals recorded for restricted paths if: github.repository_owner == 'NVIDIA' runs-on: ubuntu-latest permissions: + issues: write pull-requests: read steps: - - name: Check PR author organization for restricted paths + - name: Inspect PR author signals for restricted paths env: # PR metadata inputs AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }} + EXISTING_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} PR_AUTHOR: ${{ github.event.pull_request.user.login }} PR_NUMBER: ${{ github.event.pull_request.number }} PR_URL: ${{ github.event.pull_request.html_url }} + # Workflow policy inputs + PUBLIC_MEMBER_ORG: NVIDIA + REVIEW_LABEL: Check-PR-author-ORG + # API request context/auth GH_TOKEN: ${{ github.token }} + GITHUB_API_URL: ${{ github.api_url }} REPO: ${{ github.repository }} run: | + set -euo pipefail + if ! MATCHING_RESTRICTED_PATHS=$( gh api \ --paginate \ @@ -71,40 +82,104 @@ jobs: echo '```' } - IS_ALLOWED=false + HAS_TRUE_POSITIVE_SIGNAL=false + LABEL_ACTION="not needed (no restricted paths)" + PUBLIC_MEMBER_CHECK="not needed (no restricted paths)" + TRUE_POSITIVE_SIGNALS="(none)" + case "$AUTHOR_ASSOCIATION" in - COLLABORATOR|MEMBER|OWNER) - IS_ALLOWED=true + MEMBER|OWNER) + HAS_TRUE_POSITIVE_SIGNAL=true + LABEL_ACTION="not needed (author association is a true positive)" + PUBLIC_MEMBER_CHECK="skipped (author association is a true positive)" + TRUE_POSITIVE_SIGNALS="author_association:$AUTHOR_ASSOCIATION" ;; esac - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$IS_ALLOWED" = "false" ]; then - echo "::error::This PR failed the author organization check. See the job summary for details." - { - echo "## PR Author Organization Check Failed" - echo "" - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - echo "" - write_matching_restricted_paths - echo "" - echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." - echo "" - echo "Please update the PR at: $PR_URL" - } >> "$GITHUB_STEP_SUMMARY" - exit 1 + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then + PUBLIC_MEMBER_STATUS=$(curl \ + --silent \ + --show-error \ + --output /dev/null \ + --write-out '%{http_code}' \ + -H "Authorization: Bearer $GH_TOKEN" \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "$GITHUB_API_URL/orgs/$PUBLIC_MEMBER_ORG/public_members/$PR_AUTHOR") + + case "$PUBLIC_MEMBER_STATUS" in + 204) + HAS_TRUE_POSITIVE_SIGNAL=true + LABEL_ACTION="not needed (public org membership is a true positive)" + PUBLIC_MEMBER_CHECK="204 (public member)" + TRUE_POSITIVE_SIGNALS="public_org_membership:$PUBLIC_MEMBER_ORG" + ;; + 404) + PUBLIC_MEMBER_CHECK="404 (not a public member)" + ;; + *) + echo "::error::Failed to determine whether the PR author is a public $PUBLIC_MEMBER_ORG member." + { + echo "## PR Author Organization Check Failed" + echo "" + echo "- **Error**: Unexpected HTTP status from \`/orgs/$PUBLIC_MEMBER_ORG/public_members/$PR_AUTHOR\`: \`$PUBLIC_MEMBER_STATUS\`." + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + echo "" + write_matching_restricted_paths + echo "" + echo "Please update the PR at: $PR_URL" + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + ;; + esac + fi + + LABEL_ALREADY_PRESENT=false + if jq -e --arg label "$REVIEW_LABEL" '.[] == $label' <<<"$EXISTING_LABELS" >/dev/null; then + LABEL_ALREADY_PRESENT=true + fi + + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then + if [ "$LABEL_ALREADY_PRESENT" = "true" ]; then + LABEL_ACTION="already present" + elif ! gh issue edit "$PR_NUMBER" --repo "$REPO" --add-label "$REVIEW_LABEL"; then + echo "::error::Failed to add the $REVIEW_LABEL label." + { + echo "## PR Author Organization Check Failed" + echo "" + echo "- **Error**: Failed to add the \`$REVIEW_LABEL\` label." + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Public $PUBLIC_MEMBER_ORG membership check**: $PUBLIC_MEMBER_CHECK" + echo "" + write_matching_restricted_paths + echo "" + echo "Please update the PR at: $PR_URL" + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + else + LABEL_ACTION="added" + fi fi { - echo "## PR Author Organization Check Passed" + echo "## PR Author Organization Check Completed" echo "" echo "- **Author**: $PR_AUTHOR" echo "- **Author association**: $AUTHOR_ASSOCIATION" echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + echo "- **Public $PUBLIC_MEMBER_ORG membership check**: $PUBLIC_MEMBER_CHECK" + echo "- **True positive signals**: $TRUE_POSITIVE_SIGNALS" + echo "- **Label action**: $LABEL_ACTION" if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then echo "" write_matching_restricted_paths fi + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then + echo "" + echo "- **Manual follow-up**: No true positive signal was found, so \`$REVIEW_LABEL\` is required." + fi } >> "$GITHUB_STEP_SUMMARY" From bc16d972c4b4d1e5c0276f9383e22b5571203691 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 8 Apr 2026 12:28:54 -0700 Subject: [PATCH 09/12] Revert "CI: label PRs without trusted author signals" This reverts commit 9dcf7b16b0bfc9594bd7a598c039000b5143abf6. --- .github/workflows/pr-author-org-check.yml | 121 ++++------------------ 1 file changed, 23 insertions(+), 98 deletions(-) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index 46cbffd476..4af725bc69 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -1,11 +1,9 @@ # SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -name: "CI: Check PR author signals for restricted paths" +name: "CI: Check PR author organization for restricted paths" on: - # Label updates on fork PRs require pull_request_target permissions. - # TODO BEFORE MERGING: change to pull_request_target pull_request: types: - opened @@ -15,33 +13,24 @@ on: jobs: check-author-org: - name: PR author signals recorded for restricted paths + name: PR author may modify restricted paths if: github.repository_owner == 'NVIDIA' runs-on: ubuntu-latest permissions: - issues: write pull-requests: read steps: - - name: Inspect PR author signals for restricted paths + - name: Check PR author organization for restricted paths env: # PR metadata inputs AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }} - EXISTING_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} PR_AUTHOR: ${{ github.event.pull_request.user.login }} PR_NUMBER: ${{ github.event.pull_request.number }} PR_URL: ${{ github.event.pull_request.html_url }} - # Workflow policy inputs - PUBLIC_MEMBER_ORG: NVIDIA - REVIEW_LABEL: Check-PR-author-ORG - # API request context/auth GH_TOKEN: ${{ github.token }} - GITHUB_API_URL: ${{ github.api_url }} REPO: ${{ github.repository }} run: | - set -euo pipefail - if ! MATCHING_RESTRICTED_PATHS=$( gh api \ --paginate \ @@ -82,104 +71,40 @@ jobs: echo '```' } - HAS_TRUE_POSITIVE_SIGNAL=false - LABEL_ACTION="not needed (no restricted paths)" - PUBLIC_MEMBER_CHECK="not needed (no restricted paths)" - TRUE_POSITIVE_SIGNALS="(none)" - + IS_ALLOWED=false case "$AUTHOR_ASSOCIATION" in - MEMBER|OWNER) - HAS_TRUE_POSITIVE_SIGNAL=true - LABEL_ACTION="not needed (author association is a true positive)" - PUBLIC_MEMBER_CHECK="skipped (author association is a true positive)" - TRUE_POSITIVE_SIGNALS="author_association:$AUTHOR_ASSOCIATION" + COLLABORATOR|MEMBER|OWNER) + IS_ALLOWED=true ;; esac - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then - PUBLIC_MEMBER_STATUS=$(curl \ - --silent \ - --show-error \ - --output /dev/null \ - --write-out '%{http_code}' \ - -H "Authorization: Bearer $GH_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - "$GITHUB_API_URL/orgs/$PUBLIC_MEMBER_ORG/public_members/$PR_AUTHOR") - - case "$PUBLIC_MEMBER_STATUS" in - 204) - HAS_TRUE_POSITIVE_SIGNAL=true - LABEL_ACTION="not needed (public org membership is a true positive)" - PUBLIC_MEMBER_CHECK="204 (public member)" - TRUE_POSITIVE_SIGNALS="public_org_membership:$PUBLIC_MEMBER_ORG" - ;; - 404) - PUBLIC_MEMBER_CHECK="404 (not a public member)" - ;; - *) - echo "::error::Failed to determine whether the PR author is a public $PUBLIC_MEMBER_ORG member." - { - echo "## PR Author Organization Check Failed" - echo "" - echo "- **Error**: Unexpected HTTP status from \`/orgs/$PUBLIC_MEMBER_ORG/public_members/$PR_AUTHOR\`: \`$PUBLIC_MEMBER_STATUS\`." - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - echo "" - write_matching_restricted_paths - echo "" - echo "Please update the PR at: $PR_URL" - } >> "$GITHUB_STEP_SUMMARY" - exit 1 - ;; - esac - fi - - LABEL_ALREADY_PRESENT=false - if jq -e --arg label "$REVIEW_LABEL" '.[] == $label' <<<"$EXISTING_LABELS" >/dev/null; then - LABEL_ALREADY_PRESENT=true - fi - - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then - if [ "$LABEL_ALREADY_PRESENT" = "true" ]; then - LABEL_ACTION="already present" - elif ! gh issue edit "$PR_NUMBER" --repo "$REPO" --add-label "$REVIEW_LABEL"; then - echo "::error::Failed to add the $REVIEW_LABEL label." - { - echo "## PR Author Organization Check Failed" - echo "" - echo "- **Error**: Failed to add the \`$REVIEW_LABEL\` label." - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Public $PUBLIC_MEMBER_ORG membership check**: $PUBLIC_MEMBER_CHECK" - echo "" - write_matching_restricted_paths - echo "" - echo "Please update the PR at: $PR_URL" - } >> "$GITHUB_STEP_SUMMARY" - exit 1 - else - LABEL_ACTION="added" - fi + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$IS_ALLOWED" = "false" ]; then + echo "::error::This PR failed the author organization check. See the job summary for details." + { + echo "## PR Author Organization Check Failed" + echo "" + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + echo "" + write_matching_restricted_paths + echo "" + echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." + echo "" + echo "Please update the PR at: $PR_URL" + } >> "$GITHUB_STEP_SUMMARY" + exit 1 fi { - echo "## PR Author Organization Check Completed" + echo "## PR Author Organization Check Passed" echo "" echo "- **Author**: $PR_AUTHOR" echo "- **Author association**: $AUTHOR_ASSOCIATION" echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - echo "- **Public $PUBLIC_MEMBER_ORG membership check**: $PUBLIC_MEMBER_CHECK" - echo "- **True positive signals**: $TRUE_POSITIVE_SIGNALS" - echo "- **Label action**: $LABEL_ACTION" if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then echo "" write_matching_restricted_paths fi - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then - echo "" - echo "- **Manual follow-up**: No true positive signal was found, so \`$REVIEW_LABEL\` is required." - fi } >> "$GITHUB_STEP_SUMMARY" From 539461fb8a5f4a988fcc4b6154f3aa738f8dd924 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 8 Apr 2026 12:35:30 -0700 Subject: [PATCH 10/12] CI: use checked-in PR author allowlist Replace the public-membership probe with a checked-in allowlist so restricted-path PRs can still get a known true positive during rollout while labeling authors that need manual review. Made-with: Cursor --- .github/workflows/pr-author-org-check.yml | 103 ++++++++++++++++------ 1 file changed, 77 insertions(+), 26 deletions(-) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index 4af725bc69..60b9e8809e 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -1,9 +1,11 @@ # SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -name: "CI: Check PR author organization for restricted paths" +name: "CI: Check PR author signals for restricted paths" on: + # Label updates on fork PRs require pull_request_target permissions. + # TODO BEFORE MERGING: change to pull_request_target pull_request: types: - opened @@ -13,24 +15,35 @@ on: jobs: check-author-org: - name: PR author may modify restricted paths + name: PR author signals recorded for restricted paths if: github.repository_owner == 'NVIDIA' runs-on: ubuntu-latest permissions: + issues: write pull-requests: read steps: - - name: Check PR author organization for restricted paths + - name: Inspect PR author signals for restricted paths env: # PR metadata inputs AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association || 'NONE' }} + EXISTING_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} PR_AUTHOR: ${{ github.event.pull_request.user.login }} PR_NUMBER: ${{ github.event.pull_request.number }} PR_URL: ${{ github.event.pull_request.html_url }} + # Workflow policy inputs + REVIEW_LABEL: Check-PR-author-ORG + + # Checked-in allowlist inputs + INTERNAL_AUTHOR_ALLOWLIST: | + rwgk + # API request context/auth GH_TOKEN: ${{ github.token }} REPO: ${{ github.repository }} run: | + set -euo pipefail + if ! MATCHING_RESTRICTED_PATHS=$( gh api \ --paginate \ @@ -71,40 +84,78 @@ jobs: echo '```' } - IS_ALLOWED=false - case "$AUTHOR_ASSOCIATION" in - COLLABORATOR|MEMBER|OWNER) - IS_ALLOWED=true - ;; - esac + HAS_TRUE_POSITIVE_SIGNAL=false + ALLOWLIST_CHECK="not needed (no restricted paths)" + LABEL_ACTION="not needed (no restricted paths)" + TRUE_POSITIVE_SIGNALS="(none)" + PR_AUTHOR_CANONICAL=${PR_AUTHOR,,} - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$IS_ALLOWED" = "false" ]; then - echo "::error::This PR failed the author organization check. See the job summary for details." - { - echo "## PR Author Organization Check Failed" - echo "" - echo "- **Author**: $PR_AUTHOR" - echo "- **Author association**: $AUTHOR_ASSOCIATION" - echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" - echo "" - write_matching_restricted_paths - echo "" - echo "- **Policy**: See \`cuda_bindings/LICENSE\` and \`cuda_python/LICENSE\`. Only NVIDIA organization members may modify files under \`cuda_bindings/\` or \`cuda_python/\`." - echo "" - echo "Please update the PR at: $PR_URL" - } >> "$GITHUB_STEP_SUMMARY" - exit 1 + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then + case "$AUTHOR_ASSOCIATION" in + MEMBER|OWNER) + HAS_TRUE_POSITIVE_SIGNAL=true + ALLOWLIST_CHECK="skipped (author association is a true positive)" + LABEL_ACTION="not needed (author association is a true positive)" + TRUE_POSITIVE_SIGNALS="author_association:$AUTHOR_ASSOCIATION" + ;; + esac + + if [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then + if printf '%s\n' "$INTERNAL_AUTHOR_ALLOWLIST" | tr '[:upper:]' '[:lower:]' | grep -Fxq "$PR_AUTHOR_CANONICAL"; then + HAS_TRUE_POSITIVE_SIGNAL=true + ALLOWLIST_CHECK="matched ($PR_AUTHOR_CANONICAL)" + LABEL_ACTION="not needed (workflow allowlist is a true positive)" + TRUE_POSITIVE_SIGNALS="workflow_allowlist:$PR_AUTHOR_CANONICAL" + else + ALLOWLIST_CHECK="not matched ($PR_AUTHOR_CANONICAL)" + fi + fi + fi + + LABEL_ALREADY_PRESENT=false + if jq -e --arg label "$REVIEW_LABEL" '.[] == $label' <<<"$EXISTING_LABELS" >/dev/null; then + LABEL_ALREADY_PRESENT=true + fi + + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then + if [ "$LABEL_ALREADY_PRESENT" = "true" ]; then + LABEL_ACTION="already present" + elif ! gh issue edit "$PR_NUMBER" --repo "$REPO" --add-label "$REVIEW_LABEL"; then + echo "::error::Failed to add the $REVIEW_LABEL label." + { + echo "## PR Author Organization Check Failed" + echo "" + echo "- **Error**: Failed to add the \`$REVIEW_LABEL\` label." + echo "- **Author**: $PR_AUTHOR" + echo "- **Author association**: $AUTHOR_ASSOCIATION" + echo "- **Allowlist check**: $ALLOWLIST_CHECK" + echo "" + write_matching_restricted_paths + echo "" + echo "Please update the PR at: $PR_URL" + } >> "$GITHUB_STEP_SUMMARY" + exit 1 + else + LABEL_ACTION="added" + fi fi { - echo "## PR Author Organization Check Passed" + echo "## PR Author Organization Check Completed" echo "" echo "- **Author**: $PR_AUTHOR" echo "- **Author association**: $AUTHOR_ASSOCIATION" echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" + echo "- **Allowlist check**: $ALLOWLIST_CHECK" + echo "- **True positive signals**: $TRUE_POSITIVE_SIGNALS" + echo "- **Label action**: $LABEL_ACTION" if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then echo "" write_matching_restricted_paths fi + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then + echo "" + echo "- **Manual follow-up**: No true positive signal was found, so \`$REVIEW_LABEL\` is required." + fi } >> "$GITHUB_STEP_SUMMARY" From c6753f7311abd3ddaa366f0207cb094a3336c537 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 8 Apr 2026 13:14:51 -0700 Subject: [PATCH 11/12] CI: rename PR author trusted signal wording Replace the remaining "true positive" terminology with "trusted signal" so the workflow summary and implementation language match the current manual-review design. Made-with: Cursor --- .github/workflows/pr-author-org-check.yml | 28 +++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index 60b9e8809e..e8e30b35e5 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -84,28 +84,28 @@ jobs: echo '```' } - HAS_TRUE_POSITIVE_SIGNAL=false + HAS_TRUSTED_SIGNAL=false ALLOWLIST_CHECK="not needed (no restricted paths)" LABEL_ACTION="not needed (no restricted paths)" - TRUE_POSITIVE_SIGNALS="(none)" + TRUSTED_SIGNALS="(none)" PR_AUTHOR_CANONICAL=${PR_AUTHOR,,} if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then case "$AUTHOR_ASSOCIATION" in MEMBER|OWNER) - HAS_TRUE_POSITIVE_SIGNAL=true - ALLOWLIST_CHECK="skipped (author association is a true positive)" - LABEL_ACTION="not needed (author association is a true positive)" - TRUE_POSITIVE_SIGNALS="author_association:$AUTHOR_ASSOCIATION" + HAS_TRUSTED_SIGNAL=true + ALLOWLIST_CHECK="skipped (author association is a trusted signal)" + LABEL_ACTION="not needed (author association is a trusted signal)" + TRUSTED_SIGNALS="author_association:$AUTHOR_ASSOCIATION" ;; esac - if [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then + if [ "$HAS_TRUSTED_SIGNAL" = "false" ]; then if printf '%s\n' "$INTERNAL_AUTHOR_ALLOWLIST" | tr '[:upper:]' '[:lower:]' | grep -Fxq "$PR_AUTHOR_CANONICAL"; then - HAS_TRUE_POSITIVE_SIGNAL=true + HAS_TRUSTED_SIGNAL=true ALLOWLIST_CHECK="matched ($PR_AUTHOR_CANONICAL)" - LABEL_ACTION="not needed (workflow allowlist is a true positive)" - TRUE_POSITIVE_SIGNALS="workflow_allowlist:$PR_AUTHOR_CANONICAL" + LABEL_ACTION="not needed (workflow allowlist is a trusted signal)" + TRUSTED_SIGNALS="workflow_allowlist:$PR_AUTHOR_CANONICAL" else ALLOWLIST_CHECK="not matched ($PR_AUTHOR_CANONICAL)" fi @@ -117,7 +117,7 @@ jobs: LABEL_ALREADY_PRESENT=true fi - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUSTED_SIGNAL" = "false" ]; then if [ "$LABEL_ALREADY_PRESENT" = "true" ]; then LABEL_ACTION="already present" elif ! gh issue edit "$PR_NUMBER" --repo "$REPO" --add-label "$REVIEW_LABEL"; then @@ -148,14 +148,14 @@ jobs: echo "- **Touches restricted paths**: $TOUCHES_RESTRICTED_PATHS" echo "- **Restricted paths**: \`cuda_bindings/\`, \`cuda_python/\`" echo "- **Allowlist check**: $ALLOWLIST_CHECK" - echo "- **True positive signals**: $TRUE_POSITIVE_SIGNALS" + echo "- **Trusted signals**: $TRUSTED_SIGNALS" echo "- **Label action**: $LABEL_ACTION" if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ]; then echo "" write_matching_restricted_paths fi - if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUE_POSITIVE_SIGNAL" = "false" ]; then + if [ "$TOUCHES_RESTRICTED_PATHS" = "true" ] && [ "$HAS_TRUSTED_SIGNAL" = "false" ]; then echo "" - echo "- **Manual follow-up**: No true positive signal was found, so \`$REVIEW_LABEL\` is required." + echo "- **Manual follow-up**: No trusted signal was found, so \`$REVIEW_LABEL\` is required." fi } >> "$GITHUB_STEP_SUMMARY" From 4d4cb8469eccf99f9dd656fba2874f1aa897df2f Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 8 Apr 2026 13:20:25 -0700 Subject: [PATCH 12/12] CI: clarify renamed restricted path matches Show both the previous and current path in the PR author check summary so rename-triggered matches are understandable during manual review. Made-with: Cursor --- .github/workflows/pr-author-org-check.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr-author-org-check.yml b/.github/workflows/pr-author-org-check.yml index e8e30b35e5..96e5b8f9a1 100644 --- a/.github/workflows/pr-author-org-check.yml +++ b/.github/workflows/pr-author-org-check.yml @@ -55,7 +55,11 @@ jobs: or (.filename | startswith("cuda_python/")) or ((.previous_filename // "") | startswith("cuda_python/")) ) - | .filename + | if (.previous_filename // "") != "" then + "\(.previous_filename) -> \(.filename)" + else + .filename + end ' \ "repos/$REPO/pulls/$PR_NUMBER/files" ); then