Support pr view for intra-org forks
This commit is contained in:
parent
c35d725b0b
commit
96ac8d6a2f
3 changed files with 96 additions and 7 deletions
39
acceptance/testdata/pr/pr-view-same-org-fork.txtar
vendored
Normal file
39
acceptance/testdata/pr/pr-view-same-org-fork.txtar
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# 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'
|
||||
|
|
@ -246,27 +246,36 @@ func (f *finder) parseCurrentBranch() (string, int, error) {
|
|||
return "", prNumber, nil
|
||||
}
|
||||
|
||||
var branchOwner string
|
||||
var gitRemoteRepo ghrepo.Interface
|
||||
if branchConfig.RemoteURL != nil {
|
||||
// the branch merges from a remote specified by URL
|
||||
if r, err := ghrepo.FromURL(branchConfig.RemoteURL); err == nil {
|
||||
branchOwner = r.RepoOwner()
|
||||
gitRemoteRepo = r
|
||||
}
|
||||
} else if branchConfig.RemoteName != "" {
|
||||
// the branch merges from a remote specified by name
|
||||
rem, _ := f.remotesFn()
|
||||
if r, err := rem.FindByName(branchConfig.RemoteName); err == nil {
|
||||
branchOwner = r.RepoOwner()
|
||||
gitRemoteRepo = r
|
||||
}
|
||||
}
|
||||
|
||||
if branchOwner != "" {
|
||||
if gitRemoteRepo != nil {
|
||||
if strings.HasPrefix(branchConfig.MergeRef, "refs/heads/") {
|
||||
prHeadRef = strings.TrimPrefix(branchConfig.MergeRef, "refs/heads/")
|
||||
}
|
||||
// prepend `OWNER:` if this branch is pushed to a fork
|
||||
if !strings.EqualFold(branchOwner, f.repo.RepoOwner()) {
|
||||
prHeadRef = fmt.Sprintf("%s:%s", branchOwner, prHeadRef)
|
||||
// This is determined by:
|
||||
// - The repo having a different owner
|
||||
// - The repo having the same owner but a different name (private org fork)
|
||||
// I suspect that the implementation of the second case may be broken in the face
|
||||
// of a repo rename, where the remote hasn't been updated locally. This is a
|
||||
// frequent issue in commands that use SmartBaseRepoFunc. It's not any worse than not
|
||||
// supporting this case at all though.
|
||||
sameOwner := strings.EqualFold(gitRemoteRepo.RepoOwner(), f.repo.RepoOwner())
|
||||
sameOwnerDifferentRepoName := sameOwner && !strings.EqualFold(gitRemoteRepo.RepoName(), f.repo.RepoName())
|
||||
if !sameOwner || sameOwnerDifferentRepoName {
|
||||
prHeadRef = fmt.Sprintf("%s:%s", gitRemoteRepo.RepoOwner(), prHeadRef)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ func TestFind(t *testing.T) {
|
|||
wantRepo: "https://github.com/OWNER/REPO",
|
||||
},
|
||||
{
|
||||
name: "current branch with upstream configuration",
|
||||
name: "current branch with upstream RemoteURL configuration",
|
||||
args: args{
|
||||
selector: "",
|
||||
fields: []string{"id", "number"},
|
||||
|
|
@ -384,6 +384,47 @@ func TestFind(t *testing.T) {
|
|||
wantPR: 13,
|
||||
wantRepo: "https://github.com/OWNER/REPO",
|
||||
},
|
||||
{
|
||||
name: "current branch with upstream and fork in same org",
|
||||
args: args{
|
||||
selector: "",
|
||||
fields: []string{"id", "number"},
|
||||
baseRepoFn: func() (ghrepo.Interface, error) {
|
||||
return ghrepo.FromFullName("OWNER/REPO")
|
||||
},
|
||||
branchFn: func() (string, error) {
|
||||
return "blueberries", nil
|
||||
},
|
||||
branchConfig: func(branch string) (c git.BranchConfig) {
|
||||
c.RemoteName = "origin"
|
||||
return
|
||||
},
|
||||
remotesFn: func() (context.Remotes, error) {
|
||||
return context.Remotes{{
|
||||
Remote: &git.Remote{Name: "origin"},
|
||||
Repo: ghrepo.New("OWNER", "REPO-FORK"),
|
||||
}}, nil
|
||||
},
|
||||
},
|
||||
httpStub: func(r *httpmock.Registry) {
|
||||
r.Register(
|
||||
httpmock.GraphQL(`query PullRequestForBranch\b`),
|
||||
httpmock.StringResponse(`{"data":{"repository":{
|
||||
"pullRequests":{"nodes":[
|
||||
{
|
||||
"number": 13,
|
||||
"state": "OPEN",
|
||||
"baseRefName": "main",
|
||||
"headRefName": "blueberries",
|
||||
"isCrossRepository": true,
|
||||
"headRepositoryOwner": {"login":"OWNER"}
|
||||
}
|
||||
]}
|
||||
}}}`))
|
||||
},
|
||||
wantPR: 13,
|
||||
wantRepo: "https://github.com/OWNER/REPO",
|
||||
},
|
||||
{
|
||||
name: "current branch made by pr checkout",
|
||||
args: args{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue