Skip to content

Commit a6710ec

Browse files
author
Nate Smith
authored
Merge pull request cli#3924 from cli/rest-org-repo-bug
fix repo create in org with license/ignore
2 parents 717c91c + 589b695 commit a6710ec

File tree

4 files changed

+117
-13
lines changed

4 files changed

+117
-13
lines changed

pkg/cmd/factory/http.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ func NewHTTPClient(io *iostreams.IOStreams, cfg configGetter, appVersion string,
113113
opts = append(opts,
114114
api.AddHeaderFunc("Accept", func(req *http.Request) (string, error) {
115115
accept := "application/vnd.github.merge-info-preview+json" // PullRequest.mergeStateStatus
116+
accept += ", application/vnd.github.nebula-preview" // visibility when RESTing repos into an org
116117
if ghinstance.IsEnterprise(getHost(req)) {
117118
accept += ", application/vnd.github.antiope-preview" // Commit.statusCheckRollup
118119
accept += ", application/vnd.github.shadow-cat-preview" // PullRequest.isDraft

pkg/cmd/factory/http_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func TestNewHTTPClient(t *testing.T) {
3939
wantHeader: map[string]string{
4040
"authorization": "token MYTOKEN",
4141
"user-agent": "GitHub CLI v1.2.3",
42-
"accept": "application/vnd.github.merge-info-preview+json",
42+
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview",
4343
},
4444
wantStderr: "",
4545
},
@@ -69,7 +69,7 @@ func TestNewHTTPClient(t *testing.T) {
6969
wantHeader: map[string]string{
7070
"authorization": "",
7171
"user-agent": "GitHub CLI v1.2.3",
72-
"accept": "application/vnd.github.merge-info-preview+json",
72+
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview",
7373
},
7474
wantStderr: "",
7575
},
@@ -85,14 +85,14 @@ func TestNewHTTPClient(t *testing.T) {
8585
wantHeader: map[string]string{
8686
"authorization": "token MYTOKEN",
8787
"user-agent": "GitHub CLI v1.2.3",
88-
"accept": "application/vnd.github.merge-info-preview+json",
88+
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview",
8989
},
9090
wantStderr: heredoc.Doc(`
9191
* Request at <time>
9292
* Request to http://<host>:<port>
9393
> GET / HTTP/1.1
9494
> Host: github.com
95-
> Accept: application/vnd.github.merge-info-preview+json
95+
> Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
9696
> Authorization: token ████████████████████
9797
> User-Agent: GitHub CLI v1.2.3
9898
@@ -113,7 +113,7 @@ func TestNewHTTPClient(t *testing.T) {
113113
wantHeader: map[string]string{
114114
"authorization": "token GHETOKEN",
115115
"user-agent": "GitHub CLI v1.2.3",
116-
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.antiope-preview, application/vnd.github.shadow-cat-preview",
116+
"accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview, application/vnd.github.antiope-preview, application/vnd.github.shadow-cat-preview",
117117
},
118118
wantStderr: "",
119119
},

pkg/cmd/repo/create/create_test.go

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -622,8 +622,8 @@ func TestRepoCreate_WithGitIgnore(t *testing.T) {
622622
if repoName := reqBody.Name; repoName != "REPO" {
623623
t.Errorf("expected %q, got %q", "REPO", repoName)
624624
}
625-
if repoVisibility := reqBody.Visibility; repoVisibility != "PRIVATE" {
626-
t.Errorf("expected %q, got %q", "PRIVATE", repoVisibility)
625+
if repoVisibility := reqBody.Visibility; repoVisibility != "private" {
626+
t.Errorf("expected %q, got %q", "private", repoVisibility)
627627
}
628628
if ownerId := reqBody.OwnerId; ownerId != "OWNERID" {
629629
t.Errorf("expected %q, got %q", "OWNERID", ownerId)
@@ -721,8 +721,97 @@ func TestRepoCreate_WithBothGitIgnoreLicense(t *testing.T) {
721721
if repoName := reqBody.Name; repoName != "REPO" {
722722
t.Errorf("expected %q, got %q", "REPO", repoName)
723723
}
724-
if repoVisibility := reqBody.Visibility; repoVisibility != "PRIVATE" {
725-
t.Errorf("expected %q, got %q", "PRIVATE", repoVisibility)
724+
if repoVisibility := reqBody.Visibility; repoVisibility != "private" {
725+
t.Errorf("expected %q, got %q", "private", repoVisibility)
726+
}
727+
if ownerId := reqBody.OwnerId; ownerId != "OWNERID" {
728+
t.Errorf("expected %q, got %q", "OWNERID", ownerId)
729+
}
730+
}
731+
732+
func TestRepoCreate_WithGitIgnore_Org(t *testing.T) {
733+
cs, cmdTeardown := run.Stub()
734+
defer cmdTeardown(t)
735+
736+
cs.Register(`git remote add -f origin https://github\.com/OWNER/REPO\.git`, 0, "")
737+
cs.Register(`git rev-parse --show-toplevel`, 0, "")
738+
739+
as, surveyTearDown := prompt.InitAskStubber()
740+
defer surveyTearDown()
741+
742+
as.Stub([]*prompt.QuestionStub{
743+
{
744+
Name: "repoVisibility",
745+
Value: "PRIVATE",
746+
},
747+
})
748+
749+
as.Stub([]*prompt.QuestionStub{
750+
{
751+
Name: "addGitIgnore",
752+
Value: true,
753+
},
754+
})
755+
756+
as.Stub([]*prompt.QuestionStub{
757+
{
758+
Name: "chooseGitIgnore",
759+
Value: "Go",
760+
},
761+
})
762+
763+
as.Stub([]*prompt.QuestionStub{
764+
{
765+
Name: "addLicense",
766+
Value: false,
767+
},
768+
})
769+
770+
as.Stub([]*prompt.QuestionStub{
771+
{
772+
Name: "confirmSubmit",
773+
Value: true,
774+
},
775+
})
776+
777+
reg := &httpmock.Registry{}
778+
reg.Register(
779+
httpmock.REST("GET", "users/OWNER"),
780+
httpmock.StringResponse(`{ "node_id": "OWNERID", "type":"Organization" }`))
781+
reg.Register(
782+
httpmock.REST("GET", "gitignore/templates"),
783+
httpmock.StringResponse(`["Actionscript","Android","AppceleratorTitanium","Autotools","Bancha","C","C++","Go"]`))
784+
reg.Register(
785+
httpmock.REST("POST", "orgs/OWNER/repos"),
786+
httpmock.StringResponse(`{"name":"REPO", "owner":{"login": "OWNER"}, "html_url":"https://github.com/OWNER/REPO"}`))
787+
httpClient := &http.Client{Transport: reg}
788+
789+
output, err := runCommand(httpClient, "OWNER/REPO", true)
790+
if err != nil {
791+
t.Errorf("error running command `repo create`: %v", err)
792+
}
793+
794+
assert.Equal(t, "", output.String())
795+
assert.Equal(t, "✓ Created repository OWNER/REPO on GitHub\n✓ Added remote https://github.com/OWNER/REPO.git\n", output.Stderr())
796+
797+
var reqBody struct {
798+
Name string
799+
Visibility string
800+
OwnerId string
801+
LicenseTemplate string
802+
}
803+
804+
if len(reg.Requests) != 3 {
805+
t.Fatalf("expected 3 HTTP request, got %d", len(reg.Requests))
806+
}
807+
808+
bodyBytes, _ := ioutil.ReadAll(reg.Requests[2].Body)
809+
_ = json.Unmarshal(bodyBytes, &reqBody)
810+
if repoName := reqBody.Name; repoName != "REPO" {
811+
t.Errorf("expected %q, got %q", "REPO", repoName)
812+
}
813+
if repoVisibility := reqBody.Visibility; repoVisibility != "private" {
814+
t.Errorf("expected %q, got %q", "private", repoVisibility)
726815
}
727816
if ownerId := reqBody.OwnerId; ownerId != "OWNERID" {
728817
t.Errorf("expected %q, got %q", "OWNERID", ownerId)

pkg/cmd/repo/create/http.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/json"
66
"fmt"
77
"net/http"
8+
"strings"
89

910
"github.com/cli/cli/api"
1011
)
@@ -38,6 +39,9 @@ type repoTemplateInput struct {
3839
func repoCreate(client *http.Client, hostname string, input repoCreateInput, templateRepositoryID string) (*api.Repository, error) {
3940
apiClient := api.NewClientFromHTTP(client)
4041

42+
ownerName := input.OwnerID
43+
isOrg := false
44+
4145
if input.TeamID != "" {
4246
orgID, teamID, err := resolveOrganizationTeam(apiClient, hostname, input.OwnerID, input.TeamID)
4347
if err != nil {
@@ -46,7 +50,9 @@ func repoCreate(client *http.Client, hostname string, input repoCreateInput, tem
4650
input.TeamID = teamID
4751
input.OwnerID = orgID
4852
} else if input.OwnerID != "" {
49-
orgID, err := resolveOrganization(apiClient, hostname, input.OwnerID)
53+
var orgID string
54+
var err error
55+
orgID, isOrg, err = resolveOrganization(apiClient, hostname, input.OwnerID)
5056
if err != nil {
5157
return nil, err
5258
}
@@ -109,12 +115,19 @@ func repoCreate(client *http.Client, hostname string, input repoCreateInput, tem
109115
}
110116

111117
if input.GitIgnoreTemplate != "" || input.LicenseTemplate != "" {
118+
input.Visibility = strings.ToLower(input.Visibility)
112119
body := &bytes.Buffer{}
113120
enc := json.NewEncoder(body)
114121
if err := enc.Encode(input); err != nil {
115122
return nil, err
116123
}
117-
repo, err := api.CreateRepoTransformToV4(apiClient, hostname, "POST", "user/repos", body)
124+
125+
path := "user/repos"
126+
if isOrg {
127+
path = fmt.Sprintf("orgs/%s/repos", ownerName)
128+
}
129+
130+
repo, err := api.CreateRepoTransformToV4(apiClient, hostname, "POST", path, body)
118131
if err != nil {
119132
return nil, err
120133
}
@@ -141,12 +154,13 @@ func repoCreate(client *http.Client, hostname string, input repoCreateInput, tem
141154
}
142155

143156
// using API v3 here because the equivalent in GraphQL needs `read:org` scope
144-
func resolveOrganization(client *api.Client, hostname, orgName string) (string, error) {
157+
func resolveOrganization(client *api.Client, hostname, orgName string) (string, bool, error) {
145158
var response struct {
146159
NodeID string `json:"node_id"`
160+
Type string
147161
}
148162
err := client.REST(hostname, "GET", fmt.Sprintf("users/%s", orgName), nil, &response)
149-
return response.NodeID, err
163+
return response.NodeID, response.Type == "Organization", err
150164
}
151165

152166
// using API v3 here because the equivalent in GraphQL needs `read:org` scope

0 commit comments

Comments
 (0)