Skip to content

[agent-issue]: create-pull-request cannot target a repository from another Azure DevOps organisation #1934

Description

@dhavalpopat

Submission requirements

  • I generated this issue with an agent that used .github/agents/ado-aw.agent.md.
  • I reviewed the generated issue and confirm it is being filed directly in githubnext/ado-aw.

Problem summary

repos: accepts a repository in another Azure DevOps organisation, and the checkout works, but create-pull-request cannot target it. The safe-output executor builds every Git API call from a single AZURE_DEVOPS_ORG_URL + SYSTEM_TEAMPROJECT, so a repository alias belonging to a different organisation resolves against the wrong one and cannot be found.

The result is a workflow that can read a repository — the agent greps it, traces a failure into it, concludes the fix belongs there — and then cannot act on that conclusion. create-pull-request advertises the capability: its repository parameter is documented as "a repository alias from the checkout list", and every alias in repos: is such an alias, whichever organisation it came from.

This is not a permissions problem. In our case the pipeline identity has Read, Contribute, CreateBranch and PullRequestContribute on the cross-organisation repositories, verified with permissionevaluationbatch against that organisation. The credential would work; the URL it is used against is the wrong one.

Reproduction details

Environment: ado-aw 0.50.0, standalone target, engine copilot.

Front matter — three of the four repositories are in msazure/One, two are in msazuredev/AzureForOperatorsIndustry:

repos:
  - One/azlocal-overlay
  - name: AzureForOperatorsIndustry/nc-api-testing
    ref: refs/heads/main
    endpoint: afoi-x-org-pipeline
  - name: AzureForOperatorsIndustry/nc-resource-testing
    ref: refs/heads/main
    endpoint: afoi-x-org-pipeline

The checkout succeeds and the agent reads those repositories happily. The executor, however, receives only:

env:
  SYSTEM_ACCESSTOKEN: $(SC_WRITE_TOKEN)
  ADO_AW_SELF_REPOSITORY_DIRECTORY: $(Build.SourcesDirectory)/self
  ADO_AW_SELF_REPOSITORY_NAME: AzureStack-Solution-CI-Infra

ADO_AW_SELF_REPOSITORY_* are the only repository variables the binary knows — strings on the released binary shows no other ADO_AW_*REPOSITORY* names — so a non-self alias has no organisation, project or repository id attached to it, and the request is composed against AZURE_DEVOPS_ORG_URL.

Confirming where the repositories actually live:

GET msazure.visualstudio.com/One/_apis/git/repositories/azlocal-overlay      -> 200
GET msazure.visualstudio.com/One/_apis/git/repositories/nc-api-testing       -> 404
GET dev.azure.com/msazuredev/AzureForOperatorsIndustry/.../nc-api-testing    -> 200

Observed: a pull request cannot be created against a cross-organisation alias.
Expected: create-pull-request can target any repository in repos:, as its repository parameter describes.

Note --dry-run reports success for all of these, because it skips the API calls where the resolution would fail:

[1/3] create-pull-request - ✓ - [DRY-RUN] Would execute: create PR: '...' in repo 'azlocal-overlay'
[2/3] create-pull-request - ✓ - [DRY-RUN] Would execute: create PR: '...' in repo 'nc-api-testing'

So the limitation is invisible until a run genuinely tries, which for a workflow that only raises a PR when confident may be weeks after the pipeline is set up.

Proposed next step

Carry the organisation, project and repository id per checkout alias rather than only for self — the compiler already knows all three from repos:, since it emits the checkout: steps — and have create-pull-request compose its URL from the alias's own context. The service connection named in endpoint: is the natural place to get a credential for that organisation, mirroring how the checkout authenticates.

Failing that, two smaller improvements would each have saved us the investigation:

  1. Fail at compile time. If create-pull-request is enabled and repos: contains an alias outside the pipeline's organisation, say so when compiling. The mismatch is fully known then.
  2. Make --dry-run resolve the repository. Reporting "would execute" for a target that cannot be resolved is the least useful answer, and dry-run is exactly where this should surface.

Workaround for anyone hitting this: restrict pull requests to same-organisation repositories and have the agent write the proposed change into the work item for the others.

Metadata

Metadata

Labels

bugSomething isn't workingrustPull requests that update rust code

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions