Merge pull request #3924 from cli/rest-org-repo-bug
fix repo create in org with license/ignore
This commit is contained in:
commit
a6710ec506
4 changed files with 117 additions and 13 deletions
|
|
@ -113,6 +113,7 @@ func NewHTTPClient(io *iostreams.IOStreams, cfg configGetter, appVersion string,
|
|||
opts = append(opts,
|
||||
api.AddHeaderFunc("Accept", func(req *http.Request) (string, error) {
|
||||
accept := "application/vnd.github.merge-info-preview+json" // PullRequest.mergeStateStatus
|
||||
accept += ", application/vnd.github.nebula-preview" // visibility when RESTing repos into an org
|
||||
if ghinstance.IsEnterprise(getHost(req)) {
|
||||
accept += ", application/vnd.github.antiope-preview" // Commit.statusCheckRollup
|
||||
accept += ", application/vnd.github.shadow-cat-preview" // PullRequest.isDraft
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ func TestNewHTTPClient(t *testing.T) {
|
|||
wantHeader: map[string]string{
|
||||
"authorization": "token MYTOKEN",
|
||||
"user-agent": "GitHub CLI v1.2.3",
|
||||
"accept": "application/vnd.github.merge-info-preview+json",
|
||||
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview",
|
||||
},
|
||||
wantStderr: "",
|
||||
},
|
||||
|
|
@ -69,7 +69,7 @@ func TestNewHTTPClient(t *testing.T) {
|
|||
wantHeader: map[string]string{
|
||||
"authorization": "",
|
||||
"user-agent": "GitHub CLI v1.2.3",
|
||||
"accept": "application/vnd.github.merge-info-preview+json",
|
||||
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview",
|
||||
},
|
||||
wantStderr: "",
|
||||
},
|
||||
|
|
@ -85,14 +85,14 @@ func TestNewHTTPClient(t *testing.T) {
|
|||
wantHeader: map[string]string{
|
||||
"authorization": "token MYTOKEN",
|
||||
"user-agent": "GitHub CLI v1.2.3",
|
||||
"accept": "application/vnd.github.merge-info-preview+json",
|
||||
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview",
|
||||
},
|
||||
wantStderr: heredoc.Doc(`
|
||||
* Request at <time>
|
||||
* Request to http://<host>:<port>
|
||||
> GET / HTTP/1.1
|
||||
> Host: github.com
|
||||
> Accept: application/vnd.github.merge-info-preview+json
|
||||
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
|
||||
> Authorization: token ████████████████████
|
||||
> User-Agent: GitHub CLI v1.2.3
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ func TestNewHTTPClient(t *testing.T) {
|
|||
wantHeader: map[string]string{
|
||||
"authorization": "token GHETOKEN",
|
||||
"user-agent": "GitHub CLI v1.2.3",
|
||||
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.antiope-preview, application/vnd.github.shadow-cat-preview",
|
||||
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview, application/vnd.github.antiope-preview, application/vnd.github.shadow-cat-preview",
|
||||
},
|
||||
wantStderr: "",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -622,8 +622,8 @@ func TestRepoCreate_WithGitIgnore(t *testing.T) {
|
|||
if repoName := reqBody.Name; repoName != "REPO" {
|
||||
t.Errorf("expected %q, got %q", "REPO", repoName)
|
||||
}
|
||||
if repoVisibility := reqBody.Visibility; repoVisibility != "PRIVATE" {
|
||||
t.Errorf("expected %q, got %q", "PRIVATE", repoVisibility)
|
||||
if repoVisibility := reqBody.Visibility; repoVisibility != "private" {
|
||||
t.Errorf("expected %q, got %q", "private", repoVisibility)
|
||||
}
|
||||
if ownerId := reqBody.OwnerId; ownerId != "OWNERID" {
|
||||
t.Errorf("expected %q, got %q", "OWNERID", ownerId)
|
||||
|
|
@ -721,8 +721,97 @@ func TestRepoCreate_WithBothGitIgnoreLicense(t *testing.T) {
|
|||
if repoName := reqBody.Name; repoName != "REPO" {
|
||||
t.Errorf("expected %q, got %q", "REPO", repoName)
|
||||
}
|
||||
if repoVisibility := reqBody.Visibility; repoVisibility != "PRIVATE" {
|
||||
t.Errorf("expected %q, got %q", "PRIVATE", repoVisibility)
|
||||
if repoVisibility := reqBody.Visibility; repoVisibility != "private" {
|
||||
t.Errorf("expected %q, got %q", "private", repoVisibility)
|
||||
}
|
||||
if ownerId := reqBody.OwnerId; ownerId != "OWNERID" {
|
||||
t.Errorf("expected %q, got %q", "OWNERID", ownerId)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoCreate_WithGitIgnore_Org(t *testing.T) {
|
||||
cs, cmdTeardown := run.Stub()
|
||||
defer cmdTeardown(t)
|
||||
|
||||
cs.Register(`git remote add -f origin https://github\.com/OWNER/REPO\.git`, 0, "")
|
||||
cs.Register(`git rev-parse --show-toplevel`, 0, "")
|
||||
|
||||
as, surveyTearDown := prompt.InitAskStubber()
|
||||
defer surveyTearDown()
|
||||
|
||||
as.Stub([]*prompt.QuestionStub{
|
||||
{
|
||||
Name: "repoVisibility",
|
||||
Value: "PRIVATE",
|
||||
},
|
||||
})
|
||||
|
||||
as.Stub([]*prompt.QuestionStub{
|
||||
{
|
||||
Name: "addGitIgnore",
|
||||
Value: true,
|
||||
},
|
||||
})
|
||||
|
||||
as.Stub([]*prompt.QuestionStub{
|
||||
{
|
||||
Name: "chooseGitIgnore",
|
||||
Value: "Go",
|
||||
},
|
||||
})
|
||||
|
||||
as.Stub([]*prompt.QuestionStub{
|
||||
{
|
||||
Name: "addLicense",
|
||||
Value: false,
|
||||
},
|
||||
})
|
||||
|
||||
as.Stub([]*prompt.QuestionStub{
|
||||
{
|
||||
Name: "confirmSubmit",
|
||||
Value: true,
|
||||
},
|
||||
})
|
||||
|
||||
reg := &httpmock.Registry{}
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "users/OWNER"),
|
||||
httpmock.StringResponse(`{ "node_id": "OWNERID", "type":"Organization" }`))
|
||||
reg.Register(
|
||||
httpmock.REST("GET", "gitignore/templates"),
|
||||
httpmock.StringResponse(`["Actionscript","Android","AppceleratorTitanium","Autotools","Bancha","C","C++","Go"]`))
|
||||
reg.Register(
|
||||
httpmock.REST("POST", "orgs/OWNER/repos"),
|
||||
httpmock.StringResponse(`{"name":"REPO", "owner":{"login": "OWNER"}, "html_url":"https://github.com/OWNER/REPO"}`))
|
||||
httpClient := &http.Client{Transport: reg}
|
||||
|
||||
output, err := runCommand(httpClient, "OWNER/REPO", true)
|
||||
if err != nil {
|
||||
t.Errorf("error running command `repo create`: %v", err)
|
||||
}
|
||||
|
||||
assert.Equal(t, "", output.String())
|
||||
assert.Equal(t, "✓ Created repository OWNER/REPO on GitHub\n✓ Added remote https://github.com/OWNER/REPO.git\n", output.Stderr())
|
||||
|
||||
var reqBody struct {
|
||||
Name string
|
||||
Visibility string
|
||||
OwnerId string
|
||||
LicenseTemplate string
|
||||
}
|
||||
|
||||
if len(reg.Requests) != 3 {
|
||||
t.Fatalf("expected 3 HTTP request, got %d", len(reg.Requests))
|
||||
}
|
||||
|
||||
bodyBytes, _ := ioutil.ReadAll(reg.Requests[2].Body)
|
||||
_ = json.Unmarshal(bodyBytes, &reqBody)
|
||||
if repoName := reqBody.Name; repoName != "REPO" {
|
||||
t.Errorf("expected %q, got %q", "REPO", repoName)
|
||||
}
|
||||
if repoVisibility := reqBody.Visibility; repoVisibility != "private" {
|
||||
t.Errorf("expected %q, got %q", "private", repoVisibility)
|
||||
}
|
||||
if ownerId := reqBody.OwnerId; ownerId != "OWNERID" {
|
||||
t.Errorf("expected %q, got %q", "OWNERID", ownerId)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/cli/cli/api"
|
||||
)
|
||||
|
|
@ -38,6 +39,9 @@ type repoTemplateInput struct {
|
|||
func repoCreate(client *http.Client, hostname string, input repoCreateInput, templateRepositoryID string) (*api.Repository, error) {
|
||||
apiClient := api.NewClientFromHTTP(client)
|
||||
|
||||
ownerName := input.OwnerID
|
||||
isOrg := false
|
||||
|
||||
if input.TeamID != "" {
|
||||
orgID, teamID, err := resolveOrganizationTeam(apiClient, hostname, input.OwnerID, input.TeamID)
|
||||
if err != nil {
|
||||
|
|
@ -46,7 +50,9 @@ func repoCreate(client *http.Client, hostname string, input repoCreateInput, tem
|
|||
input.TeamID = teamID
|
||||
input.OwnerID = orgID
|
||||
} else if input.OwnerID != "" {
|
||||
orgID, err := resolveOrganization(apiClient, hostname, input.OwnerID)
|
||||
var orgID string
|
||||
var err error
|
||||
orgID, isOrg, err = resolveOrganization(apiClient, hostname, input.OwnerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -109,12 +115,19 @@ func repoCreate(client *http.Client, hostname string, input repoCreateInput, tem
|
|||
}
|
||||
|
||||
if input.GitIgnoreTemplate != "" || input.LicenseTemplate != "" {
|
||||
input.Visibility = strings.ToLower(input.Visibility)
|
||||
body := &bytes.Buffer{}
|
||||
enc := json.NewEncoder(body)
|
||||
if err := enc.Encode(input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repo, err := api.CreateRepoTransformToV4(apiClient, hostname, "POST", "user/repos", body)
|
||||
|
||||
path := "user/repos"
|
||||
if isOrg {
|
||||
path = fmt.Sprintf("orgs/%s/repos", ownerName)
|
||||
}
|
||||
|
||||
repo, err := api.CreateRepoTransformToV4(apiClient, hostname, "POST", path, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -141,12 +154,13 @@ func repoCreate(client *http.Client, hostname string, input repoCreateInput, tem
|
|||
}
|
||||
|
||||
// using API v3 here because the equivalent in GraphQL needs `read:org` scope
|
||||
func resolveOrganization(client *api.Client, hostname, orgName string) (string, error) {
|
||||
func resolveOrganization(client *api.Client, hostname, orgName string) (string, bool, error) {
|
||||
var response struct {
|
||||
NodeID string `json:"node_id"`
|
||||
Type string
|
||||
}
|
||||
err := client.REST(hostname, "GET", fmt.Sprintf("users/%s", orgName), nil, &response)
|
||||
return response.NodeID, err
|
||||
return response.NodeID, response.Type == "Organization", err
|
||||
}
|
||||
|
||||
// using API v3 here because the equivalent in GraphQL needs `read:org` scope
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue