github.com/google/go-github/v68@v68.0.0/github/apps.go (about)

     1  // Copyright 2016 The go-github AUTHORS. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package github
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  )
    12  
    13  // AppsService provides access to the installation related functions
    14  // in the GitHub API.
    15  //
    16  // GitHub API docs: https://docs.github.com/rest/apps/
    17  type AppsService service
    18  
    19  // App represents a GitHub App.
    20  type App struct {
    21  	ID                 *int64                   `json:"id,omitempty"`
    22  	Slug               *string                  `json:"slug,omitempty"`
    23  	NodeID             *string                  `json:"node_id,omitempty"`
    24  	Owner              *User                    `json:"owner,omitempty"`
    25  	Name               *string                  `json:"name,omitempty"`
    26  	Description        *string                  `json:"description,omitempty"`
    27  	ExternalURL        *string                  `json:"external_url,omitempty"`
    28  	HTMLURL            *string                  `json:"html_url,omitempty"`
    29  	CreatedAt          *Timestamp               `json:"created_at,omitempty"`
    30  	UpdatedAt          *Timestamp               `json:"updated_at,omitempty"`
    31  	Permissions        *InstallationPermissions `json:"permissions,omitempty"`
    32  	Events             []string                 `json:"events,omitempty"`
    33  	InstallationsCount *int                     `json:"installations_count,omitempty"`
    34  }
    35  
    36  // InstallationToken represents an installation token.
    37  type InstallationToken struct {
    38  	Token        *string                  `json:"token,omitempty"`
    39  	ExpiresAt    *Timestamp               `json:"expires_at,omitempty"`
    40  	Permissions  *InstallationPermissions `json:"permissions,omitempty"`
    41  	Repositories []*Repository            `json:"repositories,omitempty"`
    42  }
    43  
    44  // InstallationTokenOptions allow restricting a token's access to specific repositories.
    45  type InstallationTokenOptions struct {
    46  	// The IDs of the repositories that the installation token can access.
    47  	// Providing repository IDs restricts the access of an installation token to specific repositories.
    48  	RepositoryIDs []int64 `json:"repository_ids,omitempty"`
    49  
    50  	// The names of the repositories that the installation token can access.
    51  	// Providing repository names restricts the access of an installation token to specific repositories.
    52  	Repositories []string `json:"repositories,omitempty"`
    53  
    54  	// The permissions granted to the access token.
    55  	// The permissions object includes the permission names and their access type.
    56  	Permissions *InstallationPermissions `json:"permissions,omitempty"`
    57  }
    58  
    59  type InstallationTokenListRepoOptions struct {
    60  	// The IDs of the repositories that the installation token can access.
    61  	// Providing repository IDs restricts the access of an installation token to specific repositories.
    62  	RepositoryIDs []int64 `json:"repository_ids"`
    63  
    64  	// The names of the repositories that the installation token can access.
    65  	// Providing repository names restricts the access of an installation token to specific repositories.
    66  	Repositories []string `json:"repositories,omitempty"`
    67  
    68  	// The permissions granted to the access token.
    69  	// The permissions object includes the permission names and their access type.
    70  	Permissions *InstallationPermissions `json:"permissions,omitempty"`
    71  }
    72  
    73  // InstallationPermissions lists the repository and organization permissions for an installation.
    74  //
    75  // Permission names taken from:
    76  //
    77  //	https://docs.github.com/enterprise-server@3.0/rest/apps#create-an-installation-access-token-for-an-app
    78  //	https://docs.github.com/rest/apps#create-an-installation-access-token-for-an-app
    79  type InstallationPermissions struct {
    80  	Actions                                 *string `json:"actions,omitempty"`
    81  	ActionsVariables                        *string `json:"actions_variables,omitempty"`
    82  	Administration                          *string `json:"administration,omitempty"`
    83  	Attestations                            *string `json:"attestations,omitempty"`
    84  	Blocking                                *string `json:"blocking,omitempty"`
    85  	Checks                                  *string `json:"checks,omitempty"`
    86  	Codespaces                              *string `json:"codespaces,omitempty"`
    87  	CodespacesLifecycleAdmin                *string `json:"codespaces_lifecycle_admin,omitempty"`
    88  	CodespacesMetadata                      *string `json:"codespaces_metadata,omitempty"`
    89  	CodespacesSecrets                       *string `json:"codespaces_secrets,omitempty"`
    90  	CodespacesUserSecrets                   *string `json:"codespaces_user_secrets,omitempty"`
    91  	Contents                                *string `json:"contents,omitempty"`
    92  	ContentReferences                       *string `json:"content_references,omitempty"`
    93  	CopilotMessages                         *string `json:"copilot_messages,omitempty"`
    94  	DependabotSecrets                       *string `json:"dependabot_secrets,omitempty"`
    95  	Deployments                             *string `json:"deployments,omitempty"`
    96  	Discussions                             *string `json:"discussions,omitempty"`
    97  	Emails                                  *string `json:"emails,omitempty"`
    98  	Environments                            *string `json:"environments,omitempty"`
    99  	Followers                               *string `json:"followers,omitempty"`
   100  	Gists                                   *string `json:"gists,omitempty"`
   101  	GitSigningSSHPublicKeys                 *string `json:"git_signing_ssh_public_keys,omitempty"`
   102  	GPGKeys                                 *string `json:"gpg_keys,omitempty"`
   103  	InteractionLimits                       *string `json:"interaction_limits,omitempty"`
   104  	Issues                                  *string `json:"issues,omitempty"`
   105  	Keys                                    *string `json:"keys,omitempty"`
   106  	Metadata                                *string `json:"metadata,omitempty"`
   107  	Members                                 *string `json:"members,omitempty"`
   108  	MergeQueues                             *string `json:"merge_queues,omitempty"`
   109  	OrganizationActionsVariables            *string `json:"organization_actions_variables,omitempty"`
   110  	OrganizationAdministration              *string `json:"organization_administration,omitempty"`
   111  	OrganizationAnnouncementBanners         *string `json:"organization_announcement_banners,omitempty"`
   112  	OrganizationAPIInsights                 *string `json:"organization_api_insights,omitempty"`
   113  	OrganizationCodespaces                  *string `json:"organization_codespaces,omitempty"`
   114  	OrganizationCodespacesSecrets           *string `json:"organization_codespaces_secrets,omitempty"`
   115  	OrganizationCodespacesSettings          *string `json:"organization_codespaces_settings,omitempty"`
   116  	OrganizationCopilotSeatManagement       *string `json:"organization_copilot_seat_management,omitempty"`
   117  	OrganizationCustomProperties            *string `json:"organization_custom_properties,omitempty"`
   118  	OrganizationCustomRoles                 *string `json:"organization_custom_roles,omitempty"`
   119  	OrganizationCustomOrgRoles              *string `json:"organization_custom_org_roles,omitempty"`
   120  	OrganizationDependabotSecrets           *string `json:"organization_dependabot_secrets,omitempty"`
   121  	OrganizationEvents                      *string `json:"organization_events,omitempty"`
   122  	OrganizationHooks                       *string `json:"organization_hooks,omitempty"`
   123  	OrganizationKnowledgeBases              *string `json:"organization_knowledge_bases,omitempty"`
   124  	OrganizationPackages                    *string `json:"organization_packages,omitempty"`
   125  	OrganizationPersonalAccessTokens        *string `json:"organization_personal_access_tokens,omitempty"`
   126  	OrganizationPersonalAccessTokenRequests *string `json:"organization_personal_access_token_requests,omitempty"`
   127  	OrganizationPlan                        *string `json:"organization_plan,omitempty"`
   128  	OrganizationPreReceiveHooks             *string `json:"organization_pre_receive_hooks,omitempty"`
   129  	OrganizationProjects                    *string `json:"organization_projects,omitempty"`
   130  	OrganizationSecrets                     *string `json:"organization_secrets,omitempty"`
   131  	OrganizationSelfHostedRunners           *string `json:"organization_self_hosted_runners,omitempty"`
   132  	OrganizationUserBlocking                *string `json:"organization_user_blocking,omitempty"`
   133  	Packages                                *string `json:"packages,omitempty"`
   134  	Pages                                   *string `json:"pages,omitempty"`
   135  	Plan                                    *string `json:"plan,omitempty"`
   136  	Profile                                 *string `json:"profile,omitempty"`
   137  	PullRequests                            *string `json:"pull_requests,omitempty"`
   138  	RepositoryAdvisories                    *string `json:"repository_advisories,omitempty"`
   139  	RepositoryCustomProperties              *string `json:"repository_custom_properties,omitempty"`
   140  	RepositoryHooks                         *string `json:"repository_hooks,omitempty"`
   141  	RepositoryProjects                      *string `json:"repository_projects,omitempty"`
   142  	RepositoryPreReceiveHooks               *string `json:"repository_pre_receive_hooks,omitempty"`
   143  	Secrets                                 *string `json:"secrets,omitempty"`
   144  	SecretScanningAlerts                    *string `json:"secret_scanning_alerts,omitempty"`
   145  	SecurityEvents                          *string `json:"security_events,omitempty"`
   146  	SingleFile                              *string `json:"single_file,omitempty"`
   147  	Starring                                *string `json:"starring,omitempty"`
   148  	Statuses                                *string `json:"statuses,omitempty"`
   149  	TeamDiscussions                         *string `json:"team_discussions,omitempty"`
   150  	UserEvents                              *string `json:"user_events,omitempty"`
   151  	VulnerabilityAlerts                     *string `json:"vulnerability_alerts,omitempty"`
   152  	Watching                                *string `json:"watching,omitempty"`
   153  	Workflows                               *string `json:"workflows,omitempty"`
   154  }
   155  
   156  // InstallationRequest represents a pending GitHub App installation request.
   157  type InstallationRequest struct {
   158  	ID        *int64     `json:"id,omitempty"`
   159  	NodeID    *string    `json:"node_id,omitempty"`
   160  	Account   *User      `json:"account,omitempty"`
   161  	Requester *User      `json:"requester,omitempty"`
   162  	CreatedAt *Timestamp `json:"created_at,omitempty"`
   163  }
   164  
   165  // Installation represents a GitHub Apps installation.
   166  type Installation struct {
   167  	ID                     *int64                   `json:"id,omitempty"`
   168  	NodeID                 *string                  `json:"node_id,omitempty"`
   169  	AppID                  *int64                   `json:"app_id,omitempty"`
   170  	AppSlug                *string                  `json:"app_slug,omitempty"`
   171  	TargetID               *int64                   `json:"target_id,omitempty"`
   172  	Account                *User                    `json:"account,omitempty"`
   173  	AccessTokensURL        *string                  `json:"access_tokens_url,omitempty"`
   174  	RepositoriesURL        *string                  `json:"repositories_url,omitempty"`
   175  	HTMLURL                *string                  `json:"html_url,omitempty"`
   176  	TargetType             *string                  `json:"target_type,omitempty"`
   177  	SingleFileName         *string                  `json:"single_file_name,omitempty"`
   178  	RepositorySelection    *string                  `json:"repository_selection,omitempty"`
   179  	Events                 []string                 `json:"events,omitempty"`
   180  	SingleFilePaths        []string                 `json:"single_file_paths,omitempty"`
   181  	Permissions            *InstallationPermissions `json:"permissions,omitempty"`
   182  	CreatedAt              *Timestamp               `json:"created_at,omitempty"`
   183  	UpdatedAt              *Timestamp               `json:"updated_at,omitempty"`
   184  	HasMultipleSingleFiles *bool                    `json:"has_multiple_single_files,omitempty"`
   185  	SuspendedBy            *User                    `json:"suspended_by,omitempty"`
   186  	SuspendedAt            *Timestamp               `json:"suspended_at,omitempty"`
   187  }
   188  
   189  // Attachment represents a GitHub Apps attachment.
   190  type Attachment struct {
   191  	ID    *int64  `json:"id,omitempty"`
   192  	Title *string `json:"title,omitempty"`
   193  	Body  *string `json:"body,omitempty"`
   194  }
   195  
   196  // ContentReference represents a reference to a URL in an issue or pull request.
   197  type ContentReference struct {
   198  	ID        *int64  `json:"id,omitempty"`
   199  	NodeID    *string `json:"node_id,omitempty"`
   200  	Reference *string `json:"reference,omitempty"`
   201  }
   202  
   203  func (i Installation) String() string {
   204  	return Stringify(i)
   205  }
   206  
   207  // Get a single GitHub App. Passing the empty string will get
   208  // the authenticated GitHub App.
   209  //
   210  // Note: appSlug is just the URL-friendly name of your GitHub App.
   211  // You can find this on the settings page for your GitHub App
   212  // (e.g., https://github.com/settings/apps/:app_slug).
   213  //
   214  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-an-app
   215  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-the-authenticated-app
   216  //
   217  //meta:operation GET /app
   218  //meta:operation GET /apps/{app_slug}
   219  func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) {
   220  	var u string
   221  	if appSlug != "" {
   222  		u = fmt.Sprintf("apps/%v", appSlug)
   223  	} else {
   224  		u = "app"
   225  	}
   226  
   227  	req, err := s.client.NewRequest("GET", u, nil)
   228  	if err != nil {
   229  		return nil, nil, err
   230  	}
   231  
   232  	app := new(App)
   233  	resp, err := s.client.Do(ctx, req, app)
   234  	if err != nil {
   235  		return nil, resp, err
   236  	}
   237  
   238  	return app, resp, nil
   239  }
   240  
   241  // ListInstallationRequests lists the pending installation requests that the current GitHub App has.
   242  //
   243  // GitHub API docs: https://docs.github.com/rest/apps/apps#list-installation-requests-for-the-authenticated-app
   244  //
   245  //meta:operation GET /app/installation-requests
   246  func (s *AppsService) ListInstallationRequests(ctx context.Context, opts *ListOptions) ([]*InstallationRequest, *Response, error) {
   247  	u, err := addOptions("app/installation-requests", opts)
   248  	if err != nil {
   249  		return nil, nil, err
   250  	}
   251  
   252  	req, err := s.client.NewRequest("GET", u, nil)
   253  	if err != nil {
   254  		return nil, nil, err
   255  	}
   256  
   257  	var i []*InstallationRequest
   258  	resp, err := s.client.Do(ctx, req, &i)
   259  	if err != nil {
   260  		return nil, resp, err
   261  	}
   262  
   263  	return i, resp, nil
   264  }
   265  
   266  // ListInstallations lists the installations that the current GitHub App has.
   267  //
   268  // GitHub API docs: https://docs.github.com/rest/apps/apps#list-installations-for-the-authenticated-app
   269  //
   270  //meta:operation GET /app/installations
   271  func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) {
   272  	u, err := addOptions("app/installations", opts)
   273  	if err != nil {
   274  		return nil, nil, err
   275  	}
   276  
   277  	req, err := s.client.NewRequest("GET", u, nil)
   278  	if err != nil {
   279  		return nil, nil, err
   280  	}
   281  
   282  	var i []*Installation
   283  	resp, err := s.client.Do(ctx, req, &i)
   284  	if err != nil {
   285  		return nil, resp, err
   286  	}
   287  
   288  	return i, resp, nil
   289  }
   290  
   291  // GetInstallation returns the specified installation.
   292  //
   293  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-an-installation-for-the-authenticated-app
   294  //
   295  //meta:operation GET /app/installations/{installation_id}
   296  func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) {
   297  	return s.getInstallation(ctx, fmt.Sprintf("app/installations/%v", id))
   298  }
   299  
   300  // ListUserInstallations lists installations that are accessible to the authenticated user.
   301  //
   302  // GitHub API docs: https://docs.github.com/rest/apps/installations#list-app-installations-accessible-to-the-user-access-token
   303  //
   304  //meta:operation GET /user/installations
   305  func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) {
   306  	u, err := addOptions("user/installations", opts)
   307  	if err != nil {
   308  		return nil, nil, err
   309  	}
   310  
   311  	req, err := s.client.NewRequest("GET", u, nil)
   312  	if err != nil {
   313  		return nil, nil, err
   314  	}
   315  
   316  	var i struct {
   317  		Installations []*Installation `json:"installations"`
   318  	}
   319  	resp, err := s.client.Do(ctx, req, &i)
   320  	if err != nil {
   321  		return nil, resp, err
   322  	}
   323  
   324  	return i.Installations, resp, nil
   325  }
   326  
   327  // SuspendInstallation suspends the specified installation.
   328  //
   329  // GitHub API docs: https://docs.github.com/rest/apps/apps#suspend-an-app-installation
   330  //
   331  //meta:operation PUT /app/installations/{installation_id}/suspended
   332  func (s *AppsService) SuspendInstallation(ctx context.Context, id int64) (*Response, error) {
   333  	u := fmt.Sprintf("app/installations/%v/suspended", id)
   334  
   335  	req, err := s.client.NewRequest("PUT", u, nil)
   336  	if err != nil {
   337  		return nil, err
   338  	}
   339  
   340  	return s.client.Do(ctx, req, nil)
   341  }
   342  
   343  // UnsuspendInstallation unsuspends the specified installation.
   344  //
   345  // GitHub API docs: https://docs.github.com/rest/apps/apps#unsuspend-an-app-installation
   346  //
   347  //meta:operation DELETE /app/installations/{installation_id}/suspended
   348  func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Response, error) {
   349  	u := fmt.Sprintf("app/installations/%v/suspended", id)
   350  
   351  	req, err := s.client.NewRequest("DELETE", u, nil)
   352  	if err != nil {
   353  		return nil, err
   354  	}
   355  
   356  	return s.client.Do(ctx, req, nil)
   357  }
   358  
   359  // DeleteInstallation deletes the specified installation.
   360  //
   361  // GitHub API docs: https://docs.github.com/rest/apps/apps#delete-an-installation-for-the-authenticated-app
   362  //
   363  //meta:operation DELETE /app/installations/{installation_id}
   364  func (s *AppsService) DeleteInstallation(ctx context.Context, id int64) (*Response, error) {
   365  	u := fmt.Sprintf("app/installations/%v", id)
   366  
   367  	req, err := s.client.NewRequest("DELETE", u, nil)
   368  	if err != nil {
   369  		return nil, err
   370  	}
   371  
   372  	return s.client.Do(ctx, req, nil)
   373  }
   374  
   375  // CreateInstallationToken creates a new installation token.
   376  //
   377  // GitHub API docs: https://docs.github.com/rest/apps/apps#create-an-installation-access-token-for-an-app
   378  //
   379  //meta:operation POST /app/installations/{installation_id}/access_tokens
   380  func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opts *InstallationTokenOptions) (*InstallationToken, *Response, error) {
   381  	u := fmt.Sprintf("app/installations/%v/access_tokens", id)
   382  
   383  	req, err := s.client.NewRequest("POST", u, opts)
   384  	if err != nil {
   385  		return nil, nil, err
   386  	}
   387  
   388  	t := new(InstallationToken)
   389  	resp, err := s.client.Do(ctx, req, t)
   390  	if err != nil {
   391  		return nil, resp, err
   392  	}
   393  
   394  	return t, resp, nil
   395  }
   396  
   397  // CreateInstallationTokenListRepos creates a new installation token with a list of all repositories in an installation which is not possible with CreateInstallationToken.
   398  //
   399  // It differs from CreateInstallationToken by taking InstallationTokenListRepoOptions as a parameter which does not omit RepositoryIDs if that field is nil or an empty array.
   400  //
   401  // GitHub API docs: https://docs.github.com/rest/apps/apps#create-an-installation-access-token-for-an-app
   402  //
   403  //meta:operation POST /app/installations/{installation_id}/access_tokens
   404  func (s *AppsService) CreateInstallationTokenListRepos(ctx context.Context, id int64, opts *InstallationTokenListRepoOptions) (*InstallationToken, *Response, error) {
   405  	u := fmt.Sprintf("app/installations/%v/access_tokens", id)
   406  
   407  	req, err := s.client.NewRequest("POST", u, opts)
   408  	if err != nil {
   409  		return nil, nil, err
   410  	}
   411  
   412  	t := new(InstallationToken)
   413  	resp, err := s.client.Do(ctx, req, t)
   414  	if err != nil {
   415  		return nil, resp, err
   416  	}
   417  
   418  	return t, resp, nil
   419  }
   420  
   421  // CreateAttachment creates a new attachment on user comment containing a url.
   422  //
   423  // GitHub API docs: https://docs.github.com/enterprise-server@3.3/rest/reference/apps#create-a-content-attachment
   424  //
   425  //meta:operation POST /repos/{owner}/{repo}/content_references/{content_reference_id}/attachments
   426  func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID int64, title, body string) (*Attachment, *Response, error) {
   427  	u := fmt.Sprintf("content_references/%v/attachments", contentReferenceID)
   428  	payload := &Attachment{Title: Ptr(title), Body: Ptr(body)}
   429  	req, err := s.client.NewRequest("POST", u, payload)
   430  	if err != nil {
   431  		return nil, nil, err
   432  	}
   433  
   434  	// TODO: remove custom Accept headers when APIs fully launch.
   435  	req.Header.Set("Accept", mediaTypeContentAttachmentsPreview)
   436  
   437  	m := &Attachment{}
   438  	resp, err := s.client.Do(ctx, req, m)
   439  	if err != nil {
   440  		return nil, resp, err
   441  	}
   442  
   443  	return m, resp, nil
   444  }
   445  
   446  // FindOrganizationInstallation finds the organization's installation information.
   447  //
   448  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-an-organization-installation-for-the-authenticated-app
   449  //
   450  //meta:operation GET /orgs/{org}/installation
   451  func (s *AppsService) FindOrganizationInstallation(ctx context.Context, org string) (*Installation, *Response, error) {
   452  	return s.getInstallation(ctx, fmt.Sprintf("orgs/%v/installation", org))
   453  }
   454  
   455  // FindRepositoryInstallation finds the repository's installation information.
   456  //
   457  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-a-repository-installation-for-the-authenticated-app
   458  //
   459  //meta:operation GET /repos/{owner}/{repo}/installation
   460  func (s *AppsService) FindRepositoryInstallation(ctx context.Context, owner, repo string) (*Installation, *Response, error) {
   461  	return s.getInstallation(ctx, fmt.Sprintf("repos/%v/%v/installation", owner, repo))
   462  }
   463  
   464  // FindRepositoryInstallationByID finds the repository's installation information.
   465  //
   466  // Note: FindRepositoryInstallationByID uses the undocumented GitHub API endpoint "GET /repositories/{repository_id}/installation".
   467  //
   468  //meta:operation GET /repositories/{repository_id}/installation
   469  func (s *AppsService) FindRepositoryInstallationByID(ctx context.Context, id int64) (*Installation, *Response, error) {
   470  	return s.getInstallation(ctx, fmt.Sprintf("repositories/%d/installation", id))
   471  }
   472  
   473  // FindUserInstallation finds the user's installation information.
   474  //
   475  // GitHub API docs: https://docs.github.com/rest/apps/apps#get-a-user-installation-for-the-authenticated-app
   476  //
   477  //meta:operation GET /users/{username}/installation
   478  func (s *AppsService) FindUserInstallation(ctx context.Context, user string) (*Installation, *Response, error) {
   479  	return s.getInstallation(ctx, fmt.Sprintf("users/%v/installation", user))
   480  }
   481  
   482  func (s *AppsService) getInstallation(ctx context.Context, url string) (*Installation, *Response, error) {
   483  	req, err := s.client.NewRequest("GET", url, nil)
   484  	if err != nil {
   485  		return nil, nil, err
   486  	}
   487  
   488  	i := new(Installation)
   489  	resp, err := s.client.Do(ctx, req, i)
   490  	if err != nil {
   491  		return nil, resp, err
   492  	}
   493  
   494  	return i, resp, nil
   495  }