Skip to content

compiler: buildSharedPRCheckoutSteps ignores push-to-pull-request-branch.target-repo (and update-pull-request.target-repo) when create-pull-request is not configured #30472

Description

@bryanchen-d

Bug

When a workflow configures safe-outputs.push-to-pull-request-branch.target-repo without also configuring safe-outputs.create-pull-request, the compiler-emitted safe_outputs job checks out the workflow repo instead of the target repo. The handler's git ls-remote --exit-code --heads origin <pr-branch> then fails with exit code 2 because origin points at the wrong repository.

This is the exact gap PR #22244 set out to fix. That PR was closed without merge on 2026-03-22; PR #28388 (which closed tracking issue #21306) only fixed the JS handler's directory handling, not the Go compiler step generation. As a result, the regression is still present on main (verified at HEAD of pkg/workflow/compiler_safe_outputs_steps.go) and against gh-aw extension v0.71.5.

Repro

Workflow config (abbreviated, real workflow at microsoft/vscode-engineering/.github/workflows/errors-fix-driver.md):

on:
  workflow_dispatch:
    inputs:
      pr_number: { type: string, required: true }

safe-outputs:
  github-token: ${{ steps.safe-outputs-app-token.outputs.token }}
  push-to-pull-request-branch:
    target-repo: "microsoft/vscode"
  update-pull-request:
    target-repo: "microsoft/vscode"
  # NOTE: no create-pull-request configured

tools:
  github:
    github-token: ${{ steps.safe-outputs-app-token.outputs.token }}

# checkout block puts target repo at workspace root
# (workflow repo is at ./workflow-repo)

The compiled safe_outputs job emits:

- name: Checkout repository
  if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
  uses: actions/checkout@...
  with:
    ref: ${{ github.base_ref || ... }}
    token: ${{ steps.safe-outputs-app-token.outputs.token }}
    persist-credentials: false
    fetch-depth: 1
    # <-- repository: missing
- name: Configure Git credentials
  env:
    REPO_NAME: ${{ github.repository }}   # <-- wrong repo (vscode-engineering, not vscode)
    ...
  run: |
    git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"

The handler actions/setup/js/push_to_pull_request_branch.cjs then runs:

git ls-remote --exit-code --heads origin fix/listview-null-row-guard-314134-...

against origin = microsoft/vscode-engineering, exits with code 2, and fails the job.

Root cause (source)

pkg/workflow/compiler_safe_outputs_steps.go::buildSharedPRCheckoutSteps only consults CreatePullRequests.TargetRepoSlug when picking targetRepoSlug:

// Priority: create-pull-request target-repo > trialLogicalRepoSlug > default (source repo)
var targetRepoSlug string
if data.SafeOutputs.CreatePullRequests != nil &&
    data.SafeOutputs.CreatePullRequests.TargetRepoSlug != "" {
    targetRepoSlug = data.SafeOutputs.CreatePullRequests.TargetRepoSlug
} else if c.trialMode && c.trialLogicalRepoSlug != "" {
    targetRepoSlug = c.trialLogicalRepoSlug
}
// missing: PushToPullRequestBranch.TargetRepoSlug fallback

REPO_NAME and repository: are then both elided from the emitted YAML. The same is true for UpdatePullRequest.TargetRepoSlug, which has identical semantics for cross-repo updates.

Expected

When any of the following are set (and create-pull-request is not), the safe_outputs job should check out the configured target repo and set REPO_NAME accordingly:

  • push-to-pull-request-branch.target-repo
  • update-pull-request.target-repo (same problem class)

PR #22244's CheckoutManager-based design (each safe output independently registers its checkout requirement, manager dedupes) is the right shape; that PR just never landed.

Workaround

Add a no-op create-pull-request to safe-outputs purely to trick the compiler — undesirable because it changes runtime guards/permissions and risks accidental PR creation.

Affected versions

  • gh-aw extension v0.71.1 → v0.71.5 (current). Compiler main HEAD as of 2026-05-05 still has the gap.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions