Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions github/actions_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,24 @@ type TotalCacheUsage struct {
TotalActiveCachesCount int `json:"total_active_caches_count"`
}

// ActionsCacheRetentionLimit represents the GitHub Actions cache retention limit for an organization.
//
// GitHub API docs: https://docs.github.com/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-retention-limit-for-an-organization
type ActionsCacheRetentionLimit struct {
// MaxCacheRetentionDays is the maximum duration, in days, for which caches
// in a repository may be retained.
MaxCacheRetentionDays *int `json:"max_cache_retention_days,omitempty"`
}

// ActionsCacheStorageLimit represents the GitHub Actions cache storage limit for an organization.
//
// GitHub API docs: https://docs.github.com/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-storage-limit-for-an-organization
type ActionsCacheStorageLimit struct {
// MaxCacheSizeGB is the maximum size limit for the sum of all caches in a
// repository, in gigabytes.
MaxCacheSizeGB *int `json:"max_cache_size_gb,omitempty"`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI - I just realized that we have not been terribly consistent in the use of integer types for fields representing GigaBytes, so I'm fine to leave this as-is.

$ rg _gb | grep int
github/actions_hosted_runners.go:       MemoryGB  int    `json:"memory_gb"`  // The available RAM for the machine spec. Example: 32
github/actions_hosted_runners.go:       StorageGB int    `json:"storage_gb"` // The available SSD storage for the machine spec. Example: 300
github/actions_hosted_runners.go:       SizeGB      *int64  `json:"size_gb"`      // Image size in GB. Example: 86
github/actions_hosted_runners.go:       SizeGB       int       `json:"size_gb"`
github/actions_hosted_runners.go:       SizeGB      int    `json:"size_gb"`

}

// ActionsCacheListOptions represents a list of all possible optional Query parameters for ListCaches method.
//
// GitHub API docs: https://docs.github.com/rest/actions/cache?apiVersion=2022-11-28#list-github-actions-caches-for-a-repository
Expand Down Expand Up @@ -247,3 +265,87 @@ func (s *ActionsService) GetTotalCacheUsageForEnterprise(ctx context.Context, en

return cacheUsage, res, err
}

// GetCacheRetentionLimitForOrg gets the GitHub Actions cache retention limit for an organization.
// Repositories in the organization may not set a higher cache retention limit.
//
// Permissions: OAuth tokens and personal access tokens (classic) need the admin:organization scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-retention-limit-for-an-organization
//
//meta:operation GET /organizations/{org}/actions/cache/retention-limit
func (s *ActionsService) GetCacheRetentionLimitForOrg(ctx context.Context, org string) (*ActionsCacheRetentionLimit, *Response, error) {
u := fmt.Sprintf("organizations/%v/actions/cache/retention-limit", org)
req, err := s.client.NewRequest(ctx, "GET", u, nil)
if err != nil {
return nil, nil, err
}

var limit *ActionsCacheRetentionLimit
res, err := s.client.Do(req, &limit)
if err != nil {
return nil, res, err
}

return limit, res, nil
}

// SetCacheRetentionLimitForOrg sets the GitHub Actions cache retention limit for an organization.
// Repositories in the organization may not set a higher cache retention limit.
//
// Permissions: OAuth tokens and personal access tokens (classic) need the admin:organization scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/rest/actions/cache?apiVersion=2022-11-28#set-github-actions-cache-retention-limit-for-an-organization
//
//meta:operation PUT /organizations/{org}/actions/cache/retention-limit
func (s *ActionsService) SetCacheRetentionLimitForOrg(ctx context.Context, org string, body ActionsCacheRetentionLimit) (*Response, error) {
u := fmt.Sprintf("organizations/%v/actions/cache/retention-limit", org)
req, err := s.client.NewRequest(ctx, "PUT", u, body)
if err != nil {
return nil, err
}

return s.client.Do(req, nil)
}

