diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml index 70b78ce72944..d29bd00486be 100644 --- a/.github/workflows/check-change-note.yml +++ b/.github/workflows/check-change-note.yml @@ -1,10 +1,11 @@ name: Check change note permissions: + contents: read pull-requests: read on: - pull_request_target: + pull_request: types: [labeled, unlabeled, opened, synchronize, reopened, ready_for_review] paths: - "*/ql/src/**/*.ql" @@ -23,7 +24,7 @@ jobs: env: REPO: ${{ github.repository }} PULL_REQUEST_NUMBER: ${{ github.event.number }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ github.token }} runs-on: ubuntu-latest steps: diff --git a/.github/workflows/labeler-apply.yml b/.github/workflows/labeler-apply.yml new file mode 100644 index 000000000000..8f75b00c7244 --- /dev/null +++ b/.github/workflows/labeler-apply.yml @@ -0,0 +1,100 @@ +name: "Pull Request Labeler Apply" + +on: + workflow_run: + workflows: ["Pull Request Labeler"] + types: [completed] + +permissions: {} + +jobs: + triage: + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + pull-requests: write + steps: + - name: Validate pull request from workflow_run + id: validate + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + RUN_ID: ${{ github.event.workflow_run.id }} + run: | + set -euo pipefail + + run_json=$(gh api "repos/$REPO/actions/runs/$RUN_ID") + event=$(jq -r '.event' <<<"$run_json") + conclusion=$(jq -r '.conclusion' <<<"$run_json") + head_sha=$(jq -r '.head_sha' <<<"$run_json") + head_repo=$(jq -r '.head_repository.full_name // empty' <<<"$run_json") + + if [ "$event" != "pull_request" ] || [ "$conclusion" != "success" ]; then + echo "apply=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + pr_number=$(jq -r 'if (.pull_requests | length) == 1 then .pull_requests[0].number else empty end' <<<"$run_json") + + if [ -z "$pr_number" ]; then + prs_json=$(gh api -H 'Accept: application/vnd.github+json' "repos/$REPO/commits/$head_sha/pulls" || echo '[]') + pr_number=$(jq -r 'map(select(.state == "open")) | if length == 1 then .[0].number else empty end' <<<"$prs_json" 2>/dev/null || true) + fi + + if [ -z "$pr_number" ]; then + head_owner=$(jq -r '.head_repository.owner.login // empty' <<<"$run_json") + head_branch=$(jq -r '.head_branch // empty' <<<"$run_json") + if [ -n "$head_owner" ] && [ -n "$head_branch" ]; then + prs_json=$(gh api --method GET "repos/$REPO/pulls" -f state=open -f head="$head_owner:$head_branch" || echo '[]') + pr_number=$(jq -r 'if length == 1 then .[0].number else empty end' <<<"$prs_json" 2>/dev/null || true) + fi + fi + + if [ -z "$pr_number" ]; then + echo "Could not identify a unique open pull request for workflow run $RUN_ID; skipping." + echo "apply=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + pr_json=$(gh api "repos/$REPO/pulls/$pr_number" || true) + if [ -z "$pr_json" ]; then + echo "Pull request #$pr_number could not be fetched; skipping." + echo "apply=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + state=$(jq -r '.state // empty' <<<"$pr_json" 2>/dev/null || true) + base_repo=$(jq -r '.base.repo.full_name // empty' <<<"$pr_json" 2>/dev/null || true) + pr_head_sha=$(jq -r '.head.sha // empty' <<<"$pr_json" 2>/dev/null || true) + pr_head_repo=$(jq -r '.head.repo.full_name // empty' <<<"$pr_json" 2>/dev/null || true) + + if [ -z "$state" ]; then + echo "Pull request #$pr_number could not be parsed; skipping." + echo "apply=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + if [ "$state" != "open" ] || [ "$base_repo" != "$REPO" ]; then + echo "Pull request #$pr_number is no longer an open pull request against $REPO; skipping." + echo "apply=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + if [ "$pr_head_sha" != "$head_sha" ] || [ "$pr_head_repo" != "$head_repo" ]; then + echo "Pull request #$pr_number changed since workflow run $RUN_ID; skipping stale labeling." + echo "apply=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + + echo "number=$pr_number" >> "$GITHUB_OUTPUT" + echo "apply=true" >> "$GITHUB_OUTPUT" + + - uses: actions/labeler@v4 + if: steps.validate.outputs.apply == 'true' + with: + repo-token: "${{ github.token }}" + pr-number: ${{ steps.validate.outputs.number }} diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 512fa40d2e3a..f6f54382f9b8 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -1,15 +1,16 @@ name: "Pull Request Labeler" + on: -- pull_request_target + pull_request: + types: [opened, synchronize, reopened] permissions: contents: read - pull-requests: write + pull-requests: read jobs: - triage: + request-labels: runs-on: ubuntu-latest steps: - - uses: actions/labeler@v4 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" + - name: Request privileged labeling + run: echo "Labels are applied by the workflow_run writer after re-validating the pull request."