Skip to content

ci: label pull requests from workflow_run instead of pull_request_target - #2778

Merged
andygrove merged 1 commit into
apache:mainfrom
codekongdev:ci/labeler-workflow-run
Nov 8, 2026
Merged

andygrove merged 1 commit into
apache:mainfrom
codekongdev:ci/labeler-workflow-run

Conversation

@codekongdev

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Closes #2773.

Rationale for this change

GitHub blocks the pull_request_target trigger by default on public repositories from December 2, 2026, with brownouts before then, and ASF infra is disabling it for ASF repositories. The Labeler workflow (.github/workflows/dev_pr.yml) runs on that trigger, so pull requests would stop getting their path labels. Upstream tracking issue: apache/datafusion#26406.

What changes are included in this PR?

The labeler is split into two workflows, following the lookup that apache/datafusion#26683 and apache/datafusion-comet#7482 use:

  • dev_pr_trigger.yml (new, Labeler trigger) runs on pull_request for opened, reopened and synchronize. It has permissions: {} and does nothing. It exists only so that its completion can start the labeler.
  • dev_pr.yml (Labeler) now runs on workflow_run when the trigger completes. workflow_run always runs the default branch's copy of the file, with a token that can write labels on fork pull requests. The job:
    • finds the open pull requests whose head repository, branch and commit match the triggering run, with actions/github-script. workflow_run.pull_requests is empty for fork pull requests, so it can't be used. No artifact is read and nothing from the pull request is checked out or run. A commit that is no longer a head matches nothing, because the run for the newer push labels the pull request. If one branch has pull requests open against several bases, all of them are labeled.
    • passes the numbers to actions/labeler@v7.0.0 through its pr-number input. The config file, sync-labels: true and the macos-latest runner stay the same. With no checkout, the labeler reads .github/workflows/dev_pr/labeler.yml through the API at the default branch's commit.
    • declares permissions: {} at the top level and contents: read and pull-requests: write on the job.
    • keeps the concurrency group with cancellation. It is now keyed on the head repository and branch, because workflow_run doesn't carry the pull request number.

I also removed the commented-out actions-label-merge-conflict step. It was written for pull_request_target and wouldn't work as it is under workflow_run.

Behavior changes:

  • edited is no longer a trigger. The old labeling step already skipped it, so it only started a job that did nothing. reopened is new.
  • A first-time contributor's trigger run may wait for maintainer approval, depending on the repository's Actions settings. Their pull request isn't labeled until the run is approved.
  • GitHub doesn't run pull_request workflows while a pull request has merge conflicts. A conflicting pull request is labeled once the conflict is resolved.
  • A pull request runs its own copy of dev_pr_trigger.yml, so it can change or delete it. The only effect is that the pull request isn't labeled. dev_pr.yml reads nothing from the run apart from its head repository, branch and commit.
  • branch-53, branch-54 and branch-55 still have the pull_request_target version of dev_pr.yml. Backport pull requests won't be labeled once the trigger is blocked unless dev_pr_trigger.yml is backported too. The labeler on main picks up trigger runs from any branch. I left that for a follow-up.

Are there any user-facing changes?

No. This only changes CI.

How are these changes tested?

workflow_run only fires from the default branch's copy of a workflow, so this can't run end to end before it merges. What I checked:

  • Both files parse as YAML. workflows: [Labeler trigger] matches the trigger's name, and no other workflow uses that name. actions/github-script is owned by actions, which the ASF allowlist check trusts.
  • I extracted the github-script body from dev_pr.yml and ran it with Node against the real REST API, using the payloads of real pull_request runs in this repository:
  • I checked the actions/labeler v7.0.0 source. pr-number is read with getMultilineInput, and a config file that isn't on disk is fetched through the API at github.context.sha. Under workflow_run that is the latest commit on the default branch.

After this merges, opening or pushing to a pull request should run Labeler trigger and then Labeler, and the pull request should get its labels.

🤖 Generated with Claude Code

GitHub blocks the pull_request_target trigger by default on public
repositories from December 2, 2026, and ASF infra is disabling it for ASF
repositories. The Labeler workflow (dev_pr.yml) runs on that trigger.

Split it in two:

- dev_pr_trigger.yml runs on pull_request with no permissions and does
  nothing. Its completion starts the labeler.
- dev_pr.yml runs on workflow_run from the default branch with
  pull-requests: write. It looks up the open pull requests whose head
  repository, branch and commit match the triggering run, and passes
  them to actions/labeler through its pr-number input. Nothing from the
  pull request is checked out or run, and no artifact is read.

Closes apache#2773.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@andygrove andygrove left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking this up, and for the thorough testing notes! The split matches what we did in Comet, and I like that the write job reads nothing from the run beyond the head repository, branch and commit. A few small suggestions, mostly borrowed from the Comet version:

  • Could the job's if: also check github.repository == 'apache/datafusion-ballista'? Otherwise every fork with Actions enabled runs the labeler against its own pull requests.
  • The trigger only runs an echo, so ubuntu-latest (or ubuntu-slim) would save a macOS runner on every push. macOS runners are the scarce ones in the ASF pool. The labeler job could move too.
  • Maybe add timeout-minutes: 10 on the labeling job.

None of these block, so approving. I'll keep an eye on the first pull request after this merges to make sure it gets labeled.

@andygrove
andygrove enabled auto-merge November 8, 2026 20:58
@andygrove
andygrove added this pull request to the merge queue Nov 8, 2026
Merged via the queue into apache:main with commit 23c3372 Nov 8, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate Labeler workflow away from pull_request_target

2 participants