Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow an empty array of repo ids as a request parameter #3155

Merged
merged 10 commits into from
Apr 29, 2024
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/enterprise-server@3.3/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.