* 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) | |||
} |