Skip to content

Comments

Fix: Use target repository for git operations in create-pull-request#15501

Merged
pelikhan merged 3 commits intomainfrom
copilot/fix-safe-outputs-git-operations
Feb 13, 2026
Merged

Fix: Use target repository for git operations in create-pull-request#15501
pelikhan merged 3 commits intomainfrom
copilot/fix-safe-outputs-git-operations

Conversation

Copy link
Contributor

Copilot AI commented Feb 13, 2026

When create-pull-request specifies target-repo, git operations (checkout, fetch, push) incorrectly used the source repository. The target repo was only used for the PR API call, causing failures when the base branch exists only in the target repo (e.g., vnext branch in cross-repo PRs).

Changes

Compiler updates:

  • buildCheckoutRepository: Added targetRepoSlug parameter, sets repository: on actions/checkout when specified
  • generateGitConfigurationStepsWithToken: Added targetRepoSlug parameter, sets REPO_NAME env var to target repo instead of ${{ github.repository }}
  • buildSharedPRCheckoutSteps: Extracts target-repo from create-pull-request config and passes to checkout/git config steps
  • buildCreateOutputPullRequestJob: Passes target-repo to checkout and git config generation

Testing:

  • Added integration tests for cross-repo and same-repo checkout scenarios

Example

Before (wrong):

- name: Checkout repository
  uses: actions/checkout@v6
  with:
    token: ${{ github.token }}
- name: Configure Git credentials
  env:
    REPO_NAME: ${{ github.repository }}  # source repo

After (correct):

- name: Checkout repository
  uses: actions/checkout@v6
  with:
    repository: microsoft/vscode-docs  # target repo
    token: ${{ github.token }}
- name: Configure Git credentials
  env:
    REPO_NAME: "microsoft/vscode-docs"  # target repo
Original prompt

This section details on the original issue you should resolve

<issue_title>Bug: create-pull-request target-repo is ignored by git operations in safe_outputs job</issue_title>
<issue_description>## Summary

When create-pull-request is configured with target-repo, the safe_outputs job's git operations (checkout, fetch, push) still target the source repository instead of the target. The target-repo value is only used by the GitHub API call to create the PR — all local git operations use the source repo.

