Skip to content

push_to_pull_request_branch: no repo param, so target:'*' can't push to sub-repo checkouts in multi-repo workflows #46099

Description

@heiskr

Summary

push_to_pull_request_branch has no repo (or target-repo) input, so in a multi-repo workflow where several repos are checked out into subdirectories and the safe output uses target: "*", the handler cannot determine which sub-repo checkout a PR lives in. It always runs git from GITHUB_WORKSPACE (the primary/root checkout) and fails when the PR's branch only exists in a sub-repo checkout.

Filed by @heiskr (with GitHub Copilot). I couldn't fully dedupe against existing issues because the search API was returning 503s at filing time — please close as duplicate if one exists.

Repro

A workflow checks out 7 repos into subdirectories (docs-internal/, docs-content/, ...), GITHUB_WORKSPACE is the primary repo root, and:

safe-outputs:
  push-to-pull-request-branch:
    target: "*"
    allowed-repos: [github/docs-internal, github/docs-content, ...]

The agent commits to a branch inside one sub-repo checkout (e.g. docs-internal/), then calls push_to_pull_request_branch(pull_request_number: 62133, branch: fix-...). It fails:

git rev-parse fails with 'Needed a single revision'
because <branch> only exists in docs-internal/ checkout

Root cause

In actions/setup/js/safe_outputs_tools.json, the tool's input schema is [message, branch, pull_request_number, secrecy, integrity]no repo — and x-safe-outputs-target-requirements["*"] is { primary: pull_request_number, anyOf: [pull_request_number] }.

In actions/setup/js/safe_outputs_handlers.cjs, the push handler resolves the working directory only when a repo is known:

if (((entry.repo && entry.repo.trim()) || pushConfig["target-repo"]) && !repoCwd) {
  const checkoutResult = findRepoCheckout(itemRepo); // resolves sub-repo checkout dir
  ...
}

For target: "*", pushConfig["target-repo"] is empty and the tool never supplies entry.repo, so this branch never runs. repoCwd stays null and every git op runs from GITHUB_WORKSPACE.

Contrast: create_pull_request works

create_pull_request does expose a repo param and reaches findRepoCheckout(repoSlug) via entry.repo, so it correctly targets sub-repo checkouts. push_to_pull_request_branch is missing the equivalent.

Proposed fix

Add a repo (owner/repo) input to push_to_pull_request_branch, mirroring create_pull_request, and include it in the wildcard anyOf so the agent must supply it when target: "*". Then findRepoCheckout(itemRepo) can resolve the correct sub-repo checkout. pull_request_number alone is ambiguous across repos.

Version

gh-aw v0.82.11 (latest at time of filing). Handler is unchanged from v0.82.7.

Real-world impact

github/docs-team's pr-janitor-agent scans and fixes PRs across 7 docs repos; cross-repo pushes fail every run. Tracked downstream in github/docs-team#7104.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions