More granular loops, update go-github

This commit adds:

  * more granular loops for various operations
  * update go-github to latest version
  * skip trying to fetch runner info for canceled or skipped jobs
  * loops use waitgroups to signal exit

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2023-06-23 08:16:41 +00:00
parent f84da48f5b
commit a9cf5127a9
412 changed files with 26323 additions and 4101 deletions

View file

@ -1,117 +0,0 @@
// Copyright 2021 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"
)
// GetAuditLogOptions sets up optional parameters to query audit-log endpoint.
type GetAuditLogOptions struct {
Phrase *string `url:"phrase,omitempty"` // A search phrase. (Optional.)
Include *string `url:"include,omitempty"` // Event type includes. Can be one of "web", "git", "all". Default: "web". (Optional.)
Order *string `url:"order,omitempty"` // The order of audit log events. Can be one of "asc" or "desc". Default: "desc". (Optional.)
ListCursorOptions
}
// HookConfig describes metadata about a webhook configuration.
type HookConfig struct {
ContentType *string `json:"content_type,omitempty"`
InsecureSSL *string `json:"insecure_ssl,omitempty"`
URL *string `json:"url,omitempty"`
// Secret is returned obfuscated by GitHub, but it can be set for outgoing requests.
Secret *string `json:"secret,omitempty"`
}
// AuditEntry describes the fields that may be represented by various audit-log "action" entries.
// For a list of actions see - https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/reviewing-the-audit-log-for-your-organization#audit-log-actions
type AuditEntry struct {
Action *string `json:"action,omitempty"` // The name of the action that was performed, for example `user.login` or `repo.create`.
Active *bool `json:"active,omitempty"`
ActiveWas *bool `json:"active_was,omitempty"`
Actor *string `json:"actor,omitempty"` // The actor who performed the action.
BlockedUser *string `json:"blocked_user,omitempty"`
Business *string `json:"business,omitempty"`
CancelledAt *Timestamp `json:"cancelled_at,omitempty"`
CompletedAt *Timestamp `json:"completed_at,omitempty"`
Conclusion *string `json:"conclusion,omitempty"`
Config *HookConfig `json:"config,omitempty"`
ConfigWas *HookConfig `json:"config_was,omitempty"`
ContentType *string `json:"content_type,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
DeployKeyFingerprint *string `json:"deploy_key_fingerprint,omitempty"`
DocumentID *string `json:"_document_id,omitempty"`
Emoji *string `json:"emoji,omitempty"`
EnvironmentName *string `json:"environment_name,omitempty"`
Event *string `json:"event,omitempty"`
Events []string `json:"events,omitempty"`
EventsWere []string `json:"events_were,omitempty"`
Explanation *string `json:"explanation,omitempty"`
Fingerprint *string `json:"fingerprint,omitempty"`
HeadBranch *string `json:"head_branch,omitempty"`
HeadSHA *string `json:"head_sha,omitempty"`
HookID *int64 `json:"hook_id,omitempty"`
IsHostedRunner *bool `json:"is_hosted_runner,omitempty"`
JobName *string `json:"job_name,omitempty"`
LimitedAvailability *bool `json:"limited_availability,omitempty"`
Message *string `json:"message,omitempty"`
Name *string `json:"name,omitempty"`
OldUser *string `json:"old_user,omitempty"`
OpenSSHPublicKey *string `json:"openssh_public_key,omitempty"`
Org *string `json:"org,omitempty"`
PreviousVisibility *string `json:"previous_visibility,omitempty"`
ReadOnly *string `json:"read_only,omitempty"`
Repo *string `json:"repo,omitempty"`
Repository *string `json:"repository,omitempty"`
RepositoryPublic *bool `json:"repository_public,omitempty"`
RunAttempt *int64 `json:"run_attempt,omitempty"`
RunnerGroupID *int64 `json:"runner_group_id,omitempty"`
RunnerGroupName *string `json:"runner_group_name,omitempty"`
RunnerID *int64 `json:"runner_id,omitempty"`
RunnerLabels []string `json:"runner_labels,omitempty"`
RunnerName *string `json:"runner_name,omitempty"`
SecretsPassed []string `json:"secrets_passed,omitempty"`
SourceVersion *string `json:"source_version,omitempty"`
StartedAt *Timestamp `json:"started_at,omitempty"`
TargetLogin *string `json:"target_login,omitempty"`
TargetVersion *string `json:"target_version,omitempty"`
Team *string `json:"team,omitempty"`
Timestamp *Timestamp `json:"@timestamp,omitempty"` // The time the audit log event occurred, given as a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time).
TransportProtocolName *string `json:"transport_protocol_name,omitempty"` // A human readable name for the protocol (for example, HTTP or SSH) used to transfer Git data.
TransportProtocol *int `json:"transport_protocol,omitempty"` // The type of protocol (for example, HTTP=1 or SSH=2) used to transfer Git data.
TriggerID *int64 `json:"trigger_id,omitempty"`
User *string `json:"user,omitempty"` // The user that was affected by the action performed (if available).
Visibility *string `json:"visibility,omitempty"` // The repository visibility, for example `public` or `private`.
WorkflowID *int64 `json:"workflow_id,omitempty"`
WorkflowRunID *int64 `json:"workflow_run_id,omitempty"`
}
// GetAuditLog gets the audit-log entries for an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/orgs#get-the-audit-log-for-an-organization
func (s *OrganizationsService) GetAuditLog(ctx context.Context, org string, opts *GetAuditLogOptions) ([]*AuditEntry, *Response, error) {
u := fmt.Sprintf("orgs/%v/audit-log", 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 auditEntries []*AuditEntry
resp, err := s.client.Do(ctx, req, &auditEntries)
if err != nil {
return nil, resp, err
}
return auditEntries, resp, nil
}

View file

@ -12,20 +12,34 @@ import (
"net/url"
)
// Artifact reprents a GitHub artifact. Artifacts allow sharing
// ArtifactWorkflowRun represents a GitHub artifact's workflow run.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/artifacts
type ArtifactWorkflowRun struct {
ID *int64 `json:"id,omitempty"`
RepositoryID *int64 `json:"repository_id,omitempty"`
HeadRepositoryID *int64 `json:"head_repository_id,omitempty"`
HeadBranch *string `json:"head_branch,omitempty"`
HeadSHA *string `json:"head_sha,omitempty"`
}
// Artifact represents 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://docs.github.com/en/rest/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"`
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
Name *string `json:"name,omitempty"`
SizeInBytes *int64 `json:"size_in_bytes,omitempty"`
URL *string `json:"url,omitempty"`
ArchiveDownloadURL *string `json:"archive_download_url,omitempty"`
Expired *bool `json:"expired,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ExpiresAt *Timestamp `json:"expires_at,omitempty"`
WorkflowRun *ArtifactWorkflowRun `json:"workflow_run,omitempty"`
}
// ArtifactList represents a list of GitHub artifacts.

View file

@ -0,0 +1,235 @@
// Copyright 2022 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"
)
// ActionsCache represents a GitHub action cache.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#about-the-cache-api
type ActionsCache struct {
ID *int64 `json:"id,omitempty" url:"-"`
Ref *string `json:"ref,omitempty" url:"ref"`
Key *string `json:"key,omitempty" url:"key"`
Version *string `json:"version,omitempty" url:"-"`
LastAccessedAt *Timestamp `json:"last_accessed_at,omitempty" url:"-"`
CreatedAt *Timestamp `json:"created_at,omitempty" url:"-"`
SizeInBytes *int64 `json:"size_in_bytes,omitempty" url:"-"`
}
// ActionsCacheList represents a list of GitHub actions Cache.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#list-github-actions-caches-for-a-repository
type ActionsCacheList struct {
TotalCount int `json:"total_count"`
ActionsCaches []*ActionsCache `json:"actions_caches,omitempty"`
}
// ActionsCacheUsage represents a GitHub Actions Cache Usage object.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-usage-for-a-repository
type ActionsCacheUsage struct {
FullName string `json:"full_name"`
ActiveCachesSizeInBytes int64 `json:"active_caches_size_in_bytes"`
ActiveCachesCount int `json:"active_caches_count"`
}
// ActionsCacheUsageList represents a list of repositories with GitHub Actions cache usage for an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-usage-for-a-repository
type ActionsCacheUsageList struct {
TotalCount int `json:"total_count"`
RepoCacheUsage []*ActionsCacheUsage `json:"repository_cache_usages,omitempty"`
}
// TotalCacheUsage represents total GitHub actions cache usage of an organization or enterprise.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-usage-for-an-enterprise
type TotalCacheUsage struct {
TotalActiveCachesUsageSizeInBytes int64 `json:"total_active_caches_size_in_bytes"`
TotalActiveCachesCount int `json:"total_active_caches_count"`
}
// ActionsCacheListOptions represents a list of all possible optional Query parameters for ListCaches method.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#list-github-actions-caches-for-a-repository
type ActionsCacheListOptions struct {
ListOptions
// The Git reference for the results you want to list.
// The ref for a branch can be formatted either as refs/heads/<branch name>
// or simply <branch name>. To reference a pull request use refs/pull/<number>/merge
Ref *string `url:"ref,omitempty"`
Key *string `url:"key,omitempty"`
// Can be one of: "created_at", "last_accessed_at", "size_in_bytes". Default: "last_accessed_at"
Sort *string `url:"sort,omitempty"`
// Can be one of: "asc", "desc" Default: desc
Direction *string `url:"direction,omitempty"`
}
// ListCaches lists the GitHub Actions caches for a repository.
// You must authenticate using an access token with the repo scope to use this endpoint.
//
// Permissions: must have the actions:read permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#list-github-actions-caches-for-a-repository
func (s *ActionsService) ListCaches(ctx context.Context, owner, repo string, opts *ActionsCacheListOptions) (*ActionsCacheList, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/caches", 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
}
actionCacheList := new(ActionsCacheList)
resp, err := s.client.Do(ctx, req, actionCacheList)
if err != nil {
return nil, resp, err
}
return actionCacheList, resp, nil
}
// DeleteCachesByKey deletes one or more GitHub Actions caches for a repository, using a complete cache key.
// By default, all caches that match the provided key are deleted, but you can optionally provide
// a Git ref to restrict deletions to caches that match both the provided key and the Git ref.
// The ref for a branch can be formatted either as "refs/heads/<branch name>" or simply "<branch name>".
// To reference a pull request use "refs/pull/<number>/merge". If you don't want to use ref just pass nil in parameter.
//
// Permissions: You must authenticate using an access token with the repo scope to use this endpoint. GitHub Apps must have the actions:write permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-github-actions-caches-for-a-repository-using-a-cache-key
func (s *ActionsService) DeleteCachesByKey(ctx context.Context, owner, repo, key string, ref *string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/caches", owner, repo)
u, err := addOptions(u, ActionsCache{Key: &key, Ref: ref})
if err != nil {
return nil, err
}
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// DeleteCachesByID deletes a GitHub Actions cache for a repository, using a cache ID.
//
// Permissions: You must authenticate using an access token with the repo scope to use this endpoint. GitHub Apps must have the actions:write permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#delete-a-github-actions-cache-for-a-repository-using-a-cache-id
func (s *ActionsService) DeleteCachesByID(ctx context.Context, owner, repo string, cacheID int64) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/caches/%v", owner, repo, cacheID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// GetCacheUsageForRepo gets GitHub Actions cache usage for a repository. The data fetched using this API is refreshed approximately every 5 minutes,
// so values returned from this endpoint may take at least 5 minutes to get updated.
//
// Permissions: Anyone with read access to the repository can use this endpoint. If the repository is private, you must use an
// access token with the repo scope. GitHub Apps must have the actions:read permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-usage-for-a-repository
func (s *ActionsService) GetCacheUsageForRepo(ctx context.Context, owner, repo string) (*ActionsCacheUsage, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/cache/usage", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
cacheUsage := new(ActionsCacheUsage)
res, err := s.client.Do(ctx, req, cacheUsage)
if err != nil {
return nil, res, err
}
return cacheUsage, res, err
}
// ListCacheUsageByRepoForOrg lists repositories and their GitHub Actions cache usage for an organization. The data fetched using this API is
// refreshed approximately every 5 minutes, so values returned from this endpoint may take at least 5 minutes to get updated.
//
// Permissions: You must authenticate using an access token with the read:org scope to use this endpoint.
// GitHub Apps must have the organization_admistration:read permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#list-repositories-with-github-actions-cache-usage-for-an-organization
func (s *ActionsService) ListCacheUsageByRepoForOrg(ctx context.Context, org string, opts *ListOptions) (*ActionsCacheUsageList, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/cache/usage-by-repository", 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
}
cacheUsage := new(ActionsCacheUsageList)
res, err := s.client.Do(ctx, req, cacheUsage)
if err != nil {
return nil, res, err
}
return cacheUsage, res, err
}
// GetTotalCacheUsageForOrg gets the total GitHub Actions cache usage for an organization. The data fetched using this API is refreshed approximately every
// 5 minutes, so values returned from this endpoint may take at least 5 minutes to get updated.
//
// Permissions: You must authenticate using an access token with the read:org scope to use this endpoint.
// GitHub Apps must have the organization_admistration:read permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-usage-for-an-organization
func (s *ActionsService) GetTotalCacheUsageForOrg(ctx context.Context, org string) (*TotalCacheUsage, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/cache/usage", org)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
cacheUsage := new(TotalCacheUsage)
res, err := s.client.Do(ctx, req, cacheUsage)
if err != nil {
return nil, res, err
}
return cacheUsage, res, err
}
// GetTotalCacheUsageForEnterprise gets the total GitHub Actions cache usage for an enterprise. The data fetched using this API is refreshed approximately every 5 minutes,
// so values returned from this endpoint may take at least 5 minutes to get updated.
//
// Permissions: You must authenticate using an access token with the "admin:enterprise" scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-usage-for-an-enterprise
func (s *ActionsService) GetTotalCacheUsageForEnterprise(ctx context.Context, enterprise string) (*TotalCacheUsage, *Response, error) {
u := fmt.Sprintf("enterprises/%v/actions/cache/usage", enterprise)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
cacheUsage := new(TotalCacheUsage)
res, err := s.client.Do(ctx, req, cacheUsage)
if err != nil {
return nil, res, err
}
return cacheUsage, res, err
}

View file

@ -0,0 +1,73 @@
// Copyright 2023 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"
)
// OIDCSubjectClaimCustomTemplate represents an OIDC subject claim customization template.
type OIDCSubjectClaimCustomTemplate struct {
UseDefault *bool `json:"use_default,omitempty"`
IncludeClaimKeys []string `json:"include_claim_keys,omitempty"`
}
// GetOrgOIDCSubjectClaimCustomTemplate gets the subject claim customization template for an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/oidc#get-the-customization-template-for-an-oidc-subject-claim-for-an-organization
func (s *ActionsService) GetOrgOIDCSubjectClaimCustomTemplate(ctx context.Context, org string) (*OIDCSubjectClaimCustomTemplate, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/oidc/customization/sub", org)
return s.getOIDCSubjectClaimCustomTemplate(ctx, u)
}
// GetRepoOIDCSubjectClaimCustomTemplate gets the subject claim customization template for a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/oidc#get-the-customization-template-for-an-oidc-subject-claim-for-a-repository
func (s *ActionsService) GetRepoOIDCSubjectClaimCustomTemplate(ctx context.Context, owner, repo string) (*OIDCSubjectClaimCustomTemplate, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/oidc/customization/sub", owner, repo)
return s.getOIDCSubjectClaimCustomTemplate(ctx, u)
}
func (s *ActionsService) getOIDCSubjectClaimCustomTemplate(ctx context.Context, url string) (*OIDCSubjectClaimCustomTemplate, *Response, error) {
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
tmpl := new(OIDCSubjectClaimCustomTemplate)
resp, err := s.client.Do(ctx, req, tmpl)
if err != nil {
return nil, resp, err
}
return tmpl, resp, nil
}
// SetOrgOIDCSubjectClaimCustomTemplate sets the subject claim customization for an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/oidc#set-the-customization-template-for-an-oidc-subject-claim-for-an-organization
func (s *ActionsService) SetOrgOIDCSubjectClaimCustomTemplate(ctx context.Context, org string, template *OIDCSubjectClaimCustomTemplate) (*Response, error) {
u := fmt.Sprintf("orgs/%v/actions/oidc/customization/sub", org)
return s.setOIDCSubjectClaimCustomTemplate(ctx, u, template)
}
// SetRepoOIDCSubjectClaimCustomTemplate sets the subject claim customization for a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/oidc#set-the-customization-template-for-an-oidc-subject-claim-for-a-repository
func (s *ActionsService) SetRepoOIDCSubjectClaimCustomTemplate(ctx context.Context, owner, repo string, template *OIDCSubjectClaimCustomTemplate) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/oidc/customization/sub", owner, repo)
return s.setOIDCSubjectClaimCustomTemplate(ctx, u, template)
}
func (s *ActionsService) setOIDCSubjectClaimCustomTemplate(ctx context.Context, url string, template *OIDCSubjectClaimCustomTemplate) (*Response, error) {
req, err := s.client.NewRequest("PUT", url, template)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}

View file

@ -0,0 +1,247 @@
// Copyright 2023 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"
)
// OrgRequiredWorkflow represents a required workflow object at the org level.
type OrgRequiredWorkflow struct {
ID *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Path *string `json:"path,omitempty"`
Scope *string `json:"scope,omitempty"`
Ref *string `json:"ref,omitempty"`
State *string `json:"state,omitempty"`
SelectedRepositoriesURL *string `json:"selected_repositories_url,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Repository *Repository `json:"repository,omitempty"`
}
// OrgRequiredWorkflows represents the required workflows for the org.
type OrgRequiredWorkflows struct {
TotalCount *int `json:"total_count,omitempty"`
RequiredWorkflows []*OrgRequiredWorkflow `json:"required_workflows,omitempty"`
}
// CreateUpdateRequiredWorkflowOptions represents the input object used to create or update required workflows.
type CreateUpdateRequiredWorkflowOptions struct {
WorkflowFilePath *string `json:"workflow_file_path,omitempty"`
RepositoryID *int64 `json:"repository_id,omitempty"`
Scope *string `json:"scope,omitempty"`
SelectedRepositoryIDs *SelectedRepoIDs `json:"selected_repository_ids,omitempty"`
}
// RequiredWorkflowSelectedRepos represents the repos that a required workflow is applied to.
type RequiredWorkflowSelectedRepos struct {
TotalCount *int `json:"total_count,omitempty"`
Repositories []*Repository `json:"repositories,omitempty"`
}
// RepoRequiredWorkflow represents a required workflow object at the repo level.
type RepoRequiredWorkflow 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"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
BadgeURL *string `json:"badge_url,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
SourceRepository *Repository `json:"source_repository,omitempty"`
}
// RepoRequiredWorkflows represents the required workflows for a repo.
type RepoRequiredWorkflows struct {
TotalCount *int `json:"total_count,omitempty"`
RequiredWorkflows []*RepoRequiredWorkflow `json:"required_workflows,omitempty"`
}
// ListOrgRequiredWorkflows lists the RequiredWorkflows for an org.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#list-required-workflows
func (s *ActionsService) ListOrgRequiredWorkflows(ctx context.Context, org string, opts *ListOptions) (*OrgRequiredWorkflows, *Response, error) {
url := fmt.Sprintf("orgs/%v/actions/required_workflows", org)
u, err := addOptions(url, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
requiredWorkflows := new(OrgRequiredWorkflows)
resp, err := s.client.Do(ctx, req, &requiredWorkflows)
if err != nil {
return nil, resp, err
}
return requiredWorkflows, resp, nil
}
// CreateRequiredWorkflow creates the required workflow in an org.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#create-a-required-workflow
func (s *ActionsService) CreateRequiredWorkflow(ctx context.Context, org string, createRequiredWorkflowOptions *CreateUpdateRequiredWorkflowOptions) (*OrgRequiredWorkflow, *Response, error) {
url := fmt.Sprintf("orgs/%v/actions/required_workflows", org)
req, err := s.client.NewRequest("POST", url, createRequiredWorkflowOptions)
if err != nil {
return nil, nil, err
}
orgRequiredWorkflow := new(OrgRequiredWorkflow)
resp, err := s.client.Do(ctx, req, orgRequiredWorkflow)
if err != nil {
return nil, resp, err
}
return orgRequiredWorkflow, resp, nil
}
// GetRequiredWorkflowByID get the RequiredWorkflows for an org by its ID.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#list-required-workflows
func (s *ActionsService) GetRequiredWorkflowByID(ctx context.Context, owner string, requiredWorkflowID int64) (*OrgRequiredWorkflow, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/required_workflows/%v", owner, requiredWorkflowID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
requiredWorkflow := new(OrgRequiredWorkflow)
resp, err := s.client.Do(ctx, req, &requiredWorkflow)
if err != nil {
return nil, resp, err
}
return requiredWorkflow, resp, nil
}
// UpdateRequiredWorkflow updates a required workflow in an org.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#update-a-required-workflow
func (s *ActionsService) UpdateRequiredWorkflow(ctx context.Context, org string, requiredWorkflowID int64, updateRequiredWorkflowOptions *CreateUpdateRequiredWorkflowOptions) (*OrgRequiredWorkflow, *Response, error) {
url := fmt.Sprintf("orgs/%v/actions/required_workflows/%v", org, requiredWorkflowID)
req, err := s.client.NewRequest("PATCH", url, updateRequiredWorkflowOptions)
if err != nil {
return nil, nil, err
}
orgRequiredWorkflow := new(OrgRequiredWorkflow)
resp, err := s.client.Do(ctx, req, orgRequiredWorkflow)
if err != nil {
return nil, resp, err
}
return orgRequiredWorkflow, resp, nil
}
// DeleteRequiredWorkflow deletes a required workflow in an org.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#update-a-required-workflow
func (s *ActionsService) DeleteRequiredWorkflow(ctx context.Context, org string, requiredWorkflowID int64) (*Response, error) {
url := fmt.Sprintf("orgs/%v/actions/required_workflows/%v", org, requiredWorkflowID)
req, err := s.client.NewRequest("DELETE", url, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// ListRequiredWorkflowSelectedRepos lists the Repositories selected for a workflow.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#list-selected-repositories-for-a-required-workflow
func (s *ActionsService) ListRequiredWorkflowSelectedRepos(ctx context.Context, org string, requiredWorkflowID int64, opts *ListOptions) (*RequiredWorkflowSelectedRepos, *Response, error) {
url := fmt.Sprintf("orgs/%v/actions/required_workflows/%v/repositories", org, requiredWorkflowID)
u, err := addOptions(url, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
requiredWorkflowRepos := new(RequiredWorkflowSelectedRepos)
resp, err := s.client.Do(ctx, req, &requiredWorkflowRepos)
if err != nil {
return nil, resp, err
}
return requiredWorkflowRepos, resp, nil
}
// SetRequiredWorkflowSelectedRepos sets the Repositories selected for a workflow.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#sets-repositories-for-a-required-workflow
func (s *ActionsService) SetRequiredWorkflowSelectedRepos(ctx context.Context, org string, requiredWorkflowID int64, ids SelectedRepoIDs) (*Response, error) {
type repoIDs struct {
SelectedIDs SelectedRepoIDs `json:"selected_repository_ids"`
}
url := fmt.Sprintf("orgs/%v/actions/required_workflows/%v/repositories", org, requiredWorkflowID)
req, err := s.client.NewRequest("PUT", url, repoIDs{SelectedIDs: ids})
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// AddRepoToRequiredWorkflow adds the Repository to a required workflow.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#add-a-repository-to-a-required-workflow
func (s *ActionsService) AddRepoToRequiredWorkflow(ctx context.Context, org string, requiredWorkflowID, repoID int64) (*Response, error) {
url := fmt.Sprintf("orgs/%v/actions/required_workflows/%v/repositories/%v", org, requiredWorkflowID, repoID)
req, err := s.client.NewRequest("PUT", url, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// RemoveRepoFromRequiredWorkflow removes the Repository from a required workflow.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#add-a-repository-to-a-required-workflow
func (s *ActionsService) RemoveRepoFromRequiredWorkflow(ctx context.Context, org string, requiredWorkflowID, repoID int64) (*Response, error) {
url := fmt.Sprintf("orgs/%v/actions/required_workflows/%v/repositories/%v", org, requiredWorkflowID, repoID)
req, err := s.client.NewRequest("DELETE", url, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// ListRepoRequiredWorkflows lists the RequiredWorkflows for a repo.
//
// Github API docs:https://docs.github.com/en/rest/actions/required-workflows?apiVersion=2022-11-28#list-repository-required-workflows
func (s *ActionsService) ListRepoRequiredWorkflows(ctx context.Context, owner, repo string, opts *ListOptions) (*RepoRequiredWorkflows, *Response, error) {
url := fmt.Sprintf("repos/%v/%v/actions/required_workflows", owner, repo)
u, err := addOptions(url, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
requiredWorkflows := new(RepoRequiredWorkflows)
resp, err := s.client.Do(ctx, req, &requiredWorkflows)
if err != nil {
return nil, resp, err
}
return requiredWorkflows, resp, nil
}

View file

@ -45,6 +45,60 @@ func (s *ActionsService) ListRunnerApplicationDownloads(ctx context.Context, own
return rads, resp, nil
}
// GenerateJITConfigRequest specifies body parameters to GenerateRepoJITConfig.
type GenerateJITConfigRequest struct {
Name string `json:"name"`
RunnerGroupID int64 `json:"runner_group_id"`
WorkFolder *string `json:"work_folder,omitempty"`
// Labels represents the names of the custom labels to add to the runner.
// Minimum items: 1. Maximum items: 100.
Labels []string `json:"labels"`
}
// JITRunnerConfig represents encoded JIT configuration that can be used to bootstrap a self-hosted runner.
type JITRunnerConfig struct {
EncodedJITConfig *string `json:"encoded_jit_config,omitempty"`
}
// GenerateOrgJITConfig generate a just-in-time configuration for an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-configuration-for-a-just-in-time-runner-for-an-organization
func (s *ActionsService) GenerateOrgJITConfig(ctx context.Context, owner string, request *GenerateJITConfigRequest) (*JITRunnerConfig, *Response, error) {
u := fmt.Sprintf("orgs/%v/actions/runners/generate-jitconfig", owner)
req, err := s.client.NewRequest("POST", u, request)
if err != nil {
return nil, nil, err
}
jitConfig := new(JITRunnerConfig)
resp, err := s.client.Do(ctx, req, jitConfig)
if err != nil {
return nil, resp, err
}
return jitConfig, resp, nil
}
// GenerateRepoJITConfig generates a just-in-time configuration for a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-configuration-for-a-just-in-time-runner-for-a-repository
func (s *ActionsService) GenerateRepoJITConfig(ctx context.Context, owner, repo string, request *GenerateJITConfigRequest) (*JITRunnerConfig, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runners/generate-jitconfig", owner, repo)
req, err := s.client.NewRequest("POST", u, request)
if err != nil {
return nil, nil, err
}
jitConfig := new(JITRunnerConfig)
resp, err := s.client.Do(ctx, req, jitConfig)
if err != nil {
return nil, resp, err
}
return jitConfig, 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"`