// GetCacheStorageLimitForOrg gets the GitHub Actions cache storage limit for an organization.
// Repositories in the organization may not set a higher cache storage limit.
//
// Permissions: OAuth tokens and personal access tokens (classic) need the admin:organization scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/rest/actions/cache?apiVersion=2022-11-28#get-github-actions-cache-storage-limit-for-an-organization
//
//meta:operation GET /organizations/{org}/actions/cache/storage-limit
func (s *ActionsService) GetCacheStorageLimitForOrg(ctx context.Context, org string) (*ActionsCacheStorageLimit, *Response, error) {
u := fmt.Sprintf("organizations/%v/actions/cache/storage-limit", org)
req, err := s.client.NewRequest(ctx, "GET", u, nil)
if err != nil {
return nil, nil, err
}

var limit *ActionsCacheStorageLimit
res, err := s.client.Do(req, &limit)
if err != nil {
return nil, res, err
}

return limit, res, nil
}

// SetCacheStorageLimitForOrg sets the GitHub Actions cache storage limit for an organization.
// Repositories in the organization may not set a higher cache storage limit.
//
// Permissions: OAuth tokens and personal access tokens (classic) need the admin:organization scope to use this endpoint.
//
// GitHub API docs: https://docs.github.com/rest/actions/cache?apiVersion=2022-11-28#set-github-actions-cache-storage-limit-for-an-organization
//
//meta:operation PUT /organizations/{org}/actions/cache/storage-limit
func (s *ActionsService) SetCacheStorageLimitForOrg(ctx context.Context, org string, body ActionsCacheStorageLimit) (*Response, error) {
u := fmt.Sprintf("organizations/%v/actions/cache/storage-limit", org)
req, err := s.client.NewRequest(ctx, "PUT", u, body)
if err != nil {
return nil, err
}

return s.client.Do(req, nil)
}
214 changes: 214 additions & 0 deletions github/actions_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,3 +515,217 @@ func TestActionsService_GetCacheUsageForEnterprise_notFound(t *testing.T) {
t.Errorf("Actions.GetTotalCacheUsageForEnterprise return %+v, want nil", caches)
}
}

func TestActionsService_GetCacheRetentionLimitForOrg(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

mux.HandleFunc("/organizations/o/actions/cache/retention-limit", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"max_cache_retention_days":14}`)
})

ctx := t.Context()
limit, _, err := client.Actions.GetCacheRetentionLimitForOrg(ctx, "o")
if err != nil {
t.Errorf("Actions.GetCacheRetentionLimitForOrg returned error: %v", err)
}

want := &ActionsCacheRetentionLimit{MaxCacheRetentionDays: new(14)}
if !cmp.Equal(limit, want) {
t.Errorf("Actions.GetCacheRetentionLimitForOrg returned %+v, want %+v", limit, want)
}

const methodName = "GetCacheRetentionLimitForOrg"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Actions.GetCacheRetentionLimitForOrg(ctx, "\n")
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Actions.GetCacheRetentionLimitForOrg(ctx, "o")
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestActionsService_GetCacheRetentionLimitForOrg_invalidOrganization(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

ctx := t.Context()
_, _, err := client.Actions.GetCacheRetentionLimitForOrg(ctx, "%")
testURLParseError(t, err)
}

func TestActionsService_GetCacheRetentionLimitForOrg_notFound(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

mux.HandleFunc("/organizations/o/actions/cache/retention-limit", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})

ctx := t.Context()
limit, resp, err := client.Actions.GetCacheRetentionLimitForOrg(ctx, "o")
if err == nil {
t.Error("Expected HTTP 404 response")
}
if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
t.Errorf("Actions.GetCacheRetentionLimitForOrg return status %v, want %v", got, want)
}
if limit != nil {
t.Errorf("Actions.GetCacheRetentionLimitForOrg return %+v, want nil", limit)
}
}

func TestActionsService_SetCacheRetentionLimitForOrg(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

input := ActionsCacheRetentionLimit{MaxCacheRetentionDays: new(14)}

mux.HandleFunc("/organizations/o/actions/cache/retention-limit", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
testJSONBody(t, r, input)
w.WriteHeader(http.StatusNoContent)
})

ctx := t.Context()
resp, err := client.Actions.SetCacheRetentionLimitForOrg(ctx, "o", input)
if err != nil {
t.Errorf("Actions.SetCacheRetentionLimitForOrg returned error: %v", err)
}
if got, want := resp.StatusCode, http.StatusNoContent; got != want {
t.Errorf("Actions.SetCacheRetentionLimitForOrg return status %v, want %v", got, want)
}

const methodName = "SetCacheRetentionLimitForOrg"
testBadOptions(t, methodName, func() (err error) {
_, err = client.Actions.SetCacheRetentionLimitForOrg(ctx, "\n", input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
return client.Actions.SetCacheRetentionLimitForOrg(ctx, "o", input)
})
}

func TestActionsService_SetCacheRetentionLimitForOrg_invalidOrganization(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

ctx := t.Context()
_, err := client.Actions.SetCacheRetentionLimitForOrg(ctx, "%", ActionsCacheRetentionLimit{})
testURLParseError(t, err)
}

func TestActionsService_GetCacheStorageLimitForOrg(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

mux.HandleFunc("/organizations/o/actions/cache/storage-limit", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"max_cache_size_gb":10}`)
})

