diff --git a/github/actions_cache.go b/github/actions_cache.go index 73e82700839..41e777f96e2 100644 --- a/github/actions_cache.go +++ b/github/actions_cache.go @@ -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"` +} + // 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 @@ -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) +} diff --git a/github/actions_cache_test.go b/github/actions_cache_test.go index f94c71c2f4c..94909f07c7c 100644 --- a/github/actions_cache_test.go +++ b/github/actions_cache_test.go @@ -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) +} diff --git a/github/github-accessors.go b/github/github-accessors.go index d6eb81ebf72..04e7ca0e54b 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -254,6 +254,22 @@ func (a *ActionsCacheListOptions) GetSort() string { return *a.Sort } +// GetMaxCacheRetentionDays returns the MaxCacheRetentionDays field if it's non-nil, zero value otherwise. +func (a *ActionsCacheRetentionLimit) GetMaxCacheRetentionDays() int { + if a == nil || a.MaxCacheRetentionDays == nil { + return 0 + } + return *a.MaxCacheRetentionDays +} + +// GetMaxCacheSizeGB returns the MaxCacheSizeGB field if it's non-nil, zero value otherwise. +func (a *ActionsCacheStorageLimit) GetMaxCacheSizeGB() int { + if a == nil || a.MaxCacheSizeGB == nil { + return 0 + } + return *a.MaxCacheSizeGB +} + // GetActiveCachesCount returns the ActiveCachesCount field. func (a *ActionsCacheUsage) GetActiveCachesCount() int { if a == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 8d0098a8944..59225cbbca6 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -324,6 +324,28 @@ func TestActionsCacheListOptions_GetSort(tt *testing.T) { a.GetSort() } +func TestActionsCacheRetentionLimit_GetMaxCacheRetentionDays(tt *testing.T) { + tt.Parallel() + var zeroValue int + a := &ActionsCacheRetentionLimit{MaxCacheRetentionDays: &zeroValue} + a.GetMaxCacheRetentionDays() + a = &ActionsCacheRetentionLimit{} + a.GetMaxCacheRetentionDays() + a = nil + a.GetMaxCacheRetentionDays() +} + +func TestActionsCacheStorageLimit_GetMaxCacheSizeGB(tt *testing.T) { + tt.Parallel() + var zeroValue int + a := &ActionsCacheStorageLimit{MaxCacheSizeGB: &zeroValue} + a.GetMaxCacheSizeGB() + a = &ActionsCacheStorageLimit{} + a.GetMaxCacheSizeGB() + a = nil + a.GetMaxCacheSizeGB() +} + func TestActionsCacheUsage_GetActiveCachesCount(tt *testing.T) { tt.Parallel() a := &ActionsCacheUsage{}