This means:

  • git fetch origin <base-branch> fetches from the source repo (fails if branch doesn't exist there)
  • git push origin <branch> pushes to the source repo (wrong repo)
  • git ls-remote --heads origin checks the source repo
  • actions/checkout checks out the source repo

The bug is masked when base-branch happens to exist on both repos (e.g., main), but is exposed when using a branch that only exists on the target (e.g., vnext).

Reproduction

Workflow in org/engineering-repo targeting org/docs-repo with a non-default branch:

safe-outputs:
    github-token: ${{ secrets.CROSS_REPO_PAT }}
    create-pull-request:
        target-repo: 'org/docs-repo'
        base-branch: vnext
        draft: true

The vnext branch exists on org/docs-repo but not on org/engineering-repo.

Result: fatal: couldn't find remote ref vnext

Note: base-branch: main works only by coincidence — main exists on both repos.

Root cause

Two places in the code:

1. Compiler: checkout always targets source repo

compiler_safe_outputs_steps.go L118:

The Checkout repository step never sets the repository: parameter for cross-repo cases (only for trialMode). It always checks out github.repository (the source repo).

2. Compiler: git remote points to source repo

compiler_safe_outputs_steps.go L130:

REPO_NAME: ${{ github.repository }}

The git remote is configured to the source repo, not the target.

3. Handler: no remote reconfiguration

create_pull_request.cjs L463:

await exec.exec(`git fetch origin ${baseBranch}`);

The handler assumes origin already points to the target repo. It never reconfigures the git remote when target-repo is set.

All subsequent git operations (git push origin, git ls-remote --heads origin, git checkout -b ... origin/...) also go to the source repo.

Expected behavior

When target-repo is set on create-pull-request, the safe_outputs job should:

  • Either checkout the target repo directly (via repository: param on actions/checkout), OR
  • Reconfigure the git remote to point to the target repo before git fetch/git push

Workaround

Use base-branch: main (which exists on both repos). The PR will target main in the target repo. The reviewer must manually change the base branch to vnext after creation.

Environment

  • gh-aw CLI: v0.43.7
  • Compiler output confirms the issue — safe_outputs job in the .lock.yml shows:
    • Checkout repository with no repository: parameter
    • REPO_NAME: ${{ github.repository }} in git config
    • Handler config has "target-repo":"org/docs-repo","base_branch":"vnext" but the git remote is never updated
      </issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

- Update buildCheckoutRepository to accept and use targetRepoSlug parameter
- Update generateGitConfigurationStepsWithToken to use target repo for REPO_NAME
- Fix buildSharedPRCheckoutSteps in consolidated safe-outputs job to use target-repo
- Add integration tests for cross-repo and same-repo checkout scenarios

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix safe_outputs job to target correct repository Fix: Use target repository for git operations in create-pull-request Feb 13, 2026
Copilot AI requested a review from pelikhan February 13, 2026 20:03
@pelikhan pelikhan marked this pull request as ready for review February 13, 2026 20:20
Copilot AI review requested due to automatic review settings February 13, 2026 20:20
@pelikhan pelikhan merged commit 4e09787 into main Feb 13, 2026
51 checks passed
@pelikhan pelikhan deleted the copilot/fix-safe-outputs-git-operations branch February 13, 2026 20:20
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request fixes a critical bug where create-pull-request's target-repo configuration was ignored by git operations (checkout, fetch, push) in the safe_outputs job. The PR ensures that when a target repository is specified, both the actions/checkout step and git remote configuration use the target repository instead of the source repository.

Changes:

  • Modified buildCheckoutRepository to accept a targetRepoSlug parameter and set the repository: field on actions/checkout when specified
  • Modified generateGitConfigurationStepsWithToken to accept a targetRepoSlug parameter and configure REPO_NAME to the target repository
  • Updated buildSharedPRCheckoutSteps to extract and pass the target-repo from create-pull-request config to checkout and git configuration steps
  • Added integration tests to verify cross-repo and same-repo checkout behavior

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pkg/workflow/yaml_generation.go Added targetRepoSlug parameter to generateGitConfigurationStepsWithToken with correct priority logic (targetRepoSlug > trialLogicalRepoSlug > default)
pkg/workflow/push_to_pull_request_branch.go Added targetRepoSlug parameter to buildCheckoutRepository but contains priority logic bug where trialLogicalRepoSlug can override targetRepoSlug
pkg/workflow/publish_assets.go Updated call to buildCheckoutRepository to pass empty string for target repo (no target repo for upload assets)
pkg/workflow/create_pull_request.go Updated to pass TargetRepoSlug from config to both buildCheckoutRepository and generateGitConfigurationStepsWithToken
pkg/workflow/compiler_safe_outputs_steps.go Updated buildSharedPRCheckoutSteps to extract target-repo and configure both checkout and git config correctly with proper priority logic
pkg/workflow/create_pull_request_cross_repo_integration_test.go Added integration tests for cross-repo and same-repo checkout scenarios
Comments suppressed due to low confidence (1)

pkg/workflow/push_to_pull_request_branch.go:39

  • The priority logic for determining effectiveTargetRepo is inverted. When both targetRepoSlug and trialLogicalRepoSlug are set, the code gives priority to trialLogicalRepoSlug instead of targetRepoSlug as documented.

The current code:

  • Sets effectiveTargetRepo = targetRepoSlug
  • Then overwrites it with trialLogicalRepoSlug if in trial mode

This means trialLogicalRepoSlug takes priority over targetRepoSlug, which contradicts the comment on line 35 that states "Priority: targetRepoSlug > trialLogicalRepoSlug > default".

The correct logic should check if targetRepoSlug is empty before using trialLogicalRepoSlug.

	effectiveTargetRepo := targetRepoSlug
	if c.trialMode && c.trialLogicalRepoSlug != "" {
		effectiveTargetRepo = c.trialLogicalRepoSlug
	}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +49 to +50
// Add token for trial mode or when checking out a different repository
if c.trialMode || targetRepoSlug != "" {
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

The condition for adding a token should consider effectiveTargetRepo instead of just targetRepoSlug. If trialLogicalRepoSlug is set (in trial mode), a token is already included, but the current logic may not include a token when only targetRepoSlug is set without trial mode.

However, after the priority bug is fixed, this condition should be: if effectiveTargetRepo != "" to properly handle all cases where we're checking out a different repository.

This issue also appears on line 36 of the same file.

Suggested change
// Add token for trial mode or when checking out a different repository
if c.trialMode || targetRepoSlug != "" {
// Add token when checking out a different repository
if effectiveTargetRepo != "" {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: create-pull-request target-repo is ignored by git operations in safe_outputs job

2 participants