ctx := t.Context()
limit, _, err := client.Actions.GetCacheStorageLimitForOrg(ctx, "o")
if err != nil {
t.Errorf("Actions.GetCacheStorageLimitForOrg returned error: %v", err)
}

want := &ActionsCacheStorageLimit{MaxCacheSizeGB: new(10)}
if !cmp.Equal(limit, want) {
t.Errorf("Actions.GetCacheStorageLimitForOrg returned %+v, want %+v", limit, want)
}

const methodName = "GetCacheStorageLimitForOrg"
testBadOptions(t, methodName, func() (err error) {
_, _, err = client.Actions.GetCacheStorageLimitForOrg(ctx, "\n")
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Actions.GetCacheStorageLimitForOrg(ctx, "o")
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestActionsService_GetCacheStorageLimitForOrg_invalidOrganization(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

ctx := t.Context()
_, _, err := client.Actions.GetCacheStorageLimitForOrg(ctx, "%")
testURLParseError(t, err)
}

func TestActionsService_GetCacheStorageLimitForOrg_notFound(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

mux.HandleFunc("/organizations/o/actions/cache/storage-limit", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})

ctx := t.Context()
limit, resp, err := client.Actions.GetCacheStorageLimitForOrg(ctx, "o")
if err == nil {
t.Error("Expected HTTP 404 response")
}
if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
t.Errorf("Actions.GetCacheStorageLimitForOrg return status %v, want %v", got, want)
}
if limit != nil {
t.Errorf("Actions.GetCacheStorageLimitForOrg return %+v, want nil", limit)
}
}

func TestActionsService_SetCacheStorageLimitForOrg(t *testing.T) {
t.Parallel()
client, mux, _ := setup(t)

input := ActionsCacheStorageLimit{MaxCacheSizeGB: new(10)}

mux.HandleFunc("/organizations/o/actions/cache/storage-limit", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
testJSONBody(t, r, input)
w.WriteHeader(http.StatusNoContent)
})

ctx := t.Context()
resp, err := client.Actions.SetCacheStorageLimitForOrg(ctx, "o", input)
if err != nil {
t.Errorf("Actions.SetCacheStorageLimitForOrg returned error: %v", err)
}
if got, want := resp.StatusCode, http.StatusNoContent; got != want {
t.Errorf("Actions.SetCacheStorageLimitForOrg return status %v, want %v", got, want)
}

const methodName = "SetCacheStorageLimitForOrg"
testBadOptions(t, methodName, func() (err error) {
_, err = client.Actions.SetCacheStorageLimitForOrg(ctx, "\n", input)
return err
})

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
return client.Actions.SetCacheStorageLimitForOrg(ctx, "o", input)
})
}

func TestActionsService_SetCacheStorageLimitForOrg_invalidOrganization(t *testing.T) {
t.Parallel()
client, _, _ := setup(t)

ctx := t.Context()
_, err := client.Actions.SetCacheStorageLimitForOrg(ctx, "%", ActionsCacheStorageLimit{})
testURLParseError(t, err)
}
16 changes: 16 additions & 0 deletions github/github-accessors.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions github/github-accessors_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading