Skip to content

Commit

Permalink
Allow an empty array of repo ids as a request parameter (#3155)
Browse files Browse the repository at this point in the history
Fixes: #3106.
  • Loading branch information
Matthew-Reidy authored Apr 29, 2024
1 parent d067824 commit 108f958
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 0 deletions.
38 changes: 38 additions & 0 deletions github/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,20 @@ type InstallationTokenOptions struct {
Permissions *InstallationPermissions `json:"permissions,omitempty"`
}

type InstallationTokenListRepoOptions struct {
// The IDs of the repositories that the installation token can access.
// Providing repository IDs restricts the access of an installation token to specific repositories.
RepositoryIDs []int64 `json:"repository_ids"`

// The names of the repositories that the installation token can access.
// Providing repository names restricts the access of an installation token to specific repositories.
Repositories []string `json:"repositories,omitempty"`

// The permissions granted to the access token.
// The permissions object includes the permission names and their access type.
Permissions *InstallationPermissions `json:"permissions,omitempty"`
}

// InstallationPermissions lists the repository and organization permissions for an installation.
//
// Permission names taken from:
Expand Down Expand Up @@ -344,6 +358,30 @@ func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opt
return t, resp, nil
}

// CreateInstallationTokenListRepos creates a new installation token with a list of all repositories in an installation which is not possible with CreateInstallationToken.
//
// It differs from CreateInstallationToken by taking InstallationTokenListRepoOptions as a parameter which does not omit RepositoryIDs if that field is nil or an empty array.
//
// GitHub API docs: https://docs.github.com/rest/apps/apps#create-an-installation-access-token-for-an-app
//
//meta:operation POST /app/installations/{installation_id}/access_tokens
func (s *AppsService) CreateInstallationTokenListRepos(ctx context.Context, id int64, opts *InstallationTokenListRepoOptions) (*InstallationToken, *Response, error) {
u := fmt.Sprintf("app/installations/%v/access_tokens", id)

req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
return nil, nil, err
}

t := new(InstallationToken)
resp, err := s.client.Do(ctx, req, t)
if err != nil {
return nil, resp, err
}

return t, resp, nil
}

// CreateAttachment creates a new attachment on user comment containing a url.
//
// GitHub API docs: https://docs.github.com/[email protected]/rest/reference/apps#create-a-content-attachment
Expand Down
71 changes: 71 additions & 0 deletions github/apps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,77 @@ func TestAppsService_CreateInstallationTokenWithOptions(t *testing.T) {
}
}

func TestAppsService_CreateInstallationTokenListReposWithOptions(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

installationTokenListRepoOptions := &InstallationTokenListRepoOptions{
Repositories: []string{"foo"},
Permissions: &InstallationPermissions{
Contents: String("write"),
Issues: String("read"),
},
}

mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) {
v := new(InstallationTokenListRepoOptions)
assertNilError(t, json.NewDecoder(r.Body).Decode(v))

if !cmp.Equal(v, installationTokenListRepoOptions) {
t.Errorf("request sent %+v, want %+v", v, installationTokenListRepoOptions)
}

testMethod(t, r, "POST")
fmt.Fprint(w, `{"token":"t"}`)
})

ctx := context.Background()
token, _, err := client.Apps.CreateInstallationTokenListRepos(ctx, 1, installationTokenListRepoOptions)
if err != nil {
t.Errorf("Apps.CreateInstallationTokenListRepos returned error: %v", err)
}

want := &InstallationToken{Token: String("t")}
if !cmp.Equal(token, want) {
t.Errorf("Apps.CreateInstallationTokenListRepos returned %+v, want %+v", token, want)
}
}

func TestAppsService_CreateInstallationTokenListReposWithNoOptions(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
fmt.Fprint(w, `{"token":"t"}`)
})

ctx := context.Background()
token, _, err := client.Apps.CreateInstallationTokenListRepos(ctx, 1, nil)
if err != nil {
t.Errorf("Apps.CreateInstallationTokenListRepos returned error: %v", err)
}

want := &InstallationToken{Token: String("t")}
if !cmp.Equal(token, want) {
t.Errorf("Apps.CreateInstallationTokenListRepos returned %+v, want %+v", token, want)
}

const methodName = "CreateInstallationTokenListRepos"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Apps.CreateInstallationTokenListRepos(ctx, -1, nil)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Apps.CreateInstallationTokenListRepos(ctx, 1, nil)
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestAppsService_CreateAttachement(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()
Expand Down
8 changes: 8 additions & 0 deletions github/github-accessors.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions github/github-accessors_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 108f958

Please sign in to comment.