BYBOWU > Blog > Web development

GitHub Actions pull_request_target changes: Fix Now

blog hero image
GitHub just changed how pull_request_target and environment branch protections work, with enforcement starting December 8, 2025. If you rely on PR-triggered deployments or secrets, your pipelines can silently stop matching rules—or worse, expose credentials. This field guide explains exactly what changed, why it matters, and the fast path to safe defaults. I’ll also fold in this month’s runner updates so you can fix policy, labels, and performance in one sprint.
📅
Published
Nov 13, 2025
🏷️
Category
Web development
⏱️
Read Time
10 min

GitHub’s pull_request_target changes land on December 8, 2025—and they’re not cosmetic. The event now always executes from your default branch, and environment branch protection rules evaluate against the executing ref for pull request events. If your deployment rules, checkout logic, or secrets gating assume the old behavior, expect blocked jobs or unexpected secret exposure when enforcement starts. (github.blog)

Diagram of default branch vs PR merge ref execution in GitHub Actions

What exactly changed in pull_request_target changes

Here’s the precise behavior shift. For pull_request_target, the workflow file and the commit used to run the job come from the repository’s default branch—no more sourcing from the pull request’s base branch. GitHub also aligned ref semantics: GITHUB_REF now resolves to the default branch and GITHUB_SHA points to its latest commit during these events. (github.blog)

Environment branch protection rules now evaluate against the execution reference, not the PR head. Concretely, for pull_request family events, your environments evaluate against refs/pull/<number>/merge. For pull_request_target, environments evaluate against the default branch. If your environment filters only allow main or release branches, some PR jobs will stop matching until you update patterns. Enforcement starts December 8, 2025. (github.blog)

Why this matters more than it sounds

Teams historically used pull_request_target to run privileged checks or deployments on code from forks. The old model sometimes executed outdated workflow files from a non-default base branch, which created a class of vulnerabilities. The new default-branch sourcing closes that hole—but it also means any branch-specific assumptions in your pipelines will break the moment enforcement turns on. (github.blog)

There’s another knock-on effect: environment rules that once matched PR branches by name now evaluate against refs/pull/<number>/merge or the default branch for pull_request_target. If you gate secrets on branch patterns like release/*, those patterns won’t match a PR merge ref unless you explicitly account for it. (github.blog)

The one-week fix plan

Here’s the path I’ve used to land changes safely inside one sprint. It keeps your deployments flowing, reduces blast radius, and avoids last‑minute fire drills.

1) Find every workflow that uses pull_request_target

Search your org for on: [pull_request_target] and on: pull_request_target:. Flag jobs that access secrets, write to environments, or deploy. Don’t forget composite and reusable workflows—your repos might call a centrally maintained workflow that uses pull_request_target.

2) Decide: do you actually need pull_request_target?

If the job doesn’t need elevated secrets or write permissions, switch to pull_request. Use least privilege by setting the default token to read-only at the org/repo level and elevate per job only where it’s truly justified. In many orgs, that single swap eliminates 70–80% of risk and policy churn.

3) Update environment branch rules so jobs still resolve

For environments used by pull_request jobs, include patterns for refs/pull/*/merge. For environments used by pull_request_target, allow the default branch explicitly (typically main). This aligns your checks with the execution ref GitHub will evaluate on December 8. (github.blog)

4) Gate untrusted contributions the right way

For forks, favor a two‑phase approach: run unprivileged checks with pull_request; then, on approval, trigger a privileged workflow_run or workflow_dispatch job on the default branch with environment protections. That pattern keeps secrets out of direct fork context while preserving contributor velocity.

5) Harden your YAML

Use actions/checkout with persist-credentials: false and explicit permissions blocks. Pin third‑party actions by commit SHA. Avoid ref: ${{ github.head_ref }} in privileged jobs; if you must fetch PR code, fetch it read‑only and treat artifacts as untrusted. Code scanning can help catch risky patterns in workflows. (github.blog)

