This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/dev/pr-12528-d2d018e792b2bf6bd9b2ac6d7f3747c685c72338 in repository https://gitbox.apache.org/repos/asf/seatunnel.git
commit 0cd6bd46f33bc7e8728d2c27f964c1688b23a34d Author: Goutam Adwant <[email protected]> AuthorDate: Thu Oct 22 14:26:33 2026 +0000 [Improve][CI] Run labeler and Build-check workflows on workflow_run instead of pull_request_target (#12725) --- .github/workflows/add-label.yml | 54 +++++++++++++++++++++++++++--- .github/workflows/notify_test_workflow.yml | 46 +++++++++++++++++-------- .github/workflows/pr-signal.yml | 38 +++++++++++++++++++++ 3 files changed, 120 insertions(+), 18 deletions(-) diff --git a/.github/workflows/add-label.yml b/.github/workflows/add-label.yml index 401009b229..ae6babc117 100644 --- a/.github/workflows/add-label.yml +++ b/.github/workflows/add-label.yml @@ -15,21 +15,67 @@ # limitations under the License. # +# Runs from the default branch after `PR signal` (pr-signal.yml) completes for a +# pull request. The pull request is resolved from the workflow_run payload and +# labelled through the API; no pull request code is checked out or run. name: Pull Request Labeler on: - pull_request_target: - types: [opened, reopened, synchronize] + workflow_run: + workflows: ["PR signal"] + types: [completed] +permissions: {} + +# `action_required` is a signal run of a first-time contributor that waits for workflow +# approval. Nothing of theirs has run, and this job only reads API metadata, so it does not +# wait for the approval. After approval the signal completes again and this job runs again, +# which is harmless. jobs: labeler: + if: >- + github.event.workflow_run.event == 'pull_request' + && (github.event.workflow_run.conclusion == 'success' + || github.event.workflow_run.conclusion == 'action_required') + && github.event.workflow_run.head_repository != null permissions: contents: read pull-requests: write runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v4 - - uses: actions/labeler@v5 + with: + persist-credentials: false + - name: Resolve the pull requests of the signalled run + id: pr + uses: actions/github-script@v7 + env: + HEAD_OWNER: ${{ github.event.workflow_run.head_repository.owner.login }} + HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }} + HEAD_SHA: ${{ github.event.workflow_run.head_sha }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { HEAD_OWNER, HEAD_BRANCH, HEAD_SHA } = process.env + const pulls = await github.paginate('GET /repos/{owner}/{repo}/pulls', { + owner: context.repo.owner, + repo: context.repo.repo, + head: `${HEAD_OWNER}:${HEAD_BRANCH}`, + state: 'open', + per_page: 100, + }) + // The same fork branch can be open against more than one base branch; label every + // PR whose head is the signalled commit. A branch that moved on after the signal + // is labelled by the run for its newer head. + const numbers = pulls.filter((p) => p.head.sha === HEAD_SHA).map((p) => String(p.number)) + if (numbers.length === 0) { + core.notice(`No open pull request with head ${HEAD_OWNER}:${HEAD_BRANCH}@${HEAD_SHA}`) + } + core.setOutput('numbers', numbers.join('\n')) + - if: steps.pr.outputs.numbers != '' + uses: actions/labeler@v5 with: repo-token: ${{ secrets.GITHUB_TOKEN }} configuration-path: '.github/workflows/labeler/label-scope-conf.yml' - sync-labels: true \ No newline at end of file + sync-labels: true + pr-number: ${{ steps.pr.outputs.numbers }} diff --git a/.github/workflows/notify_test_workflow.yml b/.github/workflows/notify_test_workflow.yml index 829a2ad9f6..d2295fda77 100644 --- a/.github/workflows/notify_test_workflow.yml +++ b/.github/workflows/notify_test_workflow.yml @@ -23,14 +23,31 @@ # So, the name was changed to make sense in that context too. # See also https://github.community/t/specify-check-suite-when-creating-a-checkrun/118380/10 name: On pull request update +# Runs from the default branch after `PR signal` (pr-signal.yml) completes for a +# pull request, which replaces `pull_request_target`. Everything it needs (head +# SHA, head repository and branch) comes from the workflow_run payload; no pull +# request code is checked out or run. on: - pull_request_target: - types: [opened, reopened, synchronize] + workflow_run: + workflows: ["PR signal"] + types: [completed] +permissions: {} + +# `action_required` is a signal run of a first-time contributor that waits for workflow +# approval. Nothing of theirs has run, and this job only reads API metadata, so it does not +# wait for the approval. After approval the signal completes again and this job runs again, +# which is harmless. jobs: notify: name: Notify test workflow + if: >- + github.event.workflow_run.event == 'pull_request' + && (github.event.workflow_run.conclusion == 'success' + || github.event.workflow_run.conclusion == 'action_required') + && github.event.workflow_run.head_repository != null runs-on: ubuntu-latest + timeout-minutes: 10 permissions: actions: read checks: write @@ -48,23 +65,24 @@ jobs: // TODO: Should use pull_request.user and pull_request.user.repos_url? // If a different person creates a commit to another forked repo, // it wouldn't be able to detect. - const head_sha = context.payload.pull_request.head.sha + const signal_run = context.payload.workflow_run + const head_sha = signal_run.head_sha const params = { - owner: context.payload.pull_request.head.repo.owner.login, - repo: context.payload.pull_request.head.repo.name, + owner: signal_run.head_repository.owner.login, + repo: signal_run.head_repository.name, workflow_id: 'build_main.yml', - branch: context.payload.pull_request.head.ref, + branch: signal_run.head_branch, per_page: 100, } const check_run_params = { - owner: context.payload.pull_request.head.repo.owner.login, - repo: context.payload.pull_request.head.repo.name, - ref: context.payload.pull_request.head.ref, + owner: signal_run.head_repository.owner.login, + repo: signal_run.head_repository.name, + ref: signal_run.head_branch, per_page: 100, } - console.log('Ref: ' + context.payload.pull_request.head.ref) - console.log('SHA: ' + context.payload.pull_request.head.sha) + console.log('Ref: ' + signal_run.head_branch) + console.log('SHA: ' + head_sha) const name = 'Build' const createDetectionFailedCheck = async () => { @@ -144,7 +162,7 @@ jobs: const check_runs = await github.request(check_run_endpoint, check_run_params) console.log('check_runs: ' + JSON.stringify(check_runs)) const actions_url = 'https://github.com/' - + context.payload.pull_request.head.repo.full_name + + signal_run.head_repository.full_name + '/actions/runs/' + run_id const run_url_part = '/actions/runs/' + run_id @@ -171,8 +189,8 @@ jobs: title: 'Test results', summary: '[See test results](' + check_run_url + ')', text: JSON.stringify({ - owner: context.payload.pull_request.head.repo.owner.login, - repo: context.payload.pull_request.head.repo.name, + owner: signal_run.head_repository.owner.login, + repo: signal_run.head_repository.name, run_id: run_id }) }, diff --git a/.github/workflows/pr-signal.yml b/.github/workflows/pr-signal.yml new file mode 100644 index 0000000000..afc4684e5d --- /dev/null +++ b/.github/workflows/pr-signal.yml @@ -0,0 +1,38 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Does nothing itself. It completes, and that completion starts the privileged +# `workflow_run` workflows (labeler, Build check) from the default branch, which +# replaces `pull_request_target`. See +# https://infra.apache.org/github-actions-policy.html ("A safer replacement for +# pull_request_target"). Consumers read the PR through the API from the +# `workflow_run` payload and never check out or run pull request code. +name: PR signal +on: + pull_request: + types: [opened, reopened, synchronize] + +permissions: {} + +jobs: + signal: + name: Signal pull request update + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: "Do nothing. Only trigger the corresponding workflow_run event" + run: echo "pull request updated"
