* upgrate go-github client to v32.1.0 * migratefor-closed-social
@ -1,230 +0,0 @@ | |||||
// Copyright 2016 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
"time" | |||||
) | |||||
// AppsService provides access to the installation related functions | |||||
// in the GitHub API. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/ | |||||
type AppsService service | |||||
// App represents a GitHub App. | |||||
type App struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Owner *User `json:"owner,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
Description *string `json:"description,omitempty"` | |||||
ExternalURL *string `json:"external_url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
CreatedAt *time.Time `json:"created_at,omitempty"` | |||||
UpdatedAt *time.Time `json:"updated_at,omitempty"` | |||||
} | |||||
// InstallationToken represents an installation token. | |||||
type InstallationToken struct { | |||||
Token *string `json:"token,omitempty"` | |||||
ExpiresAt *time.Time `json:"expires_at,omitempty"` | |||||
} | |||||
// InstallationPermissions lists the permissions for metadata, contents, issues and single file for an installation. | |||||
type InstallationPermissions struct { | |||||
Metadata *string `json:"metadata,omitempty"` | |||||
Contents *string `json:"contents,omitempty"` | |||||
Issues *string `json:"issues,omitempty"` | |||||
SingleFile *string `json:"single_file,omitempty"` | |||||
} | |||||
// Installation represents a GitHub Apps installation. | |||||
type Installation struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
AppID *int64 `json:"app_id,omitempty"` | |||||
TargetID *int64 `json:"target_id,omitempty"` | |||||
Account *User `json:"account,omitempty"` | |||||
AccessTokensURL *string `json:"access_tokens_url,omitempty"` | |||||
RepositoriesURL *string `json:"repositories_url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
TargetType *string `json:"target_type,omitempty"` | |||||
SingleFileName *string `json:"single_file_name,omitempty"` | |||||
RepositorySelection *string `json:"repository_selection,omitempty"` | |||||
Events []string `json:"events,omitempty"` | |||||
Permissions *InstallationPermissions `json:"permissions,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
} | |||||
func (i Installation) String() string { | |||||
return Stringify(i) | |||||
} | |||||
// Get a single GitHub App. Passing the empty string will get | |||||
// the authenticated GitHub App. | |||||
// | |||||
// Note: appSlug is just the URL-friendly name of your GitHub App. | |||||
// You can find this on the settings page for your GitHub App | |||||
// (e.g., https://github.com/settings/apps/:app_slug). | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-github-app | |||||
func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) { | |||||
var u string | |||||
if appSlug != "" { | |||||
u = fmt.Sprintf("apps/%v", appSlug) | |||||
} else { | |||||
u = "app" | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
app := new(App) | |||||
resp, err := s.client.Do(ctx, req, app) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return app, resp, nil | |||||
} | |||||
// ListInstallations lists the installations that the current GitHub App has. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#find-installations | |||||
func (s *AppsService) ListInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) { | |||||
u, err := addOptions("app/installations", opt) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
var i []*Installation | |||||
resp, err := s.client.Do(ctx, req, &i) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return i, resp, nil | |||||
} | |||||
// GetInstallation returns the specified installation. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#get-a-single-installation | |||||
func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("app/installations/%v", id)) | |||||
} | |||||
// ListUserInstallations lists installations that are accessible to the authenticated user. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-user | |||||
func (s *AppsService) ListUserInstallations(ctx context.Context, opt *ListOptions) ([]*Installation, *Response, error) { | |||||
u, err := addOptions("user/installations", opt) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
var i struct { | |||||
Installations []*Installation `json:"installations"` | |||||
} | |||||
resp, err := s.client.Do(ctx, req, &i) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return i.Installations, resp, nil | |||||
} | |||||
// CreateInstallationToken creates a new installation token. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#create-a-new-installation-token | |||||
func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64) (*InstallationToken, *Response, error) { | |||||
u := fmt.Sprintf("app/installations/%v/access_tokens", id) | |||||
req, err := s.client.NewRequest("POST", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
t := new(InstallationToken) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// FindOrganizationInstallation finds the organization's installation information. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#find-organization-installation | |||||
func (s *AppsService) FindOrganizationInstallation(ctx context.Context, org string) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("orgs/%v/installation", org)) | |||||
} | |||||
// FindRepositoryInstallation finds the repository's installation information. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#find-repository-installation | |||||
func (s *AppsService) FindRepositoryInstallation(ctx context.Context, owner, repo string) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("repos/%v/%v/installation", owner, repo)) | |||||
} | |||||
// FindRepositoryInstallationByID finds the repository's installation information. | |||||
// | |||||
// Note: FindRepositoryInstallationByID uses the undocumented GitHub API endpoint /repositories/:id/installation. | |||||
func (s *AppsService) FindRepositoryInstallationByID(ctx context.Context, id int64) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("repositories/%d/installation", id)) | |||||
} | |||||
// FindUserInstallation finds the user's installation information. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#find-repository-installation | |||||
func (s *AppsService) FindUserInstallation(ctx context.Context, user string) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("users/%v/installation", user)) | |||||
} | |||||
func (s *AppsService) getInstallation(ctx context.Context, url string) (*Installation, *Response, error) { | |||||
req, err := s.client.NewRequest("GET", url, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
i := new(Installation) | |||||
resp, err := s.client.Do(ctx, req, i) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return i, resp, nil | |||||
} |
@ -1,457 +0,0 @@ | |||||
// Copyright 2018 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
"strings" | |||||
"time" | |||||
) | |||||
// TeamsService provides access to the team-related functions | |||||
// in the GitHub API. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/ | |||||
type TeamsService service | |||||
// Team represents a team within a GitHub organization. Teams are used to | |||||
// manage access to an organization's repositories. | |||||
type Team struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
Description *string `json:"description,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
Slug *string `json:"slug,omitempty"` | |||||
// Permission specifies the default permission for repositories owned by the team. | |||||
Permission *string `json:"permission,omitempty"` | |||||
// Privacy identifies the level of privacy this team should have. | |||||
// Possible values are: | |||||
// secret - only visible to organization owners and members of this team | |||||
// closed - visible to all members of this organization | |||||
// Default is "secret". | |||||
Privacy *string `json:"privacy,omitempty"` | |||||
MembersCount *int `json:"members_count,omitempty"` | |||||
ReposCount *int `json:"repos_count,omitempty"` | |||||
Organization *Organization `json:"organization,omitempty"` | |||||
MembersURL *string `json:"members_url,omitempty"` | |||||
RepositoriesURL *string `json:"repositories_url,omitempty"` | |||||
Parent *Team `json:"parent,omitempty"` | |||||
// LDAPDN is only available in GitHub Enterprise and when the team | |||||
// membership is synchronized with LDAP. | |||||
LDAPDN *string `json:"ldap_dn,omitempty"` | |||||
} | |||||
func (t Team) String() string { | |||||
return Stringify(t) | |||||
} | |||||
// Invitation represents a team member's invitation status. | |||||
type Invitation struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
Login *string `json:"login,omitempty"` | |||||
Email *string `json:"email,omitempty"` | |||||
// Role can be one of the values - 'direct_member', 'admin', 'billing_manager', 'hiring_manager', or 'reinstate'. | |||||
Role *string `json:"role,omitempty"` | |||||
CreatedAt *time.Time `json:"created_at,omitempty"` | |||||
Inviter *User `json:"inviter,omitempty"` | |||||
TeamCount *int `json:"team_count,omitempty"` | |||||
InvitationTeamURL *string `json:"invitation_team_url,omitempty"` | |||||
} | |||||
func (i Invitation) String() string { | |||||
return Stringify(i) | |||||
} | |||||
// ListTeams lists all of the teams for an organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-teams | |||||
func (s *TeamsService) ListTeams(ctx context.Context, org string, opt *ListOptions) ([]*Team, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams", org) | |||||
u, err := addOptions(u, opt) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeNestedTeamsPreview) | |||||
var teams []*Team | |||||
resp, err := s.client.Do(ctx, req, &teams) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teams, resp, nil | |||||
} | |||||
// GetTeam fetches a team by ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#get-team | |||||
func (s *TeamsService) GetTeam(ctx context.Context, team int64) (*Team, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v", team) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeNestedTeamsPreview) | |||||
t := new(Team) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// NewTeam represents a team to be created or modified. | |||||
type NewTeam struct { | |||||
Name string `json:"name"` // Name of the team. (Required.) | |||||
Description *string `json:"description,omitempty"` | |||||
Maintainers []string `json:"maintainers,omitempty"` | |||||
RepoNames []string `json:"repo_names,omitempty"` | |||||
ParentTeamID *int64 `json:"parent_team_id,omitempty"` | |||||
// Deprecated: Permission is deprecated when creating or editing a team in an org | |||||
// using the new GitHub permission model. It no longer identifies the | |||||
// permission a team has on its repos, but only specifies the default | |||||
// permission a repo is initially added with. Avoid confusion by | |||||
// specifying a permission value when calling AddTeamRepo. | |||||
Permission *string `json:"permission,omitempty"` | |||||
// Privacy identifies the level of privacy this team should have. | |||||
// Possible values are: | |||||
// secret - only visible to organization owners and members of this team | |||||
// closed - visible to all members of this organization | |||||
// Default is "secret". | |||||
Privacy *string `json:"privacy,omitempty"` | |||||
// LDAPDN may be used in GitHub Enterprise when the team membership | |||||
// is synchronized with LDAP. | |||||
LDAPDN *string `json:"ldap_dn,omitempty"` | |||||
} | |||||
func (s NewTeam) String() string { | |||||
return Stringify(s) | |||||
} | |||||
// CreateTeam creates a new team within an organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#create-team | |||||
func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam) (*Team, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams", org) | |||||
req, err := s.client.NewRequest("POST", u, team) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeNestedTeamsPreview) | |||||
t := new(Team) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// EditTeam edits a team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#edit-team | |||||
func (s *TeamsService) EditTeam(ctx context.Context, id int64, team NewTeam) (*Team, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v", id) | |||||
req, err := s.client.NewRequest("PATCH", u, team) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeNestedTeamsPreview) | |||||
t := new(Team) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// DeleteTeam deletes a team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#delete-team | |||||
func (s *TeamsService) DeleteTeam(ctx context.Context, team int64) (*Response, error) { | |||||
u := fmt.Sprintf("teams/%v", team) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
req.Header.Set("Accept", mediaTypeNestedTeamsPreview) | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// ListChildTeams lists child teams for a team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams | |||||
func (s *TeamsService) ListChildTeams(ctx context.Context, teamID int64, opt *ListOptions) ([]*Team, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/teams", teamID) | |||||
u, err := addOptions(u, opt) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req.Header.Set("Accept", mediaTypeNestedTeamsPreview) | |||||
var teams []*Team | |||||
resp, err := s.client.Do(ctx, req, &teams) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teams, resp, nil | |||||
} | |||||
// ListTeamRepos lists the repositories that the specified team has access to. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repos | |||||
func (s *TeamsService) ListTeamRepos(ctx context.Context, team int64, opt *ListOptions) ([]*Repository, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/repos", team) | |||||
u, err := addOptions(u, opt) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when topics API fully launches. | |||||
headers := []string{mediaTypeTopicsPreview, mediaTypeNestedTeamsPreview} | |||||
req.Header.Set("Accept", strings.Join(headers, ", ")) | |||||
var repos []*Repository | |||||
resp, err := s.client.Do(ctx, req, &repos) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return repos, resp, nil | |||||
} | |||||
// IsTeamRepo checks if a team manages the specified repository. If the | |||||
// repository is managed by team, a Repository is returned which includes the | |||||
// permissions team has for that repo. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#check-if-a-team-manages-a-repository | |||||
func (s *TeamsService) IsTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Repository, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
headers := []string{mediaTypeOrgPermissionRepo, mediaTypeNestedTeamsPreview} | |||||
req.Header.Set("Accept", strings.Join(headers, ", ")) | |||||
repository := new(Repository) | |||||
resp, err := s.client.Do(ctx, req, repository) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return repository, resp, nil | |||||
} | |||||
// TeamAddTeamRepoOptions specifies the optional parameters to the | |||||
// TeamsService.AddTeamRepo method. | |||||
type TeamAddTeamRepoOptions struct { | |||||
// Permission specifies the permission to grant the team on this repository. | |||||
// Possible values are: | |||||
// pull - team members can pull, but not push to or administer this repository | |||||
// push - team members can pull and push, but not administer this repository | |||||
// admin - team members can pull, push and administer this repository | |||||
// | |||||
// If not specified, the team's permission attribute will be used. | |||||
Permission string `json:"permission,omitempty"` | |||||
} | |||||
// AddTeamRepo adds a repository to be managed by the specified team. The | |||||
// specified repository must be owned by the organization to which the team | |||||
// belongs, or a direct fork of a repository owned by the organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#add-team-repo | |||||
func (s *TeamsService) AddTeamRepo(ctx context.Context, team int64, owner string, repo string, opt *TeamAddTeamRepoOptions) (*Response, error) { | |||||
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) | |||||
req, err := s.client.NewRequest("PUT", u, opt) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// RemoveTeamRepo removes a repository from being managed by the specified | |||||
// team. Note that this does not delete the repository, it just removes it | |||||
// from the team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-repo | |||||
func (s *TeamsService) RemoveTeamRepo(ctx context.Context, team int64, owner string, repo string) (*Response, error) { | |||||
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// ListUserTeams lists a user's teams | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-user-teams | |||||
func (s *TeamsService) ListUserTeams(ctx context.Context, opt *ListOptions) ([]*Team, *Response, error) { | |||||
u := "user/teams" | |||||
u, err := addOptions(u, opt) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeNestedTeamsPreview) | |||||
var teams []*Team | |||||
resp, err := s.client.Do(ctx, req, &teams) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teams, resp, nil | |||||
} | |||||
// ListTeamProjects lists the organization projects for a team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects | |||||
func (s *TeamsService) ListTeamProjects(ctx context.Context, teamID int64) ([]*Project, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/projects", teamID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
var projects []*Project | |||||
resp, err := s.client.Do(ctx, req, &projects) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return projects, resp, nil | |||||
} | |||||
// ReviewTeamProjects checks whether a team has read, write, or admin | |||||
// permissions for an organization project. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#review-a-team-project | |||||
func (s *TeamsService) ReviewTeamProjects(ctx context.Context, teamID, projectID int64) (*Project, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
projects := &Project{} | |||||
resp, err := s.client.Do(ctx, req, &projects) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return projects, resp, nil | |||||
} | |||||
// TeamProjectOptions specifies the optional parameters to the | |||||
// TeamsService.AddTeamProject method. | |||||
type TeamProjectOptions struct { | |||||
// Permission specifies the permission to grant to the team for this project. | |||||
// Possible values are: | |||||
// "read" - team members can read, but not write to or administer this project. | |||||
// "write" - team members can read and write, but not administer this project. | |||||
// "admin" - team members can read, write and administer this project. | |||||
// | |||||
Permission *string `json:"permission,omitempty"` | |||||
} | |||||
// AddTeamProject adds an organization project to a team. To add a project to a team or | |||||
// update the team's permission on a project, the authenticated user must have admin | |||||
// permissions for the project. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project | |||||
func (s *TeamsService) AddTeamProject(ctx context.Context, teamID, projectID int64, opt *TeamProjectOptions) (*Response, error) { | |||||
u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID) | |||||
req, err := s.client.NewRequest("PUT", u, opt) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// RemoveTeamProject removes an organization project from a team. An organization owner or | |||||
// a team maintainer can remove any project from the team. To remove a project from a team | |||||
// as an organization member, the authenticated user must have "read" access to both the team | |||||
// and project, or "admin" access to the team or project. | |||||
// Note: This endpoint removes the project from the team, but does not delete it. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#remove-team-project | |||||
func (s *TeamsService) RemoveTeamProject(ctx context.Context, teamID int64, projectID int64) (*Response, error) { | |||||
u := fmt.Sprintf("teams/%v/projects/%v", teamID, projectID) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeNestedTeamsPreview, mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
return s.client.Do(ctx, req, nil) | |||||
} |
@ -1,155 +0,0 @@ | |||||
// Copyright 2018 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
// DiscussionComment represents a GitHub dicussion in a team. | |||||
type DiscussionComment struct { | |||||
Author *User `json:"author,omitempty"` | |||||
Body *string `json:"body,omitempty"` | |||||
BodyHTML *string `json:"body_html,omitempty"` | |||||
BodyVersion *string `json:"body_version,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
LastEditedAt *Timestamp `json:"last_edited_at,omitempty"` | |||||
DiscussionURL *string `json:"discussion_url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Number *int `json:"number,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
Reactions *Reactions `json:"reactions,omitempty"` | |||||
} | |||||
func (c DiscussionComment) String() string { | |||||
return Stringify(c) | |||||
} | |||||
// DiscussionCommentListOptions specifies optional parameters to the | |||||
// TeamServices.ListComments method. | |||||
type DiscussionCommentListOptions struct { | |||||
// Sorts the discussion comments by the date they were created. | |||||
// Accepted values are asc and desc. Default is desc. | |||||
Direction string `url:"direction,omitempty"` | |||||
} | |||||
// ListComments lists all comments on a team discussion. | |||||
// Authenticated user must grant read:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-comments | |||||
func (s *TeamsService) ListComments(ctx context.Context, teamID int64, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions/%v/comments", teamID, discussionNumber) | |||||
u, err := addOptions(u, options) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
var comments []*DiscussionComment | |||||
resp, err := s.client.Do(ctx, req, &comments) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return comments, resp, nil | |||||
} | |||||
// GetComment gets a specific comment on a team discussion. | |||||
// Authenticated user must grant read:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-single-comment | |||||
func (s *TeamsService) GetComment(ctx context.Context, teamID int64, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v", teamID, discussionNumber, commentNumber) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
discussionComment := &DiscussionComment{} | |||||
resp, err := s.client.Do(ctx, req, discussionComment) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return discussionComment, resp, nil | |||||
} | |||||
// CreateComment creates a new discussion post on a team discussion. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-comment | |||||
func (s *TeamsService) CreateComment(ctx context.Context, teamID int64, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions/%v/comments", teamID, discsusionNumber) | |||||
req, err := s.client.NewRequest("POST", u, comment) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
discussionComment := &DiscussionComment{} | |||||
resp, err := s.client.Do(ctx, req, discussionComment) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return discussionComment, resp, nil | |||||
} | |||||
// EditComment edits the body text of a discussion comment. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// User is allowed to edit body of a comment only. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#edit-a-comment | |||||
func (s *TeamsService) EditComment(ctx context.Context, teamID int64, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v", teamID, discussionNumber, commentNumber) | |||||
req, err := s.client.NewRequest("PATCH", u, comment) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
discussionComment := &DiscussionComment{} | |||||
resp, err := s.client.Do(ctx, req, discussionComment) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return discussionComment, resp, nil | |||||
} | |||||
// DeleteComment deletes a comment on a team discussion. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-comment | |||||
func (s *TeamsService) DeleteComment(ctx context.Context, teamID int64, discussionNumber, commentNumber int) (*Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions/%v/comments/%v", teamID, discussionNumber, commentNumber) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
return s.client.Do(ctx, req, nil) | |||||
} |
@ -1,160 +0,0 @@ | |||||
// Copyright 2018 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
// TeamDiscussion represents a GitHub dicussion in a team. | |||||
type TeamDiscussion struct { | |||||
Author *User `json:"author,omitempty"` | |||||
Body *string `json:"body,omitempty"` | |||||
BodyHTML *string `json:"body_html,omitempty"` | |||||
BodyVersion *string `json:"body_version,omitempty"` | |||||
CommentsCount *int `json:"comments_count,omitempty"` | |||||
CommentsURL *string `json:"comments_url,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
LastEditedAt *Timestamp `json:"last_edited_at,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Number *int `json:"number,omitempty"` | |||||
Pinned *bool `json:"pinned,omitempty"` | |||||
Private *bool `json:"private,omitempty"` | |||||
TeamURL *string `json:"team_url,omitempty"` | |||||
Title *string `json:"title,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
Reactions *Reactions `json:"reactions,omitempty"` | |||||
} | |||||
func (d TeamDiscussion) String() string { | |||||
return Stringify(d) | |||||
} | |||||
// DiscussionListOptions specifies optional parameters to the | |||||
// TeamServices.ListDiscussions method. | |||||
type DiscussionListOptions struct { | |||||
// Sorts the discussion by the date they were created. | |||||
// Accepted values are asc and desc. Default is desc. | |||||
Direction string `url:"direction,omitempty"` | |||||
} | |||||
// ListDiscussions lists all discussions on team's page. | |||||
// Authenticated user must grant read:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussions/#list-discussions | |||||
func (s *TeamsService) ListDiscussions(ctx context.Context, teamID int64, options *DiscussionListOptions) ([]*TeamDiscussion, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions", teamID) | |||||
u, err := addOptions(u, options) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
var teamDiscussions []*TeamDiscussion | |||||
resp, err := s.client.Do(ctx, req, &teamDiscussions) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teamDiscussions, resp, nil | |||||
} | |||||
// GetDiscussion gets a specific discussion on a team's page. | |||||
// Authenticated user must grant read:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussions/#get-a-single-discussion | |||||
func (s *TeamsService) GetDiscussion(ctx context.Context, teamID int64, discussionNumber int) (*TeamDiscussion, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions/%v", teamID, discussionNumber) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
teamDiscussion := &TeamDiscussion{} | |||||
resp, err := s.client.Do(ctx, req, teamDiscussion) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teamDiscussion, resp, nil | |||||
} | |||||
// CreateDiscussion creates a new discussion post on a team's page. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussions/#create-a-discussion | |||||
func (s *TeamsService) CreateDiscussion(ctx context.Context, teamID int64, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions", teamID) | |||||
req, err := s.client.NewRequest("POST", u, discussion) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
teamDiscussion := &TeamDiscussion{} | |||||
resp, err := s.client.Do(ctx, req, teamDiscussion) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teamDiscussion, resp, nil | |||||
} | |||||
// EditDiscussion edits the title and body text of a discussion post. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// User is allowed to change Title and Body of a discussion only. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussions/#edit-a-discussion | |||||
func (s *TeamsService) EditDiscussion(ctx context.Context, teamID int64, discussionNumber int, discussion TeamDiscussion) (*TeamDiscussion, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions/%v", teamID, discussionNumber) | |||||
req, err := s.client.NewRequest("PATCH", u, discussion) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
teamDiscussion := &TeamDiscussion{} | |||||
resp, err := s.client.Do(ctx, req, teamDiscussion) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teamDiscussion, resp, nil | |||||
} | |||||
// DeleteDiscussion deletes a discussion from team's page. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussions/#delete-a-discussion | |||||
func (s *TeamsService) DeleteDiscussion(ctx context.Context, teamID int64, discussionNumber int) (*Response, error) { | |||||
u := fmt.Sprintf("teams/%v/discussions/%v", teamID, discussionNumber) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeTeamDiscussionsPreview) | |||||
return s.client.Do(ctx, req, nil) | |||||
} |
@ -1,174 +0,0 @@ | |||||
// Copyright 2018 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
// TeamListTeamMembersOptions specifies the optional parameters to the | |||||
// TeamsService.ListTeamMembers method. | |||||
type TeamListTeamMembersOptions struct { | |||||
// Role filters members returned by their role in the team. Possible | |||||
// values are "all", "member", "maintainer". Default is "all". | |||||
Role string `url:"role,omitempty"` | |||||
ListOptions | |||||
} | |||||
// ListTeamMembers lists all of the users who are members of the specified | |||||
// team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/members/#list-team-members | |||||
func (s *TeamsService) ListTeamMembers(ctx context.Context, team int64, opt *TeamListTeamMembersOptions) ([]*User, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/members", team) | |||||
u, err := addOptions(u, opt) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req.Header.Set("Accept", mediaTypeNestedTeamsPreview) | |||||
var members []*User | |||||
resp, err := s.client.Do(ctx, req, &members) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return members, resp, nil | |||||
} | |||||
// IsTeamMember checks if a user is a member of the specified team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-member | |||||
// | |||||
// Deprecated: This API has been marked as deprecated in the Github API docs, | |||||
// TeamsService.GetTeamMembership method should be used instead. | |||||
func (s *TeamsService) IsTeamMember(ctx context.Context, team int64, user string) (bool, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/members/%v", team, user) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return false, nil, err | |||||
} | |||||
resp, err := s.client.Do(ctx, req, nil) | |||||
member, err := parseBoolResponse(err) | |||||
return member, resp, err | |||||
} | |||||
// GetTeamMembership returns the membership status for a user in a team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/members/#get-team-membership | |||||
func (s *TeamsService) GetTeamMembership(ctx context.Context, team int64, user string) (*Membership, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/memberships/%v", team, user) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req.Header.Set("Accept", mediaTypeNestedTeamsPreview) | |||||
t := new(Membership) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// TeamAddTeamMembershipOptions specifies the optional | |||||
// parameters to the TeamsService.AddTeamMembership method. | |||||
type TeamAddTeamMembershipOptions struct { | |||||
// Role specifies the role the user should have in the team. Possible | |||||
// values are: | |||||
// member - a normal member of the team | |||||
// maintainer - a team maintainer. Able to add/remove other team | |||||
// members, promote other team members to team | |||||
// maintainer, and edit the team’s name and description | |||||
// | |||||
// Default value is "member". | |||||
Role string `json:"role,omitempty"` | |||||
} | |||||
// AddTeamMembership adds or invites a user to a team. | |||||
// | |||||
// In order to add a membership between a user and a team, the authenticated | |||||
// user must have 'admin' permissions to the team or be an owner of the | |||||
// organization that the team is associated with. | |||||
// | |||||
// If the user is already a part of the team's organization (meaning they're on | |||||
// at least one other team in the organization), this endpoint will add the | |||||
// user to the team. | |||||
// | |||||
// If the user is completely unaffiliated with the team's organization (meaning | |||||
// they're on none of the organization's teams), this endpoint will send an | |||||
// invitation to the user via email. This newly-created membership will be in | |||||
// the "pending" state until the user accepts the invitation, at which point | |||||
// the membership will transition to the "active" state and the user will be | |||||
// added as a member of the team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/members/#add-or-update-team-membership | |||||
func (s *TeamsService) AddTeamMembership(ctx context.Context, team int64, user string, opt *TeamAddTeamMembershipOptions) (*Membership, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/memberships/%v", team, user) | |||||
req, err := s.client.NewRequest("PUT", u, opt) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
t := new(Membership) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// RemoveTeamMembership removes a user from a team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/members/#remove-team-membership | |||||
func (s *TeamsService) RemoveTeamMembership(ctx context.Context, team int64, user string) (*Response, error) { | |||||
u := fmt.Sprintf("teams/%v/memberships/%v", team, user) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// ListPendingTeamInvitations get pending invitaion list in team. | |||||
// Warning: The API may change without advance notice during the preview period. | |||||
// Preview features are not supported for production use. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/members/#list-pending-team-invitations | |||||
func (s *TeamsService) ListPendingTeamInvitations(ctx context.Context, team int64, opt *ListOptions) ([]*Invitation, *Response, error) { | |||||
u := fmt.Sprintf("teams/%v/invitations", team) | |||||
u, err := addOptions(u, opt) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var pendingInvitations []*Invitation | |||||
resp, err := s.client.Do(ctx, req, &pendingInvitations) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return pendingInvitations, resp, nil | |||||
} |
@ -0,0 +1,12 @@ | |||||
// Copyright 2020 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
// ActionsService handles communication with the actions related | |||||
// methods of the GitHub API. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/ | |||||
type ActionsService service |
@ -0,0 +1,164 @@ | |||||
// Copyright 2020 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
"net/http" | |||||
"net/url" | |||||
) | |||||
// Artifact reprents a GitHub artifact. Artifacts allow sharing | |||||
// data between jobs in a workflow and provide storage for data | |||||
// once a workflow is complete. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/ | |||||
type Artifact struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
SizeInBytes *int64 `json:"size_in_bytes,omitempty"` | |||||
ArchiveDownloadURL *string `json:"archive_download_url,omitempty"` | |||||
Expired *bool `json:"expired,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
ExpiresAt *Timestamp `json:"expires_at,omitempty"` | |||||
} | |||||
// ArtifactList represents a list of GitHub artifacts. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/ | |||||
type ArtifactList struct { | |||||
TotalCount *int64 `json:"total_count,omitempty"` | |||||
Artifacts []*Artifact `json:"artifacts,omitempty"` | |||||
} | |||||
// ListArtifacts lists all artifacts that belong to a repository. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-artifacts-for-a-repository | |||||
func (s *ActionsService) ListArtifacts(ctx context.Context, owner, repo string, opts *ListOptions) (*ArtifactList, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/artifacts", owner, repo) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
artifactList := new(ArtifactList) | |||||
resp, err := s.client.Do(ctx, req, artifactList) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return artifactList, resp, nil | |||||
} | |||||
// ListWorkflowRunArtifacts lists all artifacts that belong to a workflow run. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#list-workflow-run-artifacts | |||||
func (s *ActionsService) ListWorkflowRunArtifacts(ctx context.Context, owner, repo string, runID int64, opts *ListOptions) (*ArtifactList, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/artifacts", owner, repo, runID) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
artifactList := new(ArtifactList) | |||||
resp, err := s.client.Do(ctx, req, artifactList) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return artifactList, resp, nil | |||||
} | |||||
// GetArtifact gets a specific artifact for a workflow run. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#get-an-artifact | |||||
func (s *ActionsService) GetArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Artifact, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
artifact := new(Artifact) | |||||
resp, err := s.client.Do(ctx, req, artifact) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return artifact, resp, nil | |||||
} | |||||
// DownloadArtifact gets a redirect URL to download an archive for a repository. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#download-an-artifact | |||||
func (s *ActionsService) DownloadArtifact(ctx context.Context, owner, repo string, artifactID int64, followRedirects bool) (*url.URL, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v/zip", owner, repo, artifactID) | |||||
resp, err := s.getDownloadArtifactFromURL(ctx, u, followRedirects) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
if resp.StatusCode != http.StatusFound { | |||||
return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) | |||||
} | |||||
parsedURL, err := url.Parse(resp.Header.Get("Location")) | |||||
return parsedURL, newResponse(resp), nil | |||||
} | |||||
func (s *ActionsService) getDownloadArtifactFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) { | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
var resp *http.Response | |||||
// Use http.DefaultTransport if no custom Transport is configured | |||||
req = withContext(ctx, req) | |||||
if s.client.client.Transport == nil { | |||||
resp, err = http.DefaultTransport.RoundTrip(req) | |||||
} else { | |||||
resp, err = s.client.client.Transport.RoundTrip(req) | |||||
} | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
resp.Body.Close() | |||||
// If redirect response is returned, follow it | |||||
if followRedirects && resp.StatusCode == http.StatusMovedPermanently { | |||||
u = resp.Header.Get("Location") | |||||
resp, err = s.getDownloadArtifactFromURL(ctx, u, false) | |||||
} | |||||
return resp, err | |||||
} | |||||
// DeleteArtifact deletes a workflow run artifact. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/artifacts/#delete-an-artifact | |||||
func (s *ActionsService) DeleteArtifact(ctx context.Context, owner, repo string, artifactID int64) (*Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v", owner, repo, artifactID) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} |
@ -0,0 +1,277 @@ | |||||
// Copyright 2020 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
// RunnerApplicationDownload represents a binary for the self-hosted runner application that can be downloaded. | |||||
type RunnerApplicationDownload struct { | |||||
OS *string `json:"os,omitempty"` | |||||
Architecture *string `json:"architecture,omitempty"` | |||||
DownloadURL *string `json:"download_url,omitempty"` | |||||
Filename *string `json:"filename,omitempty"` | |||||
} | |||||
// ListRunnerApplicationDownloads lists self-hosted runner application binaries that can be downloaded and run. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-runner-applications-for-a-repository | |||||
func (s *ActionsService) ListRunnerApplicationDownloads(ctx context.Context, owner, repo string) ([]*RunnerApplicationDownload, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runners/downloads", owner, repo) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var rads []*RunnerApplicationDownload | |||||
resp, err := s.client.Do(ctx, req, &rads) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return rads, resp, nil | |||||
} | |||||
// RegistrationToken represents a token that can be used to add a self-hosted runner to a repository. | |||||
type RegistrationToken struct { | |||||
Token *string `json:"token,omitempty"` | |||||
ExpiresAt *Timestamp `json:"expires_at,omitempty"` | |||||
} | |||||
// CreateRegistrationToken creates a token that can be used to add a self-hosted runner. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-registration-token-for-a-repository | |||||
func (s *ActionsService) CreateRegistrationToken(ctx context.Context, owner, repo string) (*RegistrationToken, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runners/registration-token", owner, repo) | |||||
req, err := s.client.NewRequest("POST", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
registrationToken := new(RegistrationToken) | |||||
resp, err := s.client.Do(ctx, req, registrationToken) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return registrationToken, resp, nil | |||||
} | |||||
// Runner represents a self-hosted runner registered with a repository. | |||||
type Runner struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
OS *string `json:"os,omitempty"` | |||||
Status *string `json:"status,omitempty"` | |||||
} | |||||
// Runners represents a collection of self-hosted runners for a repository. | |||||
type Runners struct { | |||||
TotalCount int `json:"total_count"` | |||||
Runners []*Runner `json:"runners"` | |||||
} | |||||
// ListRunners lists all the self-hosted runners for a repository. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-a-repository | |||||
func (s *ActionsService) ListRunners(ctx context.Context, owner, repo string, opts *ListOptions) (*Runners, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runners", owner, repo) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
runners := &Runners{} | |||||
resp, err := s.client.Do(ctx, req, &runners) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return runners, resp, nil | |||||
} | |||||
// GetRunner gets a specific self-hosted runner for a repository using its runner ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#get-a-self-hosted-runner-for-a-repository | |||||
func (s *ActionsService) GetRunner(ctx context.Context, owner, repo string, runnerID int64) (*Runner, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
runner := new(Runner) | |||||
resp, err := s.client.Do(ctx, req, runner) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return runner, resp, nil | |||||
} | |||||
// RemoveToken represents a token that can be used to remove a self-hosted runner from a repository. | |||||
type RemoveToken struct { | |||||
Token *string `json:"token,omitempty"` | |||||
ExpiresAt *Timestamp `json:"expires_at,omitempty"` | |||||
} | |||||
// CreateRemoveToken creates a token that can be used to remove a self-hosted runner from a repository. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-remove-token-for-a-repository | |||||
func (s *ActionsService) CreateRemoveToken(ctx context.Context, owner, repo string) (*RemoveToken, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runners/remove-token", owner, repo) | |||||
req, err := s.client.NewRequest("POST", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
removeToken := new(RemoveToken) | |||||
resp, err := s.client.Do(ctx, req, removeToken) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return removeToken, resp, nil | |||||
} | |||||
// RemoveRunner forces the removal of a self-hosted runner in a repository using the runner id. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#delete-a-self-hosted-runner-from-a-repository | |||||
func (s *ActionsService) RemoveRunner(ctx context.Context, owner, repo string, runnerID int64) (*Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runners/%v", owner, repo, runnerID) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// ListOrganizationRunnerApplicationDownloads lists self-hosted runner application binaries that can be downloaded and run. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-runner-applications-for-an-organization | |||||
func (s *ActionsService) ListOrganizationRunnerApplicationDownloads(ctx context.Context, owner string) ([]*RunnerApplicationDownload, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/runners/downloads", owner) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var rads []*RunnerApplicationDownload | |||||
resp, err := s.client.Do(ctx, req, &rads) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return rads, resp, nil | |||||
} | |||||
// CreateOrganizationRegistrationToken creates a token that can be used to add a self-hosted runner to an organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-registration-token-for-an-organization | |||||
func (s *ActionsService) CreateOrganizationRegistrationToken(ctx context.Context, owner string) (*RegistrationToken, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/runners/registration-token", owner) | |||||
req, err := s.client.NewRequest("POST", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
registrationToken := new(RegistrationToken) | |||||
resp, err := s.client.Do(ctx, req, registrationToken) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return registrationToken, resp, nil | |||||
} | |||||
// ListOrganizationRunners lists all the self-hosted runners for an organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#list-self-hosted-runners-for-an-organization | |||||
func (s *ActionsService) ListOrganizationRunners(ctx context.Context, owner string, opts *ListOptions) (*Runners, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/runners", owner) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
runners := &Runners{} | |||||
resp, err := s.client.Do(ctx, req, &runners) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return runners, resp, nil | |||||
} | |||||
// GetOrganizationRunner gets a specific self-hosted runner for an organization using its runner ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#get-a-self-hosted-runner-for-an-organization | |||||
func (s *ActionsService) GetOrganizationRunner(ctx context.Context, owner string, runnerID int64) (*Runner, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/runners/%v", owner, runnerID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
runner := new(Runner) | |||||
resp, err := s.client.Do(ctx, req, runner) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return runner, resp, nil | |||||
} | |||||
// CreateOrganizationRemoveToken creates a token that can be used to remove a self-hosted runner from an organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#create-a-remove-token-for-an-organization | |||||
func (s *ActionsService) CreateOrganizationRemoveToken(ctx context.Context, owner string) (*RemoveToken, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/runners/remove-token", owner) | |||||
req, err := s.client.NewRequest("POST", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
removeToken := new(RemoveToken) | |||||
resp, err := s.client.Do(ctx, req, removeToken) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return removeToken, resp, nil | |||||
} | |||||
// RemoveOrganizationRunner forces the removal of a self-hosted runner from an organization using the runner id. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/self-hosted-runners/#delete-a-self-hosted-runner-from-an-organization | |||||
func (s *ActionsService) RemoveOrganizationRunner(ctx context.Context, owner string, runnerID int64) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/runners/%v", owner, runnerID) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} |
@ -0,0 +1,299 @@ | |||||
// Copyright 2020 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
// PublicKey represents the public key that should be used to encrypt secrets. | |||||
type PublicKey struct { | |||||
KeyID *string `json:"key_id"` | |||||
Key *string `json:"key"` | |||||
} | |||||
// GetRepoPublicKey gets a public key that should be used for secret encryption. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-repository-public-key | |||||
func (s *ActionsService) GetRepoPublicKey(ctx context.Context, owner, repo string) (*PublicKey, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/secrets/public-key", owner, repo) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
pubKey := new(PublicKey) | |||||
resp, err := s.client.Do(ctx, req, pubKey) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return pubKey, resp, nil | |||||
} | |||||
// GetOrgPublicKey gets a public key that should be used for secret encryption. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-an-organization-public-key | |||||
func (s *ActionsService) GetOrgPublicKey(ctx context.Context, org string) (*PublicKey, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/secrets/public-key", org) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
pubKey := new(PublicKey) | |||||
resp, err := s.client.Do(ctx, req, pubKey) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return pubKey, resp, nil | |||||
} | |||||
// Secret represents a repository action secret. | |||||
type Secret struct { | |||||
Name string `json:"name"` | |||||
CreatedAt Timestamp `json:"created_at"` | |||||
UpdatedAt Timestamp `json:"updated_at"` | |||||
Visibility string `json:"visibility,omitempty"` | |||||
SelectedRepositoriesURL string `json:"selected_repositories_url,omitempty"` | |||||
} | |||||
// Secrets represents one item from the ListSecrets response. | |||||
type Secrets struct { | |||||
TotalCount int `json:"total_count"` | |||||
Secrets []*Secret `json:"secrets"` | |||||
} | |||||
// ListRepoSecrets lists all secrets available in a repository | |||||
// without revealing their encrypted values. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-repository-secrets | |||||
func (s *ActionsService) ListRepoSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/secrets", owner, repo) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
secrets := new(Secrets) | |||||
resp, err := s.client.Do(ctx, req, &secrets) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return secrets, resp, nil | |||||
} | |||||
// GetRepoSecret gets a single repository secret without revealing its encrypted value. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-a-repository-secret | |||||
func (s *ActionsService) GetRepoSecret(ctx context.Context, owner, repo, name string) (*Secret, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
secret := new(Secret) | |||||
resp, err := s.client.Do(ctx, req, secret) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return secret, resp, nil | |||||
} | |||||
// SelectedRepoIDs are the repository IDs that have access to the secret. | |||||
type SelectedRepoIDs []int64 | |||||
// EncryptedSecret represents a secret that is encrypted using a public key. | |||||
// | |||||
// The value of EncryptedValue must be your secret, encrypted with | |||||
// LibSodium (see documentation here: https://libsodium.gitbook.io/doc/bindings_for_other_languages) | |||||
// using the public key retrieved using the GetPublicKey method. | |||||
type EncryptedSecret struct { | |||||
Name string `json:"-"` | |||||
KeyID string `json:"key_id"` | |||||
EncryptedValue string `json:"encrypted_value"` | |||||
Visibility string `json:"visibility,omitempty"` | |||||
SelectedRepositoryIDs SelectedRepoIDs `json:"selected_repository_ids,omitempty"` | |||||
} | |||||
// CreateOrUpdateRepoSecret creates or updates a repository secret with an encrypted value. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-a-repository-secret | |||||
func (s *ActionsService) CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *EncryptedSecret) (*Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, eSecret.Name) | |||||
req, err := s.client.NewRequest("PUT", u, eSecret) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// DeleteRepoSecret deletes a secret in a repository using the secret name. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-a-repository-secret | |||||
func (s *ActionsService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) (*Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/secrets/%v", owner, repo, name) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// ListOrgSecrets lists all secrets available in an organization | |||||
// without revealing their encrypted values. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-organization-secrets | |||||
func (s *ActionsService) ListOrgSecrets(ctx context.Context, org string, opts *ListOptions) (*Secrets, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/secrets", org) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
secrets := new(Secrets) | |||||
resp, err := s.client.Do(ctx, req, &secrets) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return secrets, resp, nil | |||||
} | |||||
// GetOrgSecret gets a single organization secret without revealing its encrypted value. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#get-an-organization-secret | |||||
func (s *ActionsService) GetOrgSecret(ctx context.Context, org, name string) (*Secret, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
secret := new(Secret) | |||||
resp, err := s.client.Do(ctx, req, secret) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return secret, resp, nil | |||||
} | |||||
// CreateOrUpdateOrgSecret creates or updates an organization secret with an encrypted value. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#create-or-update-an-organization-secret | |||||
func (s *ActionsService) CreateOrUpdateOrgSecret(ctx context.Context, org string, eSecret *EncryptedSecret) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, eSecret.Name) | |||||
req, err := s.client.NewRequest("PUT", u, eSecret) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// SelectedReposList represents the list of repositories selected for an organization secret. | |||||
type SelectedReposList struct { | |||||
TotalCount *int `json:"total_count,omitempty"` | |||||
Repositories []*Repository `json:"repositories,omitempty"` | |||||
} | |||||
// ListSelectedReposForOrgSecret lists all repositories that have access to a secret. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-selected-repositories-for-an-organization-secret | |||||
func (s *ActionsService) ListSelectedReposForOrgSecret(ctx context.Context, org, name string) (*SelectedReposList, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
result := new(SelectedReposList) | |||||
resp, err := s.client.Do(ctx, req, result) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return result, resp, nil | |||||
} | |||||
// SetSelectedReposForOrgSecret sets the repositories that have access to a secret. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#set-selected-repositories-for-an-organization-secret | |||||
func (s *ActionsService) SetSelectedReposForOrgSecret(ctx context.Context, org, name string, ids SelectedRepoIDs) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories", org, name) | |||||
type repoIDs struct { | |||||
SelectedIDs SelectedRepoIDs `json:"selected_repository_ids,omitempty"` | |||||
} | |||||
req, err := s.client.NewRequest("PUT", u, repoIDs{SelectedIDs: ids}) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// AddSelectedRepoToOrgSecret adds a repository to an organization secret. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#add-selected-repository-to-an-organization-secret | |||||
func (s *ActionsService) AddSelectedRepoToOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID) | |||||
req, err := s.client.NewRequest("PUT", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// RemoveSelectedRepoFromOrgSecret removes a repository from an organization secret. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#remove-selected-repository-from-an-organization-secret | |||||
func (s *ActionsService) RemoveSelectedRepoFromOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/secrets/%v/repositories/%v", org, name, *repo.ID) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// DeleteOrgSecret deletes a secret in an organization using the secret name. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/secrets/#delete-an-organization-secret | |||||
func (s *ActionsService) DeleteOrgSecret(ctx context.Context, org, name string) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/actions/secrets/%v", org, name) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} |
@ -0,0 +1,149 @@ | |||||
// Copyright 2020 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
"net/http" | |||||
"net/url" | |||||
) | |||||
// TaskStep represents a single task step from a sequence of tasks of a job. | |||||
type TaskStep struct { | |||||
Name *string `json:"name,omitempty"` | |||||
Status *string `json:"status,omitempty"` | |||||
Conclusion *string `json:"conclusion,omitempty"` | |||||
Number *int64 `json:"number,omitempty"` | |||||
StartedAt *Timestamp `json:"started_at,omitempty"` | |||||
CompletedAt *Timestamp `json:"completed_at,omitempty"` | |||||
} | |||||
// WorkflowJob represents a repository action workflow job. | |||||
type WorkflowJob struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
RunID *int64 `json:"run_id,omitempty"` | |||||
RunURL *string `json:"run_url,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
HeadSHA *string `json:"head_sha,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
Status *string `json:"status,omitempty"` | |||||
Conclusion *string `json:"conclusion,omitempty"` | |||||
StartedAt *Timestamp `json:"started_at,omitempty"` | |||||
CompletedAt *Timestamp `json:"completed_at,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
Steps []*TaskStep `json:"steps,omitempty"` | |||||
CheckRunURL *string `json:"check_run_url,omitempty"` | |||||
} | |||||
// Jobs represents a slice of repository action workflow job. | |||||
type Jobs struct { | |||||
TotalCount *int `json:"total_count,omitempty"` | |||||
Jobs []*WorkflowJob `json:"jobs,omitempty"` | |||||
} | |||||
// ListWorkflowJobsOptions specifies optional parameters to ListWorkflowJobs. | |||||
type ListWorkflowJobsOptions struct { | |||||
// Filter specifies how jobs should be filtered by their completed_at timestamp. | |||||
// Possible values are: | |||||
// latest - Returns jobs from the most recent execution of the workflow run | |||||
// all - Returns all jobs for a workflow run, including from old executions of the workflow run | |||||
// | |||||
// Default value is "latest". | |||||
Filter string `url:"filter,omitempty"` | |||||
ListOptions | |||||
} | |||||
// ListWorkflowJobs lists all jobs for a workflow run. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#list-jobs-for-a-workflow-run | |||||
func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo string, runID int64, opts *ListWorkflowJobsOptions) (*Jobs, *Response, error) { | |||||
u := fmt.Sprintf("repos/%s/%s/actions/runs/%v/jobs", owner, repo, runID) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
jobs := new(Jobs) | |||||
resp, err := s.client.Do(ctx, req, &jobs) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return jobs, resp, nil | |||||
} | |||||
// GetWorkflowJobByID gets a specific job in a workflow run by ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#get-a-job-for-a-workflow-run | |||||
func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo string, jobID int64) (*WorkflowJob, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v", owner, repo, jobID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
job := new(WorkflowJob) | |||||
resp, err := s.client.Do(ctx, req, job) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return job, resp, nil | |||||
} | |||||
// GetWorkflowJobLogs gets a redirect URL to download a plain text file of logs for a workflow job. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-jobs/#download-job-logs-for-a-workflow-run | |||||
func (s *ActionsService) GetWorkflowJobLogs(ctx context.Context, owner, repo string, jobID int64, followRedirects bool) (*url.URL, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v/logs", owner, repo, jobID) | |||||
resp, err := s.getWorkflowLogsFromURL(ctx, u, followRedirects) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
if resp.StatusCode != http.StatusFound { | |||||
return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) | |||||
} | |||||
parsedURL, err := url.Parse(resp.Header.Get("Location")) | |||||
return parsedURL, newResponse(resp), err | |||||
} | |||||
func (s *ActionsService) getWorkflowLogsFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) { | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
var resp *http.Response | |||||
// Use http.DefaultTransport if no custom Transport is configured | |||||
req = withContext(ctx, req) | |||||
if s.client.client.Transport == nil { | |||||
resp, err = http.DefaultTransport.RoundTrip(req) | |||||
} else { | |||||
resp, err = s.client.client.Transport.RoundTrip(req) | |||||
} | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
resp.Body.Close() | |||||
// If redirect response is returned, follow it | |||||
if followRedirects && resp.StatusCode == http.StatusMovedPermanently { | |||||
u = resp.Header.Get("Location") | |||||
resp, err = s.getWorkflowLogsFromURL(ctx, u, false) | |||||
} | |||||
return resp, err | |||||
} |
@ -0,0 +1,235 @@ | |||||
// Copyright 2020 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
"net/http" | |||||
"net/url" | |||||
) | |||||
// WorkflowRun represents a repository action workflow run. | |||||
type WorkflowRun struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
HeadBranch *string `json:"head_branch,omitempty"` | |||||
HeadSHA *string `json:"head_sha,omitempty"` | |||||
RunNumber *int `json:"run_number,omitempty"` | |||||
Event *string `json:"event,omitempty"` | |||||
Status *string `json:"status,omitempty"` | |||||
Conclusion *string `json:"conclusion,omitempty"` | |||||
WorkflowID *int64 `json:"workflow_id,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
PullRequests []*PullRequest `json:"pull_requests,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
JobsURL *string `json:"jobs_url,omitempty"` | |||||
LogsURL *string `json:"logs_url,omitempty"` | |||||
CheckSuiteURL *string `json:"check_suite_url,omitempty"` | |||||
ArtifactsURL *string `json:"artifacts_url,omitempty"` | |||||
CancelURL *string `json:"cancel_url,omitempty"` | |||||
RerunURL *string `json:"rerun_url,omitempty"` | |||||
HeadCommit *HeadCommit `json:"head_commit,omitempty"` | |||||
WorkflowURL *string `json:"workflow_url,omitempty"` | |||||
Repository *Repository `json:"repository,omitempty"` | |||||
HeadRepository *Repository `json:"head_repository,omitempty"` | |||||
} | |||||
// WorkflowRuns represents a slice of repository action workflow run. | |||||
type WorkflowRuns struct { | |||||
TotalCount *int `json:"total_count,omitempty"` | |||||
WorkflowRuns []*WorkflowRun `json:"workflow_runs,omitempty"` | |||||
} | |||||
// ListWorkflowRunsOptions specifies optional parameters to ListWorkflowRuns. | |||||
type ListWorkflowRunsOptions struct { | |||||
Actor string `url:"actor,omitempty"` | |||||
Branch string `url:"branch,omitempty"` | |||||
Event string `url:"event,omitempty"` | |||||
Status string `url:"status,omitempty"` | |||||
ListOptions | |||||
} | |||||
// WorkflowRunUsage represents a usage of a specific workflow run. | |||||
type WorkflowRunUsage struct { | |||||
Billable *WorkflowRunEnvironment `json:"billable,omitempty"` | |||||
RunDurationMS *int64 `json:"run_duration_ms,omitempty"` | |||||
} | |||||
// WorkflowRunEnvironment represents different runner environments available for a workflow run. | |||||
type WorkflowRunEnvironment struct { | |||||
Ubuntu *WorkflowRunBill `json:"UBUNTU,omitempty"` | |||||
MacOS *WorkflowRunBill `json:"MACOS,omitempty"` | |||||
Windows *WorkflowRunBill `json:"WINDOWS,omitempty"` | |||||
} | |||||
// WorkflowRunBill specifies billable time for a specific environment in a workflow run. | |||||
type WorkflowRunBill struct { | |||||
TotalMS *int64 `json:"total_ms,omitempty"` | |||||
Jobs *int `json:"jobs,omitempty"` | |||||
} | |||||
func (s *ActionsService) listWorkflowRuns(ctx context.Context, endpoint string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { | |||||
u, err := addOptions(endpoint, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
runs := new(WorkflowRuns) | |||||
resp, err := s.client.Do(ctx, req, &runs) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return runs, resp, nil | |||||
} | |||||
// ListWorkflowRunsByID lists all workflow runs by workflow ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs | |||||
func (s *ActionsService) ListWorkflowRunsByID(ctx context.Context, owner, repo string, workflowID int64, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { | |||||
u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowID) | |||||
return s.listWorkflowRuns(ctx, u, opts) | |||||
} | |||||
// ListWorkflowRunsByFileName lists all workflow runs by workflow file name. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs | |||||
func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, repo, workflowFileName string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { | |||||
u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowFileName) | |||||
return s.listWorkflowRuns(ctx, u, opts) | |||||
} | |||||
// ListRepositoryWorkflowRuns lists all workflow runs for a repository. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#list-workflow-runs-for-a-repository | |||||
func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, repo string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) { | |||||
u := fmt.Sprintf("repos/%s/%s/actions/runs", owner, repo) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
runs := new(WorkflowRuns) | |||||
resp, err := s.client.Do(ctx, req, &runs) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return runs, resp, nil | |||||
} | |||||
// GetWorkflowRunByID gets a specific workflow run by ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#get-a-workflow-run | |||||
func (s *ActionsService) GetWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRun, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v", owner, repo, runID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
run := new(WorkflowRun) | |||||
resp, err := s.client.Do(ctx, req, run) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return run, resp, nil | |||||
} | |||||
// RerunWorkflow re-runs a workflow by ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#re-run-a-workflow | |||||
func (s *ActionsService) RerunWorkflowByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/rerun", owner, repo, runID) | |||||
req, err := s.client.NewRequest("POST", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// CancelWorkflowRunByID cancels a workflow run by ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#cancel-a-workflow-run | |||||
func (s *ActionsService) CancelWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/cancel", owner, repo, runID) | |||||
req, err := s.client.NewRequest("POST", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// GetWorkflowRunLogs gets a redirect URL to download a plain text file of logs for a workflow run. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#download-workflow-run-logs | |||||
func (s *ActionsService) GetWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64, followRedirects bool) (*url.URL, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID) | |||||
resp, err := s.getWorkflowLogsFromURL(ctx, u, followRedirects) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
if resp.StatusCode != http.StatusFound { | |||||
return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status) | |||||
} | |||||
parsedURL, err := url.Parse(resp.Header.Get("Location")) | |||||
return parsedURL, newResponse(resp), err | |||||
} | |||||
// DeleteWorkflowRunLogs deletes all logs for a workflow run. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#delete-workflow-run-logs | |||||
func (s *ActionsService) DeleteWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64) (*Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// GetWorkflowRunUsageByID gets a specific workflow usage run by run ID in the unit of billable milliseconds. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflow-runs/#get-workflow-run-usage | |||||
func (s *ActionsService) GetWorkflowRunUsageByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRunUsage, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/timing", owner, repo, runID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
workflowRunUsage := new(WorkflowRunUsage) | |||||
resp, err := s.client.Do(ctx, req, workflowRunUsage) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return workflowRunUsage, resp, nil | |||||
} |
@ -0,0 +1,138 @@ | |||||
// Copyright 2020 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
// Workflow represents a repository action workflow. | |||||
type Workflow struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
Path *string `json:"path,omitempty"` | |||||
State *string `json:"state,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
BadgeURL *string `json:"badge_url,omitempty"` | |||||
} | |||||
// Workflows represents a slice of repository action workflows. | |||||
type Workflows struct { | |||||
TotalCount *int `json:"total_count,omitempty"` | |||||
Workflows []*Workflow `json:"workflows,omitempty"` | |||||
} | |||||
// WorkflowUsage represents a usage of a specific workflow. | |||||
type WorkflowUsage struct { | |||||
Billable *WorkflowEnvironment `json:"billable,omitempty"` | |||||
} | |||||
// WorkflowEnvironment represents different runner environments available for a workflow. | |||||
type WorkflowEnvironment struct { | |||||
Ubuntu *WorkflowBill `json:"UBUNTU,omitempty"` | |||||
MacOS *WorkflowBill `json:"MACOS,omitempty"` | |||||
Windows *WorkflowBill `json:"WINDOWS,omitempty"` | |||||
} | |||||
// WorkflowBill specifies billable time for a specific environment in a workflow. | |||||
type WorkflowBill struct { | |||||
TotalMS *int64 `json:"total_ms,omitempty"` | |||||
} | |||||
// ListWorkflows lists all workflows in a repository. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#list-repository-workflows | |||||
func (s *ActionsService) ListWorkflows(ctx context.Context, owner, repo string, opts *ListOptions) (*Workflows, *Response, error) { | |||||
u := fmt.Sprintf("repos/%s/%s/actions/workflows", owner, repo) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
workflows := new(Workflows) | |||||
resp, err := s.client.Do(ctx, req, &workflows) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return workflows, resp, nil | |||||
} | |||||
// GetWorkflowByID gets a specific workflow by ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow | |||||
func (s *ActionsService) GetWorkflowByID(ctx context.Context, owner, repo string, workflowID int64) (*Workflow, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowID) | |||||
return s.getWorkflow(ctx, u) | |||||
} | |||||
// GetWorkflowByFileName gets a specific workflow by file name. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow | |||||
func (s *ActionsService) GetWorkflowByFileName(ctx context.Context, owner, repo, workflowFileName string) (*Workflow, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowFileName) | |||||
return s.getWorkflow(ctx, u) | |||||
} | |||||
func (s *ActionsService) getWorkflow(ctx context.Context, url string) (*Workflow, *Response, error) { | |||||
req, err := s.client.NewRequest("GET", url, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
workflow := new(Workflow) | |||||
resp, err := s.client.Do(ctx, req, workflow) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return workflow, resp, nil | |||||
} | |||||
// GetWorkflowUsageByID gets a specific workflow usage by ID in the unit of billable milliseconds. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage | |||||
func (s *ActionsService) GetWorkflowUsageByID(ctx context.Context, owner, repo string, workflowID int64) (*WorkflowUsage, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowID) | |||||
return s.getWorkflowUsage(ctx, u) | |||||
} | |||||
// GetWorkflowUsageByFileName gets a specific workflow usage by file name in the unit of billable milliseconds. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage | |||||
func (s *ActionsService) GetWorkflowUsageByFileName(ctx context.Context, owner, repo, workflowFileName string) (*WorkflowUsage, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowFileName) | |||||
return s.getWorkflowUsage(ctx, u) | |||||
} | |||||
func (s *ActionsService) getWorkflowUsage(ctx context.Context, url string) (*WorkflowUsage, *Response, error) { | |||||
req, err := s.client.NewRequest("GET", url, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
workflowUsage := new(WorkflowUsage) | |||||
resp, err := s.client.Do(ctx, req, workflowUsage) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return workflowUsage, resp, nil | |||||
} |
@ -0,0 +1,89 @@ | |||||
// Copyright 2019 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
// createOrgRequest is a subset of Organization and is used internally | |||||
// by CreateOrg to pass only the known fields for the endpoint. | |||||
type createOrgRequest struct { | |||||
Login *string `json:"login,omitempty"` | |||||
Admin *string `json:"admin,omitempty"` | |||||
} | |||||
// CreateOrg creates a new organization in GitHub Enterprise. | |||||
// | |||||
// Note that only a subset of the org fields are used and org must | |||||
// not be nil. | |||||
// | |||||
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#create-an-organization | |||||
func (s *AdminService) CreateOrg(ctx context.Context, org *Organization, admin string) (*Organization, *Response, error) { | |||||
u := "admin/organizations" | |||||
orgReq := &createOrgRequest{ | |||||
Login: org.Login, | |||||
Admin: &admin, | |||||
} | |||||
req, err := s.client.NewRequest("POST", u, orgReq) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
o := new(Organization) | |||||
resp, err := s.client.Do(ctx, req, o) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return o, resp, nil | |||||
} | |||||
// renameOrgRequest is a subset of Organization and is used internally | |||||
// by RenameOrg and RenameOrgByName to pass only the known fields for the endpoint. | |||||
type renameOrgRequest struct { | |||||
Login *string `json:"login,omitempty"` | |||||
} | |||||
// RenameOrgResponse is the response given when renaming an Organization. | |||||
type RenameOrgResponse struct { | |||||
Message *string `json:"message,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
} | |||||
// RenameOrg renames an organization in GitHub Enterprise. | |||||
// | |||||
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#rename-an-organization | |||||
func (s *AdminService) RenameOrg(ctx context.Context, org *Organization, newName string) (*RenameOrgResponse, *Response, error) { | |||||
return s.RenameOrgByName(ctx, *org.Login, newName) | |||||
} | |||||
// RenameOrgByName renames an organization in GitHub Enterprise using its current name. | |||||
// | |||||
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/orgs/#rename-an-organization | |||||
func (s *AdminService) RenameOrgByName(ctx context.Context, org, newName string) (*RenameOrgResponse, *Response, error) { | |||||
u := fmt.Sprintf("admin/organizations/%v", org) | |||||
orgReq := &renameOrgRequest{ | |||||
Login: &newName, | |||||
} | |||||
req, err := s.client.NewRequest("PATCH", u, orgReq) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
o := new(RenameOrgResponse) | |||||
resp, err := s.client.Do(ctx, req, o) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return o, resp, nil | |||||
} |
@ -0,0 +1,133 @@ | |||||
// Copyright 2019 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
// createUserRequest is a subset of User and is used internally | |||||
// by CreateUser to pass only the known fields for the endpoint. | |||||
type createUserRequest struct { | |||||
Login *string `json:"login,omitempty"` | |||||
Email *string `json:"email,omitempty"` | |||||
} | |||||
// CreateUser creates a new user in GitHub Enterprise. | |||||
// | |||||
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-a-new-user | |||||
func (s *AdminService) CreateUser(ctx context.Context, login, email string) (*User, *Response, error) { | |||||
u := "admin/users" | |||||
userReq := &createUserRequest{ | |||||
Login: &login, | |||||
Email: &email, | |||||
} | |||||
req, err := s.client.NewRequest("POST", u, userReq) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var user User | |||||
resp, err := s.client.Do(ctx, req, &user) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return &user, resp, nil | |||||
} | |||||
// DeleteUser deletes a user in GitHub Enterprise. | |||||
// | |||||
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-a-user | |||||
func (s *AdminService) DeleteUser(ctx context.Context, username string) (*Response, error) { | |||||
u := "admin/users/" + username | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
resp, err := s.client.Do(ctx, req, nil) | |||||
if err != nil { | |||||
return resp, err | |||||
} | |||||
return resp, nil | |||||
} | |||||
// ImpersonateUserOptions represents the scoping for the OAuth token. | |||||
type ImpersonateUserOptions struct { | |||||
Scopes []string `json:"scopes,omitempty"` | |||||
} | |||||
// OAuthAPP represents the GitHub Site Administrator OAuth app. | |||||
type OAuthAPP struct { | |||||
URL *string `json:"url,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
ClientID *string `json:"client_id,omitempty"` | |||||
} | |||||
func (s OAuthAPP) String() string { | |||||
return Stringify(s) | |||||
} | |||||
// UserAuthorization represents the impersonation response. | |||||
type UserAuthorization struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
Scopes []string `json:"scopes,omitempty"` | |||||
Token *string `json:"token,omitempty"` | |||||
TokenLastEight *string `json:"token_last_eight,omitempty"` | |||||
HashedToken *string `json:"hashed_token,omitempty"` | |||||
App *OAuthAPP `json:"app,omitempty"` | |||||
Note *string `json:"note,omitempty"` | |||||
NoteURL *string `json:"note_url,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
Fingerprint *string `json:"fingerprint,omitempty"` | |||||
} | |||||
// CreateUserImpersonation creates an impersonation OAuth token. | |||||
// | |||||
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#create-an-impersonation-oauth-token | |||||
func (s *AdminService) CreateUserImpersonation(ctx context.Context, username string, opts *ImpersonateUserOptions) (*UserAuthorization, *Response, error) { | |||||
u := fmt.Sprintf("admin/users/%s/authorizations", username) | |||||
req, err := s.client.NewRequest("POST", u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
a := new(UserAuthorization) | |||||
resp, err := s.client.Do(ctx, req, a) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return a, resp, nil | |||||
} | |||||
// DeleteUserImpersonation deletes an impersonation OAuth token. | |||||
// | |||||
// GitHub Enterprise API docs: https://developer.github.com/enterprise/v3/enterprise-admin/users/#delete-an-impersonation-oauth-token | |||||
func (s *AdminService) DeleteUserImpersonation(ctx context.Context, username string) (*Response, error) { | |||||
u := fmt.Sprintf("admin/users/%s/authorizations", username) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
resp, err := s.client.Do(ctx, req, nil) | |||||
if err != nil { | |||||
return resp, err | |||||
} | |||||
return resp, nil | |||||
} |
@ -0,0 +1,349 @@ | |||||
// Copyright 2016 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
"time" | |||||
) | |||||
// AppsService provides access to the installation related functions | |||||
// in the GitHub API. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/ | |||||
type AppsService service | |||||
// App represents a GitHub App. | |||||
type App struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
Slug *string `json:"slug,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Owner *User `json:"owner,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
Description *string `json:"description,omitempty"` | |||||
ExternalURL *string `json:"external_url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
Permissions *InstallationPermissions `json:"permissions,omitempty"` | |||||
Events []string `json:"events,omitempty"` | |||||
} | |||||
// InstallationToken represents an installation token. | |||||
type InstallationToken struct { | |||||
Token *string `json:"token,omitempty"` | |||||
ExpiresAt *time.Time `json:"expires_at,omitempty"` | |||||
Permissions *InstallationPermissions `json:"permissions,omitempty"` | |||||
Repositories []*Repository `json:"repositories,omitempty"` | |||||
} | |||||
// InstallationTokenOptions allow restricting a token's access to specific repositories. | |||||
type InstallationTokenOptions 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,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: | |||||
// https://developer.github.com/v3/apps/permissions/ | |||||
// https://developer.github.com/enterprise/v3/apps/permissions/ | |||||
type InstallationPermissions struct { | |||||
Administration *string `json:"administration,omitempty"` | |||||
Blocking *string `json:"blocking,omitempty"` | |||||
Checks *string `json:"checks,omitempty"` | |||||
Contents *string `json:"contents,omitempty"` | |||||
ContentReferences *string `json:"content_references,omitempty"` | |||||
Deployments *string `json:"deployments,omitempty"` | |||||
Emails *string `json:"emails,omitempty"` | |||||
Followers *string `json:"followers,omitempty"` | |||||
Issues *string `json:"issues,omitempty"` | |||||
Metadata *string `json:"metadata,omitempty"` | |||||
Members *string `json:"members,omitempty"` | |||||
OrganizationAdministration *string `json:"organization_administration,omitempty"` | |||||
OrganizationHooks *string `json:"organization_hooks,omitempty"` | |||||
OrganizationPlan *string `json:"organization_plan,omitempty"` | |||||
OrganizationPreReceiveHooks *string `json:"organization_pre_receive_hooks,omitempty"` | |||||
OrganizationProjects *string `json:"organization_projects,omitempty"` | |||||
OrganizationUserBlocking *string `json:"organization_user_blocking,omitempty"` | |||||
Packages *string `json:"packages,omitempty"` | |||||
Pages *string `json:"pages,omitempty"` | |||||
PullRequests *string `json:"pull_requests,omitempty"` | |||||
RepositoryHooks *string `json:"repository_hooks,omitempty"` | |||||
RepositoryProjects *string `json:"repository_projects,omitempty"` | |||||
RepositoryPreReceiveHooks *string `json:"repository_pre_receive_hooks,omitempty"` | |||||
SingleFile *string `json:"single_file,omitempty"` | |||||
Statuses *string `json:"statuses,omitempty"` | |||||
TeamDiscussions *string `json:"team_discussions,omitempty"` | |||||
VulnerabilityAlerts *string `json:"vulnerability_alerts,omitempty"` | |||||
} | |||||
// Installation represents a GitHub Apps installation. | |||||
type Installation struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
AppID *int64 `json:"app_id,omitempty"` | |||||
TargetID *int64 `json:"target_id,omitempty"` | |||||
Account *User `json:"account,omitempty"` | |||||
AccessTokensURL *string `json:"access_tokens_url,omitempty"` | |||||
RepositoriesURL *string `json:"repositories_url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
TargetType *string `json:"target_type,omitempty"` | |||||
SingleFileName *string `json:"single_file_name,omitempty"` | |||||
RepositorySelection *string `json:"repository_selection,omitempty"` | |||||
Events []string `json:"events,omitempty"` | |||||
Permissions *InstallationPermissions `json:"permissions,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
} | |||||
// Attachment represents a GitHub Apps attachment. | |||||
type Attachment struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
Title *string `json:"title,omitempty"` | |||||
Body *string `json:"body,omitempty"` | |||||
} | |||||
func (i Installation) String() string { | |||||
return Stringify(i) | |||||
} | |||||
// Get a single GitHub App. Passing the empty string will get | |||||
// the authenticated GitHub App. | |||||
// | |||||
// Note: appSlug is just the URL-friendly name of your GitHub App. | |||||
// You can find this on the settings page for your GitHub App | |||||
// (e.g., https://github.com/settings/apps/:app_slug). | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#get-the-authenticated-app | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#get-an-app | |||||
func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response, error) { | |||||
var u string | |||||
if appSlug != "" { | |||||
u = fmt.Sprintf("apps/%v", appSlug) | |||||
} else { | |||||
u = "app" | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
app := new(App) | |||||
resp, err := s.client.Do(ctx, req, app) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return app, resp, nil | |||||
} | |||||
// ListInstallations lists the installations that the current GitHub App has. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#list-installations-for-the-authenticated-app | |||||
func (s *AppsService) ListInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) { | |||||
u, err := addOptions("app/installations", opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
var i []*Installation | |||||
resp, err := s.client.Do(ctx, req, &i) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return i, resp, nil | |||||
} | |||||
// GetInstallation returns the specified installation. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#get-an-installation-for-the-authenticated-app | |||||
func (s *AppsService) GetInstallation(ctx context.Context, id int64) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("app/installations/%v", id)) | |||||
} | |||||
// ListUserInstallations lists installations that are accessible to the authenticated user. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/installations/#list-app-installations-accessible-to-the-user-access-token | |||||
func (s *AppsService) ListUserInstallations(ctx context.Context, opts *ListOptions) ([]*Installation, *Response, error) { | |||||
u, err := addOptions("user/installations", opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
var i struct { | |||||
Installations []*Installation `json:"installations"` | |||||
} | |||||
resp, err := s.client.Do(ctx, req, &i) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return i.Installations, resp, nil | |||||
} | |||||
// SuspendInstallation suspends the specified installation. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#suspend-an-app-installation | |||||
func (s *AppsService) SuspendInstallation(ctx context.Context, id int64) (*Response, error) { | |||||
u := fmt.Sprintf("app/installations/%v/suspended", id) | |||||
req, err := s.client.NewRequest("PUT", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// UnsuspendInstallation unsuspends the specified installation. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#unsuspend-an-app-installation | |||||
func (s *AppsService) UnsuspendInstallation(ctx context.Context, id int64) (*Response, error) { | |||||
u := fmt.Sprintf("app/installations/%v/suspended", id) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// DeleteInstallation deletes the specified installation. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#delete-an-installation-for-the-authenticated-app | |||||
func (s *AppsService) DeleteInstallation(ctx context.Context, id int64) (*Response, error) { | |||||
u := fmt.Sprintf("app/installations/%v", id) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// CreateInstallationToken creates a new installation token. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#create-an-installation-access-token-for-an-app | |||||
func (s *AppsService) CreateInstallationToken(ctx context.Context, id int64, opts *InstallationTokenOptions) (*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 | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
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://developer.github.com/v3/apps/installations/#create-a-content-attachment | |||||
func (s *AppsService) CreateAttachment(ctx context.Context, contentReferenceID int64, title, body string) (*Attachment, *Response, error) { | |||||
u := fmt.Sprintf("content_references/%v/attachments", contentReferenceID) | |||||
payload := &Attachment{Title: String(title), Body: String(body)} | |||||
req, err := s.client.NewRequest("POST", u, payload) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept headers when APIs fully launch. | |||||
req.Header.Set("Accept", mediaTypeReactionsPreview) | |||||
m := &Attachment{} | |||||
resp, err := s.client.Do(ctx, req, m) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return m, resp, nil | |||||
} | |||||
// FindOrganizationInstallation finds the organization's installation information. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#get-an-organization-installation-for-the-authenticated-app | |||||
func (s *AppsService) FindOrganizationInstallation(ctx context.Context, org string) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("orgs/%v/installation", org)) | |||||
} | |||||
// FindRepositoryInstallation finds the repository's installation information. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#get-a-repository-installation-for-the-authenticated-app | |||||
func (s *AppsService) FindRepositoryInstallation(ctx context.Context, owner, repo string) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("repos/%v/%v/installation", owner, repo)) | |||||
} | |||||
// FindRepositoryInstallationByID finds the repository's installation information. | |||||
// | |||||
// Note: FindRepositoryInstallationByID uses the undocumented GitHub API endpoint /repositories/:id/installation. | |||||
func (s *AppsService) FindRepositoryInstallationByID(ctx context.Context, id int64) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("repositories/%d/installation", id)) | |||||
} | |||||
// FindUserInstallation finds the user's installation information. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#get-a-user-installation-for-the-authenticated-app | |||||
func (s *AppsService) FindUserInstallation(ctx context.Context, user string) (*Installation, *Response, error) { | |||||
return s.getInstallation(ctx, fmt.Sprintf("users/%v/installation", user)) | |||||
} | |||||
func (s *AppsService) getInstallation(ctx context.Context, url string) (*Installation, *Response, error) { | |||||
req, err := s.client.NewRequest("GET", url, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
req.Header.Set("Accept", mediaTypeIntegrationPreview) | |||||
i := new(Installation) | |||||
resp, err := s.client.Do(ctx, req, i) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return i, resp, nil | |||||
} |
@ -0,0 +1,53 @@ | |||||
// Copyright 2019 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
const ( | |||||
mediaTypeAppManifestPreview = "application/vnd.github.fury-preview+json" | |||||
) | |||||
// AppConfig describes the configuration of a GitHub App. | |||||
type AppConfig struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Owner *User `json:"owner,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
Description *string `json:"description,omitempty"` | |||||
ExternalURL *string `json:"external_url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
ClientID *string `json:"client_id,omitempty"` | |||||
ClientSecret *string `json:"client_secret,omitempty"` | |||||
WebhookSecret *string `json:"webhook_secret,omitempty"` | |||||
PEM *string `json:"pem,omitempty"` | |||||
} | |||||
// CompleteAppManifest completes the App manifest handshake flow for the given | |||||
// code. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/apps/#create-a-github-app-from-a-manifest | |||||
func (s *AppsService) CompleteAppManifest(ctx context.Context, code string) (*AppConfig, *Response, error) { | |||||
u := fmt.Sprintf("app-manifests/%s/conversions", code) | |||||
req, err := s.client.NewRequest("POST", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req.Header.Set("Accept", mediaTypeAppManifestPreview) | |||||
cfg := new(AppConfig) | |||||
resp, err := s.client.Do(ctx, req, cfg) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return cfg, resp, nil | |||||
} |
@ -0,0 +1,117 @@ | |||||
// Copyright 2020 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
"strconv" | |||||
"strings" | |||||
) | |||||
// CodeScanningService handles communication with the code scanning related | |||||
// methods of the GitHub API. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/code-scanning/ | |||||
type CodeScanningService service | |||||
type Alert struct { | |||||
RuleID *string `json:"rule_id,omitempty"` | |||||
RuleSeverity *string `json:"rule_severity,omitempty"` | |||||
RuleDescription *string `json:"rule_description,omitempty"` | |||||
Tool *string `json:"tool,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
Open *bool `json:"open,omitempty"` | |||||
ClosedBy *User `json:"closed_by,omitempty"` | |||||
ClosedAt *Timestamp `json:"closed_at,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
} | |||||
// ID returns the ID associated with an alert. It is the number at the end of the security alert's URL. | |||||
func (a *Alert) ID() int64 { | |||||
if a == nil { | |||||
return 0 | |||||
} | |||||
s := a.GetHTMLURL() | |||||
// Check for an ID to parse at the end of the url | |||||
if i := strings.LastIndex(s, "/"); i >= 0 { | |||||
s = s[i+1:] | |||||
} | |||||
// Return the alert ID as a 64-bit integer. Unable to convert or out of range returns 0. | |||||
id, err := strconv.ParseInt(s, 10, 64) | |||||
if err != nil { | |||||
return 0 | |||||
} | |||||
return id | |||||
} | |||||
// AlertListOptions specifies optional parameters to the CodeScanningService.ListAlerts | |||||
// method. | |||||
type AlertListOptions struct { | |||||
// State of the code scanning alerts to list. Set to closed to list only closed code scanning alerts. Default: open | |||||
State string `url:"state,omitempty"` | |||||
// Return code scanning alerts for a specific branch reference. The ref must be formatted as heads/<branch name>. | |||||
Ref string `url:"ref,omitempty"` | |||||
} | |||||
// ListAlertsForRepo lists code scanning alerts for a repository. | |||||
// | |||||
// Lists all open code scanning alerts for the default branch (usually master) and protected branches in a repository. | |||||
// You must use an access token with the security_events scope to use this endpoint. GitHub Apps must have the security_events | |||||
// read permission to use this endpoint. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/code-scanning/#list-code-scanning-alerts-for-a-repository | |||||
func (s *CodeScanningService) ListAlertsForRepo(ctx context.Context, owner, repo string, opts *AlertListOptions) ([]*Alert, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts", owner, repo) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var alerts []*Alert | |||||
resp, err := s.client.Do(ctx, req, &alerts) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return alerts, resp, nil | |||||
} | |||||
// GetAlert gets a single code scanning alert for a repository. | |||||
// | |||||
// You must use an access token with the security_events scope to use this endpoint. | |||||
// GitHub Apps must have the security_events read permission to use this endpoint. | |||||
// | |||||
// The security alert_id is the number at the end of the security alert's URL. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/code-scanning/#get-a-code-scanning-alert | |||||
func (s *CodeScanningService) GetAlert(ctx context.Context, owner, repo string, id int64) (*Alert, *Response, error) { | |||||
u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts/%v", owner, repo, id) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
a := new(Alert) | |||||
resp, err := s.client.Do(ctx, req, a) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return a, resp, nil | |||||
} |
@ -0,0 +1,101 @@ | |||||
// Copyright 2020 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
// Package represents a GitHub package. | |||||
type Package struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
PackageType *string `json:"package_type,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
Owner *User `json:"owner,omitempty"` | |||||
PackageVersion *PackageVersion `json:"package_version,omitempty"` | |||||
Registry *PackageRegistry `json:"registry,omitempty"` | |||||
} | |||||
func (p Package) String() string { | |||||
return Stringify(p) | |||||
} | |||||
// PackageVersion represents a GitHub package version. | |||||
type PackageVersion struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
Version *string `json:"version,omitempty"` | |||||
Summary *string `json:"summary,omitempty"` | |||||
Body *string `json:"body,omitempty"` | |||||
BodyHTML *string `json:"body_html,omitempty"` | |||||
Release *PackageRelease `json:"release,omitempty"` | |||||
Manifest *string `json:"manifest,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
TagName *string `json:"tag_name,omitempty"` | |||||
TargetCommitish *string `json:"target_commitish,omitempty"` | |||||
TargetOID *string `json:"target_oid,omitempty"` | |||||
Draft *bool `json:"draft,omitempty"` | |||||
Prerelease *bool `json:"prerelease,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
PackageFiles []*PackageFile `json:"package_files,omitempty"` | |||||
Author *User `json:"author,omitempty"` | |||||
InstallationCommand *string `json:"installation_command,omitempty"` | |||||
} | |||||
func (pv PackageVersion) String() string { | |||||
return Stringify(pv) | |||||
} | |||||
// PackageRelease represents a GitHub package version release. | |||||
type PackageRelease struct { | |||||
URL *string `json:"url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
ID *int64 `json:"id,omitempty"` | |||||
TagName *string `json:"tag_name,omitempty"` | |||||
TargetCommitish *string `json:"target_commitish,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
Draft *bool `json:"draft,omitempty"` | |||||
Author *User `json:"author,omitempty"` | |||||
Prerelease *bool `json:"prerelease,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
PublishedAt *Timestamp `json:"published_at,omitempty"` | |||||
} | |||||
func (r PackageRelease) String() string { | |||||
return Stringify(r) | |||||
} | |||||
// PackageFile represents a GitHub package version release file. | |||||
type PackageFile struct { | |||||
DownloadURL *string `json:"download_url,omitempty"` | |||||
ID *int64 `json:"id,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
SHA256 *string `json:"sha256,omitempty"` | |||||
SHA1 *string `json:"sha1,omitempty"` | |||||
MD5 *string `json:"md5,omitempty"` | |||||
ContentType *string `json:"content_type,omitempty"` | |||||
State *string `json:"state,omitempty"` | |||||
Author *User `json:"author,omitempty"` | |||||
Size *int64 `json:"size,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
} | |||||
func (pf PackageFile) String() string { | |||||
return Stringify(pf) | |||||
} | |||||
// PackageRegistry represents a GitHub package registry. | |||||
type PackageRegistry struct { | |||||
AboutURL *string `json:"about_url,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
Type *string `json:"type,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
Vendor *string `json:"vendor,omitempty"` | |||||
} | |||||
func (r PackageRegistry) String() string { | |||||
return Stringify(r) | |||||
} |
@ -0,0 +1,850 @@ | |||||
// Copyright 2018 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
"net/http" | |||||
"strings" | |||||
"time" | |||||
) | |||||
// TeamsService provides access to the team-related functions | |||||
// in the GitHub API. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/ | |||||
type TeamsService service | |||||
// Team represents a team within a GitHub organization. Teams are used to | |||||
// manage access to an organization's repositories. | |||||
type Team struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Name *string `json:"name,omitempty"` | |||||
Description *string `json:"description,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
Slug *string `json:"slug,omitempty"` | |||||
// Permission specifies the default permission for repositories owned by the team. | |||||
Permission *string `json:"permission,omitempty"` | |||||
// Privacy identifies the level of privacy this team should have. | |||||
// Possible values are: | |||||
// secret - only visible to organization owners and members of this team | |||||
// closed - visible to all members of this organization | |||||
// Default is "secret". | |||||
Privacy *string `json:"privacy,omitempty"` | |||||
MembersCount *int `json:"members_count,omitempty"` | |||||
ReposCount *int `json:"repos_count,omitempty"` | |||||
Organization *Organization `json:"organization,omitempty"` | |||||
MembersURL *string `json:"members_url,omitempty"` | |||||
RepositoriesURL *string `json:"repositories_url,omitempty"` | |||||
Parent *Team `json:"parent,omitempty"` | |||||
// LDAPDN is only available in GitHub Enterprise and when the team | |||||
// membership is synchronized with LDAP. | |||||
LDAPDN *string `json:"ldap_dn,omitempty"` | |||||
} | |||||
func (t Team) String() string { | |||||
return Stringify(t) | |||||
} | |||||
// Invitation represents a team member's invitation status. | |||||
type Invitation struct { | |||||
ID *int64 `json:"id,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Login *string `json:"login,omitempty"` | |||||
Email *string `json:"email,omitempty"` | |||||
// Role can be one of the values - 'direct_member', 'admin', 'billing_manager', 'hiring_manager', or 'reinstate'. | |||||
Role *string `json:"role,omitempty"` | |||||
CreatedAt *time.Time `json:"created_at,omitempty"` | |||||
Inviter *User `json:"inviter,omitempty"` | |||||
TeamCount *int `json:"team_count,omitempty"` | |||||
InvitationTeamURL *string `json:"invitation_team_url,omitempty"` | |||||
} | |||||
func (i Invitation) String() string { | |||||
return Stringify(i) | |||||
} | |||||
// ListTeams lists all of the teams for an organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-teams | |||||
func (s *TeamsService) ListTeams(ctx context.Context, org string, opts *ListOptions) ([]*Team, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams", org) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var teams []*Team | |||||
resp, err := s.client.Do(ctx, req, &teams) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teams, resp, nil | |||||
} | |||||
// GetTeamByID fetches a team, given a specified organization ID, by ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#get-a-team-by-name | |||||
func (s *TeamsService) GetTeamByID(ctx context.Context, orgID, teamID int64) (*Team, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
t := new(Team) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// GetTeamBySlug fetches a team, given a specified organization name, by slug. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#get-a-team-by-name | |||||
func (s *TeamsService) GetTeamBySlug(ctx context.Context, org, slug string) (*Team, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
t := new(Team) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// NewTeam represents a team to be created or modified. | |||||
type NewTeam struct { | |||||
Name string `json:"name"` // Name of the team. (Required.) | |||||
Description *string `json:"description,omitempty"` | |||||
Maintainers []string `json:"maintainers,omitempty"` | |||||
RepoNames []string `json:"repo_names,omitempty"` | |||||
ParentTeamID *int64 `json:"parent_team_id,omitempty"` | |||||
// Deprecated: Permission is deprecated when creating or editing a team in an org | |||||
// using the new GitHub permission model. It no longer identifies the | |||||
// permission a team has on its repos, but only specifies the default | |||||
// permission a repo is initially added with. Avoid confusion by | |||||
// specifying a permission value when calling AddTeamRepo. | |||||
Permission *string `json:"permission,omitempty"` | |||||
// Privacy identifies the level of privacy this team should have. | |||||
// Possible values are: | |||||
// secret - only visible to organization owners and members of this team | |||||
// closed - visible to all members of this organization | |||||
// Default is "secret". | |||||
Privacy *string `json:"privacy,omitempty"` | |||||
// LDAPDN may be used in GitHub Enterprise when the team membership | |||||
// is synchronized with LDAP. | |||||
LDAPDN *string `json:"ldap_dn,omitempty"` | |||||
} | |||||
func (s NewTeam) String() string { | |||||
return Stringify(s) | |||||
} | |||||
// CreateTeam creates a new team within an organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#create-a-team | |||||
func (s *TeamsService) CreateTeam(ctx context.Context, org string, team NewTeam) (*Team, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams", org) | |||||
req, err := s.client.NewRequest("POST", u, team) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
t := new(Team) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// newTeamNoParent is the same as NewTeam but ensures that the | |||||
// "parent_team_id" field will be null. It is for internal use | |||||
// only and should not be exported. | |||||
type newTeamNoParent struct { | |||||
Name string `json:"name"` | |||||
Description *string `json:"description,omitempty"` | |||||
Maintainers []string `json:"maintainers,omitempty"` | |||||
RepoNames []string `json:"repo_names,omitempty"` | |||||
ParentTeamID *int64 `json:"parent_team_id"` // This will be "null" | |||||
Privacy *string `json:"privacy,omitempty"` | |||||
LDAPDN *string `json:"ldap_dn,omitempty"` | |||||
} | |||||
// copyNewTeamWithoutParent is used to set the "parent_team_id" | |||||
// field to "null" after copying the other fields from a NewTeam. | |||||
// It is for internal use only and should not be exported. | |||||
func copyNewTeamWithoutParent(team *NewTeam) *newTeamNoParent { | |||||
return &newTeamNoParent{ | |||||
Name: team.Name, | |||||
Description: team.Description, | |||||
Maintainers: team.Maintainers, | |||||
RepoNames: team.RepoNames, | |||||
Privacy: team.Privacy, | |||||
LDAPDN: team.LDAPDN, | |||||
} | |||||
} | |||||
// EditTeamByID edits a team, given an organization ID, selected by ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#update-a-team | |||||
func (s *TeamsService) EditTeamByID(ctx context.Context, orgID, teamID int64, team NewTeam, removeParent bool) (*Team, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) | |||||
var req *http.Request | |||||
var err error | |||||
if removeParent { | |||||
teamRemoveParent := copyNewTeamWithoutParent(&team) | |||||
req, err = s.client.NewRequest("PATCH", u, teamRemoveParent) | |||||
} else { | |||||
req, err = s.client.NewRequest("PATCH", u, team) | |||||
} | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
t := new(Team) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// EditTeamBySlug edits a team, given an organization name, by slug. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#update-a-team | |||||
func (s *TeamsService) EditTeamBySlug(ctx context.Context, org, slug string, team NewTeam, removeParent bool) (*Team, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) | |||||
var req *http.Request | |||||
var err error | |||||
if removeParent { | |||||
teamRemoveParent := copyNewTeamWithoutParent(&team) | |||||
req, err = s.client.NewRequest("PATCH", u, teamRemoveParent) | |||||
} else { | |||||
req, err = s.client.NewRequest("PATCH", u, team) | |||||
} | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
t := new(Team) | |||||
resp, err := s.client.Do(ctx, req, t) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return t, resp, nil | |||||
} | |||||
// DeleteTeamByID deletes a team referenced by ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#delete-a-team | |||||
func (s *TeamsService) DeleteTeamByID(ctx context.Context, orgID, teamID int64) (*Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v", orgID, teamID) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// DeleteTeamBySlug deletes a team reference by slug. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#delete-a-team | |||||
func (s *TeamsService) DeleteTeamBySlug(ctx context.Context, org, slug string) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v", org, slug) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// ListChildTeamsByParentID lists child teams for a parent team given parent ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams | |||||
func (s *TeamsService) ListChildTeamsByParentID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Team, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/teams", orgID, teamID) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var teams []*Team | |||||
resp, err := s.client.Do(ctx, req, &teams) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teams, resp, nil | |||||
} | |||||
// ListChildTeamsByParentSlug lists child teams for a parent team given parent slug. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-child-teams | |||||
func (s *TeamsService) ListChildTeamsByParentSlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Team, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/teams", org, slug) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var teams []*Team | |||||
resp, err := s.client.Do(ctx, req, &teams) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teams, resp, nil | |||||
} | |||||
// ListTeamReposByID lists the repositories given a team ID that the specified team has access to. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repositories | |||||
func (s *TeamsService) ListTeamReposByID(ctx context.Context, orgID, teamID int64, opts *ListOptions) ([]*Repository, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/repos", orgID, teamID) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when topics API fully launches. | |||||
headers := []string{mediaTypeTopicsPreview} | |||||
req.Header.Set("Accept", strings.Join(headers, ", ")) | |||||
var repos []*Repository | |||||
resp, err := s.client.Do(ctx, req, &repos) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return repos, resp, nil | |||||
} | |||||
// ListTeamReposBySlug lists the repositories given a team slug that the specified team has access to. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-team-repositories | |||||
func (s *TeamsService) ListTeamReposBySlug(ctx context.Context, org, slug string, opts *ListOptions) ([]*Repository, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/repos", org, slug) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when topics API fully launches. | |||||
headers := []string{mediaTypeTopicsPreview} | |||||
req.Header.Set("Accept", strings.Join(headers, ", ")) | |||||
var repos []*Repository | |||||
resp, err := s.client.Do(ctx, req, &repos) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return repos, resp, nil | |||||
} | |||||
// IsTeamRepoByID checks if a team, given its ID, manages the specified repository. If the | |||||
// repository is managed by team, a Repository is returned which includes the | |||||
// permissions team has for that repo. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-repository | |||||
func (s *TeamsService) IsTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Repository, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
headers := []string{mediaTypeOrgPermissionRepo} | |||||
req.Header.Set("Accept", strings.Join(headers, ", ")) | |||||
repository := new(Repository) | |||||
resp, err := s.client.Do(ctx, req, repository) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return repository, resp, nil | |||||
} | |||||
// IsTeamRepoBySlug checks if a team, given its slug, manages the specified repository. If the | |||||
// repository is managed by team, a Repository is returned which includes the | |||||
// permissions team has for that repo. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-repository | |||||
func (s *TeamsService) IsTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Repository, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
headers := []string{mediaTypeOrgPermissionRepo} | |||||
req.Header.Set("Accept", strings.Join(headers, ", ")) | |||||
repository := new(Repository) | |||||
resp, err := s.client.Do(ctx, req, repository) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return repository, resp, nil | |||||
} | |||||
// TeamAddTeamRepoOptions specifies the optional parameters to the | |||||
// TeamsService.AddTeamRepo method. | |||||
type TeamAddTeamRepoOptions struct { | |||||
// Permission specifies the permission to grant the team on this repository. | |||||
// Possible values are: | |||||
// pull - team members can pull, but not push to or administer this repository | |||||
// push - team members can pull and push, but not administer this repository | |||||
// admin - team members can pull, push and administer this repository | |||||
// maintain - team members can manage the repository without access to sensitive or destructive actions. | |||||
// triage - team members can proactively manage issues and pull requests without write access. | |||||
// | |||||
// If not specified, the team's permission attribute will be used. | |||||
Permission string `json:"permission,omitempty"` | |||||
} | |||||
// AddTeamRepoByID adds a repository to be managed by the specified team given the team ID. | |||||
// The specified repository must be owned by the organization to which the team | |||||
// belongs, or a direct fork of a repository owned by the organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository-permissions | |||||
func (s *TeamsService) AddTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) | |||||
req, err := s.client.NewRequest("PUT", u, opts) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// AddTeamRepoBySlug adds a repository to be managed by the specified team given the team slug. | |||||
// The specified repository must be owned by the organization to which the team | |||||
// belongs, or a direct fork of a repository owned by the organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-repository-permissions | |||||
func (s *TeamsService) AddTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string, opts *TeamAddTeamRepoOptions) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) | |||||
req, err := s.client.NewRequest("PUT", u, opts) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// RemoveTeamRepoByID removes a repository from being managed by the specified | |||||
// team given the team ID. Note that this does not delete the repository, it | |||||
// just removes it from the team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-repository-from-a-team | |||||
func (s *TeamsService) RemoveTeamRepoByID(ctx context.Context, orgID, teamID int64, owner, repo string) (*Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/repos/%v/%v", orgID, teamID, owner, repo) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// RemoveTeamRepoBySlug removes a repository from being managed by the specified | |||||
// team given the team slug. Note that this does not delete the repository, it | |||||
// just removes it from the team. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-repository-from-a-team | |||||
func (s *TeamsService) RemoveTeamRepoBySlug(ctx context.Context, org, slug, owner, repo string) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/repos/%v/%v", org, slug, owner, repo) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// ListUserTeams lists a user's teams | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-teams-for-the-authenticated-user | |||||
func (s *TeamsService) ListUserTeams(ctx context.Context, opts *ListOptions) ([]*Team, *Response, error) { | |||||
u := "user/teams" | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var teams []*Team | |||||
resp, err := s.client.Do(ctx, req, &teams) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return teams, resp, nil | |||||
} | |||||
// ListTeamProjectsByID lists the organization projects for a team given the team ID. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects | |||||
func (s *TeamsService) ListTeamProjectsByID(ctx context.Context, orgID, teamID int64) ([]*Project, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/projects", orgID, teamID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
var projects []*Project | |||||
resp, err := s.client.Do(ctx, req, &projects) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return projects, resp, nil | |||||
} | |||||
// ListTeamProjectsBySlug lists the organization projects for a team given the team slug. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#list-team-projects | |||||
func (s *TeamsService) ListTeamProjectsBySlug(ctx context.Context, org, slug string) ([]*Project, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/projects", org, slug) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
var projects []*Project | |||||
resp, err := s.client.Do(ctx, req, &projects) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return projects, resp, nil | |||||
} | |||||
// ReviewTeamProjectsByID checks whether a team, given its ID, has read, write, or admin | |||||
// permissions for an organization project. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-project | |||||
func (s *TeamsService) ReviewTeamProjectsByID(ctx context.Context, orgID, teamID, projectID int64) (*Project, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
projects := &Project{} | |||||
resp, err := s.client.Do(ctx, req, &projects) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return projects, resp, nil | |||||
} | |||||
// ReviewTeamProjectsBySlug checks whether a team, given its slug, has read, write, or admin | |||||
// permissions for an organization project. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#check-team-permissions-for-a-project | |||||
func (s *TeamsService) ReviewTeamProjectsBySlug(ctx context.Context, org, slug string, projectID int64) (*Project, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
projects := &Project{} | |||||
resp, err := s.client.Do(ctx, req, &projects) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return projects, resp, nil | |||||
} | |||||
// TeamProjectOptions specifies the optional parameters to the | |||||
// TeamsService.AddTeamProject method. | |||||
type TeamProjectOptions struct { | |||||
// Permission specifies the permission to grant to the team for this project. | |||||
// Possible values are: | |||||
// "read" - team members can read, but not write to or administer this project. | |||||
// "write" - team members can read and write, but not administer this project. | |||||
// "admin" - team members can read, write and administer this project. | |||||
// | |||||
Permission *string `json:"permission,omitempty"` | |||||
} | |||||
// AddTeamProjectByID adds an organization project to a team given the team ID. | |||||
// To add a project to a team or update the team's permission on a project, the | |||||
// authenticated user must have admin permissions for the project. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project-permissions | |||||
func (s *TeamsService) AddTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64, opts *TeamProjectOptions) (*Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) | |||||
req, err := s.client.NewRequest("PUT", u, opts) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// AddTeamProjectBySlug adds an organization project to a team given the team slug. | |||||
// To add a project to a team or update the team's permission on a project, the | |||||
// authenticated user must have admin permissions for the project. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#add-or-update-team-project-permissions | |||||
func (s *TeamsService) AddTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64, opts *TeamProjectOptions) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) | |||||
req, err := s.client.NewRequest("PUT", u, opts) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// RemoveTeamProjectByID removes an organization project from a team given team ID. | |||||
// An organization owner or a team maintainer can remove any project from the team. | |||||
// To remove a project from a team as an organization member, the authenticated user | |||||
// must have "read" access to both the team and project, or "admin" access to the team | |||||
// or project. | |||||
// Note: This endpoint removes the project from the team, but does not delete it. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-project-from-a-team | |||||
func (s *TeamsService) RemoveTeamProjectByID(ctx context.Context, orgID, teamID, projectID int64) (*Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/projects/%v", orgID, teamID, projectID) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// RemoveTeamProjectBySlug removes an organization project from a team given team slug. | |||||
// An organization owner or a team maintainer can remove any project from the team. | |||||
// To remove a project from a team as an organization member, the authenticated user | |||||
// must have "read" access to both the team and project, or "admin" access to the team | |||||
// or project. | |||||
// Note: This endpoint removes the project from the team, but does not delete it. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/#remove-a-project-from-a-team | |||||
func (s *TeamsService) RemoveTeamProjectBySlug(ctx context.Context, org, slug string, projectID int64) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/projects/%v", org, slug, projectID) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
// TODO: remove custom Accept header when this API fully launches. | |||||
acceptHeaders := []string{mediaTypeProjectsPreview} | |||||
req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// IDPGroupList represents a list of external identity provider (IDP) groups. | |||||
type IDPGroupList struct { | |||||
Groups []*IDPGroup `json:"groups"` | |||||
} | |||||
// IDPGroup represents an external identity provider (IDP) group. | |||||
type IDPGroup struct { | |||||
GroupID *string `json:"group_id,omitempty"` | |||||
GroupName *string `json:"group_name,omitempty"` | |||||
GroupDescription *string `json:"group_description,omitempty"` | |||||
} | |||||
// ListIDPGroupsInOrganization lists IDP groups available in an organization. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-an-organization | |||||
func (s *TeamsService) ListIDPGroupsInOrganization(ctx context.Context, org string, opts *ListCursorOptions) (*IDPGroupList, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/team-sync/groups", org) | |||||
u, err := addOptions(u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
groups := new(IDPGroupList) | |||||
resp, err := s.client.Do(ctx, req, groups) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return groups, resp, nil | |||||
} | |||||
// ListIDPGroupsForTeamByID lists IDP groups connected to a team on GitHub | |||||
// given organization and team IDs. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-a-team | |||||
func (s *TeamsService) ListIDPGroupsForTeamByID(ctx context.Context, orgID, teamID int64) (*IDPGroupList, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/team-sync/group-mappings", orgID, teamID) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
groups := new(IDPGroupList) | |||||
resp, err := s.client.Do(ctx, req, groups) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return groups, resp, err | |||||
} | |||||
// ListIDPGroupsForTeamBySlug lists IDP groups connected to a team on GitHub | |||||
// given organization name and team slug. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#list-idp-groups-for-a-team | |||||
func (s *TeamsService) ListIDPGroupsForTeamBySlug(ctx context.Context, org, slug string) (*IDPGroupList, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/team-sync/group-mappings", org, slug) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
groups := new(IDPGroupList) | |||||
resp, err := s.client.Do(ctx, req, groups) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return groups, resp, err | |||||
} | |||||
// CreateOrUpdateIDPGroupConnectionsByID creates, updates, or removes a connection | |||||
// between a team and an IDP group given organization and team IDs. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#create-or-update-idp-group-connections | |||||
func (s *TeamsService) CreateOrUpdateIDPGroupConnectionsByID(ctx context.Context, orgID, teamID int64, opts IDPGroupList) (*IDPGroupList, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/team-sync/group-mappings", orgID, teamID) | |||||
req, err := s.client.NewRequest("PATCH", u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
groups := new(IDPGroupList) | |||||
resp, err := s.client.Do(ctx, req, groups) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return groups, resp, nil | |||||
} | |||||
// CreateOrUpdateIDPGroupConnectionsBySlug creates, updates, or removes a connection | |||||
// between a team and an IDP group given organization name and team slug. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/team_sync/#create-or-update-idp-group-connections | |||||
func (s *TeamsService) CreateOrUpdateIDPGroupConnectionsBySlug(ctx context.Context, org, slug string, opts IDPGroupList) (*IDPGroupList, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/team-sync/group-mappings", org, slug) | |||||
req, err := s.client.NewRequest("PATCH", u, opts) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
groups := new(IDPGroupList) | |||||
resp, err := s.client.Do(ctx, req, groups) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return groups, resp, nil | |||||
} |
@ -0,0 +1,242 @@ | |||||
// Copyright 2018 The go-github AUTHORS. All rights reserved. | |||||
// | |||||
// Use of this source code is governed by a BSD-style | |||||
// license that can be found in the LICENSE file. | |||||
package github | |||||
import ( | |||||
"context" | |||||
"fmt" | |||||
) | |||||
// DiscussionComment represents a GitHub dicussion in a team. | |||||
type DiscussionComment struct { | |||||
Author *User `json:"author,omitempty"` | |||||
Body *string `json:"body,omitempty"` | |||||
BodyHTML *string `json:"body_html,omitempty"` | |||||
BodyVersion *string `json:"body_version,omitempty"` | |||||
CreatedAt *Timestamp `json:"created_at,omitempty"` | |||||
LastEditedAt *Timestamp `json:"last_edited_at,omitempty"` | |||||
DiscussionURL *string `json:"discussion_url,omitempty"` | |||||
HTMLURL *string `json:"html_url,omitempty"` | |||||
NodeID *string `json:"node_id,omitempty"` | |||||
Number *int `json:"number,omitempty"` | |||||
UpdatedAt *Timestamp `json:"updated_at,omitempty"` | |||||
URL *string `json:"url,omitempty"` | |||||
Reactions *Reactions `json:"reactions,omitempty"` | |||||
} | |||||
func (c DiscussionComment) String() string { | |||||
return Stringify(c) | |||||
} | |||||
// DiscussionCommentListOptions specifies optional parameters to the | |||||
// TeamServices.ListComments method. | |||||
type DiscussionCommentListOptions struct { | |||||
// Sorts the discussion comments by the date they were created. | |||||
// Accepted values are asc and desc. Default is desc. | |||||
Direction string `url:"direction,omitempty"` | |||||
ListOptions | |||||
} | |||||
// ListCommentsByID lists all comments on a team discussion by team ID. | |||||
// Authenticated user must grant read:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-discussion-comments | |||||
func (s *TeamsService) ListCommentsByID(ctx context.Context, orgID, teamID int64, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments", orgID, teamID, discussionNumber) | |||||
u, err := addOptions(u, options) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var comments []*DiscussionComment | |||||
resp, err := s.client.Do(ctx, req, &comments) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return comments, resp, nil | |||||
} | |||||
// ListCommentsBySlug lists all comments on a team discussion by team slug. | |||||
// Authenticated user must grant read:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#list-discussion-comments | |||||
func (s *TeamsService) ListCommentsBySlug(ctx context.Context, org, slug string, discussionNumber int, options *DiscussionCommentListOptions) ([]*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments", org, slug, discussionNumber) | |||||
u, err := addOptions(u, options) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
var comments []*DiscussionComment | |||||
resp, err := s.client.Do(ctx, req, &comments) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return comments, resp, nil | |||||
} | |||||
// GetCommentByID gets a specific comment on a team discussion by team ID. | |||||
// Authenticated user must grant read:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-discussion-comment | |||||
func (s *TeamsService) GetCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
discussionComment := &DiscussionComment{} | |||||
resp, err := s.client.Do(ctx, req, discussionComment) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return discussionComment, resp, nil | |||||
} | |||||
// GetCommentBySlug gets a specific comment on a team discussion by team slug. | |||||
// Authenticated user must grant read:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#get-a-discussion-comment | |||||
func (s *TeamsService) GetCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int) (*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) | |||||
req, err := s.client.NewRequest("GET", u, nil) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
discussionComment := &DiscussionComment{} | |||||
resp, err := s.client.Do(ctx, req, discussionComment) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return discussionComment, resp, nil | |||||
} | |||||
// CreateCommentByID creates a new comment on a team discussion by team ID. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-discussion-comment | |||||
func (s *TeamsService) CreateCommentByID(ctx context.Context, orgID, teamID int64, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments", orgID, teamID, discsusionNumber) | |||||
req, err := s.client.NewRequest("POST", u, comment) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
discussionComment := &DiscussionComment{} | |||||
resp, err := s.client.Do(ctx, req, discussionComment) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return discussionComment, resp, nil | |||||
} | |||||
// CreateCommentBySlug creates a new comment on a team discussion by team slug. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#create-a-discussion-comment | |||||
func (s *TeamsService) CreateCommentBySlug(ctx context.Context, org, slug string, discsusionNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments", org, slug, discsusionNumber) | |||||
req, err := s.client.NewRequest("POST", u, comment) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
discussionComment := &DiscussionComment{} | |||||
resp, err := s.client.Do(ctx, req, discussionComment) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return discussionComment, resp, nil | |||||
} | |||||
// EditCommentByID edits the body text of a discussion comment by team ID. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// User is allowed to edit body of a comment only. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#update-a-discussion-comment | |||||
func (s *TeamsService) EditCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) | |||||
req, err := s.client.NewRequest("PATCH", u, comment) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
discussionComment := &DiscussionComment{} | |||||
resp, err := s.client.Do(ctx, req, discussionComment) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return discussionComment, resp, nil | |||||
} | |||||
// EditCommentBySlug edits the body text of a discussion comment by team slug. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// User is allowed to edit body of a comment only. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#update-a-discussion-comment | |||||
func (s *TeamsService) EditCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int, comment DiscussionComment) (*DiscussionComment, *Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) | |||||
req, err := s.client.NewRequest("PATCH", u, comment) | |||||
if err != nil { | |||||
return nil, nil, err | |||||
} | |||||
discussionComment := &DiscussionComment{} | |||||
resp, err := s.client.Do(ctx, req, discussionComment) | |||||
if err != nil { | |||||
return nil, resp, err | |||||
} | |||||
return discussionComment, resp, nil | |||||
} | |||||
// DeleteCommentByID deletes a comment on a team discussion by team ID. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-discussion-comment | |||||
func (s *TeamsService) DeleteCommentByID(ctx context.Context, orgID, teamID int64, discussionNumber, commentNumber int) (*Response, error) { | |||||
u := fmt.Sprintf("organizations/%v/team/%v/discussions/%v/comments/%v", orgID, teamID, discussionNumber, commentNumber) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} | |||||
// DeleteCommentBySlug deletes a comment on a team discussion by team slug. | |||||
// Authenticated user must grant write:discussion scope. | |||||
// | |||||
// GitHub API docs: https://developer.github.com/v3/teams/discussion_comments/#delete-a-discussion-comment | |||||
func (s *TeamsService) DeleteCommentBySlug(ctx context.Context, org, slug string, discussionNumber, commentNumber int) (*Response, error) { | |||||
u := fmt.Sprintf("orgs/%v/teams/%v/discussions/%v/comments/%v", org, slug, discussionNumber, commentNumber) | |||||
req, err := s.client.NewRequest("DELETE", u, nil) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
return s.client.Do(ctx, req, nil) | |||||
} |