6) Fix runner labels while you’re here (macOS 13 retires Dec 4)

If you still run on macos-13, you’ve already seen brownouts on November 4 and 11, with more on November 18 and 25. The macOS 13 image retires on December 4, 2025. Migrate to macos-15 or macos-latest for arm64; if you require Intel, GitHub introduced macos-15-intel as a transition label. (github.blog)

The deprecation is also tracked in the runner‑images repo with the same brownout windows. If you’ve pinned macos-13 anywhere, fix it now or expect red builds during the remaining brownouts and permanent failures after December 4. (github.com)

7) Take advantage of this month’s limits and performance bumps

Reusable workflow limits were increased to 10 nested levels and up to 50 calls per run. And M2 macOS runners are GA on xlarge labels—use them if your CI benefits from Apple Silicon performance. These updates make it easier to refactor into a privileged workflow on the default branch without collapsing into one mega‑YAML. (github.blog)

“Should we stop using pull_request_target entirely?”

No—but use it intentionally. Reserve it for workflows that must run with access to repo secrets in response to PR activity, and only after you’ve locked down inputs and actions. If your job is just lint/tests, pull_request gives you a safer baseline with fewer policy surprises when GitHub tweaks semantics. (github.blog)

“Do we need to change our environment rules right now?”

Yes, if you want uninterrupted deployments. Add patterns for refs/pull/*/merge where you expect PR jobs to hit environments, and explicitly allow your default branch for any pull_request_target environment. Then validate by opening a test PR from a fork and from a branch in‑repo to ensure both paths behave as expected on the new evaluation model. (github.blog)

“What if our main branch isn’t called ‘main’?”

Whatever your default is—main, master, or trunk—GitHub’s changes key off the default branch setting. Make sure your environment rules reference the actual default branch. I’ve seen teams quietly break PR deployments because their filters listed main while the repo default was still master.

A practical pattern for safer PR pipelines

Here’s a battle‑tested structure that maps cleanly to the new semantics:

  • Unprivileged checks on pull_request: build, test, scan; no secrets; token read‑only.
  • On approval, a workflow_run from main (default) does the privileged work: package, deploy to preview, run integration tests that need secrets, then promote to staging/prod behind environment approvals.
  • For maintainers’ branches (not forks), allow a manual workflow_dispatch fast path with the same privileged workflow, still gated by environment rules.

This keeps untrusted code out of privileged contexts and aligns your policy with how GitHub now evaluates refs for PR events. (github.blog)

Timelines and details you can paste into Slack

Key dates to unblock your team:

  • November 18, 2025 and November 25, 2025: remaining macOS 13 brownouts (14:00–00:00 UTC). Jobs on macos-13* labels can fail by design.
  • December 4, 2025: macOS 13 image retired from GitHub‑hosted runners.
  • December 8, 2025: pull_request_target and environment policy changes enforced. Update environment filters and ref assumptions before this date.
Photo of laptop with YAML and notes for Dec 4 and Dec 8 deadlines

If you need a deeper walkthrough of the semantics and pitfalls, we published a focused explainer: how the pull_request_target event is changing and what to do. For scheduling, see our “fixes by Dec 8” cutover list, and if your runners still target Ventura, follow our macOS 13 deprecation guide. (github.blog)

Gotchas I’ve already seen this week

Checkout dance breaks silently. Some repos fetch PR code in a privileged job and assume the job ref matches the PR branch. With the new model, that ref may be refs/pull/<number>/merge or the default branch. Fetch explicitly, don’t infer.

Environment filters fail closed. Teams that filtered on release/* only saw PR jobs stop deploying because the merge ref didn’t match. Add the PR merge pattern where you intend PR jobs to deploy to preview or test environments. (github.blog)

Legacy macOS labels hidden in composites. Look for runs-on in called workflows. I’ve found stale macos-13 labels buried in shared release pipelines that nobody touched in a year. Fix them while you’re in there. (github.blog)

Under‑pinned actions. If a third‑party action updates with breaking behavior while you’re refactoring, you’ll chase ghosts. Pin to a commit SHA during the migration; unpin later when you’re stable.

Let’s get practical: a 7‑day cutover checklist

Use this with your team’s standups and merge windows. It’s intentionally blunt.

  • Day 1: Org‑wide search for pull_request_target, environment:, and runs-on: macos-13. Make a column for secrets used.
  • Day 2: Flip non‑privileged pull_request_target jobs to pull_request. Add permissions: contents: read defaults and elevate per job as needed.
  • Day 3: Update environment filters: add refs/pull/*/merge and the default branch where appropriate. Test with a dummy PR from a fork.
  • Day 4: Migrate macOS runners: prefer macos-15 or macos-latest; use macos-15-intel only if you must keep x86_64. (github.blog)
  • Day 5: Extract privileged steps into a reusable workflow called from main via workflow_run. Take advantage of the new 10‑level nesting limit to simplify structure. (github.blog)
  • Day 6: Harden: pin actions by SHA, persist-credentials: false, and add code scanning on workflow files. (github.blog)
  • Day 7: Dry runs in a throwaway repo, then cut over on a calm window. Keep a rollback PR ready.

