Review Labels (apply) #373
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Review Labels (apply) | |
| # Runs after "Review Labels (trigger)" completes. Because workflow_run runs | |
| # in the base-repo context, github.token is writable even for PRs from | |
| # forks -- so the actual label edits happen here. | |
| on: | |
| workflow_run: | |
| workflows: ["Review Labels (trigger)"] | |
| types: [completed] | |
| jobs: | |
| apply: | |
| runs-on: ubuntu-latest | |
| # Only act on successful runs of the trigger workflow that were started | |
| # by one of the events we expect. Anything else is ignored outright. | |
| if: >- | |
| github.event.workflow_run.conclusion == 'success' && | |
| (github.event.workflow_run.event == 'pull_request_review' || | |
| github.event.workflow_run.event == 'pull_request_target') | |
| permissions: | |
| pull-requests: write | |
| issues: write | |
| steps: | |
| - name: Download task artifact | |
| id: download | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: label-task | |
| path: ./label-task | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ github.token }} | |
| continue-on-error: true | |
| - name: Apply labels | |
| if: steps.download.outcome == 'success' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| task_file="./label-task/task.txt" | |
| if [ ! -f "$task_file" ]; then | |
| echo "No task artifact; nothing to do." | |
| exit 0 | |
| fi | |
| pr_number=$(grep '^pr_number=' "$task_file" | cut -d= -f2-) | |
| action=$(grep '^action=' "$task_file" | cut -d= -f2-) | |
| repo="${{ github.repository }}" | |
| if [ -z "$pr_number" ] || [ -z "$action" ]; then | |
| echo "Incomplete task; nothing to do." | |
| exit 0 | |
| fi | |
| # --- Security hardening (workflow_run trust boundary) --- | |
| # The artifact comes from a workflow that can be triggered by fork | |
| # PRs. Validate everything before acting so a forged/malformed task | |
| # cannot be used to mislabel an arbitrary PR or inject gh arguments. | |
| # pr_number must be a plain positive integer. | |
| if ! printf '%s' "$pr_number" | grep -Eq '^[1-9][0-9]*$'; then | |
| echo "Invalid pr_number: '$pr_number'; aborting." | |
| exit 0 | |
| fi | |
| # action must be one of the known values. | |
| case "$action" in | |
| changes_requested|new_commits) ;; | |
| *) echo "Invalid action: '$action'; aborting."; exit 0 ;; | |
| esac | |
| # The artifact's PR must match the head SHA that the triggering | |
| # workflow_run actually ran on. This binds the task to the run that | |
| # produced it, so a fork run cannot hand off a different PR's number. | |
| run_sha="${{ github.event.workflow_run.head_sha }}" | |
| pr_sha=$(gh pr view "$pr_number" --repo "$repo" \ | |
| --json headRefOid --jq '.headRefOid' 2>/dev/null || true) | |
| if [ -n "$run_sha" ] && [ "$pr_sha" != "$run_sha" ]; then | |
| echo "PR #$pr_number head ($pr_sha) does not match triggering run ($run_sha); aborting." | |
| exit 0 | |
| fi | |
| echo "PR #$pr_number, action: $action" | |
| case "$action" in | |
| changes_requested) | |
| # A reviewer requested changes -> flag the PR. | |
| gh pr edit "$pr_number" --repo "$repo" \ | |
| --add-label "review issues" | |
| gh pr edit "$pr_number" --repo "$repo" \ | |
| --remove-label "new review needed" 2>/dev/null || true | |
| ;; | |
| new_commits) | |
| # New commits pushed -> only swap labels if the PR was | |
| # previously flagged with "review issues". Otherwise PRs that | |
| # were never reviewed would wrongly get "new review needed". | |
| has_label=$(gh pr view "$pr_number" --repo "$repo" \ | |
| --json labels --jq '.labels[].name | select(. == "review issues")') | |
| if [ -z "$has_label" ]; then | |
| echo "PR does not have \"review issues\"; nothing to do." | |
| exit 0 | |
| fi | |
| gh pr edit "$pr_number" --repo "$repo" \ | |
| --add-label "new review needed" | |
| gh pr edit "$pr_number" --repo "$repo" \ | |
| --remove-label "review issues" 2>/dev/null || true | |
| ;; | |
| *) | |
| echo "Unknown action: $action" | |
| ;; | |
| esac |