-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Description
Describe the bug
When there is a PR from a fork in the same org as the upstream, pr view will fail to find it, when determining the PR via the branch.
Testscript to demonstrate the issue. Note that we have to use gh api to create the PR because pr create cannot handle fork in the same org as the upstream for different reasons.
# Setup environment variables used for testscript
env REPO=${SCRIPT_NAME}-${RANDOM_STRING}
env FORK=${REPO}-fork
# Use gh as a credential helper
exec gh auth setup-git
# Create a repository to act as upstream with a file so it has a default branch
exec gh repo create ${ORG}/${REPO} --add-readme --private
# Defer repo cleanup of upstream
defer gh repo delete --yes ${ORG}/${REPO}
exec gh repo view ${ORG}/${REPO} --json id --jq '.id'
stdout2env REPO_ID
# Create a fork in the same org
exec gh repo fork ${ORG}/${REPO} --org ${ORG} --fork-name ${FORK}
# Defer repo cleanup of fork
defer gh repo delete --yes ${ORG}/${FORK}
sleep 1
exec gh repo view ${ORG}/${FORK} --json id --jq '.id'
stdout2env FORK_ID
# Clone the fork
exec gh repo clone ${ORG}/${FORK}
cd ${FORK}
# Prepare a branch
exec git checkout -b feature-branch
exec git commit --allow-empty -m 'Empty Commit'
exec git push -u origin feature-branch
# Create the PR spanning upstream and fork repositories, gh pr create does not support headRepositoryId needed for private forks
exec gh api graphql -F repositoryId="${REPO_ID}" -F headRepositoryId="${FORK_ID}" -F query='mutation CreatePullRequest($headRepositoryId: ID!, $repositoryId: ID!) { createPullRequest(input:{ baseRefName: "main", body: "Feature Body", draft: false, headRefName: "feature-branch", headRepositoryId: $headRepositoryId, repositoryId: $repositoryId, title:"Feature Title" }){ pullRequest{ id url } } }'
# View the PR
exec gh pr view
stdout 'Feature Title'
Implementation Details
When using the PR Finder, gh will resolve the current branch name from git. It then uses the git remote for that branch, and determines whether it should be prepended with <owner>:
cli/pkg/cmd/pr/shared/finder.go
Lines 268 to 270 in c35d725
| if !strings.EqualFold(branchOwner, f.repo.RepoOwner()) { | |
| prHeadRef = fmt.Sprintf("%s:%s", branchOwner, prHeadRef) | |
| } |
Later, it does another string concatenation based on whether a fetched PR isCrossRepository, inside the pr.HeadLabel() method, which is then compared to the aforementioned branch:
cli/pkg/cmd/pr/shared/finder.go
Line 358 in c35d725
| if pr.HeadLabel() == headBranch && (baseBranch == "" || pr.BaseRefName == baseBranch) && (pr.State == "OPEN" || resp.Repository.DefaultBranchRef.Name != headBranch) { |
However, the original decision to prepend with owner only makes sense if the fork is in a different org.
Acceptance Criteria
Given I have a PR between a fork and upstream in the same org
And Given I have the fork PR branch checked out locally
When I run gh pr view
Then I should see the PR