View file

@ -0,0 +1,293 @@
// Copyright 2023 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"
)
// ActionsVariable represents a repository action variable.
type ActionsVariable struct {
Name string `json:"name"`
Value string `json:"value"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Visibility *string `json:"visibility,omitempty"`
// Used by ListOrgVariables and GetOrgVariables
SelectedRepositoriesURL *string `json:"selected_repositories_url,omitempty"`
// Used by UpdateOrgVariable and CreateOrgVariable
SelectedRepositoryIDs *SelectedRepoIDs `json:"selected_repository_ids,omitempty"`
}
// ActionsVariables represents one item from the ListVariables response.
type ActionsVariables struct {
TotalCount int `json:"total_count"`
Variables []*ActionsVariable `json:"variables"`
}
func (s *ActionsService) listVariables(ctx context.Context, url string, opts *ListOptions) (*ActionsVariables, *Response, error) {
u, err := addOptions(url, opts)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
variables := new(ActionsVariables)
resp, err := s.client.Do(ctx, req, &variables)
if err != nil {
return nil, resp, err
}
return variables, resp, nil
}
// ListRepoVariables lists all variables available in a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#list-repository-variables
func (s *ActionsService) ListRepoVariables(ctx context.Context, owner, repo string, opts *ListOptions) (*ActionsVariables, *Response, error) {
url := fmt.Sprintf("repos/%v/%v/actions/variables", owner, repo)
return s.listVariables(ctx, url, opts)
}
// ListOrgVariables lists all variables available in an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#list-organization-variables
func (s *ActionsService) ListOrgVariables(ctx context.Context, org string, opts *ListOptions) (*ActionsVariables, *Response, error) {
url := fmt.Sprintf("orgs/%v/actions/variables", org)
return s.listVariables(ctx, url, opts)
}
// ListEnvVariables lists all variables available in an environment.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#list-environment-variables
func (s *ActionsService) ListEnvVariables(ctx context.Context, repoID int, env string, opts *ListOptions) (*ActionsVariables, *Response, error) {
url := fmt.Sprintf("repositories/%v/environments/%v/variables", repoID, env)
return s.listVariables(ctx, url, opts)
}
func (s *ActionsService) getVariable(ctx context.Context, url string) (*ActionsVariable, *Response, error) {
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
variable := new(ActionsVariable)
resp, err := s.client.Do(ctx, req, variable)
if err != nil {
return nil, resp, err
}
return variable, resp, nil
}
// GetRepoVariable gets a single repository variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#get-a-repository-variable
func (s *ActionsService) GetRepoVariable(ctx context.Context, owner, repo, name string) (*ActionsVariable, *Response, error) {
url := fmt.Sprintf("repos/%v/%v/actions/variables/%v", owner, repo, name)
return s.getVariable(ctx, url)
}
// GetOrgVariable gets a single organization variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#get-an-organization-variable
func (s *ActionsService) GetOrgVariable(ctx context.Context, org, name string) (*ActionsVariable, *Response, error) {
url := fmt.Sprintf("orgs/%v/actions/variables/%v", org, name)
return s.getVariable(ctx, url)
}
// GetEnvVariable gets a single environment variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#get-an-environment-variable
func (s *ActionsService) GetEnvVariable(ctx context.Context, repoID int, env, variableName string) (*ActionsVariable, *Response, error) {
url := fmt.Sprintf("repositories/%v/environments/%v/variables/%v", repoID, env, variableName)
return s.getVariable(ctx, url)
}
func (s *ActionsService) postVariable(ctx context.Context, url string, variable *ActionsVariable) (*Response, error) {
req, err := s.client.NewRequest("POST", url, variable)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// CreateRepoVariable creates a repository variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#create-a-repository-variable
func (s *ActionsService) CreateRepoVariable(ctx context.Context, owner, repo string, variable *ActionsVariable) (*Response, error) {
url := fmt.Sprintf("repos/%v/%v/actions/variables", owner, repo)
return s.postVariable(ctx, url, variable)
}
// CreateOrgVariable creates an organization variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#create-an-organization-variable
func (s *ActionsService) CreateOrgVariable(ctx context.Context, org string, variable *ActionsVariable) (*Response, error) {
url := fmt.Sprintf("orgs/%v/actions/variables", org)
return s.postVariable(ctx, url, variable)
}
// CreateEnvVariable creates an environment variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#create-an-environment-variable
func (s *ActionsService) CreateEnvVariable(ctx context.Context, repoID int, env string, variable *ActionsVariable) (*Response, error) {
url := fmt.Sprintf("repositories/%v/environments/%v/variables", repoID, env)
return s.postVariable(ctx, url, variable)
}
func (s *ActionsService) patchVariable(ctx context.Context, url string, variable *ActionsVariable) (*Response, error) {
req, err := s.client.NewRequest("PATCH", url, variable)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// UpdateRepoVariable updates a repository variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#update-a-repository-variable
func (s *ActionsService) UpdateRepoVariable(ctx context.Context, owner, repo string, variable *ActionsVariable) (*Response, error) {
url := fmt.Sprintf("repos/%v/%v/actions/variables/%v", owner, repo, variable.Name)
return s.patchVariable(ctx, url, variable)
}
// UpdateOrgVariable updates an organization variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#update-an-organization-variable
func (s *ActionsService) UpdateOrgVariable(ctx context.Context, org string, variable *ActionsVariable) (*Response, error) {
url := fmt.Sprintf("orgs/%v/actions/variables/%v", org, variable.Name)
return s.patchVariable(ctx, url, variable)
}
// UpdateEnvVariable updates an environment variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#create-an-environment-variable
func (s *ActionsService) UpdateEnvVariable(ctx context.Context, repoID int, env string, variable *ActionsVariable) (*Response, error) {
url := fmt.Sprintf("repositories/%v/environments/%v/variables/%v", repoID, env, variable.Name)
return s.patchVariable(ctx, url, variable)
}
func (s *ActionsService) deleteVariable(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest("DELETE", url, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// DeleteRepoVariable deletes a variable in a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#delete-a-repository-variable
func (s *ActionsService) DeleteRepoVariable(ctx context.Context, owner, repo, name string) (*Response, error) {
url := fmt.Sprintf("repos/%v/%v/actions/variables/%v", owner, repo, name)
return s.deleteVariable(ctx, url)
}
// DeleteOrgVariable deletes a variable in an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#delete-an-organization-variable
func (s *ActionsService) DeleteOrgVariable(ctx context.Context, org, name string) (*Response, error) {
url := fmt.Sprintf("orgs/%v/actions/variables/%v", org, name)
return s.deleteVariable(ctx, url)
}
// DeleteEnvVariable deletes a variable in an environment.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#delete-an-environment-variable
func (s *ActionsService) DeleteEnvVariable(ctx context.Context, repoID int, env, variableName string) (*Response, error) {
url := fmt.Sprintf("repositories/%v/environments/%v/variables/%v", repoID, env, variableName)
return s.deleteVariable(ctx, url)
}
func (s *ActionsService) listSelectedReposForVariable(ctx context.Context, url string, opts *ListOptions) (*SelectedReposList, *Response, error) {
u, err := addOptions(url, opts)
if err != nil {
return nil, nil, err
}
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
}
// ListSelectedReposForOrgVariable lists all repositories that have access to a variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#list-selected-repositories-for-an-organization-variable
func (s *ActionsService) ListSelectedReposForOrgVariable(ctx context.Context, org, name string, opts *ListOptions) (*SelectedReposList, *Response, error) {
url := fmt.Sprintf("orgs/%v/actions/variables/%v/repositories", org, name)
return s.listSelectedReposForVariable(ctx, url, opts)
}
func (s *ActionsService) setSelectedReposForVariable(ctx context.Context, url string, ids SelectedRepoIDs) (*Response, error) {
type repoIDs struct {
SelectedIDs SelectedRepoIDs `json:"selected_repository_ids"`
}
req, err := s.client.NewRequest("PUT", url, repoIDs{SelectedIDs: ids})
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// SetSelectedReposForOrgVariable sets the repositories that have access to a variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#set-selected-repositories-for-an-organization-variable
func (s *ActionsService) SetSelectedReposForOrgVariable(ctx context.Context, org, name string, ids SelectedRepoIDs) (*Response, error) {
url := fmt.Sprintf("orgs/%v/actions/variables/%v/repositories", org, name)
return s.setSelectedReposForVariable(ctx, url, ids)
}
func (s *ActionsService) addSelectedRepoToVariable(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest("PUT", url, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// AddSelectedRepoToOrgVariable adds a repository to an organization variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#add-selected-repository-to-an-organization-variable
func (s *ActionsService) AddSelectedRepoToOrgVariable(ctx context.Context, org, name string, repo *Repository) (*Response, error) {
url := fmt.Sprintf("orgs/%v/actions/variables/%v/repositories/%v", org, name, *repo.ID)
return s.addSelectedRepoToVariable(ctx, url)
}
func (s *ActionsService) removeSelectedRepoFromVariable(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest("DELETE", url, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// RemoveSelectedRepoFromOrgVariable removes a repository from an organization variable.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/variables#remove-selected-repository-from-an-organization-variable
func (s *ActionsService) RemoveSelectedRepoFromOrgVariable(ctx context.Context, org, name string, repo *Repository) (*Response, error) {
url := fmt.Sprintf("orgs/%v/actions/variables/%v/repositories/%v", org, name, *repo.ID)
return s.removeSelectedRepoFromVariable(ctx, url)
}

View file

@ -28,11 +28,13 @@ type WorkflowJob struct {
RunID *int64 `json:"run_id,omitempty"`
RunURL *string `json:"run_url,omitempty"`
NodeID *string `json:"node_id,omitempty"`
HeadBranch *string `json:"head_branch,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"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
StartedAt *Timestamp `json:"started_at,omitempty"`
CompletedAt *Timestamp `json:"completed_at,omitempty"`
Name *string `json:"name,omitempty"`
@ -45,6 +47,7 @@ type WorkflowJob struct {
RunnerGroupID *int64 `json:"runner_group_id,omitempty"`
RunnerGroupName *string `json:"runner_group_name,omitempty"`
RunAttempt *int64 `json:"run_attempt,omitempty"`
WorkflowName *string `json:"workflow_name,omitempty"`
}
// Jobs represents a slice of repository action workflow job.

View file

@ -22,6 +22,7 @@ type WorkflowRun struct {
RunNumber *int `json:"run_number,omitempty"`
RunAttempt *int `json:"run_attempt,omitempty"`
Event *string `json:"event,omitempty"`
DisplayTitle *string `json:"display_title,omitempty"`
Status *string `json:"status,omitempty"`
Conclusion *string `json:"conclusion,omitempty"`
WorkflowID *int64 `json:"workflow_id,omitempty"`
@ -55,26 +56,26 @@ type WorkflowRuns struct {
// 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"`
Created string `url:"created,omitempty"`
Actor string `url:"actor,omitempty"`
Branch string `url:"branch,omitempty"`
Event string `url:"event,omitempty"`
Status string `url:"status,omitempty"`
Created string `url:"created,omitempty"`
HeadSHA string `url:"head_sha,omitempty"`
ExcludePullRequests bool `url:"exclude_pull_requests,omitempty"`
CheckSuiteID int64 `url:"check_suite_id,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"`
Billable *WorkflowRunBillMap `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"`
}
// WorkflowRunBillMap represents different runner environments available for a workflow run.
// Its key is the name of its environment, e.g. "UBUNTU", "MACOS", "WINDOWS", etc.
type WorkflowRunBillMap map[string]*WorkflowRunBill
// WorkflowRunBill specifies billable time for a specific environment in a workflow run.
type WorkflowRunBill struct {
@ -206,6 +207,26 @@ func (s *ActionsService) GetWorkflowRunAttempt(ctx context.Context, owner, repo
return run, resp, nil
}
// GetWorkflowRunAttemptLogs gets a redirect URL to download a plain text file of logs for a workflow run for attempt number.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/workflow-runs#download-workflow-run-attempt-logs
func (s *ActionsService) GetWorkflowRunAttemptLogs(ctx context.Context, owner, repo string, runID int64, attemptNumber int, followRedirects bool) (*url.URL, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/attempts/%v/logs", owner, repo, runID, attemptNumber)
resp, err := s.client.roundTripWithOptionalFollowRedirect(ctx, u, followRedirects)
if err != nil {
return nil, nil, err
}
defer resp.Body.Close()
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
}
// RerunWorkflowByID re-runs a workflow by ID.
//
// GitHub API docs: https://docs.github.com/en/rest/actions/workflow-runs#re-run-a-workflow

View file

@ -32,15 +32,12 @@ type Workflows struct {
// WorkflowUsage represents a usage of a specific workflow.
type WorkflowUsage struct {
Billable *WorkflowEnvironment `json:"billable,omitempty"`
Billable *WorkflowBillMap `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"`
}
// WorkflowBillMap represents different runner environments available for a workflow.
// Its key is the name of its environment, e.g. "UBUNTU", "MACOS", "WINDOWS", etc.
type WorkflowBillMap map[string]*WorkflowBill
// WorkflowBill specifies billable time for a specific environment in a workflow.
type WorkflowBill struct {

View file

@ -23,8 +23,8 @@ type Notification struct {
Reason *string `json:"reason,omitempty"`
Unread *bool `json:"unread,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
LastReadAt *time.Time `json:"last_read_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
LastReadAt *Timestamp `json:"last_read_at,omitempty"`
URL *string `json:"url,omitempty"`
}
@ -97,13 +97,13 @@ func (s *ActivityService) ListRepositoryNotifications(ctx context.Context, owner
}
type markReadOptions struct {
LastReadAt time.Time `json:"last_read_at,omitempty"`
LastReadAt Timestamp `json:"last_read_at,omitempty"`
}
// MarkNotificationsRead marks all notifications up to lastRead as read.
//
// GitHub API docs: https://docs.github.com/en/rest/activity#mark-as-read
func (s *ActivityService) MarkNotificationsRead(ctx context.Context, lastRead time.Time) (*Response, error) {
func (s *ActivityService) MarkNotificationsRead(ctx context.Context, lastRead Timestamp) (*Response, error) {
opts := &markReadOptions{
LastReadAt: lastRead,
}
@ -119,7 +119,7 @@ func (s *ActivityService) MarkNotificationsRead(ctx context.Context, lastRead ti
// the specified repository as read.
//
// GitHub API docs: https://docs.github.com/en/rest/activity/notifications#mark-repository-notifications-as-read
func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, owner, repo string, lastRead time.Time) (*Response, error) {
func (s *ActivityService) MarkRepositoryNotificationsRead(ctx context.Context, owner, repo string, lastRead Timestamp) (*Response, error) {
opts := &markReadOptions{
LastReadAt: lastRead,
}

View file

@ -8,7 +8,6 @@ package github
import (
"context"
"fmt"
"time"
)
// AppsService provides access to the installation related functions
@ -19,24 +18,25 @@ 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"`
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"`
InstallationsCount *int `json:"installations_count,omitempty"`
}
// InstallationToken represents an installation token.
type InstallationToken struct {
Token *string `json:"token,omitempty"`
ExpiresAt *time.Time `json:"expires_at,omitempty"`
ExpiresAt *Timestamp `json:"expires_at,omitempty"`
Permissions *InstallationPermissions `json:"permissions,omitempty"`
Repositories []*Repository `json:"repositories,omitempty"`
}

View file

@ -46,6 +46,7 @@ type MarketplacePlan struct {
// MarketplacePurchase represents a GitHub Apps Marketplace Purchase.
type MarketplacePurchase struct {
Account *MarketplacePurchaseAccount `json:"account,omitempty"`
// BillingCycle can be one of the values "yearly", "monthly" or nil.
BillingCycle *string `json:"billing_cycle,omitempty"`
NextBillingDate *Timestamp `json:"next_billing_date,omitempty"`
@ -75,6 +76,17 @@ type MarketplacePlanAccount struct {
MarketplacePendingChange *MarketplacePendingChange `json:"marketplace_pending_change,omitempty"`
}
// MarketplacePurchaseAccount represents a GitHub Account (user or organization) for a Purchase.
type MarketplacePurchaseAccount struct {
URL *string `json:"url,omitempty"`
Type *string `json:"type,omitempty"`
ID *int64 `json:"id,omitempty"`
Login *string `json:"login,omitempty"`
OrganizationBillingEmail *string `json:"organization_billing_email,omitempty"`
Email *string `json:"email,omitempty"`
NodeID *string `json:"node_id,omitempty"`
}
// ListPlans lists all plans for your Marketplace listing.
//
// GitHub API docs: https://docs.github.com/en/rest/apps#list-plans

View file

@ -18,30 +18,27 @@ type BillingService service
// ActionBilling represents a GitHub Action billing.
type ActionBilling struct {
TotalMinutesUsed int `json:"total_minutes_used"`
TotalMinutesUsed float64 `json:"total_minutes_used"`
TotalPaidMinutesUsed float64 `json:"total_paid_minutes_used"`
IncludedMinutes int `json:"included_minutes"`
IncludedMinutes float64 `json:"included_minutes"`
MinutesUsedBreakdown MinutesUsedBreakdown `json:"minutes_used_breakdown"`
}
type MinutesUsedBreakdown struct {
Ubuntu int `json:"UBUNTU"`
MacOS int `json:"MACOS"`
Windows int `json:"WINDOWS"`
}
// MinutesUsedBreakdown counts the actions minutes used by machine type (e.g. UBUNTU, WINDOWS, MACOS).
type MinutesUsedBreakdown = map[string]int
// PackageBilling represents a GitHub Package billing.
type PackageBilling struct {
TotalGigabytesBandwidthUsed int `json:"total_gigabytes_bandwidth_used"`
TotalPaidGigabytesBandwidthUsed int `json:"total_paid_gigabytes_bandwidth_used"`
IncludedGigabytesBandwidth int `json:"included_gigabytes_bandwidth"`
TotalGigabytesBandwidthUsed int `json:"total_gigabytes_bandwidth_used"`
TotalPaidGigabytesBandwidthUsed int `json:"total_paid_gigabytes_bandwidth_used"`
IncludedGigabytesBandwidth float64 `json:"included_gigabytes_bandwidth"`
}
// StorageBilling represents a GitHub Storage billing.
type StorageBilling struct {
DaysLeftInBillingCycle int `json:"days_left_in_billing_cycle"`
EstimatedPaidStorageForMonth float64 `json:"estimated_paid_storage_for_month"`
EstimatedStorageForMonth int `json:"estimated_storage_for_month"`
EstimatedStorageForMonth float64 `json:"estimated_storage_for_month"`
}
// ActiveCommitters represents the total active committers across all repositories in an Organization.
@ -123,9 +120,14 @@ func (s *BillingService) GetStorageBillingOrg(ctx context.Context, org string) (
// GetAdvancedSecurityActiveCommittersOrg returns the GitHub Advanced Security active committers for an organization per repository.
//
// GitHub API docs: https://docs.github.com/en/rest/billing#get-github-advanced-security-active-committers-for-an-organization
func (s *BillingService) GetAdvancedSecurityActiveCommittersOrg(ctx context.Context, org string) (*ActiveCommitters, *Response, error) {
// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/billing?apiVersion=2022-11-28#get-github-advanced-security-active-committers-for-an-organization
func (s *BillingService) GetAdvancedSecurityActiveCommittersOrg(ctx context.Context, org string, opts *ListOptions) (*ActiveCommitters, *Response, error) {
u := fmt.Sprintf("orgs/%v/settings/billing/advanced-security", 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

View file

@ -173,6 +173,22 @@ type SarifAnalysis struct {
ToolName *string `json:"tool_name,omitempty"`
}
// CodeScanningAlertState specifies the state of a code scanning alert.
//
// GitHub API docs: https://docs.github.com/en/rest/code-scanning
type CodeScanningAlertState struct {
// State sets the state of the code scanning alert and is a required field.
// You must also provide DismissedReason when you set the state to "dismissed".
// State can be one of: "open", "dismissed".
State string `json:"state"`
// DismissedReason represents the reason for dismissing or closing the alert.
// It is required when the state is "dismissed".
// It can be one of: "false positive", "won't fix", "used in tests".
DismissedReason *string `json:"dismissed_reason,omitempty"`
// DismissedComment is associated with the dismissal of the alert.
DismissedComment *string `json:"dismissed_comment,omitempty"`
}
// SarifID identifies a sarif analysis upload.
//
// GitHub API docs: https://docs.github.com/en/rest/code-scanning
@ -261,6 +277,31 @@ func (s *CodeScanningService) GetAlert(ctx context.Context, owner, repo string,
return a, resp, nil
}
// UpdateAlert updates the state of 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://docs.github.com/en/rest/code-scanning?apiVersion=2022-11-28#update-a-code-scanning-alert
func (s *CodeScanningService) UpdateAlert(ctx context.Context, owner, repo string, id int64, stateInfo *CodeScanningAlertState) (*Alert, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/code-scanning/alerts/%v", owner, repo, id)
req, err := s.client.NewRequest("PATCH", u, stateInfo)
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
}
// UploadSarif uploads the result of code scanning job to GitHub.
//
// For the parameter sarif, you must first compress your SARIF file using gzip and then translate the contents of the file into a Base64 encoding string.
@ -337,3 +378,76 @@ func (s *CodeScanningService) GetAnalysis(ctx context.Context, owner, repo strin
return analysis, resp, nil
}
// DefaultSetupConfiguration represents a code scanning default setup configuration.
type DefaultSetupConfiguration struct {
State *string `json:"state,omitempty"`
Languages []string `json:"languages,omitempty"`
QuerySuite *string `json:"query_suite,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
}
// GetDefaultSetupConfiguration gets a code scanning default setup configuration.
//
// You must use an access token with the repo scope to use this
// endpoint with private repos or the public_repo scope for public repos. GitHub Apps must have the repo write
// permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/code-scanning#get-a-code-scanning-default-setup-configuration
func (s *CodeScanningService) GetDefaultSetupConfiguration(ctx context.Context, owner, repo string) (*DefaultSetupConfiguration, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/code-scanning/default-setup", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
cfg := new(DefaultSetupConfiguration)
resp, err := s.client.Do(ctx, req, cfg)
if err != nil {
return nil, resp, err
}
return cfg, resp, nil
}
// UpdateDefaultSetupConfigurationOptions specifies parameters to the CodeScanningService.UpdateDefaultSetupConfiguration
// method.
type UpdateDefaultSetupConfigurationOptions struct {
State string `json:"state"`
QuerySuite *string `json:"query_suite,omitempty"`
Languages []string `json:"languages,omitempty"`
}
// UpdateDefaultSetupConfigurationResponse represents a response from updating a code scanning default setup configuration.
type UpdateDefaultSetupConfigurationResponse struct {
RunID *int64 `json:"run_id,omitempty"`
RunURL *string `json:"run_url,omitempty"`
}
// UpdateDefaultSetupConfiguration updates a code scanning default setup configuration.
//
// You must use an access token with the repo scope to use this
// endpoint with private repos or the public_repo scope for public repos. GitHub Apps must have the repo write
// permission to use this endpoint.
//
// This method might return an AcceptedError and a status code of 202. This is because this is the status that GitHub
// returns to signify that it has now scheduled the update of the pull request branch in a background task.
//
// GitHub API docs: https://docs.github.com/en/rest/code-scanning#update-a-code-scanning-default-setup-configuration
func (s *CodeScanningService) UpdateDefaultSetupConfiguration(ctx context.Context, owner, repo string, options *UpdateDefaultSetupConfigurationOptions) (*UpdateDefaultSetupConfigurationResponse, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/code-scanning/default-setup", owner, repo)
req, err := s.client.NewRequest("PATCH", u, options)
if err != nil {
return nil, nil, err
}
a := new(UpdateDefaultSetupConfigurationResponse)
resp, err := s.client.Do(ctx, req, a)
if err != nil {
return nil, resp, err
}
return a, resp, nil
}

View file

@ -0,0 +1,254 @@
// Copyright 2023 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"
)
// CodespacesService handles communication with the Codespaces related
// methods of the GitHub API.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/
type CodespacesService service
// Codespace represents a codespace.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces
type Codespace struct {
ID *int64 `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
DisplayName *string `json:"display_name,omitempty"`
EnvironmentID *string `json:"environment_id,omitempty"`
Owner *User `json:"owner,omitempty"`
BillableOwner *User `json:"billable_owner,omitempty"`
Repository *Repository `json:"repository,omitempty"`
Machine *CodespacesMachine `json:"machine,omitempty"`
DevcontainerPath *string `json:"devcontainer_path,omitempty"`
Prebuild *bool `json:"prebuild,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
LastUsedAt *Timestamp `json:"last_used_at,omitempty"`
State *string `json:"state,omitempty"`
URL *string `json:"url,omitempty"`
GitStatus *CodespacesGitStatus `json:"git_status,omitempty"`
Location *string `json:"location,omitempty"`
IdleTimeoutMinutes *int `json:"idle_timeout_minutes,omitempty"`
WebURL *string `json:"web_url,omitempty"`
MachinesURL *string `json:"machines_url,omitempty"`
StartURL *string `json:"start_url,omitempty"`
StopURL *string `json:"stop_url,omitempty"`
PullsURL *string `json:"pulls_url,omitempty"`
RecentFolders []string `json:"recent_folders,omitempty"`
RuntimeConstraints *CodespacesRuntimeConstraints `json:"runtime_constraints,omitempty"`
PendingOperation *bool `json:"pending_operation,omitempty"`
PendingOperationDisabledReason *string `json:"pending_operation_disabled_reason,omitempty"`
IdleTimeoutNotice *string `json:"idle_timeout_notice,omitempty"`
RetentionPeriodMinutes *int `json:"retention_period_minutes,omitempty"`
RetentionExpiresAt *Timestamp `json:"retention_expires_at,omitempty"`
LastKnownStopNotice *string `json:"last_known_stop_notice,omitempty"`
}
// CodespacesGitStatus represents the git status of a codespace.
type CodespacesGitStatus struct {
Ahead *int `json:"ahead,omitempty"`
Behind *int `json:"behind,omitempty"`
HasUnpushedChanges *bool `json:"has_unpushed_changes,omitempty"`
HasUncommittedChanges *bool `json:"has_uncommitted_changes,omitempty"`
Ref *string `json:"ref,omitempty"`
}
// CodespacesMachine represents the machine type of a codespace.
type CodespacesMachine struct {
Name *string `json:"name,omitempty"`
DisplayName *string `json:"display_name,omitempty"`
OperatingSystem *string `json:"operating_system,omitempty"`
StorageInBytes *int64 `json:"storage_in_bytes,omitempty"`
MemoryInBytes *int64 `json:"memory_in_bytes,omitempty"`
CPUs *int `json:"cpus,omitempty"`
PrebuildAvailability *string `json:"prebuild_availability,omitempty"`
}
// CodespacesRuntimeConstraints represents the runtime constraints of a codespace.
type CodespacesRuntimeConstraints struct {
AllowedPortPrivacySettings []string `json:"allowed_port_privacy_settings,omitempty"`
}
// ListCodespaces represents the response from the list codespaces endpoints.
type ListCodespaces struct {
TotalCount *int `json:"total_count,omitempty"`
Codespaces []*Codespace `json:"codespaces"`
}
// ListInRepo lists codespaces for a user in a repository.
//
// Lists the codespaces associated with a specified repository and the authenticated user.
// You must authenticate using an access token with the codespace scope to use this endpoint.
// GitHub Apps must have read access to the codespaces repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#list-codespaces-in-a-repository-for-the-authenticated-user
func (s *CodespacesService) ListInRepo(ctx context.Context, owner, repo string, opts *ListOptions) (*ListCodespaces, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/codespaces", 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 codespaces *ListCodespaces
resp, err := s.client.Do(ctx, req, &codespaces)
if err != nil {
return nil, resp, err
}
return codespaces, resp, nil
}
// ListOptions represents the options for listing codespaces for a user.
type ListCodespacesOptions struct {
ListOptions
RepositoryID int64 `url:"repository_id,omitempty"`
}
// List lists codespaces for an authenticated user.
//
// Lists the authenticated user's codespaces.
// You must authenticate using an access token with the codespace scope to use this endpoint.
// GitHub Apps must have read access to the codespaces repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#list-codespaces-for-the-authenticated-user
func (s *CodespacesService) List(ctx context.Context, opts *ListCodespacesOptions) (*ListCodespaces, *Response, error) {
u := fmt.Sprint("user/codespaces")
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 codespaces *ListCodespaces
resp, err := s.client.Do(ctx, req, &codespaces)
if err != nil {
return nil, resp, err
}
return codespaces, resp, nil
}
// CreateCodespaceOptions represents options for the creation of a codespace in a repository.
type CreateCodespaceOptions struct {
Ref *string `json:"ref,omitempty"`
// Geo represents the geographic area for this codespace.
// If not specified, the value is assigned by IP.
// This property replaces location, which is being deprecated.
// Geo can be one of: `EuropeWest`, `SoutheastAsia`, `UsEast`, `UsWest`.
Geo *string `json:"geo,omitempty"`
ClientIP *string `json:"client_ip,omitempty"`
Machine *string `json:"machine,omitempty"`
DevcontainerPath *string `json:"devcontainer_path,omitempty"`
MultiRepoPermissionsOptOut *bool `json:"multi_repo_permissions_opt_out,omitempty"`
WorkingDirectory *string `json:"working_directory,omitempty"`
IdleTimeoutMinutes *int `json:"idle_timeout_minutes,omitempty"`
DisplayName *string `json:"display_name,omitempty"`
// RetentionPeriodMinutes represents the duration in minutes after codespace has gone idle in which it will be deleted.
// Must be integer minutes between 0 and 43200 (30 days).
RetentionPeriodMinutes *int `json:"retention_period_minutes,omitempty"`
}
// CreateInRepo creates a codespace in a repository.
//
// Creates a codespace owned by the authenticated user in the specified repository.
// You must authenticate using an access token with the codespace scope to use this endpoint.
// GitHub Apps must have write access to the codespaces repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#create-a-codespace-in-a-repository
func (s *CodespacesService) CreateInRepo(ctx context.Context, owner, repo string, request *CreateCodespaceOptions) (*Codespace, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/codespaces", owner, repo)
req, err := s.client.NewRequest("POST", u, request)
if err != nil {
return nil, nil, err
}
var codespace *Codespace
resp, err := s.client.Do(ctx, req, &codespace)
if err != nil {
return nil, resp, err
}
return codespace, resp, nil
}
// Start starts a codespace.
//
// You must authenticate using an access token with the codespace scope to use this endpoint.
// GitHub Apps must have write access to the codespaces_lifecycle_admin repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#start-a-codespace-for-the-authenticated-user
func (s *CodespacesService) Start(ctx context.Context, codespaceName string) (*Codespace, *Response, error) {
u := fmt.Sprintf("user/codespaces/%v/start", codespaceName)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
var codespace *Codespace
resp, err := s.client.Do(ctx, req, &codespace)
if err != nil {
return nil, resp, err
}
return codespace, resp, nil
}
// Stop stops a codespace.
//
// You must authenticate using an access token with the codespace scope to use this endpoint.
// GitHub Apps must have write access to the codespaces_lifecycle_admin repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#stop-a-codespace-for-the-authenticated-user
func (s *CodespacesService) Stop(ctx context.Context, codespaceName string) (*Codespace, *Response, error) {
u := fmt.Sprintf("user/codespaces/%v/stop", codespaceName)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
var codespace *Codespace
resp, err := s.client.Do(ctx, req, &codespace)
if err != nil {
return nil, resp, err
}
return codespace, resp, nil
}
// Delete deletes a codespace.
//
// You must authenticate using an access token with the codespace scope to use this endpoint.
// GitHub Apps must have write access to the codespaces repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/codespaces?apiVersion=2022-11-28#delete-a-codespace-for-the-authenticated-user
func (s *CodespacesService) Delete(ctx context.Context, codespaceName string) (*Response, error) {
u := fmt.Sprintf("user/codespaces/%v", codespaceName)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}

View file

@ -0,0 +1,405 @@
// Copyright 2023 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"
)
// ListUserSecrets list all secrets available for a users codespace
//
// Lists all secrets available for a user's Codespaces without revealing their encrypted values
// You must authenticate using an access token with the codespace or codespace:secrets scope to use this endpoint. User must have Codespaces access to use this endpoint
// GitHub Apps must have read access to the codespaces_user_secrets user permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#list-secrets-for-the-authenticated-user
func (s *CodespacesService) ListUserSecrets(ctx context.Context, opts *ListOptions) (*Secrets, *Response, error) {
u, err := addOptions("user/codespaces/secrets", opts)
if err != nil {
return nil, nil, err
}
return s.listSecrets(ctx, u)
}
// ListOrgSecrets list all secrets available to an org
//
// Lists all Codespaces secrets available at the organization-level without revealing their encrypted values. You must authenticate using an access token with the admin:org scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/organization-secrets?apiVersion=2022-11-28#list-organization-secrets
func (s *CodespacesService) ListOrgSecrets(ctx context.Context, org string, opts *ListOptions) (*Secrets, *Response, error) {
u := fmt.Sprintf("orgs/%v/codespaces/secrets", org)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
return s.listSecrets(ctx, u)
}
// ListRepoSecrets list all secrets available to a repo
//
// Lists all secrets available in a repository without revealing their encrypted values. You must authenticate using an access token with the repo scope to use this endpoint. GitHub Apps must have write access to the codespaces_secrets repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/repository-secrets?apiVersion=2022-11-28#list-repository-secrets
func (s *CodespacesService) ListRepoSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/codespaces/secrets", owner, repo)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
return s.listSecrets(ctx, u)
}
func (s *CodespacesService) listSecrets(ctx context.Context, url string) (*Secrets, *Response, error) {
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
var secrets *Secrets
resp, err := s.client.Do(ctx, req, &secrets)
if err != nil {
return nil, resp, err
}
return secrets, resp, nil
}
// GetUserPublicKey gets the users public key for encrypting codespace secrets
//
// Gets your public key, which you need to encrypt secrets. You need to encrypt a secret before you can create or update secrets.
// You must authenticate using an access token with the codespace or codespace:secrets scope to use this endpoint. User must have Codespaces access to use this endpoint.
// GitHub Apps must have read access to the codespaces_user_secrets user permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#get-public-key-for-the-authenticated-user
func (s *CodespacesService) GetUserPublicKey(ctx context.Context) (*PublicKey, *Response, error) {
return s.getPublicKey(ctx, "user/codespaces/secrets/public-key")
}
// GetOrgPublicKey gets the org public key for encrypting codespace secrets
//
// Gets a public key for an organization, which is required in order to encrypt secrets. You need to encrypt the value of a secret before you can create or update secrets. You must authenticate using an access token with the admin:org scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/organization-secrets?apiVersion=2022-11-28#get-an-organization-public-key
func (s *CodespacesService) GetOrgPublicKey(ctx context.Context, org string) (*PublicKey, *Response, error) {
return s.getPublicKey(ctx, fmt.Sprintf("orgs/%v/codespaces/secrets/public-key", org))
}
// GetRepoPublicKey gets the repo public key for encrypting codespace secrets
//
// Gets your public key, which you need to encrypt secrets. You need to encrypt a secret before you can create or update secrets. Anyone with read access to the repository can use this endpoint. If the repository is private you must use an access token with the repo scope. GitHub Apps must have write access to the codespaces_secrets repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/repository-secrets?apiVersion=2022-11-28#get-a-repository-public-key
func (s *CodespacesService) GetRepoPublicKey(ctx context.Context, owner, repo string) (*PublicKey, *Response, error) {
return s.getPublicKey(ctx, fmt.Sprintf("repos/%v/%v/codespaces/secrets/public-key", owner, repo))
}
func (s *CodespacesService) getPublicKey(ctx context.Context, url string) (*PublicKey, *Response, error) {
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
var publicKey *PublicKey
resp, err := s.client.Do(ctx, req, &publicKey)
if err != nil {
return nil, resp, err
}
return publicKey, resp, nil
}
// GetUserSecret gets a users codespace secret
//
// Gets a secret available to a user's codespaces without revealing its encrypted value.
// You must authenticate using an access token with the codespace or codespace:secrets scope to use this endpoint. User must have Codespaces access to use this endpoint.
// GitHub Apps must have read access to the codespaces_user_secrets user permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#get-a-secret-for-the-authenticated-user
func (s *CodespacesService) GetUserSecret(ctx context.Context, name string) (*Secret, *Response, error) {
u := fmt.Sprintf("user/codespaces/secrets/%v", name)
return s.getSecret(ctx, u)
}
// GetOrgSecret gets an org codespace secret
//
// Gets an organization secret without revealing its encrypted value. You must authenticate using an access token with the admin:org scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/organization-secrets?apiVersion=2022-11-28#get-an-organization-secret
func (s *CodespacesService) GetOrgSecret(ctx context.Context, org, name string) (*Secret, *Response, error) {
u := fmt.Sprintf("orgs/%v/codespaces/secrets/%v", org, name)
return s.getSecret(ctx, u)
}
// GetRepoSecret gets a repo codespace secret
//
// Gets a single repository secret without revealing its encrypted value. You must authenticate using an access token with the repo scope to use this endpoint. GitHub Apps must have write access to the codespaces_secrets repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/repository-secrets?apiVersion=2022-11-28#get-a-repository-secret
func (s *CodespacesService) GetRepoSecret(ctx context.Context, owner, repo, name string) (*Secret, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/codespaces/secrets/%v", owner, repo, name)
return s.getSecret(ctx, u)
}
func (s *CodespacesService) getSecret(ctx context.Context, url string) (*Secret, *Response, error) {
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
var secret *Secret
resp, err := s.client.Do(ctx, req, &secret)
if err != nil {
return nil, resp, err
}
return secret, resp, nil
}
// CreateOrUpdateUserSecret creates or updates a users codespace secret
//
// Creates or updates a secret for a user's codespace with an encrypted value. Encrypt your secret using LibSodium.
// You must authenticate using an access token with the codespace or codespace:secrets scope to use this endpoint. User must also have Codespaces access to use this endpoint.
// GitHub Apps must have write access to the codespaces_user_secrets user permission and codespaces_secrets repository permission on all referenced repositories to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#create-or-update-a-secret-for-the-authenticated-user
func (s *CodespacesService) CreateOrUpdateUserSecret(ctx context.Context, eSecret *EncryptedSecret) (*Response, error) {
u := fmt.Sprintf("user/codespaces/secrets/%v", eSecret.Name)
return s.createOrUpdateSecret(ctx, u, eSecret)
}
// CreateOrUpdateOrgSecret creates or updates an orgs codespace secret
//
// Creates or updates an organization secret with an encrypted value. Encrypt your secret using LibSodium. You must authenticate using an access token with the admin:org scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/organization-secrets?apiVersion=2022-11-28#create-or-update-an-organization-secret
func (s *CodespacesService) CreateOrUpdateOrgSecret(ctx context.Context, org string, eSecret *EncryptedSecret) (*Response, error) {
u := fmt.Sprintf("orgs/%v/codespaces/secrets/%v", org, eSecret.Name)
return s.createOrUpdateSecret(ctx, u, eSecret)
}
// CreateOrUpdateRepoSecret creates or updates a repos codespace secret
//
// Creates or updates a repository secret with an encrypted value. Encrypt your secret using LibSodium. You must authenticate using an access token with the repo scope to use this endpoint. GitHub Apps must have write access to the codespaces_secrets repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/repository-secrets?apiVersion=2022-11-28#create-or-update-a-repository-secret
func (s *CodespacesService) CreateOrUpdateRepoSecret(ctx context.Context, owner, repo string, eSecret *EncryptedSecret) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/codespaces/secrets/%v", owner, repo, eSecret.Name)
return s.createOrUpdateSecret(ctx, u, eSecret)
}
func (s *CodespacesService) createOrUpdateSecret(ctx context.Context, url string, eSecret *EncryptedSecret) (*Response, error) {
req, err := s.client.NewRequest("PUT", url, eSecret)
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
if err != nil {
return resp, err
}
return resp, nil
}
// DeleteUserSecret deletes a users codespace secret
//
// Deletes a secret from a user's codespaces using the secret name. Deleting the secret will remove access from all codespaces that were allowed to access the secret.
// You must authenticate using an access token with the codespace or codespace:secrets scope to use this endpoint. User must have Codespaces access to use this endpoint.
// GitHub Apps must have write access to the codespaces_user_secrets user permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#delete-a-secret-for-the-authenticated-user
func (s *CodespacesService) DeleteUserSecret(ctx context.Context, name string) (*Response, error) {
u := fmt.Sprintf("user/codespaces/secrets/%v", name)
return s.deleteSecret(ctx, u)
}
// DeleteOrgSecret deletes an orgs codespace secret
//
// Deletes an organization secret using the secret name. You must authenticate using an access token with the admin:org scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/organization-secrets?apiVersion=2022-11-28#delete-an-organization-secret
func (s *CodespacesService) DeleteOrgSecret(ctx context.Context, org, name string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/codespaces/secrets/%v", org, name)
return s.deleteSecret(ctx, u)
}
// DeleteRepoSecret deletes a repos codespace secret
//
// Deletes a secret in a repository using the secret name. You must authenticate using an access token with the repo scope to use this endpoint. GitHub Apps must have write access to the codespaces_secrets repository permission to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/repository-secrets?apiVersion=2022-11-28#delete-a-repository-secret
func (s *CodespacesService) DeleteRepoSecret(ctx context.Context, owner, repo, name string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/codespaces/secrets/%v", owner, repo, name)
return s.deleteSecret(ctx, u)
}
func (s *CodespacesService) deleteSecret(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest("DELETE", url, nil)
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
if err != nil {
return resp, err
}
return resp, nil
}
// ListSelectedReposForUserSecret lists the repositories that have been granted the ability to use a user's codespace secret.
//
// You must authenticate using an access token with the codespace or codespace:secrets scope to use this endpoint. User must have Codespaces access to use this endpoint.
// GitHub Apps must have read access to the codespaces_user_secrets user permission and write access to the codespaces_secrets repository permission on all referenced repositories to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#list-selected-repositories-for-a-user-secret
func (s *CodespacesService) ListSelectedReposForUserSecret(ctx context.Context, name string, opts *ListOptions) (*SelectedReposList, *Response, error) {
u := fmt.Sprintf("user/codespaces/secrets/%v/repositories", name)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
return s.listSelectedReposForSecret(ctx, u)
}
// ListSelectedReposForOrgSecret lists the repositories that have been granted the ability to use an organization's codespace secret.
//
// Lists all repositories that have been selected when the visibility for repository access to a secret is set to selected. You must authenticate using an access token with the admin:org scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/en/rest/codespaces/organization-secrets?apiVersion=2022-11-28#list-selected-repositories-for-an-organization-secret
func (s *CodespacesService) ListSelectedReposForOrgSecret(ctx context.Context, org, name string, opts *ListOptions) (*SelectedReposList, *Response, error) {
u := fmt.Sprintf("orgs/%v/codespaces/secrets/%v/repositories", org, name)
u, err := addOptions(u, opts)
if err != nil {
return nil, nil, err
}
return s.listSelectedReposForSecret(ctx, u)
}
func (s *CodespacesService) listSelectedReposForSecret(ctx context.Context, url string) (*SelectedReposList, *Response, error) {
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
var repositories *SelectedReposList
resp, err := s.client.Do(ctx, req, &repositories)
if err != nil {
return nil, resp, err
}
return repositories, resp, nil
}
// SetSelectedReposForUserSecret sets the repositories that have been granted the ability to use a user's codespace secret.
//
// You must authenticate using an access token with the codespace or codespace:secrets scope to use this endpoint. User must have Codespaces access to use this endpoint.
// GitHub Apps must have write access to the codespaces_user_secrets user permission and write access to the codespaces_secrets repository permission on all referenced repositories to use this endpoint.
//
// Github API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#set-selected-repositories-for-a-user-secret
func (s *CodespacesService) SetSelectedReposForUserSecret(ctx context.Context, name string, ids SelectedRepoIDs) (*Response, error) {
u := fmt.Sprintf("user/codespaces/secrets/%v/repositories", name)
return s.setSelectedRepoForSecret(ctx, u, ids)
}
// SetSelectedReposForOrgSecret sets the repositories that have been granted the ability to use a user's codespace secret.
//
// Replaces all repositories for an organization secret when the visibility for repository access is set to selected. The visibility is set when you Create or update an organization secret. You must authenticate using an access token with the admin:org scope to use this endpoint.
//
// Github API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#set-selected-repositories-for-a-user-secret
func (s *CodespacesService) SetSelectedReposForOrgSecret(ctx context.Context, org, name string, ids SelectedRepoIDs) (*Response, error) {
u := fmt.Sprintf("orgs/%v/codespaces/secrets/%v/repositories", org, name)
return s.setSelectedRepoForSecret(ctx, u, ids)
}
func (s *CodespacesService) setSelectedRepoForSecret(ctx context.Context, url string, ids SelectedRepoIDs) (*Response, error) {
type repoIDs struct {
SelectedIDs SelectedRepoIDs `json:"selected_repository_ids"`
}
req, err := s.client.NewRequest("PUT", url, repoIDs{SelectedIDs: ids})
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
if err != nil {
return resp, err
}
return resp, nil
}
// AddSelectedRepoToUserSecret adds a repository to the list of repositories that have been granted the ability to use a user's codespace secret.
//
// Adds a repository to the selected repositories for a user's codespace secret. You must authenticate using an access token with the codespace or codespace:secrets scope to use this endpoint. User must have Codespaces access to use this endpoint. GitHub Apps must have write access to the codespaces_user_secrets user permission and write access to the codespaces_secrets repository permission on the referenced repository to use this endpoint.
//
// Github API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#add-a-selected-repository-to-a-user-secret
func (s *CodespacesService) AddSelectedRepoToUserSecret(ctx context.Context, name string, repo *Repository) (*Response, error) {
u := fmt.Sprintf("user/codespaces/secrets/%v/repositories/%v", name, *repo.ID)
return s.addSelectedRepoToSecret(ctx, u)
}
// AddSelectedRepoToOrgSecret adds a repository to the list of repositories that have been granted the ability to use an organization's codespace secret.
//
// Adds a repository to an organization secret when the visibility for repository access is set to selected. The visibility is set when you Create or update an organization secret. You must authenticate using an access token with the admin:org scope to use this endpoint.
//
// Github API docs: https://docs.github.com/en/rest/codespaces/organization-secrets?apiVersion=2022-11-28#add-selected-repository-to-an-organization-secret
func (s *CodespacesService) AddSelectedRepoToOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) {
u := fmt.Sprintf("orgs/%v/codespaces/secrets/%v/repositories/%v", org, name, *repo.ID)
return s.addSelectedRepoToSecret(ctx, u)
}
func (s *CodespacesService) addSelectedRepoToSecret(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest("PUT", url, nil)
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
if err != nil {
return resp, err
}
return resp, nil
}
// RemoveSelectedRepoFromUserSecret removes a repository from the list of repositories that have been granted the ability to use a user's codespace secret.
//
// Removes a repository from the selected repositories for a user's codespace secret. You must authenticate using an access token with the codespace or codespace:secrets scope to use this endpoint. User must have Codespaces access to use this endpoint. GitHub Apps must have write access to the codespaces_user_secrets user permission to use this endpoint.
//
// Github API docs: https://docs.github.com/en/rest/codespaces/secrets?apiVersion=2022-11-28#remove-a-selected-repository-from-a-user-secret
func (s *CodespacesService) RemoveSelectedRepoFromUserSecret(ctx context.Context, name string, repo *Repository) (*Response, error) {
u := fmt.Sprintf("user/codespaces/secrets/%v/repositories/%v", name, *repo.ID)
return s.removeSelectedRepoFromSecret(ctx, u)
}
// RemoveSelectedRepoFromOrgSecret removes a repository from the list of repositories that have been granted the ability to use an organization's codespace secret.
//
// Removes a repository from an organization secret when the visibility for repository access is set to selected. The visibility is set when you Create or update an organization secret. You must authenticate using an access token with the admin:org scope to use this endpoint.
//
// Github API docs: https://docs.github.com/en/rest/codespaces/organization-secrets?apiVersion=2022-11-28#remove-selected-repository-from-an-organization-secret
func (s *CodespacesService) RemoveSelectedRepoFromOrgSecret(ctx context.Context, org, name string, repo *Repository) (*Response, error) {
u := fmt.Sprintf("orgs/%v/codespaces/secrets/%v/repositories/%v", org, name, *repo.ID)
return s.removeSelectedRepoFromSecret(ctx, u)
}
func (s *CodespacesService) removeSelectedRepoFromSecret(ctx context.Context, url string) (*Response, error) {
req, err := s.client.NewRequest("DELETE", url, nil)
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
if err != nil {
return resp, err
}
return resp, nil
}

View file

@ -62,6 +62,7 @@ type DependabotAlert struct {
DismissedReason *string `json:"dismissed_reason,omitempty"`
DismissedComment *string `json:"dismissed_comment,omitempty"`
FixedAt *Timestamp `json:"fixed_at,omitempty"`
Repository *Repository `json:"repository,omitempty"`
}
// ListAlertsOptions specifies the optional parameters to the DependabotService.ListRepoAlerts

View file

@ -198,7 +198,7 @@ func (s *DependabotService) ListSelectedReposForOrgSecret(ctx context.Context, o
}
// DependabotSecretsSelectedRepoIDs are the repository IDs that have access to the dependabot secrets.
type DependabotSecretsSelectedRepoIDs []string
type DependabotSecretsSelectedRepoIDs []int64
// SetSelectedReposForOrgSecret sets the repositories that have access to a Dependabot secret.
//

View file

@ -8,7 +8,7 @@ Package github provides a client for using the GitHub API.
Usage:
import "github.com/google/go-github/v48/github" // with go modules enabled (GO111MODULE=on or outside GOPATH)
import "github.com/google/go-github/v53/github" // with go modules enabled (GO111MODULE=on or outside GOPATH)
import "github.com/google/go-github/github" // with go modules disabled
Construct a new GitHub client, then use the various services on the client to

View file

@ -0,0 +1,78 @@
// Copyright 2022 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"
)
// EnterpriseSecurityAnalysisSettings represents security analysis settings for an enterprise.
type EnterpriseSecurityAnalysisSettings struct {
AdvancedSecurityEnabledForNewRepositories *bool `json:"advanced_security_enabled_for_new_repositories,omitempty"`
SecretScanningEnabledForNewRepositories *bool `json:"secret_scanning_enabled_for_new_repositories,omitempty"`
SecretScanningPushProtectionEnabledForNewRepositories *bool `json:"secret_scanning_push_protection_enabled_for_new_repositories,omitempty"`
SecretScanningPushProtectionCustomLink *string `json:"secret_scanning_push_protection_custom_link,omitempty"`
}
// GetCodeSecurityAndAnalysis gets code security and analysis features for an enterprise.
//
// GitHub API docs: https://docs.github.com/en/rest/enterprise-admin/code-security-and-analysis?apiVersion=2022-11-28#get-code-security-and-analysis-features-for-an-enterprise
func (s *EnterpriseService) GetCodeSecurityAndAnalysis(ctx context.Context, enterprise string) (*EnterpriseSecurityAnalysisSettings, *Response, error) {
u := fmt.Sprintf("enterprises/%v/code_security_and_analysis", enterprise)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
settings := new(EnterpriseSecurityAnalysisSettings)
resp, err := s.client.Do(ctx, req, settings)
if err != nil {
return nil, resp, err
}
return settings, resp, nil
}
// UpdateCodeSecurityAndAnalysis updates code security and analysis features for new repositories in an enterprise.
//
// GitHub API docs: https://docs.github.com/en/rest/enterprise-admin/code-security-and-analysis?apiVersion=2022-11-28#update-code-security-and-analysis-features-for-an-enterprise
func (s *EnterpriseService) UpdateCodeSecurityAndAnalysis(ctx context.Context, enterprise string, settings *EnterpriseSecurityAnalysisSettings) (*Response, error) {
u := fmt.Sprintf("enterprises/%v/code_security_and_analysis", enterprise)
req, err := s.client.NewRequest("PATCH", u, settings)
if err != nil {
return nil, err
}
resp, err := s.client.Do(ctx, req, nil)
if err != nil {
return resp, err
}
return resp, nil
}
// EnableDisableSecurityFeature enables or disables a security feature for all repositories in an enterprise.
//
// Valid values for securityProduct: "advanced_security", "secret_scanning", "secret_scanning_push_protection".
// Valid values for enablement: "enable_all", "disable_all".
//
// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/code-security-and-analysis?apiVersion=2022-11-28#enable-or-disable-a-security-feature
func (s *EnterpriseService) EnableDisableSecurityFeature(ctx context.Context, enterprise, securityProduct, enablement string) (*Response, error) {
u := fmt.Sprintf("enterprises/%v/%v/%v", enterprise, securityProduct, enablement)
req, err := s.client.NewRequest("POST", 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
}

View file

@ -7,7 +7,6 @@ package github
import (
"encoding/json"
"time"
)
// Event represents a GitHub event.
@ -18,7 +17,7 @@ type Event struct {
Repo *Repository `json:"repo,omitempty"`
Actor *User `json:"actor,omitempty"`
Org *Organization `json:"org,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
ID *string `json:"id,omitempty"`
}
@ -50,10 +49,14 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
payload = &DeployKeyEvent{}
case "DeploymentEvent":
payload = &DeploymentEvent{}
case "DeploymentProtectionRuleEvent":
payload = &DeploymentProtectionRuleEvent{}
case "DeploymentStatusEvent":
payload = &DeploymentStatusEvent{}
case "DiscussionEvent":
payload = &DiscussionEvent{}
case "DiscussionCommentEvent":
payload = &DiscussionCommentEvent{}
case "ForkEvent":
payload = &ForkEvent{}
case "GitHubAppAuthorizationEvent":
@ -124,6 +127,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
payload = &RepositoryVulnerabilityAlertEvent{}
case "SecretScanningAlertEvent":
payload = &SecretScanningAlertEvent{}
case "SecurityAdvisoryEvent":
payload = &SecurityAdvisoryEvent{}
case "StarEvent":
payload = &StarEvent{}
case "StatusEvent":

View file

@ -173,6 +173,25 @@ type DeploymentEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// DeploymentProtectionRuleEvent represents a deployment protection rule event.
// The Webhook event name is "deployment_protection_rule".
//
// GitHub API docs: https://docs.github.com/webhooks-and-events/webhooks/webhook-events-and-payloads#deployment_protection_rule
type DeploymentProtectionRuleEvent struct {
Action *string `json:"action,omitempty"`
Environment *string `json:"environment,omitempty"`
Event *string `json:"event,omitempty"`
// The URL Github provides for a third-party to use in order to pass/fail a deployment gate
DeploymentCallbackURL *string `json:"deployment_callback_url,omitempty"`
Deployment *Deployment `json:"deployment,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Organization *Organization `json:"organization,omitempty"`
PullRequests []*PullRequest `json:"pull_requests,omitempty"`
Sender *User `json:"sender,omitempty"`
Installation *Installation `json:"installation,omitempty"`
}
// DeploymentStatusEvent represents a deployment status.
// The Webhook event name is "deployment_status".
//
@ -189,6 +208,39 @@ type DeploymentStatusEvent struct {
Installation *Installation `json:"installation,omitempty"`
}
// DiscussionCommentEvent represents a webhook event for a comment on discussion.
// The Webhook event name is "discussion_comment".
//
// GitHub API docs: https://docs.github.com/webhooks-and-events/webhooks/webhook-events-and-payloads#discussion_comment
type DiscussionCommentEvent struct {
// Action is the action that was performed on the comment.
// Possible values are: "created", "edited", "deleted". ** check what all can be added
Action *string `json:"action,omitempty"`
Discussion *Discussion `json:"discussion,omitempty"`
Comment *CommentDiscussion `json:"comment,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"`
Installation *Installation `json:"installation,omitempty"`
}
// CommentDiscussion represents a comment in a GitHub DiscussionCommentEvent.
type CommentDiscussion struct {
AuthorAssociation *string `json:"author_association,omitempty"`
Body *string `json:"body,omitempty"`
ChildCommentCount *int `json:"child_comment_count,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
DiscussionID *int64 `json:"discussion_id,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
ID *int64 `json:"id,omitempty"`
NodeID *string `json:"node_id,omitempty"`
ParentID *int64 `json:"parent_id,omitempty"`
Reactions *Reactions `json:"reactions,omitempty"`
RepositoryURL *string `json:"repository_url,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
User *User `json:"user,omitempty"`
}
// DiscussionEvent represents a webhook event for a discussion.
// The Webhook event name is "discussion".
//
@ -299,6 +351,7 @@ type EditChange struct {
Body *EditBody `json:"body,omitempty"`
Base *EditBase `json:"base,omitempty"`
Repo *EditRepo `json:"repository,omitempty"`
Owner *EditOwner `json:"owner,omitempty"`
}
// EditTitle represents a pull-request title change.
@ -327,6 +380,17 @@ type EditRepo struct {
Name *RepoName `json:"name,omitempty"`
}
// EditOwner represents a change of repository ownership.
type EditOwner struct {
OwnerInfo *OwnerInfo `json:"from,omitempty"`
}
// OwnerInfo represents the account info of the owner of the repo (could be User or Organization but both are User structs).
type OwnerInfo struct {
User *User `json:"user,omitempty"`
Org *User `json:"organization,omitempty"`
}
// RepoName represents a change of repository name.
type RepoName struct {
From *string `json:"from,omitempty"`
@ -424,7 +488,7 @@ type InstallationEvent struct {
Repositories []*Repository `json:"repositories,omitempty"`
Sender *User `json:"sender,omitempty"`
Installation *Installation `json:"installation,omitempty"`
// TODO key "requester" is not covered
Requester *User `json:"requester,omitempty"`
}
// InstallationRepositoriesEvent is triggered when a repository is added or
@ -485,6 +549,7 @@ type IssuesEvent struct {
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
Installation *Installation `json:"installation,omitempty"`
Milestone *Milestone `json:"milestone,omitempty"`
}
// LabelEvent is triggered when a repository's label is created, edited, or deleted.
@ -1028,6 +1093,7 @@ type PushEventRepository struct {
SSHURL *string `json:"ssh_url,omitempty"`
CloneURL *string `json:"clone_url,omitempty"`
SVNURL *string `json:"svn_url,omitempty"`
Topics []string `json:"topics,omitempty"`
}
// PushEventRepoOwner is a basic representation of user/org in a PushEvent payload.
@ -1389,4 +1455,6 @@ type CodeScanningAlertEvent struct {
Repo *Repository `json:"repository,omitempty"`
Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"`
Installation *Installation `json:"installation,omitempty"`
}

View file

@ -28,8 +28,8 @@ type Gist struct {
HTMLURL *string `json:"html_url,omitempty"`
GitPullURL *string `json:"git_pull_url,omitempty"`
GitPushURL *string `json:"git_push_url,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
NodeID *string `json:"node_id,omitempty"`
}

View file

@ -8,7 +8,6 @@ package github
import (
"context"
"fmt"
"time"
)
// GistComment represents a Gist comment.
@ -17,7 +16,7 @@ type GistComment struct {
URL *string `json:"url,omitempty"`
Body *string `json:"body,omitempty"`
User *User `json:"user,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
}
func (g GistComment) String() string {

View file

@ -11,9 +11,8 @@ import (
"errors"
"fmt"
"strings"
"time"
"golang.org/x/crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp"
)
// SignatureVerification represents GPG signature verification.
@ -56,7 +55,7 @@ func (c Commit) String() string {
// CommitAuthor represents the author or committer of a commit. The commit
// author may not correspond to a GitHub User.
type CommitAuthor struct {
Date *time.Time `json:"date,omitempty"`
Date *Timestamp `json:"date,omitempty"`
Name *string `json:"name,omitempty"`
Email *string `json:"email,omitempty"`

View file

@ -24,10 +24,11 @@ import (
"time"
"github.com/google/go-querystring/query"
"golang.org/x/oauth2"
)
const (
Version = "v48.2.0"
Version = "v53.2.0"
defaultAPIVersion = "2022-11-28"
defaultBaseURL = "https://api.github.com/"
@ -39,6 +40,7 @@ const (
headerRateRemaining = "X-RateLimit-Remaining"
headerRateReset = "X-RateLimit-Reset"
headerOTP = "X-GitHub-OTP"
headerRetryAfter = "Retry-After"
headerTokenExpiration = "GitHub-Authentication-Token-Expiration"
@ -170,8 +172,9 @@ type Client struct {
// User agent used when communicating with the GitHub API.
UserAgent string
rateMu sync.Mutex
rateLimits [categories]Rate // Rate limits for the client as determined by the most recent API calls.
rateMu sync.Mutex
rateLimits [categories]Rate // Rate limits for the client as determined by the most recent API calls.
secondaryRateLimitReset time.Time // Secondary rate limit reset for the client as determined by the most recent API calls.
common service // Reuse a single struct instead of allocating one for each service on the heap.
@ -184,6 +187,7 @@ type Client struct {
Billing *BillingService
Checks *ChecksService
CodeScanning *CodeScanningService
Codespaces *CodespacesService
Dependabot *DependabotService
Enterprise *EnterpriseService
Gists *GistsService
@ -322,6 +326,7 @@ func NewClient(httpClient *http.Client) *Client {
c.Billing = (*BillingService)(&c.common)
c.Checks = (*ChecksService)(&c.common)
c.CodeScanning = (*CodeScanningService)(&c.common)
c.Codespaces = (*CodespacesService)(&c.common)
c.Dependabot = (*DependabotService)(&c.common)
c.Enterprise = (*EnterpriseService)(&c.common)
c.Gists = (*GistsService)(&c.common)
@ -346,6 +351,16 @@ func NewClient(httpClient *http.Client) *Client {
return c
}
// NewClientWithEnvProxy enhances NewClient with the HttpProxy env.
func NewClientWithEnvProxy() *Client {
return NewClient(&http.Client{Transport: &http.Transport{Proxy: http.ProxyFromEnvironment}})
}
// NewTokenClient returns a new GitHub API client authenticated with the provided token.
func NewTokenClient(ctx context.Context, token string) *Client {
return NewClient(oauth2.NewClient(ctx, oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})))
}
// NewEnterpriseClient returns a new GitHub API client with provided
// base URL and upload URL (often is your GitHub Enterprise hostname).
// If the base URL does not have the suffix "/api/v3/", it will be added automatically.
@ -564,7 +579,8 @@ type Response struct {
// propagate to Response.
Rate Rate
// token's expiration date
// token's expiration date. Timestamp is 0001-01-01 when token doesn't expire.
// So it is valid for TokenExpiration.Equal(Timestamp{}) or TokenExpiration.Time.After(time.Now())
TokenExpiration Timestamp
}
@ -664,15 +680,44 @@ func parseRate(r *http.Response) Rate {
return rate
}
// parseSecondaryRate parses the secondary rate related headers,
// and returns the time to retry after.
func parseSecondaryRate(r *http.Response) *time.Duration {
// According to GitHub support, the "Retry-After" header value will be
// an integer which represents the number of seconds that one should
// wait before resuming making requests.
if v := r.Header.Get(headerRetryAfter); v != "" {
retryAfterSeconds, _ := strconv.ParseInt(v, 10, 64) // Error handling is noop.
retryAfter := time.Duration(retryAfterSeconds) * time.Second
return &retryAfter
}
// According to GitHub support, endpoints might return x-ratelimit-reset instead,
// as an integer which represents the number of seconds since epoch UTC,
// represting the time to resume making requests.
if v := r.Header.Get(headerRateReset); v != "" {
secondsSinceEpoch, _ := strconv.ParseInt(v, 10, 64) // Error handling is noop.
retryAfter := time.Until(time.Unix(secondsSinceEpoch, 0))
return &retryAfter
}
return nil
}
// parseTokenExpiration parses the TokenExpiration related headers.
// Returns 0001-01-01 if the header is not defined or could not be parsed.
func parseTokenExpiration(r *http.Response) Timestamp {
var exp Timestamp
if v := r.Header.Get(headerTokenExpiration); v != "" {
if t, err := time.Parse("2006-01-02 03:04:05 MST", v); err == nil {
exp = Timestamp{t.Local()}
if t, err := time.Parse("2006-01-02 15:04:05 MST", v); err == nil {
return Timestamp{t.Local()}
}
// Some tokens include the timezone offset instead of the timezone.
// https://github.com/google/go-github/issues/2649
if t, err := time.Parse("2006-01-02 15:04:05 -0700", v); err == nil {
return Timestamp{t.Local()}
}
}
return exp
return Timestamp{} // 0001-01-01 00:00:00
}
type requestContext uint8
@ -696,7 +741,7 @@ func (c *Client) BareDo(ctx context.Context, req *http.Request) (*Response, erro
req = withContext(ctx, req)
rateLimitCategory := category(req.URL.Path)
rateLimitCategory := category(req.Method, req.URL.Path)
if bypass := ctx.Value(bypassRateLimitCheck); bypass == nil {
// If we've hit rate limit, don't make further requests before Reset time.
@ -706,6 +751,12 @@ func (c *Client) BareDo(ctx context.Context, req *http.Request) (*Response, erro
Rate: err.Rate,
}, err
}
// If we've hit a secondary rate limit, don't make further requests before Retry After.
if err := c.checkSecondaryRateLimitBeforeDo(ctx, req); err != nil {
return &Response{
Response: err.Response,
}, err
}
}
resp, err := c.client.Do(req)
@ -757,6 +808,14 @@ func (c *Client) BareDo(ctx context.Context, req *http.Request) (*Response, erro
aerr.Raw = b
err = aerr
}
// Update the secondary rate limit if we hit it.
rerr, ok := err.(*AbuseRateLimitError)
if ok && rerr.RetryAfter != nil {
c.rateMu.Lock()
c.secondaryRateLimitReset = time.Now().Add(*rerr.RetryAfter)
c.rateMu.Unlock()
}
}
return response, err
}
@ -821,6 +880,35 @@ func (c *Client) checkRateLimitBeforeDo(req *http.Request, rateLimitCategory rat
return nil
}
// checkSecondaryRateLimitBeforeDo does not make any network calls, but uses existing knowledge from
// current client state in order to quickly check if *AbuseRateLimitError can be immediately returned
// from Client.Do, and if so, returns it so that Client.Do can skip making a network API call unnecessarily.
// Otherwise it returns nil, and Client.Do should proceed normally.
func (c *Client) checkSecondaryRateLimitBeforeDo(ctx context.Context, req *http.Request) *AbuseRateLimitError {
c.rateMu.Lock()
secondary := c.secondaryRateLimitReset
c.rateMu.Unlock()
if !secondary.IsZero() && time.Now().Before(secondary) {
// Create a fake response.
resp := &http.Response{
Status: http.StatusText(http.StatusForbidden),
StatusCode: http.StatusForbidden,
Request: req,
Header: make(http.Header),
Body: io.NopCloser(strings.NewReader("")),
}
retryAfter := time.Until(secondary)
return &AbuseRateLimitError{
Response: resp,
Message: fmt.Sprintf("API secondary rate limit exceeded until %v, not making remote request.", secondary),
RetryAfter: &retryAfter,
}
}
return nil
}
// compareHTTPResponse returns whether two http.Response objects are equal or not.
// Currently, only StatusCode is checked. This function is used when implementing the
// Is(error) bool interface for the custom error types in this package.
@ -841,7 +929,7 @@ An ErrorResponse reports one or more errors caused by an API request.
GitHub API docs: https://docs.github.com/en/rest/#client-errors
*/
type ErrorResponse struct {
Response *http.Response // HTTP response that caused this error
Response *http.Response `json:"-"` // HTTP response that caused this error
Message string `json:"message"` // error message
Errors []Error `json:"errors"` // more detail on individual errors
// Block is only populated on certain types of errors such as code 451.
@ -1095,13 +1183,8 @@ func CheckResponse(r *http.Response) error {
Response: errorResponse.Response,
Message: errorResponse.Message,
}
if v := r.Header["Retry-After"]; len(v) > 0 {
// According to GitHub support, the "Retry-After" header value will be
// an integer which represents the number of seconds that one should
// wait before resuming making requests.
retryAfterSeconds, _ := strconv.ParseInt(v[0], 10, 64) // Error handling is noop.
retryAfter := time.Duration(retryAfterSeconds) * time.Second
abuseRateLimitError.RetryAfter = &retryAfter
if retryAfter := parseSecondaryRate(r); retryAfter != nil {
abuseRateLimitError.RetryAfter = retryAfter
}
return abuseRateLimitError
default:
@ -1191,13 +1274,36 @@ const (
categories // An array of this length will be able to contain all rate limit categories.
)
// category returns the rate limit category of the endpoint, determined by Request.URL.Path.
func category(path string) rateLimitCategory {
// category returns the rate limit category of the endpoint, determined by HTTP method and Request.URL.Path.
func category(method, path string) rateLimitCategory {
switch {
// https://docs.github.com/en/rest/rate-limit#about-rate-limits
default:
// NOTE: coreCategory is returned for actionsRunnerRegistrationCategory too,
// because no API found for this category.
return coreCategory
case strings.HasPrefix(path, "/search/"):
return searchCategory
case path == "/graphql":
return graphqlCategory
case strings.HasPrefix(path, "/app-manifests/") &&
strings.HasSuffix(path, "/conversions") &&
method == http.MethodPost:
return integrationManifestCategory
// https://docs.github.com/en/rest/migrations/source-imports#start-an-import
case strings.HasPrefix(path, "/repos/") &&
strings.HasSuffix(path, "/import") &&
method == http.MethodPut:
return sourceImportCategory
// https://docs.github.com/en/rest/code-scanning#upload-an-analysis-as-sarif-data
case strings.HasSuffix(path, "/code-scanning/sarifs"):
return codeScanningUploadCategory
// https://docs.github.com/en/enterprise-cloud@latest/rest/scim
case strings.HasPrefix(path, "/scim/"):
return scimCategory
}
}

View file

@ -10,7 +10,6 @@ import (
"context"
"encoding/json"
"fmt"
"time"
)
// IssueImportService handles communication with the issue import related
@ -29,9 +28,9 @@ type IssueImportRequest struct {
type IssueImport struct {
Title string `json:"title"`
Body string `json:"body"`
CreatedAt *time.Time `json:"created_at,omitempty"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
ClosedAt *Timestamp `json:"closed_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Assignee *string `json:"assignee,omitempty"`
Milestone *int `json:"milestone,omitempty"`
Closed *bool `json:"closed,omitempty"`
@ -40,7 +39,7 @@ type IssueImport struct {
// Comment represents comments of issue to import.
type Comment struct {
CreatedAt *time.Time `json:"created_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
Body string `json:"body"`
}
@ -53,8 +52,8 @@ type IssueImportResponse struct {
URL *string `json:"url,omitempty"`
ImportIssuesURL *string `json:"import_issues_url,omitempty"`
RepositoryURL *string `json:"repository_url,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Message *string `json:"message,omitempty"`
DocumentationURL *string `json:"documentation_url,omitempty"`
Errors []*IssueImportError `json:"errors,omitempty"`
@ -126,7 +125,7 @@ func (s *IssueImportService) CheckStatus(ctx context.Context, owner, repo string
// CheckStatusSince checks the status of multiple imported issues since a given date.
//
// https://gist.github.com/jonmagic/5282384165e0f86ef105#check-status-of-multiple-issues
func (s *IssueImportService) CheckStatusSince(ctx context.Context, owner, repo string, since time.Time) ([]*IssueImportResponse, *Response, error) {
func (s *IssueImportService) CheckStatusSince(ctx context.Context, owner, repo string, since Timestamp) ([]*IssueImportResponse, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/import/issues?since=%v", owner, repo, since.Format("2006-01-02"))
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {

View file

@ -38,9 +38,9 @@ type Issue struct {
Labels []*Label `json:"labels,omitempty"`
Assignee *User `json:"assignee,omitempty"`
Comments *int `json:"comments,omitempty"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
ClosedAt *Timestamp `json:"closed_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ClosedBy *User `json:"closed_by,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`

View file

@ -18,8 +18,8 @@ type IssueComment struct {
Body *string `json:"body,omitempty"`
User *User `json:"user,omitempty"`
Reactions *Reactions `json:"reactions,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
// AuthorAssociation is the comment author's relationship to the issue's repository.
// Possible values are "COLLABORATOR", "CONTRIBUTOR", "FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR", "MEMBER", "OWNER", or "NONE".
AuthorAssociation *string `json:"author_association,omitempty"`

View file

@ -8,7 +8,6 @@ package github
import (
"context"
"fmt"
"time"
)
// IssueEvent represents an event that occurred around an Issue or Pull Request.
@ -71,7 +70,7 @@ type IssueEvent struct {
//
Event *string `json:"event,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
Issue *Issue `json:"issue,omitempty"`
// Only present on certain events; see above.

View file

@ -8,7 +8,6 @@ package github
import (
"context"
"fmt"
"time"
)
// Milestone represents a GitHub repository milestone.
@ -24,10 +23,10 @@ type Milestone struct {
Creator *User `json:"creator,omitempty"`
OpenIssues *int `json:"open_issues,omitempty"`
ClosedIssues *int `json:"closed_issues,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
DueOn *time.Time `json:"due_on,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ClosedAt *Timestamp `json:"closed_at,omitempty"`
DueOn *Timestamp `json:"due_on,omitempty"`
NodeID *string `json:"node_id,omitempty"`
}

View file

@ -9,7 +9,6 @@ import (
"context"
"fmt"
"strings"
"time"
)
// Timeline represents an event that occurred around an Issue or Pull Request.
@ -118,7 +117,7 @@ type Timeline struct {
// The string SHA of a commit that referenced this Issue or Pull Request.
CommitID *string `json:"commit_id,omitempty"`
// The timestamp indicating when the event occurred.
CreatedAt *time.Time `json:"created_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
// The Label object including `name` and `color` attributes. Only provided for
// 'labeled' and 'unlabeled' events.
Label *Label `json:"label,omitempty"`
@ -144,12 +143,14 @@ type Timeline struct {
// The person requested to review the pull request.
Reviewer *User `json:"requested_reviewer,omitempty"`
// RequestedTeam contains the team requested to review the pull request.
RequestedTeam *Team `json:"requested_team,omitempty"`
// The person who requested a review.
Requester *User `json:"review_requester,omitempty"`
// The review summary text.
Body *string `json:"body,omitempty"`
SubmittedAt *time.Time `json:"submitted_at,omitempty"`
SubmittedAt *Timestamp `json:"submitted_at,omitempty"`
}
// Source represents a reference's source.

View file

@ -55,7 +55,9 @@ var (
"deploy_key": "DeployKeyEvent",
"deployment": "DeploymentEvent",
"deployment_status": "DeploymentStatusEvent",
"deployment_protection_rule": "DeploymentProtectionRuleEvent",
"discussion": "DiscussionEvent",
"discussion_comment": "DiscussionCommentEvent",
"fork": "ForkEvent",
"github_app_authorization": "GitHubAppAuthorizationEvent",
"gollum": "GollumEvent",
@ -91,6 +93,7 @@ var (
"repository_vulnerability_alert": "RepositoryVulnerabilityAlertEvent",
"release": "ReleaseEvent",
"secret_scanning_alert": "SecretScanningAlertEvent",
"security_advisory": "SecurityAdvisoryEvent",
"star": "StarEvent",
"status": "StatusEvent",
"team": "TeamEvent",
@ -147,13 +150,13 @@ func messageMAC(signature string) ([]byte, func() hash.Hash, error) {
return buf, hashFunc, nil
}
// ValidatePayload validates an incoming GitHub Webhook event request body
// ValidatePayloadFromBody validates an incoming GitHub Webhook event request body
// and returns the (JSON) payload.
// The Content-Type header of the payload can be "application/json" or "application/x-www-form-urlencoded".
// If the Content-Type is neither then an error is returned.
// secretToken is the GitHub Webhook secret token.
// If your webhook does not contain a secret token, you can pass nil or an empty slice.
// This is intended for local development purposes only and all webhooks should ideally set up a secret token.
// If your webhook does not contain a secret token, you can pass an empty secretToken.
// Webhooks without a secret token are not secure and should be avoided.
//
// Example usage:
//
@ -200,9 +203,8 @@ func ValidatePayloadFromBody(contentType string, readable io.Reader, signature s
return nil, fmt.Errorf("webhook request has unsupported Content-Type %q", contentType)
}
// Only validate the signature if a secret token exists. This is intended for
// local development only and all webhooks should ideally set up a secret token.
if len(secretToken) > 0 {
// Validate the signature if present or if one is expected (secretToken is non-empty).
if len(secretToken) > 0 || len(signature) > 0 {
if err := ValidateSignature(signature, body, secretToken); err != nil {
return nil, err
}

View file

@ -8,7 +8,6 @@ package github
import (
"context"
"fmt"
"time"
)
// OrganizationsService provides access to the organization related functions
@ -35,10 +34,10 @@ type Organization struct {
PublicGists *int `json:"public_gists,omitempty"`
Followers *int `json:"followers,omitempty"`
Following *int `json:"following,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
TotalPrivateRepos *int `json:"total_private_repos,omitempty"`
OwnedPrivateRepos *int `json:"owned_private_repos,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
TotalPrivateRepos *int64 `json:"total_private_repos,omitempty"`
OwnedPrivateRepos *int64 `json:"owned_private_repos,omitempty"`
PrivateGists *int `json:"private_gists,omitempty"`
DiskUsage *int `json:"disk_usage,omitempty"`
Collaborators *int `json:"collaborators,omitempty"`
@ -122,7 +121,7 @@ type Plan struct {
Name *string `json:"name,omitempty"`
Space *int `json:"space,omitempty"`
Collaborators *int `json:"collaborators,omitempty"`
PrivateRepos *int `json:"private_repos,omitempty"`
PrivateRepos *int64 `json:"private_repos,omitempty"`
FilledSeats *int `json:"filled_seats,omitempty"`
Seats *int `json:"seats,omitempty"`
}
@ -263,6 +262,19 @@ func (s *OrganizationsService) Edit(ctx context.Context, name string, org *Organ
return o, resp, nil
}
// Delete an organization by name.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/orgs#delete-an-organization
func (s *OrganizationsService) Delete(ctx context.Context, org string) (*Response, error) {
u := fmt.Sprintf("orgs/%v", org)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}
// ListInstallations lists installations for an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/orgs#list-app-installations-for-an-organization

View file

@ -0,0 +1,148 @@
// Copyright 2021 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"
)
// GetAuditLogOptions sets up optional parameters to query audit-log endpoint.
type GetAuditLogOptions struct {
Phrase *string `url:"phrase,omitempty"` // A search phrase. (Optional.)
Include *string `url:"include,omitempty"` // Event type includes. Can be one of "web", "git", "all". Default: "web". (Optional.)
Order *string `url:"order,omitempty"` // The order of audit log events. Can be one of "asc" or "desc". Default: "desc". (Optional.)
ListCursorOptions
}
// HookConfig describes metadata about a webhook configuration.
type HookConfig struct {
ContentType *string `json:"content_type,omitempty"`
InsecureSSL *string `json:"insecure_ssl,omitempty"`
URL *string `json:"url,omitempty"`
// Secret is returned obfuscated by GitHub, but it can be set for outgoing requests.
Secret *string `json:"secret,omitempty"`
}
// ActorLocation contains information about reported location for an actor.
type ActorLocation struct {
CountryCode *string `json:"country_code,omitempty"`
}
// PolicyOverrideReason contains user-supplied information about why a policy was overridden.
type PolicyOverrideReason struct {
Code *string `json:"code,omitempty"`
Message *string `json:"message,omitempty"`
}
// AuditEntry describes the fields that may be represented by various audit-log "action" entries.
// For a list of actions see - https://docs.github.com/en/github/setting-up-and-managing-organizations-and-teams/reviewing-the-audit-log-for-your-organization#audit-log-actions
type AuditEntry struct {
ActorIP *string `json:"actor_ip,omitempty"`
Action *string `json:"action,omitempty"` // The name of the action that was performed, for example `user.login` or `repo.create`.
Active *bool `json:"active,omitempty"`
ActiveWas *bool `json:"active_was,omitempty"`
Actor *string `json:"actor,omitempty"` // The actor who performed the action.
ActorLocation *ActorLocation `json:"actor_location,omitempty"`
BlockedUser *string `json:"blocked_user,omitempty"`
Business *string `json:"business,omitempty"`
CancelledAt *Timestamp `json:"cancelled_at,omitempty"`
CompletedAt *Timestamp `json:"completed_at,omitempty"`
Conclusion *string `json:"conclusion,omitempty"`
Config *HookConfig `json:"config,omitempty"`
ConfigWas *HookConfig `json:"config_was,omitempty"`
ContentType *string `json:"content_type,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
DeployKeyFingerprint *string `json:"deploy_key_fingerprint,omitempty"`
DocumentID *string `json:"_document_id,omitempty"`
Emoji *string `json:"emoji,omitempty"`
EnvironmentName *string `json:"environment_name,omitempty"`
Event *string `json:"event,omitempty"`
Events []string `json:"events,omitempty"`
EventsWere []string `json:"events_were,omitempty"`
Explanation *string `json:"explanation,omitempty"`
Fingerprint *string `json:"fingerprint,omitempty"`
HashedToken *string `json:"hashed_token,omitempty"`
HeadBranch *string `json:"head_branch,omitempty"`
HeadSHA *string `json:"head_sha,omitempty"`
HookID *int64 `json:"hook_id,omitempty"`
IsHostedRunner *bool `json:"is_hosted_runner,omitempty"`
JobName *string `json:"job_name,omitempty"`
JobWorkflowRef *string `json:"job_workflow_ref,omitempty"`
LimitedAvailability *bool `json:"limited_availability,omitempty"`
Message *string `json:"message,omitempty"`
Name *string `json:"name,omitempty"`
OAuthApplicationID *int64 `json:"oauth_application_id,omitempty"`
OldUser *string `json:"old_user,omitempty"`
OldPermission *string `json:"old_permission,omitempty"` // The permission level for membership changes, for example `admin` or `read`.
OpenSSHPublicKey *string `json:"openssh_public_key,omitempty"`
OperationType *string `json:"operation_type,omitempty"`
Org *string `json:"org,omitempty"`
OrgID *int64 `json:"org_id,omitempty"`
OverriddenCodes []string `json:"overridden_codes,omitempty"`
Permission *string `json:"permission,omitempty"` // The permission level for membership changes, for example `admin` or `read`.
PreviousVisibility *string `json:"previous_visibility,omitempty"`
ProgrammaticAccessType *string `json:"programmatic_access_type,omitempty"`
PullRequestID *int64 `json:"pull_request_id,omitempty"`
PullRequestTitle *string `json:"pull_request_title,omitempty"`
PullRequestURL *string `json:"pull_request_url,omitempty"`
ReadOnly *string `json:"read_only,omitempty"`
Reasons []*PolicyOverrideReason `json:"reasons,omitempty"`
Repo *string `json:"repo,omitempty"`
Repository *string `json:"repository,omitempty"`
RepositoryPublic *bool `json:"repository_public,omitempty"`
RunAttempt *int64 `json:"run_attempt,omitempty"`
RunnerGroupID *int64 `json:"runner_group_id,omitempty"`
RunnerGroupName *string `json:"runner_group_name,omitempty"`
RunnerID *int64 `json:"runner_id,omitempty"`
RunnerLabels []string `json:"runner_labels,omitempty"`
RunnerName *string `json:"runner_name,omitempty"`
RunNumber *int64 `json:"run_number,omitempty"`
SecretsPassed []string `json:"secrets_passed,omitempty"`
SourceVersion *string `json:"source_version,omitempty"`
StartedAt *Timestamp `json:"started_at,omitempty"`
TargetLogin *string `json:"target_login,omitempty"`
TargetVersion *string `json:"target_version,omitempty"`
Team *string `json:"team,omitempty"`
Timestamp *Timestamp `json:"@timestamp,omitempty"` // The time the audit log event occurred, given as a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time).
TokenID *int64 `json:"token_id,omitempty"`
TokenScopes *string `json:"token_scopes,omitempty"`
Topic *string `json:"topic,omitempty"`
TransportProtocolName *string `json:"transport_protocol_name,omitempty"` // A human readable name for the protocol (for example, HTTP or SSH) used to transfer Git data.
TransportProtocol *int `json:"transport_protocol,omitempty"` // The type of protocol (for example, HTTP=1 or SSH=2) used to transfer Git data.
TriggerID *int64 `json:"trigger_id,omitempty"`
User *string `json:"user,omitempty"` // The user that was affected by the action performed (if available).
UserAgent *string `json:"user_agent,omitempty"`
Visibility *string `json:"visibility,omitempty"` // The repository visibility, for example `public` or `private`.
WorkflowID *int64 `json:"workflow_id,omitempty"`
WorkflowRunID *int64 `json:"workflow_run_id,omitempty"`
}
// GetAuditLog gets the audit-log entries for an organization.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/orgs#get-the-audit-log-for-an-organization
func (s *OrganizationsService) GetAuditLog(ctx context.Context, org string, opts *GetAuditLogOptions) ([]*AuditEntry, *Response, error) {
u := fmt.Sprintf("orgs/%v/audit-log", 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 auditEntries []*AuditEntry
resp, err := s.client.Do(ctx, req, &auditEntries)
if err != nil {
return nil, resp, err
}
return auditEntries, resp, nil
}

View file

@ -32,7 +32,7 @@ type CustomRepoRoles struct {
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/custom-roles#list-custom-repository-roles-in-an-organization
func (s *OrganizationsService) ListCustomRepoRoles(ctx context.Context, org string) (*OrganizationCustomRepoRoles, *Response, error) {
u := fmt.Sprintf("orgs/%v/custom_roles", org)
u := fmt.Sprintf("orgs/%v/custom-repository-roles", org)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
@ -59,9 +59,9 @@ type CreateOrUpdateCustomRoleOptions struct {
// CreateCustomRepoRole creates a custom repository role in this organization.
// In order to create custom repository roles in an organization, the authenticated user must be an organization owner.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/custom-roles#create-a-custom-role
// GitHub API docs: https://docs.github.com/en/rest/orgs/custom-roles#create-a-custom-repository-role
func (s *OrganizationsService) CreateCustomRepoRole(ctx context.Context, org string, opts *CreateOrUpdateCustomRoleOptions) (*CustomRepoRoles, *Response, error) {
u := fmt.Sprintf("orgs/%v/custom_roles", org)
u := fmt.Sprintf("orgs/%v/custom-repository-roles", org)
req, err := s.client.NewRequest("POST", u, opts)
if err != nil {
@ -80,9 +80,9 @@ func (s *OrganizationsService) CreateCustomRepoRole(ctx context.Context, org str
// UpdateCustomRepoRole updates a custom repository role in this organization.
// In order to update custom repository roles in an organization, the authenticated user must be an organization owner.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/custom-roles#update-a-custom-role
// GitHub API docs: https://docs.github.com/en/rest/orgs/custom-roles#update-a-custom-repository-role
func (s *OrganizationsService) UpdateCustomRepoRole(ctx context.Context, org, roleID string, opts *CreateOrUpdateCustomRoleOptions) (*CustomRepoRoles, *Response, error) {
u := fmt.Sprintf("orgs/%v/custom_roles/%v", org, roleID)
u := fmt.Sprintf("orgs/%v/custom-repository-roles/%v", org, roleID)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
@ -101,9 +101,9 @@ func (s *OrganizationsService) UpdateCustomRepoRole(ctx context.Context, org, ro
// DeleteCustomRepoRole deletes an existing custom repository role in this organization.
// In order to delete custom repository roles in an organization, the authenticated user must be an organization owner.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/custom-roles#delete-a-custom-role
// GitHub API docs: https://docs.github.com/en/rest/orgs/custom-roles#delete-a-custom-repository-role
func (s *OrganizationsService) DeleteCustomRepoRole(ctx context.Context, org, roleID string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/custom_roles/%v", org, roleID)
u := fmt.Sprintf("orgs/%v/custom-repository-roles/%v", org, roleID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {

View file

@ -315,8 +315,8 @@ type CreateOrgInvitationOptions struct {
// * billing_manager - Non-owner organization members with ability to
// manage the billing settings of your organization.
// Default is "direct_member".
Role *string `json:"role"`
TeamID []int64 `json:"team_ids"`
Role *string `json:"role,omitempty"`
TeamID []int64 `json:"team_ids,omitempty"`
}
// CreateOrgInvitation invites people to an organization by using their GitHub user ID or their email address.

View file

@ -0,0 +1,105 @@
// Copyright 2023 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"
)
// GetAllOrganizationRulesets gets all the rulesets for the specified organization.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#get-all-organization-repository-rulesets
func (s *OrganizationsService) GetAllOrganizationRulesets(ctx context.Context, org string) ([]*Ruleset, *Response, error) {
u := fmt.Sprintf("orgs/%v/rulesets", org)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var rulesets []*Ruleset
resp, err := s.client.Do(ctx, req, &rulesets)
if err != nil {
return nil, resp, err
}
return rulesets, resp, nil
}
// CreateOrganizationRuleset creates a ruleset for the specified organization.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#create-an-organization-repository-ruleset
func (s *OrganizationsService) CreateOrganizationRuleset(ctx context.Context, org string, rs *Ruleset) (*Ruleset, *Response, error) {
u := fmt.Sprintf("orgs/%v/rulesets", org)
req, err := s.client.NewRequest("POST", u, rs)
if err != nil {
return nil, nil, err
}
var ruleset *Ruleset
resp, err := s.client.Do(ctx, req, &ruleset)
if err != nil {
return nil, resp, err
}
return ruleset, resp, nil
}
// GetOrganizationRuleset gets a ruleset from the specified organization.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#get-an-organization-repository-ruleset
func (s *OrganizationsService) GetOrganizationRuleset(ctx context.Context, org string, rulesetID int64) (*Ruleset, *Response, error) {
u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var ruleset *Ruleset
resp, err := s.client.Do(ctx, req, &ruleset)
if err != nil {
return nil, resp, err
}
return ruleset, resp, nil
}
// UpdateOrganizationRuleset updates a ruleset from the specified organization.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#update-an-organization-repository-ruleset
func (s *OrganizationsService) UpdateOrganizationRuleset(ctx context.Context, org string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) {
u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID)
req, err := s.client.NewRequest("PUT", u, rs)
if err != nil {
return nil, nil, err
}
var ruleset *Ruleset
resp, err := s.client.Do(ctx, req, &ruleset)
if err != nil {
return nil, resp, err
}
return ruleset, resp, nil
}
// DeleteOrganizationRuleset deletes a ruleset from the specified organization.
//
// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#delete-an-organization-repository-ruleset
func (s *OrganizationsService) DeleteOrganizationRuleset(ctx context.Context, org string, rulesetID int64) (*Response, error) {
u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(ctx, req, nil)
}

View file

@ -9,7 +9,6 @@ import (
"bytes"
"context"
"fmt"
"time"
)
// PullRequestsService handles communication with the pull request related
@ -34,10 +33,10 @@ type PullRequest struct {
Locked *bool `json:"locked,omitempty"`
Title *string `json:"title,omitempty"`
Body *string `json:"body,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
MergedAt *time.Time `json:"merged_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
ClosedAt *Timestamp `json:"closed_at,omitempty"`
MergedAt *Timestamp `json:"merged_at,omitempty"`
Labels []*Label `json:"labels,omitempty"`
User *User `json:"user,omitempty"`
Draft *bool `json:"draft,omitempty"`

View file

@ -33,8 +33,8 @@ type PullRequestComment struct {
OriginalCommitID *string `json:"original_commit_id,omitempty"`
User *User `json:"user,omitempty"`
Reactions *Reactions `json:"reactions,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
// AuthorAssociation is the comment author's relationship to the pull request's repository.
// Possible values are "COLLABORATOR", "CONTRIBUTOR", "FIRST_TIMER", "FIRST_TIME_CONTRIBUTOR", "MEMBER", "OWNER", or "NONE".
AuthorAssociation *string `json:"author_association,omitempty"`

View file

@ -9,7 +9,6 @@ import (
"context"
"errors"
"fmt"
"time"
)
var ErrMixedCommentStyles = errors.New("cannot use both position and side/line form comments")
@ -20,7 +19,7 @@ type PullRequestReview struct {
NodeID *string `json:"node_id,omitempty"`
User *User `json:"user,omitempty"`
Body *string `json:"body,omitempty"`
SubmittedAt *time.Time `json:"submitted_at,omitempty"`
SubmittedAt *Timestamp `json:"submitted_at,omitempty"`
CommitID *string `json:"commit_id,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
PullRequestURL *string `json:"pull_request_url,omitempty"`

View file

@ -68,6 +68,7 @@ type Repository struct {
AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"`
AllowAutoMerge *bool `json:"allow_auto_merge,omitempty"`
AllowForking *bool `json:"allow_forking,omitempty"`
WebCommitSignoffRequired *bool `json:"web_commit_signoff_required,omitempty"`
DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"`
UseSquashPRTitleAsDefault *bool `json:"use_squash_pr_title_as_default,omitempty"`
SquashMergeCommitTitle *string `json:"squash_merge_commit_title,omitempty"` // Can be one of: "PR_TITLE", "COMMIT_OR_PR_TITLE"
@ -495,7 +496,7 @@ func (s *RepositoriesService) CreateFromTemplate(ctx context.Context, templateOw
// Get fetches a repository.
//
// GitHub API docs: https://docs.github.com/en/rest/repos/repos#update-a-repository
// GitHub API docs: https://docs.github.com/en/rest/repos/repos#get-a-repository
func (s *RepositoriesService) Get(ctx context.Context, owner, repo string) (*Repository, *Response, error) {
u := fmt.Sprintf("repos/%v/%v", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
@ -843,10 +844,28 @@ type Protection struct {
AllowForcePushes *AllowForcePushes `json:"allow_force_pushes"`
AllowDeletions *AllowDeletions `json:"allow_deletions"`
RequiredConversationResolution *RequiredConversationResolution `json:"required_conversation_resolution"`
// LockBranch represents if the branch is marked as read-only. If this is true, users will not be able to push to the branch.
LockBranch *bool `json:"lock_branch,omitempty"`
// AllowForkSyncing represents whether users can pull changes from upstream when the branch is locked.
AllowForkSyncing *bool `json:"allow_fork_syncing,omitempty"`
BlockCreations *BlockCreations `json:"block_creations,omitempty"`
LockBranch *LockBranch `json:"lock_branch,omitempty"`
AllowForkSyncing *AllowForkSyncing `json:"allow_fork_syncing,omitempty"`
RequiredSignatures *SignaturesProtectedBranch `json:"required_signatures,omitempty"`
URL *string `json:"url,omitempty"`
}
// BlockCreations represents whether users can push changes that create branches. If this is true, this
// setting blocks pushes that create new branches, unless the push is initiated by a user, team, or app
// which has the ability to push.
type BlockCreations struct {
Enabled *bool `json:"enabled,omitempty"`
}
// LockBranch represents if the branch is marked as read-only. If this is true, users will not be able to push to the branch.
type LockBranch struct {
Enabled *bool `json:"enabled,omitempty"`
}
// AllowForkSyncing represents whether users can pull changes from upstream when the branch is locked.
type AllowForkSyncing struct {
Enabled *bool `json:"enabled,omitempty"`
}
// BranchProtectionRule represents the rule applied to a repositories branch.
@ -986,6 +1005,14 @@ type ProtectionRequest struct {
// RequiredConversationResolution, if set to true, requires all comments
// on the pull request to be resolved before it can be merged to a protected branch.
RequiredConversationResolution *bool `json:"required_conversation_resolution,omitempty"`
// BlockCreations, if set to true, will cause the restrictions setting to also block pushes
// which create new branches, unless initiated by a user, team, app with the ability to push.
BlockCreations *bool `json:"block_creations,omitempty"`
// LockBranch, if set to true, will prevent users from pushing to the branch.
LockBranch *bool `json:"lock_branch,omitempty"`
// AllowForkSyncing, if set to true, will allow users to pull changes from upstream
// when the branch is locked.
AllowForkSyncing *bool `json:"allow_fork_syncing,omitempty"`
}
// RequiredStatusChecks represents the protection status of a individual branch.
@ -998,7 +1025,9 @@ type RequiredStatusChecks struct {
Contexts []string `json:"contexts,omitempty"`
// The list of status checks to require in order to merge into this
// branch.
Checks []*RequiredStatusCheck `json:"checks"`
Checks []*RequiredStatusCheck `json:"checks"`
ContextsURL *string `json:"contexts_url,omitempty"`
URL *string `json:"url,omitempty"`
}
// RequiredStatusChecksRequest represents a request to edit a protected branch's status checks.
@ -1056,6 +1085,8 @@ type PullRequestReviewsEnforcementRequest struct {
// RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged.
// Valid values are 1-6.
RequiredApprovingReviewCount int `json:"required_approving_review_count"`
// RequireLastPushApproval specifies whether the last pusher to a pull request branch can approve it.
RequireLastPushApproval *bool `json:"require_last_push_approval,omitempty"`
}
// PullRequestReviewsEnforcementUpdate represents request to patch the pull request review
@ -1170,7 +1201,7 @@ type DismissalRestrictionsRequest struct {
Users *[]string `json:"users,omitempty"`
// The list of team slugs which can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.)
Teams *[]string `json:"teams,omitempty"`
// The list of apps which can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.)
// The list of app slugs which can dismiss pull request reviews. (Required; use nil to disable dismissal_restrictions or &[]string{} otherwise.)
Apps *[]string `json:"apps,omitempty"`
}
@ -1666,6 +1697,8 @@ func (s *RepositoriesService) ReplaceAllTopics(ctx context.Context, owner, repo
// It requires the GitHub apps to have `write` access to the `content` permission.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-apps-with-access-to-the-protected-branch
//
// Deprecated: Please use ListAppRestrictions instead.
func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
req, err := s.client.NewRequest("GET", u, nil)
@ -1682,6 +1715,16 @@ func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch
return apps, resp, nil
}
// ListAppRestrictions lists the GitHub apps that have push access to a given protected branch.
// It requires the GitHub apps to have `write` access to the `content` permission.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-apps-with-access-to-the-protected-branch
//
// Note: This is a wrapper around ListApps so a naming convention with ListUserRestrictions and ListTeamRestrictions is preserved.
func (s *RepositoriesService) ListAppRestrictions(ctx context.Context, owner, repo, branch string) ([]*App, *Response, error) {
return s.ListApps(ctx, owner, repo, branch)
}
// ReplaceAppRestrictions replaces the apps that have push access to a given protected branch.
// It removes all apps that previously had push access and grants push access to the new list of apps.
// It requires the GitHub apps to have `write` access to the `content` permission.
@ -1689,20 +1732,20 @@ func (s *RepositoriesService) ListApps(ctx context.Context, owner, repo, branch
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-app-access-restrictions
func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) {
func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner, repo, branch string, apps []string) ([]*App, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
req, err := s.client.NewRequest("PUT", u, slug)
req, err := s.client.NewRequest("PUT", u, apps)
if err != nil {
return nil, nil, err
}
var apps []*App
resp, err := s.client.Do(ctx, req, &apps)
var newApps []*App
resp, err := s.client.Do(ctx, req, &newApps)
if err != nil {
return nil, resp, err
}
return apps, resp, nil
return newApps, resp, nil
}
// AddAppRestrictions grants the specified apps push access to a given protected branch.
@ -1711,47 +1754,222 @@ func (s *RepositoriesService) ReplaceAppRestrictions(ctx context.Context, owner,
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#add-app-access-restrictions
func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) {
func (s *RepositoriesService) AddAppRestrictions(ctx context.Context, owner, repo, branch string, apps []string) ([]*App, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
req, err := s.client.NewRequest("POST", u, slug)
req, err := s.client.NewRequest("POST", u, apps)
if err != nil {
return nil, nil, err
}
var apps []*App
resp, err := s.client.Do(ctx, req, &apps)
var newApps []*App
resp, err := s.client.Do(ctx, req, &newApps)
if err != nil {
return nil, resp, err
}
return apps, resp, nil
return newApps, resp, nil
}
// RemoveAppRestrictions removes the ability of an app to push to this branch.
// RemoveAppRestrictions removes the restrictions of an app from pushing to this branch.
// It requires the GitHub apps to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-app-access-restrictions
func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, slug []string) ([]*App, *Response, error) {
func (s *RepositoriesService) RemoveAppRestrictions(ctx context.Context, owner, repo, branch string, apps []string) ([]*App, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/apps", owner, repo, branch)
req, err := s.client.NewRequest("DELETE", u, slug)
req, err := s.client.NewRequest("DELETE", u, apps)
if err != nil {
return nil, nil, err
}
var apps []*App
resp, err := s.client.Do(ctx, req, &apps)
var newApps []*App
resp, err := s.client.Do(ctx, req, &newApps)
if err != nil {
return nil, resp, err
}
return apps, resp, nil
return newApps, resp, nil
}
// ListTeamRestrictions lists the GitHub teams that have push access to a given protected branch.
// It requires the GitHub teams to have `write` access to the `content` permission.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-teams-with-access-to-the-protected-branch
func (s *RepositoriesService) ListTeamRestrictions(ctx context.Context, owner, repo, branch string) ([]*Team, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch)
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
}
// ReplaceTeamRestrictions replaces the team that have push access to a given protected branch.
// This removes all teams that previously had push access and grants push access to the new list of teams.
// It requires the GitHub teams to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-team-access-restrictions
func (s *RepositoriesService) ReplaceTeamRestrictions(ctx context.Context, owner, repo, branch string, teams []string) ([]*Team, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch)
req, err := s.client.NewRequest("PUT", u, teams)
if err != nil {
return nil, nil, err
}
var newTeams []*Team
resp, err := s.client.Do(ctx, req, &newTeams)
if err != nil {
return nil, resp, err
}
return newTeams, resp, nil
}
// AddTeamRestrictions grants the specified teams push access to a given protected branch.
// It requires the GitHub teams to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#add-team-access-restrictions
func (s *RepositoriesService) AddTeamRestrictions(ctx context.Context, owner, repo, branch string, teams []string) ([]*Team, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch)
req, err := s.client.NewRequest("POST", u, teams)
if err != nil {
return nil, nil, err
}
var newTeams []*Team
resp, err := s.client.Do(ctx, req, &newTeams)
if err != nil {
return nil, resp, err
}
return newTeams, resp, nil
}
// RemoveTeamRestrictions removes the restrictions of a team from pushing to this branch.
// It requires the GitHub teams to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-team-access-restrictions
func (s *RepositoriesService) RemoveTeamRestrictions(ctx context.Context, owner, repo, branch string, teams []string) ([]*Team, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/teams", owner, repo, branch)
req, err := s.client.NewRequest("DELETE", u, teams)
if err != nil {
return nil, nil, err
}
var newTeams []*Team
resp, err := s.client.Do(ctx, req, &newTeams)
if err != nil {
return nil, resp, err
}
return newTeams, resp, nil
}
// ListUserRestrictions lists the GitHub users that have push access to a given protected branch.
// It requires the GitHub users to have `write` access to the `content` permission.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#get-users-with-access-to-the-protected-branch
func (s *RepositoriesService) ListUserRestrictions(ctx context.Context, owner, repo, branch string) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var users []*User
resp, err := s.client.Do(ctx, req, &users)
if err != nil {
return nil, resp, err
}
return users, resp, nil
}
// ReplaceUserRestrictions replaces the user that have push access to a given protected branch.
// It removes all users that previously had push access and grants push access to the new list of users.
// It requires the GitHub users to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#set-team-access-restrictions
func (s *RepositoriesService) ReplaceUserRestrictions(ctx context.Context, owner, repo, branch string, users []string) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch)
req, err := s.client.NewRequest("PUT", u, users)
if err != nil {
return nil, nil, err
}
var newUsers []*User
resp, err := s.client.Do(ctx, req, &newUsers)
if err != nil {
return nil, resp, err
}
return newUsers, resp, nil
}
// AddUserRestrictions grants the specified users push access to a given protected branch.
// It requires the GitHub users to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#add-team-access-restrictions
func (s *RepositoriesService) AddUserRestrictions(ctx context.Context, owner, repo, branch string, users []string) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch)
req, err := s.client.NewRequest("POST", u, users)
if err != nil {
return nil, nil, err
}
var newUsers []*User
resp, err := s.client.Do(ctx, req, &newUsers)
if err != nil {
return nil, resp, err
}
return newUsers, resp, nil
}
// RemoveUserRestrictions removes the restrictions of a user from pushing to this branch.
// It requires the GitHub users to have `write` access to the `content` permission.
//
// Note: The list of users, apps, and teams in total is limited to 100 items.
//
// GitHub API docs: https://docs.github.com/en/rest/branches/branch-protection#remove-team-access-restrictions
func (s *RepositoriesService) RemoveUserRestrictions(ctx context.Context, owner, repo, branch string, users []string) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v/protection/restrictions/users", owner, repo, branch)
req, err := s.client.NewRequest("DELETE", u, users)
if err != nil {
return nil, nil, err
}
var newUsers []*User
resp, err := s.client.Do(ctx, req, &newUsers)
if err != nil {
return nil, resp, err
}
return newUsers, resp, nil
}
// TransferRequest represents a request to transfer a repository.
type TransferRequest struct {
NewOwner string `json:"new_owner"`
NewName *string `json:"new_name,omitempty"`
TeamID []int64 `json:"team_ids,omitempty"`
}

Some files were not shown because too many files have changed in this diff Show more