Zev Averbach
Zev Averbach

Reputation: 1134

How can I create a PR across forks using the Azure DevOps Service API?

I have two repos on Azure DevOps, let's call them parent_repo and child_repo. The child_repo is a fork of the parent. What I'd like to do is create a PR to merge master of child_repo to master of parent_repo using the Azure DevOps Services API, by way of its Python library.

According to these docs and this thread, forkSource is the parameter needed to indicate that the source branch is in a fork, and to provide the repo_id of that fork.

from azure.devops.connection import Connection
from msrest.authentication import BasicAuthentication

_connection = Connection(base_url=URL, creds=BasicAuthentication("", PAT))
CLIENT = _connection.clients.get_git_client()

args = {
    "git_pull_request_to_create": {
        "sourceRefName": f"refs/heads/master",
        "targetRefName": f"refs/heads/master",
        "forkSource": {"repository": {"repository": child_repo_id}},
        "title": "...",
        "description": "...",
    },
    "repository_id": parent_repo_id,
}

res = CLIENT.create_pull_request(**args)

The nested dictionary I've provided for forkSource is a result of trial and error with the library, and it does successfully create a PR. However, the PR this creates is to merge parent:master to parent:master, so it's not useful.

How can I change args so it will create a PR for child:master to parent:master?

Upvotes: 0

Views: 398

Answers (1)

Zev Averbach
Zev Averbach

Reputation: 1134

Okay, I dug a little deeper into the docs, starting here with forkSource. Following that link into here then here it became apparent that forkSource has to be formulated like so:

"forkSource": {"repository": {"id": child_repo_id}}

Oddly, the DevOps API was ignoring the nested repository param instead of (preferably) throwing an error. This change resolves the issue and creates a PR resembling the one I'm after.

Full code:

from azure.devops.connection import Connection
from msrest.authentication import BasicAuthentication

_connection = Connection(base_url=URL, creds=BasicAuthentication("", PAT))
CLIENT = _connection.clients.get_git_client()

args = {
    "git_pull_request_to_create": {
        "sourceRefName": f"refs/heads/master",
        "targetRefName": f"refs/heads/master",
        "forkSource": {"repository": {"id": child_repo_id}}, # the only change required
        "title": "...",
        "description": "...",
    },
    "repository_id": parent_repo_id,
}

res = CLIENT.create_pull_request(**args)

Upvotes: 3

Related Questions