Zooming out: what this signals for 2026

GitHub is steadily moving privileged operations behind explicit, trusted refs and environments. Expect more opinionated defaults, tighter permission scopes, and faster runner images on Apple Silicon. If your org consolidates privileged work onto the default branch and leans on environments, these policy shifts become non‑events instead of outages. (github.blog)

What to do next (developers and leads)

  • Engineers: Ship the Day 1–4 items this week. Don’t wait for Dec 8. Open a tracking issue for every repo using pull_request_target.
  • Leads: Create a temporary exception policy for teams that truly need pull_request_target. Everything else moves to pull_request plus a privileged workflow_run.
  • Platform teams: Publish a blessed reusable workflow for deployments from the default branch, with environments and approvals pre‑wired. Announce the merge window and support channel.
  • Owners: If you need a partner to audit and refactor your Actions fleet, talk to us. We’ve been shipping these cutovers for clients all month.

For a broader roundup of this month’s Actions changes and how to prioritize them alongside feature work, read our weekly fix guide for November 2025. If you’ve already made the PR‑target changes and want to accelerate the rest, our ship‑it checklist covers the quick wins. (github.blog)

People also ask

Will this break our auto‑merge rules?

It can. If your auto‑merge depends on environment checks that previously matched a branch name, update those rules to match the new execution refs and confirm the check names haven’t changed. (github.blog)

Can we keep using Intel macOS runners?

Temporarily. Use macos-15-intel as a bridge while you port to Apple Silicon. GitHub has signaled long‑term deprecation of x86_64 on macOS runner images after macOS 15 retires in Fall 2027, so plan the migration now. (github.blog)

Are reusable workflows fast enough for this pattern?

Yes, especially with the higher nesting and call limits. Consolidating privileged work into a reusable workflow reduces duplication, centralizes policy, and scales cleanly across repos. (github.blog)

Want a second set of eyes on your YAML? We build, test, and maintain pipelines for startups and enterprises alike—see what we ship on our portfolio, or browse more deep‑dive guides on the Bybowu blog.

Seven-day GitHub Actions migration checklist
Written by Viktoria Sulzhyk · BYBOWU
4,651 views

Get in Touch

Ready to start your next project? Let's discuss how we can help bring your vision to life

Email Us

[email protected]

We'll respond within 24 hours

Call Us

+1 (602) 748-9530

Available Mon-Fri, 9AM-6PM

Live Chat

Start a conversation

Get instant answers

Visit Us

Phoenix, AZ / Spain / Ukraine

Digital Innovation Hub

Send us a message

Tell us about your project and we'll get back to you

💻
🎯
🚀
💎
🔥