From 6ce3f9b7579200c74d3f0b75784de8d63af79bac Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Mon, 6 Jan 2025 17:14:53 +0000 Subject: [PATCH 01/11] feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/enterprise_rules.go | 93 ++ github/enterprise_rules_test.go | 1795 +++++++++++++++++++++++++++++++ github/orgs_rules_test.go | 146 +-- github/repos_rules.go | 17 +- 4 files changed, 1980 insertions(+), 71 deletions(-) create mode 100644 github/enterprise_rules.go create mode 100644 github/enterprise_rules_test.go diff --git a/github/enterprise_rules.go b/github/enterprise_rules.go new file mode 100644 index 00000000000..20b74c001e6 --- /dev/null +++ b/github/enterprise_rules.go @@ -0,0 +1,93 @@ +// Copyright 2025 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" +) + +// CreateEnterpriseRuleset creates a ruleset for the specified enterprise. +// +// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/rules#create-an-enterprise-repository-ruleset +// +//meta:operation POST /enterprises/{enterprise}/rulesets +func (s *EnterpriseService) CreateEnterpriseRuleset(ctx context.Context, enterprise string, rs *Ruleset) (*Ruleset, *Response, error) { + u := fmt.Sprintf("enterprises/%v/rulesets", enterprise) + + 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 +} + +// GetEnterpriseRuleset gets a ruleset from the specified enterprise. +// +// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/rules#get-an-enterprise-repository-ruleset +// +//meta:operation GET /enterprises/{enterprise}/rulesets/{ruleset_id} +func (s *EnterpriseService) GetEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64) (*Ruleset, *Response, error) { + u := fmt.Sprintf("enterprises/%v/rulesets/%v", enterprise, 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 +} + +// UpdateEnterpriseRuleset updates a ruleset from the specified enterprise. +// +// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/rules#update-an-enterprise-repository-ruleset +// +//meta:operation PUT /enterprises/{enterprise}/rulesets/{ruleset_id} +func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { + u := fmt.Sprintf("enterprises/%v/rulesets/%v", enterprise, 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 +} + +// DeleteEnterpriseRuleset deletes a ruleset from the specified enterprise. +// +// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/rules#delete-an-enterprise-repository-ruleset +// +//meta:operation DELETE /enterprises/{enterprise}/rulesets/{ruleset_id} +func (s *EnterpriseService) DeleteEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64) (*Response, error) { + u := fmt.Sprintf("enterprises/%v/rulesets/%v", enterprise, rulesetID) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + return s.client.Do(ctx, req, nil) +} diff --git a/github/enterprise_rules_test.go b/github/enterprise_rules_test.go new file mode 100644 index 00000000000..13150f04a0d --- /dev/null +++ b/github/enterprise_rules_test.go @@ -0,0 +1,1795 @@ +// Copyright 2025 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + enterprise := "e" + rulesetID := int64(21) + + mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets", enterprise), func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprintf(w, `{ + "id": %d, + "name": "ruleset", + "target": "branch", + "source_type": "Enterprise", + "source": "%s", + "enforcement": "active", + "bypass_actors": [ + { + "actor_id": 234, + "actor_type": "Team" + } + ], + "conditions": { + "organization_name": { + "include": [ + "important_organization", + "another_important_organization" + ], + "exclude": [ + "unimportant_organization" + ] + }, + "repository_name": { + "include": [ + "important_repository", + "another_important_repository" + ], + "exclude": [ + "unimportant_repository" + ], + "protected": true + }, + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + } + }, + "rules": [ + { + "type": "creation" + }, + { + "type": "update", + "parameters": { + "update_allows_fetch_and_merge": true + } + }, + { + "type": "deletion" + }, + { + "type": "required_linear_history" + }, + { + "type": "required_deployments", + "parameters": { + "required_deployment_environments": ["test"] + } + }, + { + "type": "required_signatures" + }, + { + "type": "pull_request", + "parameters": { + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": true, + "require_last_push_approval": true, + "required_approving_review_count": 1, + "required_review_thread_resolution": true + } + }, + { + "type": "required_status_checks", + "parameters": { + "required_status_checks": [ + { + "context": "test", + "integration_id": 1 + } + ], + "strict_required_status_checks_policy": true + } + }, + { + "type": "non_fast_forward" + }, + { + "type": "commit_message_pattern", + "parameters": { + "name": "avoid test commits", + "negate": true, + "operator": "starts_with", + "pattern": "[test]" + } + }, + { + "type": "commit_author_email_pattern", + "parameters": { + "operator": "contains", + "pattern": "github" + } + }, + { + "type": "committer_email_pattern", + "parameters": { + "name": "avoid commit emails", + "negate": true, + "operator": "ends_with", + "pattern": "abc" + } + }, + { + "type": "branch_name_pattern", + "parameters": { + "name": "avoid branch names", + "negate": true, + "operator": "regex", + "pattern": "github$" + } + }, + { + "type": "tag_name_pattern", + "parameters": { + "name": "avoid tag names", + "negate": true, + "operator": "contains", + "pattern": "github" + } + }, + { + "type": "code_scanning", + "parameters": { + "code_scanning_tools": [ + { + "tool": "CodeQL", + "security_alerts_threshold": "high_or_higher", + "alerts_threshold": "errors" + } + ] + } + } + ] + }`, rulesetID, enterprise) + }) + + ctx := context.Background() + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, &Ruleset{ + Name: "ruleset", + Target: Ptr("branch"), + Enforcement: "active", + BypassActors: []*BypassActor{ + { + ActorID: Ptr(int64(234)), + ActorType: Ptr("Team"), + }, + }, + Conditions: &RulesetConditions{ + OrganizationName: &RulesetOrganizationNamesConditionParameters{ + Include: []string{"important_organization", "another_important_organization"}, + Exclude: []string{"unimportant_organization"}, + }, + RepositoryName: &RulesetRepositoryNamesConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Ptr(true), + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }), + NewDeletionRule(), + NewRequiredLinearHistoryRule(), + NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ + RequiredDeploymentEnvironments: []string{"test"}, + }), + NewRequiredSignaturesRule(), + NewPullRequestRule(&PullRequestRuleParameters{ + RequireCodeOwnerReview: true, + RequireLastPushApproval: true, + RequiredApprovingReviewCount: 1, + RequiredReviewThreadResolution: true, + DismissStaleReviewsOnPush: true, + }), + NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ + RequiredStatusChecks: []RuleRequiredStatusChecks{ + { + Context: "test", + IntegrationID: Ptr(int64(1)), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: Ptr("avoid test commits"), + Negate: Ptr(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: Ptr("avoid commit emails"), + Negate: Ptr(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid branch names"), + Negate: Ptr(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid tag names"), + Negate: Ptr(true), + Operator: "contains", + Pattern: "github", + }), + NewRequiredCodeScanningRule(&RequiredCodeScanningRuleParameters{ + RequiredCodeScanningTools: []*RuleRequiredCodeScanningTool{ + { + Tool: "CodeQL", + SecurityAlertsThreshold: "high_or_higher", + AlertsThreshold: "errors", + }, + }, + }), + }, + }) + if err != nil { + t.Errorf("Enterprise.CreateEnterpriseRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: Ptr(rulesetID), + Name: "ruleset", + Target: Ptr("branch"), + SourceType: Ptr("Enterprise"), + Source: enterprise, + Enforcement: "active", + BypassActors: []*BypassActor{ + { + ActorID: Ptr(int64(234)), + ActorType: Ptr("Team"), + }, + }, + Conditions: &RulesetConditions{ + OrganizationName: &RulesetOrganizationNamesConditionParameters{ + Include: []string{"important_organization", "another_important_organization"}, + Exclude: []string{"unimportant_organization"}, + }, + RepositoryName: &RulesetRepositoryNamesConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Ptr(true), + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }), + NewDeletionRule(), + NewRequiredLinearHistoryRule(), + NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ + RequiredDeploymentEnvironments: []string{"test"}, + }), + NewRequiredSignaturesRule(), + NewPullRequestRule(&PullRequestRuleParameters{ + RequireCodeOwnerReview: true, + RequireLastPushApproval: true, + RequiredApprovingReviewCount: 1, + RequiredReviewThreadResolution: true, + DismissStaleReviewsOnPush: true, + }), + NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ + RequiredStatusChecks: []RuleRequiredStatusChecks{ + { + Context: "test", + IntegrationID: Ptr(int64(1)), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: Ptr("avoid test commits"), + Negate: Ptr(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: Ptr("avoid commit emails"), + Negate: Ptr(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid branch names"), + Negate: Ptr(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid tag names"), + Negate: Ptr(true), + Operator: "contains", + Pattern: "github", + }), + NewRequiredCodeScanningRule(&RequiredCodeScanningRuleParameters{ + RequiredCodeScanningTools: []*RuleRequiredCodeScanningTool{ + { + Tool: "CodeQL", + SecurityAlertsThreshold: "high_or_higher", + AlertsThreshold: "errors", + }, + }, + }), + }, + } + if !cmp.Equal(ruleset, want) { + t.Errorf("Enterprise.CreateEnterpriseRuleset returned %+v, want %+v", ruleset, want) + } + + const methodName = "CreateEnterpriseRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + enterprise := "e" + rulesetID := int64(21) + + mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets", enterprise), func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprintf(w, `{ + "id": %d, + "name": "ruleset", + "target": "branch", + "source_type": "Enterprise", + "source": "%s", + "enforcement": "active", + "bypass_actors": [ + { + "actor_id": 234, + "actor_type": "Team" + } + ], + "conditions": { + "organization_name": { + "include": [ + "important_organization", + "another_important_organization" + ], + "exclude": [ + "unimportant_organization" + ] + }, + "repository_property": { + "include": [ + { + "name": "testIncludeProp", + "source": "custom", + "property_values": [ + "true" + ] + } + ], + "exclude": [ + { + "name": "testExcludeProp", + "property_values": [ + "false" + ] + } + ] + }, + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + } + }, + "rules": [ + { + "type": "creation" + }, + { + "type": "update", + "parameters": { + "update_allows_fetch_and_merge": true + } + }, + { + "type": "deletion" + }, + { + "type": "required_linear_history" + }, + { + "type": "required_deployments", + "parameters": { + "required_deployment_environments": ["test"] + } + }, + { + "type": "required_signatures" + }, + { + "type": "pull_request", + "parameters": { + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": true, + "require_last_push_approval": true, + "required_approving_review_count": 1, + "required_review_thread_resolution": true + } + }, + { + "type": "required_status_checks", + "parameters": { + "required_status_checks": [ + { + "context": "test", + "integration_id": 1 + } + ], + "strict_required_status_checks_policy": true + } + }, + { + "type": "non_fast_forward" + }, + { + "type": "commit_message_pattern", + "parameters": { + "name": "avoid test commits", + "negate": true, + "operator": "starts_with", + "pattern": "[test]" + } + }, + { + "type": "commit_author_email_pattern", + "parameters": { + "operator": "contains", + "pattern": "github" + } + }, + { + "type": "committer_email_pattern", + "parameters": { + "name": "avoid commit emails", + "negate": true, + "operator": "ends_with", + "pattern": "abc" + } + }, + { + "type": "branch_name_pattern", + "parameters": { + "name": "avoid branch names", + "negate": true, + "operator": "regex", + "pattern": "github$" + } + }, + { + "type": "tag_name_pattern", + "parameters": { + "name": "avoid tag names", + "negate": true, + "operator": "contains", + "pattern": "github" + } + }, + { + "type": "code_scanning", + "parameters": { + "code_scanning_tools": [ + { + "tool": "CodeQL", + "security_alerts_threshold": "high_or_higher", + "alerts_threshold": "errors" + } + ] + } + } + ] + }`, rulesetID, enterprise) + }) + + ctx := context.Background() + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, &Ruleset{ + Name: "ruleset", + Target: Ptr("branch"), + Enforcement: "active", + BypassActors: []*BypassActor{ + { + ActorID: Ptr(int64(234)), + ActorType: Ptr("Team"), + }, + }, + Conditions: &RulesetConditions{ + OrganizationName: &RulesetOrganizationNamesConditionParameters{ + Include: []string{"important_organization", "another_important_organization"}, + Exclude: []string{"unimportant_organization"}, + }, + RepositoryProperty: &RulesetRepositoryPropertyConditionParameters{ + Include: []RulesetRepositoryPropertyTargetParameters{ + { + Name: "testIncludeProp", + Source: Ptr("custom"), + Values: []string{"true"}, + }, + }, + Exclude: []RulesetRepositoryPropertyTargetParameters{ + { + Name: "testExcludeProp", + Values: []string{"false"}, + }, + }, + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }), + NewDeletionRule(), + NewRequiredLinearHistoryRule(), + NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ + RequiredDeploymentEnvironments: []string{"test"}, + }), + NewRequiredSignaturesRule(), + NewPullRequestRule(&PullRequestRuleParameters{ + RequireCodeOwnerReview: true, + RequireLastPushApproval: true, + RequiredApprovingReviewCount: 1, + RequiredReviewThreadResolution: true, + DismissStaleReviewsOnPush: true, + }), + NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ + RequiredStatusChecks: []RuleRequiredStatusChecks{ + { + Context: "test", + IntegrationID: Ptr(int64(1)), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: Ptr("avoid test commits"), + Negate: Ptr(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: Ptr("avoid commit emails"), + Negate: Ptr(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid branch names"), + Negate: Ptr(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid tag names"), + Negate: Ptr(true), + Operator: "contains", + Pattern: "github", + }), + NewRequiredCodeScanningRule(&RequiredCodeScanningRuleParameters{ + RequiredCodeScanningTools: []*RuleRequiredCodeScanningTool{ + { + Tool: "CodeQL", + SecurityAlertsThreshold: "high_or_higher", + AlertsThreshold: "errors", + }, + }, + }), + }, + }) + if err != nil { + t.Errorf("Enterprise.CreateEnterpriseRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: Ptr(rulesetID), + Name: "ruleset", + Target: Ptr("branch"), + SourceType: Ptr("Enterprise"), + Source: enterprise, + Enforcement: "active", + BypassActors: []*BypassActor{ + { + ActorID: Ptr(int64(234)), + ActorType: Ptr("Team"), + }, + }, + Conditions: &RulesetConditions{ + OrganizationName: &RulesetOrganizationNamesConditionParameters{ + Include: []string{"important_organization", "another_important_organization"}, + Exclude: []string{"unimportant_organization"}, + }, + RepositoryProperty: &RulesetRepositoryPropertyConditionParameters{ + Include: []RulesetRepositoryPropertyTargetParameters{ + { + Name: "testIncludeProp", + Source: Ptr("custom"), + Values: []string{"true"}, + }, + }, + Exclude: []RulesetRepositoryPropertyTargetParameters{ + { + Name: "testExcludeProp", + Values: []string{"false"}, + }, + }, + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }), + NewDeletionRule(), + NewRequiredLinearHistoryRule(), + NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ + RequiredDeploymentEnvironments: []string{"test"}, + }), + NewRequiredSignaturesRule(), + NewPullRequestRule(&PullRequestRuleParameters{ + RequireCodeOwnerReview: true, + RequireLastPushApproval: true, + RequiredApprovingReviewCount: 1, + RequiredReviewThreadResolution: true, + DismissStaleReviewsOnPush: true, + }), + NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ + RequiredStatusChecks: []RuleRequiredStatusChecks{ + { + Context: "test", + IntegrationID: Ptr(int64(1)), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: Ptr("avoid test commits"), + Negate: Ptr(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: Ptr("avoid commit emails"), + Negate: Ptr(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid branch names"), + Negate: Ptr(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid tag names"), + Negate: Ptr(true), + Operator: "contains", + Pattern: "github", + }), + NewRequiredCodeScanningRule(&RequiredCodeScanningRuleParameters{ + RequiredCodeScanningTools: []*RuleRequiredCodeScanningTool{ + { + Tool: "CodeQL", + SecurityAlertsThreshold: "high_or_higher", + AlertsThreshold: "errors", + }, + }, + }), + }, + } + if !cmp.Equal(ruleset, want) { + t.Errorf("Enterprise.CreateEnterpriseRuleset returned %+v, want %+v", ruleset, want) + } + + const methodName = "CreateEnterpriseRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + enterprise := "e" + rulesetID := int64(21) + + mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets", enterprise), func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprintf(w, `{ + "id": %d, + "name": "ruleset", + "target": "branch", + "source_type": "Enterprise", + "source": "%s", + "enforcement": "active", + "bypass_actors": [ + { + "actor_id": 234, + "actor_type": "Team" + } + ], + "conditions": { + "organization_id": { + "organization_ids": [1001, 1002] + }, + "repository_name": { + "include": [ + "important_repository", + "another_important_repository" + ], + "exclude": [ + "unimportant_repository" + ], + "protected": true + }, + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + } + }, + "rules": [ + { + "type": "creation" + }, + { + "type": "update", + "parameters": { + "update_allows_fetch_and_merge": true + } + }, + { + "type": "deletion" + }, + { + "type": "required_linear_history" + }, + { + "type": "required_deployments", + "parameters": { + "required_deployment_environments": ["test"] + } + }, + { + "type": "required_signatures" + }, + { + "type": "pull_request", + "parameters": { + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": true, + "require_last_push_approval": true, + "required_approving_review_count": 1, + "required_review_thread_resolution": true + } + }, + { + "type": "required_status_checks", + "parameters": { + "required_status_checks": [ + { + "context": "test", + "integration_id": 1 + } + ], + "strict_required_status_checks_policy": true + } + }, + { + "type": "non_fast_forward" + }, + { + "type": "commit_message_pattern", + "parameters": { + "name": "avoid test commits", + "negate": true, + "operator": "starts_with", + "pattern": "[test]" + } + }, + { + "type": "commit_author_email_pattern", + "parameters": { + "operator": "contains", + "pattern": "github" + } + }, + { + "type": "committer_email_pattern", + "parameters": { + "name": "avoid commit emails", + "negate": true, + "operator": "ends_with", + "pattern": "abc" + } + }, + { + "type": "branch_name_pattern", + "parameters": { + "name": "avoid branch names", + "negate": true, + "operator": "regex", + "pattern": "github$" + } + }, + { + "type": "tag_name_pattern", + "parameters": { + "name": "avoid tag names", + "negate": true, + "operator": "contains", + "pattern": "github" + } + }, + { + "type": "code_scanning", + "parameters": { + "code_scanning_tools": [ + { + "tool": "CodeQL", + "security_alerts_threshold": "high_or_higher", + "alerts_threshold": "errors" + } + ] + } + } + ] + }`, rulesetID, enterprise) + }) + + ctx := context.Background() + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, &Ruleset{ + Name: "ruleset", + Target: Ptr("branch"), + Enforcement: "active", + BypassActors: []*BypassActor{ + { + ActorID: Ptr(int64(234)), + ActorType: Ptr("Team"), + }, + }, + Conditions: &RulesetConditions{ + OrganizationID: &RulesetOrganizationIDsConditionParameters{ + OrganizationIDs: []int64{1001, 1002}, + }, + RepositoryName: &RulesetRepositoryNamesConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Ptr(true), + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }), + NewDeletionRule(), + NewRequiredLinearHistoryRule(), + NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ + RequiredDeploymentEnvironments: []string{"test"}, + }), + NewRequiredSignaturesRule(), + NewPullRequestRule(&PullRequestRuleParameters{ + RequireCodeOwnerReview: true, + RequireLastPushApproval: true, + RequiredApprovingReviewCount: 1, + RequiredReviewThreadResolution: true, + DismissStaleReviewsOnPush: true, + }), + NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ + RequiredStatusChecks: []RuleRequiredStatusChecks{ + { + Context: "test", + IntegrationID: Ptr(int64(1)), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: Ptr("avoid test commits"), + Negate: Ptr(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: Ptr("avoid commit emails"), + Negate: Ptr(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid branch names"), + Negate: Ptr(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid tag names"), + Negate: Ptr(true), + Operator: "contains", + Pattern: "github", + }), + NewRequiredCodeScanningRule(&RequiredCodeScanningRuleParameters{ + RequiredCodeScanningTools: []*RuleRequiredCodeScanningTool{ + { + Tool: "CodeQL", + SecurityAlertsThreshold: "high_or_higher", + AlertsThreshold: "errors", + }, + }, + }), + }, + }) + if err != nil { + t.Errorf("Enterprise.CreateEnterpriseRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: Ptr(rulesetID), + Name: "ruleset", + Target: Ptr("branch"), + SourceType: Ptr("Enterprise"), + Source: enterprise, + Enforcement: "active", + BypassActors: []*BypassActor{ + { + ActorID: Ptr(int64(234)), + ActorType: Ptr("Team"), + }, + }, + Conditions: &RulesetConditions{ + OrganizationID: &RulesetOrganizationIDsConditionParameters{ + OrganizationIDs: []int64{1001, 1002}, + }, + RepositoryName: &RulesetRepositoryNamesConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Ptr(true), + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }), + NewDeletionRule(), + NewRequiredLinearHistoryRule(), + NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ + RequiredDeploymentEnvironments: []string{"test"}, + }), + NewRequiredSignaturesRule(), + NewPullRequestRule(&PullRequestRuleParameters{ + RequireCodeOwnerReview: true, + RequireLastPushApproval: true, + RequiredApprovingReviewCount: 1, + RequiredReviewThreadResolution: true, + DismissStaleReviewsOnPush: true, + }), + NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ + RequiredStatusChecks: []RuleRequiredStatusChecks{ + { + Context: "test", + IntegrationID: Ptr(int64(1)), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: Ptr("avoid test commits"), + Negate: Ptr(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: Ptr("avoid commit emails"), + Negate: Ptr(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid branch names"), + Negate: Ptr(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid tag names"), + Negate: Ptr(true), + Operator: "contains", + Pattern: "github", + }), + NewRequiredCodeScanningRule(&RequiredCodeScanningRuleParameters{ + RequiredCodeScanningTools: []*RuleRequiredCodeScanningTool{ + { + Tool: "CodeQL", + SecurityAlertsThreshold: "high_or_higher", + AlertsThreshold: "errors", + }, + }, + }), + }, + } + if !cmp.Equal(ruleset, want) { + t.Errorf("Enterprise.CreateEnterpriseRuleset returned %+v, want %+v", ruleset, want) + } + + const methodName = "CreateEnterpriseRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + enterprise := "e" + rulesetID := int64(21) + + mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets", enterprise), func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprintf(w, `{ + "id": %d, + "name": "ruleset", + "target": "branch", + "source_type": "Enterprise", + "source": "%s", + "enforcement": "active", + "bypass_actors": [ + { + "actor_id": 234, + "actor_type": "Team" + } + ], + "conditions": { + "organization_id": { + "organization_ids": [1001, 1002] + }, + "repository_property": { + "include": [ + { + "name": "testIncludeProp", + "source": "custom", + "property_values": [ + "true" + ] + } + ], + "exclude": [ + { + "name": "testExcludeProp", + "property_values": [ + "false" + ] + } + ] + }, + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + } + }, + "rules": [ + { + "type": "creation" + }, + { + "type": "update", + "parameters": { + "update_allows_fetch_and_merge": true + } + }, + { + "type": "deletion" + }, + { + "type": "required_linear_history" + }, + { + "type": "required_deployments", + "parameters": { + "required_deployment_environments": ["test"] + } + }, + { + "type": "required_signatures" + }, + { + "type": "pull_request", + "parameters": { + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": true, + "require_last_push_approval": true, + "required_approving_review_count": 1, + "required_review_thread_resolution": true + } + }, + { + "type": "required_status_checks", + "parameters": { + "required_status_checks": [ + { + "context": "test", + "integration_id": 1 + } + ], + "strict_required_status_checks_policy": true + } + }, + { + "type": "non_fast_forward" + }, + { + "type": "commit_message_pattern", + "parameters": { + "name": "avoid test commits", + "negate": true, + "operator": "starts_with", + "pattern": "[test]" + } + }, + { + "type": "commit_author_email_pattern", + "parameters": { + "operator": "contains", + "pattern": "github" + } + }, + { + "type": "committer_email_pattern", + "parameters": { + "name": "avoid commit emails", + "negate": true, + "operator": "ends_with", + "pattern": "abc" + } + }, + { + "type": "branch_name_pattern", + "parameters": { + "name": "avoid branch names", + "negate": true, + "operator": "regex", + "pattern": "github$" + } + }, + { + "type": "tag_name_pattern", + "parameters": { + "name": "avoid tag names", + "negate": true, + "operator": "contains", + "pattern": "github" + } + }, + { + "type": "code_scanning", + "parameters": { + "code_scanning_tools": [ + { + "tool": "CodeQL", + "security_alerts_threshold": "high_or_higher", + "alerts_threshold": "errors" + } + ] + } + } + ] + }`, rulesetID, enterprise) + }) + + ctx := context.Background() + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, &Ruleset{ + Name: "ruleset", + Target: Ptr("branch"), + Enforcement: "active", + BypassActors: []*BypassActor{ + { + ActorID: Ptr(int64(234)), + ActorType: Ptr("Team"), + }, + }, + Conditions: &RulesetConditions{ + OrganizationID: &RulesetOrganizationIDsConditionParameters{ + OrganizationIDs: []int64{1001, 1002}, + }, + RepositoryProperty: &RulesetRepositoryPropertyConditionParameters{ + Include: []RulesetRepositoryPropertyTargetParameters{ + { + Name: "testIncludeProp", + Source: Ptr("custom"), + Values: []string{"true"}, + }, + }, + Exclude: []RulesetRepositoryPropertyTargetParameters{ + { + Name: "testExcludeProp", + Values: []string{"false"}, + }, + }, + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }), + NewDeletionRule(), + NewRequiredLinearHistoryRule(), + NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ + RequiredDeploymentEnvironments: []string{"test"}, + }), + NewRequiredSignaturesRule(), + NewPullRequestRule(&PullRequestRuleParameters{ + RequireCodeOwnerReview: true, + RequireLastPushApproval: true, + RequiredApprovingReviewCount: 1, + RequiredReviewThreadResolution: true, + DismissStaleReviewsOnPush: true, + }), + NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ + RequiredStatusChecks: []RuleRequiredStatusChecks{ + { + Context: "test", + IntegrationID: Ptr(int64(1)), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: Ptr("avoid test commits"), + Negate: Ptr(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: Ptr("avoid commit emails"), + Negate: Ptr(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid branch names"), + Negate: Ptr(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid tag names"), + Negate: Ptr(true), + Operator: "contains", + Pattern: "github", + }), + NewRequiredCodeScanningRule(&RequiredCodeScanningRuleParameters{ + RequiredCodeScanningTools: []*RuleRequiredCodeScanningTool{ + { + Tool: "CodeQL", + SecurityAlertsThreshold: "high_or_higher", + AlertsThreshold: "errors", + }, + }, + }), + }, + }) + if err != nil { + t.Errorf("Enterprise.CreateEnterpriseRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: Ptr(rulesetID), + Name: "ruleset", + Target: Ptr("branch"), + SourceType: Ptr("Enterprise"), + Source: enterprise, + Enforcement: "active", + BypassActors: []*BypassActor{ + { + ActorID: Ptr(int64(234)), + ActorType: Ptr("Team"), + }, + }, + Conditions: &RulesetConditions{ + OrganizationID: &RulesetOrganizationIDsConditionParameters{ + OrganizationIDs: []int64{1001, 1002}, + }, + RepositoryProperty: &RulesetRepositoryPropertyConditionParameters{ + Include: []RulesetRepositoryPropertyTargetParameters{ + { + Name: "testIncludeProp", + Source: Ptr("custom"), + Values: []string{"true"}, + }, + }, + Exclude: []RulesetRepositoryPropertyTargetParameters{ + { + Name: "testExcludeProp", + Values: []string{"false"}, + }, + }, + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }), + NewDeletionRule(), + NewRequiredLinearHistoryRule(), + NewRequiredDeploymentsRule(&RequiredDeploymentEnvironmentsRuleParameters{ + RequiredDeploymentEnvironments: []string{"test"}, + }), + NewRequiredSignaturesRule(), + NewPullRequestRule(&PullRequestRuleParameters{ + RequireCodeOwnerReview: true, + RequireLastPushApproval: true, + RequiredApprovingReviewCount: 1, + RequiredReviewThreadResolution: true, + DismissStaleReviewsOnPush: true, + }), + NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ + RequiredStatusChecks: []RuleRequiredStatusChecks{ + { + Context: "test", + IntegrationID: Ptr(int64(1)), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: Ptr("avoid test commits"), + Negate: Ptr(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: Ptr("avoid commit emails"), + Negate: Ptr(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid branch names"), + Negate: Ptr(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: Ptr("avoid tag names"), + Negate: Ptr(true), + Operator: "contains", + Pattern: "github", + }), + NewRequiredCodeScanningRule(&RequiredCodeScanningRuleParameters{ + RequiredCodeScanningTools: []*RuleRequiredCodeScanningTool{ + { + Tool: "CodeQL", + SecurityAlertsThreshold: "high_or_higher", + AlertsThreshold: "errors", + }, + }, + }), + }, + } + if !cmp.Equal(ruleset, want) { + t.Errorf("Enterprise.CreateEnterpriseRuleset returned %+v, want %+v", ruleset, want) + } + + const methodName = "CreateEnterpriseRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_GetEnterpriseRuleset(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + enterprise := "e" + rulesetID := int64(26110) + + mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets/%d", enterprise, rulesetID), func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprintf(w, `{ + "id": %d, + "name": "test ruleset", + "target": "branch", + "source_type": "Enterprise", + "source": "%s", + "enforcement": "active", + "bypass_mode": "none", + "node_id": "nid", + "_links": { + "self": { + "href": "https://api.github.com/enterprises/%[2]s/rulesets/%[1]d" + } + }, + "conditions": { + "organization_name": { + "include": [ + "important_organization", + "another_important_organization" + ], + "exclude": [ + "unimportant_organization" + ] + }, + "repository_name": { + "include": [ + "important_repository", + "another_important_repository" + ], + "exclude": [ + "unimportant_repository" + ], + "protected": true + }, + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + } + }, + "rules": [ + { + "type": "creation" + } + ] + }`, rulesetID, enterprise) + }) + + ctx := context.Background() + rulesets, _, err := client.Enterprise.GetEnterpriseRuleset(ctx, enterprise, rulesetID) + if err != nil { + t.Errorf("Enterprise.GetEnterpriseRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: Ptr(rulesetID), + Name: "test ruleset", + Target: Ptr("branch"), + SourceType: Ptr("Enterprise"), + Source: enterprise, + Enforcement: "active", + NodeID: Ptr("nid"), + Links: &RulesetLinks{ + Self: &RulesetLink{HRef: Ptr(fmt.Sprintf("https://api.github.com/enterprises/%s/rulesets/%d", enterprise, rulesetID))}, + }, + Conditions: &RulesetConditions{ + OrganizationName: &RulesetOrganizationNamesConditionParameters{ + Include: []string{"important_organization", "another_important_organization"}, + Exclude: []string{"unimportant_organization"}, + }, + RepositoryName: &RulesetRepositoryNamesConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Ptr(true), + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + }, + } + if !cmp.Equal(rulesets, want) { + t.Errorf("Enterprise.GetEnterpriseRuleset returned %+v, want %+v", rulesets, want) + } + + const methodName = "GetEnterpriseRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.GetEnterpriseRuleset(ctx, enterprise, rulesetID) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_UpdateEnterpriseRuleset(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + enterprise := "e" + rulesetID := int64(26110) + + mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets/%d", enterprise, rulesetID), func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + fmt.Fprintf(w, `{ + "id": %d, + "name": "test ruleset", + "target": "branch", + "source_type": "Enterprise", + "source": "%s", + "enforcement": "active", + "bypass_mode": "none", + "node_id": "nid", + "_links": { + "self": { + "href": "https://api.github.com/enterprises/%[2]s/rulesets/%[1]d" + } + }, + "conditions": { + "organization_name": { + "include": [ + "important_organization", + "another_important_organization" + ], + "exclude": [ + "unimportant_organization" + ] + }, + "repository_name": { + "include": [ + "important_repository", + "another_important_repository" + ], + "exclude": [ + "unimportant_repository" + ], + "protected": true + }, + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + } + }, + "rules": [ + { + "type": "creation" + } + ] + }`, rulesetID, enterprise) + }) + + ctx := context.Background() + rulesets, _, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, enterprise, rulesetID, &Ruleset{ + Name: "test ruleset", + Target: Ptr("branch"), + Enforcement: "active", + Conditions: &RulesetConditions{ + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + RepositoryName: &RulesetRepositoryNamesConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Ptr(true), + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + }, + }) + if err != nil { + t.Errorf("Enterprise.UpdateEnterpriseRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: Ptr(rulesetID), + Name: "test ruleset", + Target: Ptr("branch"), + SourceType: Ptr("Enterprise"), + Source: enterprise, + Enforcement: "active", + NodeID: Ptr("nid"), + Links: &RulesetLinks{ + Self: &RulesetLink{HRef: Ptr(fmt.Sprintf("https://api.github.com/enterprises/%s/rulesets/%d", enterprise, rulesetID))}, + }, + Conditions: &RulesetConditions{ + OrganizationName: &RulesetOrganizationNamesConditionParameters{ + Include: []string{"important_organization", "another_important_organization"}, + Exclude: []string{"unimportant_organization"}, + }, + RepositoryName: &RulesetRepositoryNamesConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Ptr(true), + }, + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + }, + Rules: []*RepositoryRule{ + NewCreationRule(), + }, + } + if !cmp.Equal(rulesets, want) { + t.Errorf("Enterprise.UpdateEnterpriseRuleset returned %+v, want %+v", rulesets, want) + } + + const methodName = "UpdateEnterpriseRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, enterprise, rulesetID, nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_DeleteEnterpriseRuleset(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + enterprise := "e" + rulesetID := int64(26110) + + mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets/%d", enterprise, rulesetID), func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + ctx := context.Background() + _, err := client.Enterprise.DeleteEnterpriseRuleset(ctx, enterprise, rulesetID) + if err != nil { + t.Errorf("Enterprise.DeleteEnterpriseRuleset returned error: %v", err) + } + + const methodName = "DeleteEnterpriseRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Enterprise.DeleteEnterpriseRuleset(ctx, enterprise, rulesetID) + }) +} diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index ebc559c640c..5231d086544 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -18,14 +18,16 @@ func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { + org := "o" + + mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets", org), func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `[{ + fmt.Fprintf(w, `[{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "o", + "source": "%s", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -34,11 +36,11 @@ func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { "href": "https://api.github.com/orgs/o/rulesets/26110" } } - }]`) + }]`, org) }) ctx := context.Background() - rulesets, _, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") + rulesets, _, err := client.Organizations.GetAllOrganizationRulesets(ctx, org) if err != nil { t.Errorf("Organizations.GetAllOrganizationRulesets returned error: %v", err) } @@ -48,7 +50,7 @@ func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: "o", + Source: org, Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -62,7 +64,7 @@ func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { const methodName = "GetAllOrganizationRulesets" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") + got, resp, err := client.Organizations.GetAllOrganizationRulesets(ctx, org) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -74,14 +76,16 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) t.Parallel() client, mux, _ := setup(t) - mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { + org := "o" + + mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets", org), func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprint(w, `{ + fmt.Fprintf(w, `{ "id": 21, "name": "ruleset", "target": "branch", "source_type": "Organization", - "source": "o", + "source": "%s", "enforcement": "active", "bypass_actors": [ { @@ -216,16 +220,13 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) } } ] - }`) + }`, org) }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ - ID: Ptr(int64(21)), + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, org, &Ruleset{ Name: "ruleset", Target: Ptr("branch"), - SourceType: Ptr("Organization"), - Source: "o", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -320,7 +321,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: "o", + Source: org, Enforcement: "active", BypassActors: []*BypassActor{ { @@ -413,7 +414,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, org, nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -425,14 +426,16 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. t.Parallel() client, mux, _ := setup(t) - mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { + org := "o" + + mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets", org), func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprint(w, `{ + fmt.Fprintf(w, `{ "id": 21, "name": "ruleset", "target": "branch", "source_type": "Organization", - "source": "o", + "source": "%s", "enforcement": "active", "bypass_actors": [ { @@ -567,16 +570,13 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. } } ] - }`) + }`, org) }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ - ID: Ptr(int64(21)), + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, org, &Ruleset{ Name: "ruleset", Target: Ptr("branch"), - SourceType: Ptr("Organization"), - Source: "o", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -677,7 +677,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: "o", + Source: org, Enforcement: "active", BypassActors: []*BypassActor{ { @@ -776,7 +776,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, org, nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -788,14 +788,16 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { + org := "o" + + mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets", org), func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprint(w, `{ + fmt.Fprintf(w, `{ "id": 21, "name": "ruleset", "target": "branch", "source_type": "Organization", - "source": "o", + "source": "%s", "enforcement": "active", "bypass_actors": [ { @@ -923,16 +925,14 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { } } ] - }`) + }`, org) }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, org, &Ruleset{ ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), - SourceType: Ptr("Organization"), - Source: "o", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -1025,7 +1025,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: "o", + Source: org, Enforcement: "active", BypassActors: []*BypassActor{ { @@ -1116,7 +1116,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, org, nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1128,14 +1128,16 @@ func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + org := "o" + + mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `{ + fmt.Fprintf(w, `{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "o", + "source": "%s", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -1170,11 +1172,11 @@ func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { "type": "creation" } ] - }`) + }`, org) }) ctx := context.Background() - rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) + rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, org, 26110) if err != nil { t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned error: %v", err) } @@ -1184,7 +1186,7 @@ func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: "o", + Source: org, Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -1212,7 +1214,7 @@ func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { const methodName = "GetOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) + got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, org, 26110) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1224,14 +1226,16 @@ func TestOrganizationsService_GetOrganizationRulesetWithRepoPropCondition(t *tes t.Parallel() client, mux, _ := setup(t) - mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + org := "o" + + mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `{ + fmt.Fprintf(w, `{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "o", + "source": "%s", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -1259,11 +1263,11 @@ func TestOrganizationsService_GetOrganizationRulesetWithRepoPropCondition(t *tes "type": "creation" } ] - }`) + }`, org) }) ctx := context.Background() - rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) + rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, org, 26110) if err != nil { t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned error: %v", err) } @@ -1273,7 +1277,7 @@ func TestOrganizationsService_GetOrganizationRulesetWithRepoPropCondition(t *tes Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: "o", + Source: org, Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -1302,7 +1306,7 @@ func TestOrganizationsService_GetOrganizationRulesetWithRepoPropCondition(t *tes const methodName = "GetOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) + got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, org, 26110) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1314,14 +1318,16 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + org := "o" + + mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") - fmt.Fprint(w, `{ + fmt.Fprintf(w, `{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "o", + "source": "%s", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -1356,11 +1362,11 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { "type": "creation" } ] - }`) + }`, org) }) ctx := context.Background() - rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ + rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, org, 26110, &Ruleset{ Name: "test ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1379,7 +1385,6 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { NewCreationRule(), }, }) - if err != nil { t.Errorf("Organizations.UpdateOrganizationRuleset returned error: %v", err) } @@ -1389,7 +1394,7 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: "o", + Source: org, Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -1417,7 +1422,7 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { const methodName = "UpdateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) + got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, org, 26110, nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1429,14 +1434,16 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T t.Parallel() client, mux, _ := setup(t) - mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + org := "o" + + mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") - fmt.Fprint(w, `{ + fmt.Fprintf(w, `{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "o", + "source": "%s", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -1464,11 +1471,11 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T "type": "creation" } ] - }`) + }`, org) }) ctx := context.Background() - rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ + rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, org, 26110, &Ruleset{ Name: "test ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1488,7 +1495,6 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T NewCreationRule(), }, }) - if err != nil { t.Errorf("Organizations.UpdateOrganizationRuleset returned error: %v", err) } @@ -1498,7 +1504,7 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: "o", + Source: org, Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -1527,7 +1533,7 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T const methodName = "UpdateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) + got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, org, 26110, nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1539,12 +1545,14 @@ func TestOrganizationsService_DeleteOrganizationRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + org := "o" + + mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") }) ctx := context.Background() - _, err := client.Organizations.DeleteOrganizationRuleset(ctx, "o", 26110) + _, err := client.Organizations.DeleteOrganizationRuleset(ctx, org, 26110) if err != nil { t.Errorf("Organizations.DeleteOrganizationRuleset returned error: %v", err) } @@ -1552,6 +1560,6 @@ func TestOrganizationsService_DeleteOrganizationRuleset(t *testing.T) { const methodName = "DeleteOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - return client.Organizations.DeleteOrganizationRuleset(ctx, "0", 26110) + return client.Organizations.DeleteOrganizationRuleset(ctx, org, 26110) }) } diff --git a/github/repos_rules.go b/github/repos_rules.go index b113553a247..e68d926a8f1 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -36,14 +36,14 @@ type RulesetRefConditionParameters struct { Exclude []string `json:"exclude"` } -// RulesetRepositoryNamesConditionParameters represents the conditions object for repository_names. +// RulesetRepositoryNamesConditionParameters represents the conditions object for repository_name. type RulesetRepositoryNamesConditionParameters struct { Include []string `json:"include"` Exclude []string `json:"exclude"` Protected *bool `json:"protected,omitempty"` } -// RulesetRepositoryIDsConditionParameters represents the conditions object for repository_ids. +// RulesetRepositoryIDsConditionParameters represents the conditions object for repository_id. type RulesetRepositoryIDsConditionParameters struct { RepositoryIDs []int64 `json:"repository_ids,omitempty"` } @@ -61,6 +61,17 @@ type RulesetRepositoryPropertyConditionParameters struct { Exclude []RulesetRepositoryPropertyTargetParameters `json:"exclude"` } +// RulesetOrganizationNamesConditionParameters represents the conditions object for organization_name. +type RulesetOrganizationNamesConditionParameters struct { + Include []string `json:"include"` + Exclude []string `json:"exclude"` +} + +// RulesetOrganizationIDsConditionParameters represents the conditions object for organization_id. +type RulesetOrganizationIDsConditionParameters struct { + OrganizationIDs []int64 `json:"organization_ids,omitempty"` +} + // RulesetConditions represents the conditions object in a ruleset. // Set either RepositoryName or RepositoryID or RepositoryProperty, not more than one. type RulesetConditions struct { @@ -68,6 +79,8 @@ type RulesetConditions struct { RepositoryName *RulesetRepositoryNamesConditionParameters `json:"repository_name,omitempty"` RepositoryID *RulesetRepositoryIDsConditionParameters `json:"repository_id,omitempty"` RepositoryProperty *RulesetRepositoryPropertyConditionParameters `json:"repository_property,omitempty"` + OrganizationName *RulesetOrganizationNamesConditionParameters `json:"organization_name,omitempty"` + OrganizationID *RulesetOrganizationIDsConditionParameters `json:"organization_id,omitempty"` } // RulePatternParameters represents the rule pattern parameters. From 00bb31b16d71c80ccd6aeeb16c4a214a48266a41 Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Mon, 6 Jan 2025 18:40:49 +0000 Subject: [PATCH 02/11] fixup! feat: Added enterprise rules --- github/enterprise_rules_test.go | 143 ++++++++++++++----------------- github/orgs_rules_test.go | 144 +++++++++++++++----------------- 2 files changed, 128 insertions(+), 159 deletions(-) diff --git a/github/enterprise_rules_test.go b/github/enterprise_rules_test.go index 13150f04a0d..c6595bbebe2 100644 --- a/github/enterprise_rules_test.go +++ b/github/enterprise_rules_test.go @@ -18,17 +18,14 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) t.Parallel() client, mux, _ := setup(t) - enterprise := "e" - rulesetID := int64(21) - - mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets", enterprise), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/enterprises/e/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprintf(w, `{ - "id": %d, + fmt.Fprint(w, `{ + "id": 21, "name": "ruleset", "target": "branch", "source_type": "Enterprise", - "source": "%s", + "source": "e", "enforcement": "active", "bypass_actors": [ { @@ -172,11 +169,11 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) } } ] - }`, rulesetID, enterprise) + }`) }) ctx := context.Background() - ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, &Ruleset{ + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", &Ruleset{ Name: "ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -273,11 +270,11 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) } want := &Ruleset{ - ID: Ptr(rulesetID), + ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Enterprise"), - Source: enterprise, + Source: "e", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -374,7 +371,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) const methodName = "CreateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, nil) + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -386,17 +383,14 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testin t.Parallel() client, mux, _ := setup(t) - enterprise := "e" - rulesetID := int64(21) - - mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets", enterprise), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/enterprises/e/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprintf(w, `{ - "id": %d, + fmt.Fprint(w, `{ + "id": 21, "name": "ruleset", "target": "branch", "source_type": "Enterprise", - "source": "%s", + "source": "e", "enforcement": "active", "bypass_actors": [ { @@ -549,11 +543,11 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testin } } ] - }`, rulesetID, enterprise) + }`) }) ctx := context.Background() - ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, &Ruleset{ + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", &Ruleset{ Name: "ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -660,11 +654,11 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testin } want := &Ruleset{ - ID: Ptr(rulesetID), + ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Enterprise"), - Source: enterprise, + Source: "e", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -771,7 +765,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testin const methodName = "CreateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, nil) + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -783,17 +777,14 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - enterprise := "e" - rulesetID := int64(21) - - mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets", enterprise), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/enterprises/e/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprintf(w, `{ - "id": %d, + fmt.Fprint(w, `{ + "id": 21, "name": "ruleset", "target": "branch", "source_type": "Enterprise", - "source": "%s", + "source": "e", "enforcement": "active", "bypass_actors": [ { @@ -931,11 +922,11 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { } } ] - }`, rulesetID, enterprise) + }`) }) ctx := context.Background() - ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, &Ruleset{ + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", &Ruleset{ Name: "ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1031,11 +1022,11 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { } want := &Ruleset{ - ID: Ptr(rulesetID), + ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Enterprise"), - Source: enterprise, + Source: "e", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -1131,7 +1122,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { const methodName = "CreateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, nil) + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1143,17 +1134,14 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing. t.Parallel() client, mux, _ := setup(t) - enterprise := "e" - rulesetID := int64(21) - - mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets", enterprise), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/enterprises/e/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprintf(w, `{ - "id": %d, + fmt.Fprint(w, `{ + "id": 21, "name": "ruleset", "target": "branch", "source_type": "Enterprise", - "source": "%s", + "source": "e", "enforcement": "active", "bypass_actors": [ { @@ -1300,11 +1288,11 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing. } } ] - }`, rulesetID, enterprise) + }`) }) ctx := context.Background() - ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, &Ruleset{ + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", &Ruleset{ Name: "ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1410,11 +1398,11 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing. } want := &Ruleset{ - ID: Ptr(rulesetID), + ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Enterprise"), - Source: enterprise, + Source: "e", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -1520,7 +1508,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing. const methodName = "CreateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, enterprise, nil) + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1532,23 +1520,20 @@ func TestEnterpriseService_GetEnterpriseRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - enterprise := "e" - rulesetID := int64(26110) - - mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets/%d", enterprise, rulesetID), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/enterprises/e/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprintf(w, `{ - "id": %d, + fmt.Fprint(w, `{ + "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Enterprise", - "source": "%s", + "source": "e", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", "_links": { "self": { - "href": "https://api.github.com/enterprises/%[2]s/rulesets/%[1]d" + "href": "https://api.github.com/enterprises/e/rulesets/26110" } }, "conditions": { @@ -1586,25 +1571,25 @@ func TestEnterpriseService_GetEnterpriseRuleset(t *testing.T) { "type": "creation" } ] - }`, rulesetID, enterprise) + }`) }) ctx := context.Background() - rulesets, _, err := client.Enterprise.GetEnterpriseRuleset(ctx, enterprise, rulesetID) + rulesets, _, err := client.Enterprise.GetEnterpriseRuleset(ctx, "e", 26110) if err != nil { t.Errorf("Enterprise.GetEnterpriseRuleset returned error: %v", err) } want := &Ruleset{ - ID: Ptr(rulesetID), + ID: Ptr(int64(26110)), Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Enterprise"), - Source: enterprise, + Source: "e", Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ - Self: &RulesetLink{HRef: Ptr(fmt.Sprintf("https://api.github.com/enterprises/%s/rulesets/%d", enterprise, rulesetID))}, + Self: &RulesetLink{HRef: Ptr("https://api.github.com/enterprises/e/rulesets/26110")}, }, Conditions: &RulesetConditions{ OrganizationName: &RulesetOrganizationNamesConditionParameters{ @@ -1632,7 +1617,7 @@ func TestEnterpriseService_GetEnterpriseRuleset(t *testing.T) { const methodName = "GetEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.GetEnterpriseRuleset(ctx, enterprise, rulesetID) + got, resp, err := client.Enterprise.GetEnterpriseRuleset(ctx, "e", 26110) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1644,23 +1629,20 @@ func TestEnterpriseService_UpdateEnterpriseRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - enterprise := "e" - rulesetID := int64(26110) - - mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets/%d", enterprise, rulesetID), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/enterprises/e/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") - fmt.Fprintf(w, `{ - "id": %d, + fmt.Fprint(w, `{ + "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Enterprise", - "source": "%s", + "source": "e", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", "_links": { "self": { - "href": "https://api.github.com/enterprises/%[2]s/rulesets/%[1]d" + "href": "https://api.github.com/enterprises/e/rulesets/26110" } }, "conditions": { @@ -1698,11 +1680,11 @@ func TestEnterpriseService_UpdateEnterpriseRuleset(t *testing.T) { "type": "creation" } ] - }`, rulesetID, enterprise) + }`) }) ctx := context.Background() - rulesets, _, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, enterprise, rulesetID, &Ruleset{ + rulesets, _, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, "e", 26110, &Ruleset{ Name: "test ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1726,15 +1708,15 @@ func TestEnterpriseService_UpdateEnterpriseRuleset(t *testing.T) { } want := &Ruleset{ - ID: Ptr(rulesetID), + ID: Ptr(int64(26110)), Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Enterprise"), - Source: enterprise, + Source: "e", Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ - Self: &RulesetLink{HRef: Ptr(fmt.Sprintf("https://api.github.com/enterprises/%s/rulesets/%d", enterprise, rulesetID))}, + Self: &RulesetLink{HRef: Ptr("https://api.github.com/enterprises/e/rulesets/26110")}, }, Conditions: &RulesetConditions{ OrganizationName: &RulesetOrganizationNamesConditionParameters{ @@ -1762,7 +1744,7 @@ func TestEnterpriseService_UpdateEnterpriseRuleset(t *testing.T) { const methodName = "UpdateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, enterprise, rulesetID, nil) + got, resp, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, "e", 26110, nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1774,15 +1756,12 @@ func TestEnterpriseService_DeleteEnterpriseRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - enterprise := "e" - rulesetID := int64(26110) - - mux.HandleFunc(fmt.Sprintf("/enterprises/%s/rulesets/%d", enterprise, rulesetID), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/enterprises/e/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") }) ctx := context.Background() - _, err := client.Enterprise.DeleteEnterpriseRuleset(ctx, enterprise, rulesetID) + _, err := client.Enterprise.DeleteEnterpriseRuleset(ctx, "e", 26110) if err != nil { t.Errorf("Enterprise.DeleteEnterpriseRuleset returned error: %v", err) } @@ -1790,6 +1769,6 @@ func TestEnterpriseService_DeleteEnterpriseRuleset(t *testing.T) { const methodName = "DeleteEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - return client.Enterprise.DeleteEnterpriseRuleset(ctx, enterprise, rulesetID) + return client.Enterprise.DeleteEnterpriseRuleset(ctx, "e", 26110) }) } diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index 5231d086544..2bea8d1c276 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -18,16 +18,14 @@ func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - org := "o" - - mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets", org), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprintf(w, `[{ + fmt.Fprint(w, `[{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "%s", + "source": "o", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -36,11 +34,11 @@ func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { "href": "https://api.github.com/orgs/o/rulesets/26110" } } - }]`, org) + }]`) }) ctx := context.Background() - rulesets, _, err := client.Organizations.GetAllOrganizationRulesets(ctx, org) + rulesets, _, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") if err != nil { t.Errorf("Organizations.GetAllOrganizationRulesets returned error: %v", err) } @@ -50,7 +48,7 @@ func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: org, + Source: "o", Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -64,7 +62,7 @@ func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { const methodName = "GetAllOrganizationRulesets" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetAllOrganizationRulesets(ctx, org) + got, resp, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -76,16 +74,14 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) t.Parallel() client, mux, _ := setup(t) - org := "o" - - mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets", org), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "id": 21, "name": "ruleset", "target": "branch", "source_type": "Organization", - "source": "%s", + "source": "o", "enforcement": "active", "bypass_actors": [ { @@ -220,13 +216,16 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) } } ] - }`, org) + }`) }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, org, &Ruleset{ + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ + ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), + SourceType: Ptr("Organization"), + Source: "o", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -321,7 +320,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: org, + Source: "o", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -414,7 +413,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, org, nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -426,16 +425,14 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. t.Parallel() client, mux, _ := setup(t) - org := "o" - - mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets", org), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "id": 21, "name": "ruleset", "target": "branch", "source_type": "Organization", - "source": "%s", + "source": "o", "enforcement": "active", "bypass_actors": [ { @@ -570,13 +567,16 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. } } ] - }`, org) + }`) }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, org, &Ruleset{ + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ + ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), + SourceType: Ptr("Organization"), + Source: "o", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -677,7 +677,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: org, + Source: "o", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -776,7 +776,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, org, nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -788,16 +788,14 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - org := "o" - - mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets", org), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "id": 21, "name": "ruleset", "target": "branch", "source_type": "Organization", - "source": "%s", + "source": "o", "enforcement": "active", "bypass_actors": [ { @@ -925,14 +923,16 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { } } ] - }`, org) + }`) }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, org, &Ruleset{ + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), + SourceType: Ptr("Organization"), + Source: "o", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -1025,7 +1025,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { Name: "ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: org, + Source: "o", Enforcement: "active", BypassActors: []*BypassActor{ { @@ -1116,7 +1116,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, org, nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1128,16 +1128,14 @@ func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - org := "o" - - mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "%s", + "source": "o", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -1172,11 +1170,11 @@ func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { "type": "creation" } ] - }`, org) + }`) }) ctx := context.Background() - rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, org, 26110) + rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) if err != nil { t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned error: %v", err) } @@ -1186,7 +1184,7 @@ func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: org, + Source: "o", Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -1214,7 +1212,7 @@ func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { const methodName = "GetOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, org, 26110) + got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1226,16 +1224,14 @@ func TestOrganizationsService_GetOrganizationRulesetWithRepoPropCondition(t *tes t.Parallel() client, mux, _ := setup(t) - org := "o" - - mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "%s", + "source": "o", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -1263,11 +1259,11 @@ func TestOrganizationsService_GetOrganizationRulesetWithRepoPropCondition(t *tes "type": "creation" } ] - }`, org) + }`) }) ctx := context.Background() - rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, org, 26110) + rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) if err != nil { t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned error: %v", err) } @@ -1277,7 +1273,7 @@ func TestOrganizationsService_GetOrganizationRulesetWithRepoPropCondition(t *tes Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: org, + Source: "o", Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -1306,7 +1302,7 @@ func TestOrganizationsService_GetOrganizationRulesetWithRepoPropCondition(t *tes const methodName = "GetOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, org, 26110) + got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1318,16 +1314,14 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - org := "o" - - mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "%s", + "source": "o", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -1362,11 +1356,11 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { "type": "creation" } ] - }`, org) + }`) }) ctx := context.Background() - rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, org, 26110, &Ruleset{ + rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ Name: "test ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1394,7 +1388,7 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: org, + Source: "o", Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -1422,7 +1416,7 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { const methodName = "UpdateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, org, 26110, nil) + got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1434,16 +1428,14 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T t.Parallel() client, mux, _ := setup(t) - org := "o" - - mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") - fmt.Fprintf(w, `{ + fmt.Fprint(w, `{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "%s", + "source": "o", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -1471,11 +1463,11 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T "type": "creation" } ] - }`, org) + }`) }) ctx := context.Background() - rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, org, 26110, &Ruleset{ + rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ Name: "test ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1504,7 +1496,7 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T Name: "test ruleset", Target: Ptr("branch"), SourceType: Ptr("Organization"), - Source: org, + Source: "o", Enforcement: "active", NodeID: Ptr("nid"), Links: &RulesetLinks{ @@ -1533,7 +1525,7 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T const methodName = "UpdateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, org, 26110, nil) + got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1545,14 +1537,12 @@ func TestOrganizationsService_DeleteOrganizationRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - org := "o" - - mux.HandleFunc(fmt.Sprintf("/orgs/%s/rulesets/26110", org), func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") }) ctx := context.Background() - _, err := client.Organizations.DeleteOrganizationRuleset(ctx, org, 26110) + _, err := client.Organizations.DeleteOrganizationRuleset(ctx, "o", 26110) if err != nil { t.Errorf("Organizations.DeleteOrganizationRuleset returned error: %v", err) } @@ -1560,6 +1550,6 @@ func TestOrganizationsService_DeleteOrganizationRuleset(t *testing.T) { const methodName = "DeleteOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - return client.Organizations.DeleteOrganizationRuleset(ctx, org, 26110) + return client.Organizations.DeleteOrganizationRuleset(ctx, "0", 26110) }) } From 4af6709f39387e52ec050f0f566da56c06e9c2d0 Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Tue, 7 Jan 2025 12:17:36 +0000 Subject: [PATCH 03/11] fixup! feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/enterprise_rules.go | 8 ++++---- github/github-accessors.go | 16 ++++++++++++++++ github/github-accessors_test.go | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/github/enterprise_rules.go b/github/enterprise_rules.go index 20b74c001e6..d1c5faa5a0e 100644 --- a/github/enterprise_rules.go +++ b/github/enterprise_rules.go @@ -12,7 +12,7 @@ import ( // CreateEnterpriseRuleset creates a ruleset for the specified enterprise. // -// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/rules#create-an-enterprise-repository-ruleset +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#create-an-enterprise-repository-ruleset // //meta:operation POST /enterprises/{enterprise}/rulesets func (s *EnterpriseService) CreateEnterpriseRuleset(ctx context.Context, enterprise string, rs *Ruleset) (*Ruleset, *Response, error) { @@ -34,7 +34,7 @@ func (s *EnterpriseService) CreateEnterpriseRuleset(ctx context.Context, enterpr // GetEnterpriseRuleset gets a ruleset from the specified enterprise. // -// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/rules#get-an-enterprise-repository-ruleset +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#get-an-enterprise-repository-ruleset // //meta:operation GET /enterprises/{enterprise}/rulesets/{ruleset_id} func (s *EnterpriseService) GetEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64) (*Ruleset, *Response, error) { @@ -56,7 +56,7 @@ func (s *EnterpriseService) GetEnterpriseRuleset(ctx context.Context, enterprise // UpdateEnterpriseRuleset updates a ruleset from the specified enterprise. // -// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/rules#update-an-enterprise-repository-ruleset +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#update-an-enterprise-repository-ruleset // //meta:operation PUT /enterprises/{enterprise}/rulesets/{ruleset_id} func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { @@ -78,7 +78,7 @@ func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterpr // DeleteEnterpriseRuleset deletes a ruleset from the specified enterprise. // -// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/rules#delete-an-enterprise-repository-ruleset +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#delete-an-enterprise-repository-ruleset // //meta:operation DELETE /enterprises/{enterprise}/rulesets/{ruleset_id} func (s *EnterpriseService) DeleteEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64) (*Response, error) { diff --git a/github/github-accessors.go b/github/github-accessors.go index cf70ac59493..448154a47f4 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -21974,6 +21974,22 @@ func (r *Ruleset) GetUpdatedAt() Timestamp { return *r.UpdatedAt } +// GetOrganizationID returns the OrganizationID field. +func (r *RulesetConditions) GetOrganizationID() *RulesetOrganizationIDsConditionParameters { + if r == nil { + return nil + } + return r.OrganizationID +} + +// GetOrganizationName returns the OrganizationName field. +func (r *RulesetConditions) GetOrganizationName() *RulesetOrganizationNamesConditionParameters { + if r == nil { + return nil + } + return r.OrganizationName +} + // GetRefName returns the RefName field. func (r *RulesetConditions) GetRefName() *RulesetRefConditionParameters { if r == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index ff7530bcc0a..1e2a53f1601 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -28164,6 +28164,22 @@ func TestRuleset_GetUpdatedAt(tt *testing.T) { r.GetUpdatedAt() } +func TestRulesetConditions_GetOrganizationID(tt *testing.T) { + tt.Parallel() + r := &RulesetConditions{} + r.GetOrganizationID() + r = nil + r.GetOrganizationID() +} + +func TestRulesetConditions_GetOrganizationName(tt *testing.T) { + tt.Parallel() + r := &RulesetConditions{} + r.GetOrganizationName() + r = nil + r.GetOrganizationName() +} + func TestRulesetConditions_GetRefName(tt *testing.T) { tt.Parallel() r := &RulesetConditions{} From 4d6b96f84ce944b506d04e23dd277426eb98f705 Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Tue, 7 Jan 2025 12:20:36 +0000 Subject: [PATCH 04/11] fixup! feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/enterprise_rules.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/enterprise_rules.go b/github/enterprise_rules.go index d1c5faa5a0e..85acf27b525 100644 --- a/github/enterprise_rules.go +++ b/github/enterprise_rules.go @@ -15,7 +15,7 @@ import ( // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#create-an-enterprise-repository-ruleset // //meta:operation POST /enterprises/{enterprise}/rulesets -func (s *EnterpriseService) CreateEnterpriseRuleset(ctx context.Context, enterprise string, rs *Ruleset) (*Ruleset, *Response, error) { +func (s *EnterpriseService) CreateEnterpriseRuleset(ctx context.Context, enterprise string, rs Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("enterprises/%v/rulesets", enterprise) req, err := s.client.NewRequest("POST", u, rs) @@ -59,7 +59,7 @@ func (s *EnterpriseService) GetEnterpriseRuleset(ctx context.Context, enterprise // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#update-an-enterprise-repository-ruleset // //meta:operation PUT /enterprises/{enterprise}/rulesets/{ruleset_id} -func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { +func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64, rs Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("enterprises/%v/rulesets/%v", enterprise, rulesetID) req, err := s.client.NewRequest("PUT", u, rs) From 0e739595e68f3633f18a595699a8198d9c494351 Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Tue, 7 Jan 2025 13:06:06 +0000 Subject: [PATCH 05/11] fixup! feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/enterprise_rules_test.go | 20 ++++++++++---------- github/orgs_rules.go | 4 ++-- github/orgs_rules_test.go | 20 ++++++++++---------- github/repos_rules.go | 32 +++++++++++++++----------------- github/repos_rules_test.go | 17 ++++++++--------- 5 files changed, 45 insertions(+), 48 deletions(-) diff --git a/github/enterprise_rules_test.go b/github/enterprise_rules_test.go index c6595bbebe2..584c8bae3fe 100644 --- a/github/enterprise_rules_test.go +++ b/github/enterprise_rules_test.go @@ -173,7 +173,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) }) ctx := context.Background() - ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", &Ruleset{ + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", Ruleset{ Name: "ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -371,7 +371,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) const methodName = "CreateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", nil) + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -547,7 +547,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testin }) ctx := context.Background() - ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", &Ruleset{ + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", Ruleset{ Name: "ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -765,7 +765,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testin const methodName = "CreateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", nil) + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -926,7 +926,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { }) ctx := context.Background() - ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", &Ruleset{ + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", Ruleset{ Name: "ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1122,7 +1122,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { const methodName = "CreateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", nil) + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1292,7 +1292,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing. }) ctx := context.Background() - ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", &Ruleset{ + ruleset, _, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", Ruleset{ Name: "ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1508,7 +1508,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing. const methodName = "CreateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", nil) + got, resp, err := client.Enterprise.CreateEnterpriseRuleset(ctx, "e", Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1684,7 +1684,7 @@ func TestEnterpriseService_UpdateEnterpriseRuleset(t *testing.T) { }) ctx := context.Background() - rulesets, _, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, "e", 26110, &Ruleset{ + rulesets, _, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, "e", 26110, Ruleset{ Name: "test ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1744,7 +1744,7 @@ func TestEnterpriseService_UpdateEnterpriseRuleset(t *testing.T) { const methodName = "UpdateEnterpriseRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, "e", 26110, nil) + got, resp, err := client.Enterprise.UpdateEnterpriseRuleset(ctx, "e", 26110, Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 37c06a7333c..2fcd89a3afb 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -37,7 +37,7 @@ func (s *OrganizationsService) GetAllOrganizationRulesets(ctx context.Context, o // GitHub API docs: https://docs.github.com/rest/orgs/rules#create-an-organization-repository-ruleset // //meta:operation POST /orgs/{org}/rulesets -func (s *OrganizationsService) CreateOrganizationRuleset(ctx context.Context, org string, rs *Ruleset) (*Ruleset, *Response, error) { +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) @@ -81,7 +81,7 @@ func (s *OrganizationsService) GetOrganizationRuleset(ctx context.Context, org s // GitHub API docs: https://docs.github.com/rest/orgs/rules#update-an-organization-repository-ruleset // //meta:operation PUT /orgs/{org}/rulesets/{ruleset_id} -func (s *OrganizationsService) UpdateOrganizationRuleset(ctx context.Context, org string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { +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) diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index 2bea8d1c276..8e5ed7c66ea 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -220,7 +220,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", Ruleset{ ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), @@ -413,7 +413,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -571,7 +571,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", Ruleset{ ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), @@ -776,7 +776,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -927,7 +927,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", Ruleset{ ID: Ptr(int64(21)), Name: "ruleset", Target: Ptr("branch"), @@ -1116,7 +1116,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1360,7 +1360,7 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { }) ctx := context.Background() - rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ + rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, Ruleset{ Name: "test ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1416,7 +1416,7 @@ func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { const methodName = "UpdateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) + got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -1467,7 +1467,7 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T }) ctx := context.Background() - rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ + rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, Ruleset{ Name: "test ruleset", Target: Ptr("branch"), Enforcement: "active", @@ -1525,7 +1525,7 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T const methodName = "UpdateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) + got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } diff --git a/github/repos_rules.go b/github/repos_rules.go index e68d926a8f1..e478451b311 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -887,7 +887,7 @@ func (s *RepositoriesService) GetAllRulesets(ctx context.Context, owner, repo st // GitHub API docs: https://docs.github.com/rest/repos/rules#create-a-repository-ruleset // //meta:operation POST /repos/{owner}/{repo}/rulesets -func (s *RepositoriesService) CreateRuleset(ctx context.Context, owner, repo string, rs *Ruleset) (*Ruleset, *Response, error) { +func (s *RepositoriesService) CreateRuleset(ctx context.Context, owner, repo string, rs Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("repos/%v/%v/rulesets", owner, repo) req, err := s.client.NewRequest("POST", u, rs) @@ -932,7 +932,7 @@ func (s *RepositoriesService) GetRuleset(ctx context.Context, owner, repo string // GitHub API docs: https://docs.github.com/rest/repos/rules#update-a-repository-ruleset // //meta:operation PUT /repos/{owner}/{repo}/rulesets/{ruleset_id} -func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { +func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo string, rulesetID int64, rs Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("repos/%v/%v/rulesets/%v", owner, repo, rulesetID) req, err := s.client.NewRequest("PUT", u, rs) @@ -956,25 +956,23 @@ func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo str // GitHub API docs: https://docs.github.com/rest/repos/rules#update-a-repository-ruleset // //meta:operation PUT /repos/{owner}/{repo}/rulesets/{ruleset_id} -func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, owner, repo string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { +func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, owner, repo string, rulesetID int64, rs Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("repos/%v/%v/rulesets/%v", owner, repo, rulesetID) rsNoBypassActor := &rulesetNoOmitBypassActors{} - if rs != nil { - rsNoBypassActor = &rulesetNoOmitBypassActors{ - ID: rs.ID, - Name: rs.Name, - Target: rs.Target, - SourceType: rs.SourceType, - Source: rs.Source, - Enforcement: rs.Enforcement, - BypassActors: rs.BypassActors, - NodeID: rs.NodeID, - Links: rs.Links, - Conditions: rs.Conditions, - Rules: rs.Rules, - } + rsNoBypassActor = &rulesetNoOmitBypassActors{ + ID: rs.ID, + Name: rs.Name, + Target: rs.Target, + SourceType: rs.SourceType, + Source: rs.Source, + Enforcement: rs.Enforcement, + BypassActors: rs.BypassActors, + NodeID: rs.NodeID, + Links: rs.Links, + Conditions: rs.Conditions, + Rules: rs.Rules, } req, err := s.client.NewRequest("PUT", u, rsNoBypassActor) diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index 1597b36e110..00cf390bb07 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -590,7 +590,7 @@ func TestRepositoriesService_CreateRuleset(t *testing.T) { }) ctx := context.Background() - ruleSet, _, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{ + ruleSet, _, err := client.Repositories.CreateRuleset(ctx, "o", "repo", Ruleset{ Name: "ruleset", Enforcement: "enabled", }) @@ -612,7 +612,7 @@ func TestRepositoriesService_CreateRuleset(t *testing.T) { const methodName = "CreateRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{}) + got, resp, err := client.Repositories.CreateRuleset(ctx, "o", "repo", Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -663,7 +663,7 @@ func TestRepositoriesService_CreateRulesetWithPushRules(t *testing.T) { }) ctx := context.Background() - ruleSet, _, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{ + ruleSet, _, err := client.Repositories.CreateRuleset(ctx, "o", "repo", Ruleset{ Name: "ruleset", Enforcement: "enabled", }) @@ -700,7 +700,7 @@ func TestRepositoriesService_CreateRulesetWithPushRules(t *testing.T) { const methodName = "CreateRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{}) + got, resp, err := client.Repositories.CreateRuleset(ctx, "o", "repo", Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -759,7 +759,7 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - rs := &Ruleset{ + rs := Ruleset{ Name: "ruleset", Source: "o/repo", Enforcement: "enabled", @@ -779,7 +779,6 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { ctx := context.Background() ruleSet, _, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, rs) - if err != nil { t.Errorf("Repositories.UpdateRulesetNoBypassActor returned error: %v \n", err) } @@ -799,7 +798,7 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { const methodName = "UpdateRulesetNoBypassActor" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, nil) + got, resp, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -823,7 +822,7 @@ func TestRepositoriesService_UpdateRuleset(t *testing.T) { }) ctx := context.Background() - ruleSet, _, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, &Ruleset{ + ruleSet, _, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, Ruleset{ Name: "ruleset", Enforcement: "enabled", }) @@ -846,7 +845,7 @@ func TestRepositoriesService_UpdateRuleset(t *testing.T) { const methodName = "UpdateRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, nil) + got, resp, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } From c55fc00ba5675233af61b6de57930031f128141e Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Tue, 7 Jan 2025 13:09:50 +0000 Subject: [PATCH 06/11] fixup! feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/repos_rules.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/github/repos_rules.go b/github/repos_rules.go index e478451b311..f6abcc9aea3 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -959,9 +959,7 @@ func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo str func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, owner, repo string, rulesetID int64, rs Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("repos/%v/%v/rulesets/%v", owner, repo, rulesetID) - rsNoBypassActor := &rulesetNoOmitBypassActors{} - - rsNoBypassActor = &rulesetNoOmitBypassActors{ + rsNoBypassActor := rulesetNoOmitBypassActors{ ID: rs.ID, Name: rs.Name, Target: rs.Target, From 79089f996d5a16f9cd0f2fb14613614ec1491284 Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Tue, 7 Jan 2025 16:37:12 +0000 Subject: [PATCH 07/11] fixup! feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/enterprise_rules.go | 25 ++++++++++ github/enterprise_rules_test.go | 66 ++++++++++++++++++++++++++ github/orgs_rules.go | 25 ++++++++++ github/orgs_rules_test.go | 57 ++++++++++++++++++++++ github/repos_rules.go | 32 +++++++++++++ github/repos_rules_test.go | 83 +++++++++++++++++++++++++-------- 6 files changed, 269 insertions(+), 19 deletions(-) diff --git a/github/enterprise_rules.go b/github/enterprise_rules.go index 85acf27b525..04e93a662c6 100644 --- a/github/enterprise_rules.go +++ b/github/enterprise_rules.go @@ -76,6 +76,31 @@ func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterpr return ruleset, resp, nil } +// UpdateEnterpriseRulesetClearBypassActor clears the ruleset bypass actors for a ruleset for the specified repository. +// +// This function is necessary as the UpdateEnterpriseRuleset function does not marshal ByPassActor if passed as nil or an empty array. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#update-an-enterprise-repository-ruleset +// +//meta:operation PUT /enterprises/{enterprise}/rulesets/{ruleset_id} +func (s *EnterpriseService) UpdateEnterpriseRulesetClearBypassActor(ctx context.Context, enterprise string, rulesetID int64) (*Response, error) { + u := fmt.Sprintf("enterprises/%v/rulesets/%v", enterprise, rulesetID) + + rsClearBypassActor := rulesetClearBypassActors{} + + req, err := s.client.NewRequest("PUT", u, rsClearBypassActor) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} + // DeleteEnterpriseRuleset deletes a ruleset from the specified enterprise. // // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#delete-an-enterprise-repository-ruleset diff --git a/github/enterprise_rules_test.go b/github/enterprise_rules_test.go index 584c8bae3fe..cc1f123fc4b 100644 --- a/github/enterprise_rules_test.go +++ b/github/enterprise_rules_test.go @@ -1752,6 +1752,72 @@ func TestEnterpriseService_UpdateEnterpriseRuleset(t *testing.T) { }) } +func TestEnterpriseService_UpdateEnterpriseRulesetClearBypassActor(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + fmt.Fprint(w, `{ + "id": 26110, + "name": "test ruleset", + "target": "branch", + "source_type": "Enterprise", + "source": "e", + "enforcement": "active", + "bypass_mode": "none", + "conditions": { + "organization_name": { + "include": [ + "important_organization", + "another_important_organization" + ], + "exclude": [ + "unimportant_organization" + ] + }, + "repository_name": { + "include": [ + "important_repository", + "another_important_repository" + ], + "exclude": [ + "unimportant_repository" + ], + "protected": true + }, + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + } + }, + "rules": [ + { + "type": "creation" + } + ] + }`) + }) + + ctx := context.Background() + + _, err := client.Enterprise.UpdateEnterpriseRulesetClearBypassActor(ctx, "e", 26110) + if err != nil { + t.Errorf("Enterprise.UpdateEnterpriseRulesetClearBypassActor returned error: %v \n", err) + } + + const methodName = "UpdateEnterpriseRulesetClearBypassActor" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Enterprise.UpdateEnterpriseRulesetClearBypassActor(ctx, "e", 26110) + }) +} + func TestEnterpriseService_DeleteEnterpriseRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 2fcd89a3afb..5438a1d6fb3 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -98,6 +98,31 @@ func (s *OrganizationsService) UpdateOrganizationRuleset(ctx context.Context, or return ruleset, resp, nil } +// UpdateOrganizationRulesetClearBypassActor clears the ruleset bypass actors for a ruleset for the specified repository. +// +// This function is necessary as the UpdateOrganizationRuleset function does not marshal ByPassActor if passed as nil or an empty array. +// +// GitHub API docs: https://docs.github.com/rest/orgs/rules#update-an-organization-repository-ruleset +// +//meta:operation PUT /orgs/{org}/rulesets/{ruleset_id} +func (s *OrganizationsService) UpdateOrganizationRulesetClearBypassActor(ctx context.Context, org string, rulesetID int64) (*Response, error) { + u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID) + + rsClearBypassActor := rulesetClearBypassActors{} + + req, err := s.client.NewRequest("PUT", u, rsClearBypassActor) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} + // DeleteOrganizationRuleset deletes a ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/rest/orgs/rules#delete-an-organization-repository-ruleset diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index 8e5ed7c66ea..c7ecb09cbd2 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -1533,6 +1533,63 @@ func TestOrganizationsService_UpdateOrganizationRulesetWithRepoProp(t *testing.T }) } +func TestOrganizationsService_UpdateOrganizationRulesetClearBypassActor(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + fmt.Fprint(w, `{ + "id": 26110, + "name": "test ruleset", + "target": "branch", + "source_type": "Organization", + "source": "o", + "enforcement": "active", + "bypass_mode": "none", + "conditions": { + "repository_name": { + "include": [ + "important_repository", + "another_important_repository" + ], + "exclude": [ + "unimportant_repository" + ], + "protected": true + }, + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + } + }, + "rules": [ + { + "type": "creation" + } + ] + }`) + }) + + ctx := context.Background() + + _, err := client.Organizations.UpdateOrganizationRulesetClearBypassActor(ctx, "o", 26110) + if err != nil { + t.Errorf("Organizations.UpdateOrganizationRulesetClearBypassActor returned error: %v \n", err) + } + + const methodName = "UpdateOrganizationRulesetClearBypassActor" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Organizations.UpdateOrganizationRulesetClearBypassActor(ctx, "o", 26110) + }) +} + func TestOrganizationsService_DeleteOrganizationRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) diff --git a/github/repos_rules.go b/github/repos_rules.go index f6abcc9aea3..e4cdabc1997 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -837,6 +837,11 @@ type rulesetNoOmitBypassActors struct { Rules []*RepositoryRule `json:"rules,omitempty"` } +// rulesetClearBypassActors is used to clear the bypass actors when modifying a GitHub ruleset object. +type rulesetClearBypassActors struct { + BypassActors []*BypassActor `json:"bypass_actors"` +} + // GetRulesForBranch gets all the rules that apply to the specified branch. // // GitHub API docs: https://docs.github.com/rest/repos/rules#get-rules-for-a-branch @@ -949,10 +954,37 @@ func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo str return ruleset, resp, nil } +// UpdateRulesetClearBypassActor clears the ruleset bypass actors for a ruleset for the specified repository. +// +// This function is necessary as the UpdateRuleset function does not marshal ByPassActor if passed as nil or an empty array. +// +// GitHub API docs: https://docs.github.com/rest/repos/rules#update-a-repository-ruleset +// +//meta:operation PUT /repos/{owner}/{repo}/rulesets/{ruleset_id} +func (s *RepositoriesService) UpdateRulesetClearBypassActor(ctx context.Context, owner, repo string, rulesetID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/rulesets/%v", owner, repo, rulesetID) + + rsClearBypassActor := rulesetClearBypassActors{} + + req, err := s.client.NewRequest("PUT", u, rsClearBypassActor) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} + // UpdateRulesetNoBypassActor updates a ruleset for the specified repository. // // This function is necessary as the UpdateRuleset function does not marshal ByPassActor if passed as nil or an empty array. // +// Deprecated: Use UpdateRulesetClearBypassActor instead. +// // GitHub API docs: https://docs.github.com/rest/repos/rules#update-a-repository-ruleset // //meta:operation PUT /repos/{owner}/{repo}/rulesets/{ruleset_id} diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index 00cf390bb07..6a3190f2570 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -755,16 +755,10 @@ func TestRepositoriesService_GetRuleset(t *testing.T) { }) } -func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { +func TestRepositoriesService_UpdateRuleset(t *testing.T) { t.Parallel() client, mux, _ := setup(t) - rs := Ruleset{ - Name: "ruleset", - Source: "o/repo", - Enforcement: "enabled", - } - mux.HandleFunc("/repos/o/repo/rulesets/42", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PUT") fmt.Fprint(w, `{ @@ -777,10 +771,12 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { }) ctx := context.Background() - - ruleSet, _, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, rs) + ruleSet, _, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, Ruleset{ + Name: "ruleset", + Enforcement: "enabled", + }) if err != nil { - t.Errorf("Repositories.UpdateRulesetNoBypassActor returned error: %v \n", err) + t.Errorf("Repositories.UpdateRuleset returned error: %v", err) } want := &Ruleset{ @@ -792,13 +788,13 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { } if !cmp.Equal(ruleSet, want) { - t.Errorf("Repositories.UpdateRulesetNoBypassActor returned %+v, want %+v", ruleSet, want) + t.Errorf("Repositories.UpdateRuleset returned %+v, want %+v", ruleSet, want) } - const methodName = "UpdateRulesetNoBypassActor" + const methodName = "UpdateRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, Ruleset{}) + got, resp, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -806,7 +802,7 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { }) } -func TestRepositoriesService_UpdateRuleset(t *testing.T) { +func TestRepositoriesService_UpdateRulesetClearBypassActor(t *testing.T) { t.Parallel() client, mux, _ := setup(t) @@ -818,16 +814,65 @@ func TestRepositoriesService_UpdateRuleset(t *testing.T) { "source_type": "Repository", "source": "o/repo", "enforcement": "enabled" + "conditions": { + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + } + }, + "rules": [ + { + "type": "creation" + } + ] }`) }) ctx := context.Background() - ruleSet, _, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, Ruleset{ + + _, err := client.Repositories.UpdateRulesetClearBypassActor(ctx, "o", "repo", 42) + if err != nil { + t.Errorf("Repositories.UpdateRulesetClearBypassActor returned error: %v \n", err) + } + + const methodName = "UpdateRulesetClearBypassActor" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Repositories.UpdateRulesetClearBypassActor(ctx, "o", "repo", 42) + }) +} + +func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + rs := Ruleset{ Name: "ruleset", + Source: "o/repo", Enforcement: "enabled", + } + + mux.HandleFunc("/repos/o/repo/rulesets/42", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PUT") + fmt.Fprint(w, `{ + "id": 42, + "name": "ruleset", + "source_type": "Repository", + "source": "o/repo", + "enforcement": "enabled" + }`) }) + + ctx := context.Background() + + ruleSet, _, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, rs) if err != nil { - t.Errorf("Repositories.UpdateRuleset returned error: %v", err) + t.Errorf("Repositories.UpdateRulesetNoBypassActor returned error: %v \n", err) } want := &Ruleset{ @@ -839,13 +884,13 @@ func TestRepositoriesService_UpdateRuleset(t *testing.T) { } if !cmp.Equal(ruleSet, want) { - t.Errorf("Repositories.UpdateRuleset returned %+v, want %+v", ruleSet, want) + t.Errorf("Repositories.UpdateRulesetNoBypassActor returned %+v, want %+v", ruleSet, want) } - const methodName = "UpdateRuleset" + const methodName = "UpdateRulesetNoBypassActor" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, Ruleset{}) + got, resp, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } From 43e3eaa22b451c55f5bbfe3c329348ffe8c5387f Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Tue, 7 Jan 2025 17:16:25 +0000 Subject: [PATCH 08/11] fixup! feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/enterprise_rules_test.go | 28 ++++++++++++++++++++-------- github/event_types_test.go | 17 ++++++++++++----- github/orgs_rules_test.go | 21 +++++++++++++++------ github/repos_rules.go | 21 ++++++++++++++++----- github/repos_rules_test.go | 2 ++ 5 files changed, 65 insertions(+), 24 deletions(-) diff --git a/github/enterprise_rules_test.go b/github/enterprise_rules_test.go index cc1f123fc4b..574b8396591 100644 --- a/github/enterprise_rules_test.go +++ b/github/enterprise_rules_test.go @@ -91,6 +91,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -210,11 +211,12 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -309,11 +311,12 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoName(t *testing.T) }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -465,6 +468,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testin { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -594,11 +598,12 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testin }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -703,11 +708,12 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgNameRepoProperty(t *testin }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -844,6 +850,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -962,11 +969,12 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -1060,11 +1068,12 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoName(t *testing.T) { }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -1210,6 +1219,7 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing. { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -1338,11 +1348,12 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing. }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -1446,11 +1457,12 @@ func TestEnterpriseService_CreateEnterpriseRuleset_OrgIdRepoProperty(t *testing. }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ diff --git a/github/event_types_test.go b/github/event_types_test.go index 66d4e4989a7..b65d792e9bf 100644 --- a/github/event_types_test.go +++ b/github/event_types_test.go @@ -8651,7 +8651,6 @@ func TestRepositoryDispatchEvent_Marshal(t *testing.T) { Branch: Ptr("b"), ClientPayload: jsonMsg, Repo: &Repository{ - ID: Ptr(int64(1)), URL: Ptr("s"), Name: Ptr("n"), @@ -9770,11 +9769,12 @@ func TestRepositoryRulesetEvent_Marshal(t *testing.T) { PullRequest: &RepositoryRulesetPullRequestRule{ Type: "pull_request", Parameters: &PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }, }, RequiredStatusChecks: &RepositoryRulesetRequiredStatusChecksRule{ @@ -9977,11 +9977,12 @@ func TestRepositoryRulesetEvent_Marshal(t *testing.T) { PullRequest: &RepositoryRulesetPullRequestRule{ Type: "pull_request", Parameters: &PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }, }, RequiredStatusChecks: &RepositoryRulesetRequiredStatusChecksRule{ @@ -10131,11 +10132,12 @@ func TestRepositoryRulesetEvent_Marshal(t *testing.T) { PullRequest: &RepositoryRulesetPullRequestRule{ Type: "pull_request", Parameters: &PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }, }, RequiredStatusChecks: &RepositoryRulesetRequiredStatusChecksRule{ @@ -10285,11 +10287,12 @@ func TestRepositoryRulesetEvent_Marshal(t *testing.T) { PullRequest: &RepositoryRulesetPullRequestRule{ Type: "pull_request", Parameters: &PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }, }, RequiredStatusChecks: &RepositoryRulesetRequiredStatusChecksRule{ @@ -10630,6 +10633,7 @@ func TestRepositoryRulesetEvent_Marshal(t *testing.T) { "pull_request": { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -10863,6 +10867,7 @@ func TestRepositoryRulesetEvent_Marshal(t *testing.T) { "pull_request": { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -11024,6 +11029,7 @@ func TestRepositoryRulesetEvent_Marshal(t *testing.T) { "pull_request": { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -11186,6 +11192,7 @@ func TestRepositoryRulesetEvent_Marshal(t *testing.T) { "pull_request": { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index c7ecb09cbd2..13afd4f058e 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -138,6 +138,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -256,11 +257,12 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -351,11 +353,12 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoNames(t *testing.T) }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -489,6 +492,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -613,11 +617,12 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -714,11 +719,12 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoProperty(t *testing. }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -845,6 +851,7 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { { "type": "pull_request", "parameters": { + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -961,11 +968,12 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -1054,11 +1062,12 @@ func TestOrganizationsService_CreateOrganizationRuleset_RepoIDs(t *testing.T) { }), NewRequiredSignaturesRule(), NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, + DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 1, RequiredReviewThreadResolution: true, - DismissStaleReviewsOnPush: true, }), NewRequiredStatusChecksRule(&RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ diff --git a/github/repos_rules.go b/github/repos_rules.go index e4cdabc1997..bfa3b449395 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -11,6 +11,16 @@ import ( "fmt" ) +// MergeMethod models a GitHub merge method. +type MergeMethod string + +// This is the set of GitHub merge methods. +const ( + MergeMethodMerge MergeMethod = "merge" + MergeMethodRebase MergeMethod = "rebase" + MergeMethodSquash MergeMethod = "squash" +) + // BypassActor represents the bypass actors from a ruleset. type BypassActor struct { ActorID *int64 `json:"actor_id,omitempty"` @@ -125,11 +135,12 @@ type RequiredDeploymentEnvironmentsRuleParameters struct { // PullRequestRuleParameters represents the pull_request rule parameters. type PullRequestRuleParameters struct { - DismissStaleReviewsOnPush bool `json:"dismiss_stale_reviews_on_push"` - RequireCodeOwnerReview bool `json:"require_code_owner_review"` - RequireLastPushApproval bool `json:"require_last_push_approval"` - RequiredApprovingReviewCount int `json:"required_approving_review_count"` - RequiredReviewThreadResolution bool `json:"required_review_thread_resolution"` + AllowedMergeMethods []MergeMethod `json:"allowed_merge_methods"` + DismissStaleReviewsOnPush bool `json:"dismiss_stale_reviews_on_push"` + RequireCodeOwnerReview bool `json:"require_code_owner_review"` + RequireLastPushApproval bool `json:"require_last_push_approval"` + RequiredApprovingReviewCount int `json:"required_approving_review_count"` + RequiredReviewThreadResolution bool `json:"required_review_thread_resolution"` } // RuleRequiredStatusChecks represents the RequiredStatusChecks for the RequiredStatusChecksRuleParameters object. diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index 6a3190f2570..8ee8b9749ec 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -243,6 +243,7 @@ func TestRepositoryRule_UnmarshalJSON(t *testing.T) { data: `{ "type":"pull_request", "parameters":{ + "allowed_merge_methods": ["rebase","squash"], "dismiss_stale_reviews_on_push": true, "require_code_owner_review": true, "require_last_push_approval": true, @@ -251,6 +252,7 @@ func TestRepositoryRule_UnmarshalJSON(t *testing.T) { } }`, want: NewPullRequestRule(&PullRequestRuleParameters{ + AllowedMergeMethods: []MergeMethod{"rebase", "squash"}, DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, From 6c20af0f929dd01f327a6d975269047323dc3f2b Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Tue, 7 Jan 2025 18:07:55 +0000 Subject: [PATCH 09/11] fixup! feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/repos_rules.go | 30 +++++++++++++++++------------- github/repos_rules_test.go | 4 ++-- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/github/repos_rules.go b/github/repos_rules.go index bfa3b449395..7af057e4f0c 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -999,21 +999,25 @@ func (s *RepositoriesService) UpdateRulesetClearBypassActor(ctx context.Context, // GitHub API docs: https://docs.github.com/rest/repos/rules#update-a-repository-ruleset // //meta:operation PUT /repos/{owner}/{repo}/rulesets/{ruleset_id} -func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, owner, repo string, rulesetID int64, rs Ruleset) (*Ruleset, *Response, error) { +func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, owner, repo string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("repos/%v/%v/rulesets/%v", owner, repo, rulesetID) - rsNoBypassActor := rulesetNoOmitBypassActors{ - ID: rs.ID, - Name: rs.Name, - Target: rs.Target, - SourceType: rs.SourceType, - Source: rs.Source, - Enforcement: rs.Enforcement, - BypassActors: rs.BypassActors, - NodeID: rs.NodeID, - Links: rs.Links, - Conditions: rs.Conditions, - Rules: rs.Rules, + rsNoBypassActor := &rulesetNoOmitBypassActors{} + + if rs != nil { + rsNoBypassActor = &rulesetNoOmitBypassActors{ + ID: rs.ID, + Name: rs.Name, + Target: rs.Target, + SourceType: rs.SourceType, + Source: rs.Source, + Enforcement: rs.Enforcement, + BypassActors: rs.BypassActors, + NodeID: rs.NodeID, + Links: rs.Links, + Conditions: rs.Conditions, + Rules: rs.Rules, + } } req, err := s.client.NewRequest("PUT", u, rsNoBypassActor) diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index 8ee8b9749ec..a01ad1baf33 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -872,7 +872,7 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { ctx := context.Background() - ruleSet, _, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, rs) + ruleSet, _, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, &rs) if err != nil { t.Errorf("Repositories.UpdateRulesetNoBypassActor returned error: %v \n", err) } @@ -892,7 +892,7 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { const methodName = "UpdateRulesetNoBypassActor" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, Ruleset{}) + got, resp, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, &Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } From 2acaf4198532d04ac1202f943d42e20d913b88c1 Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Tue, 7 Jan 2025 18:14:48 +0000 Subject: [PATCH 10/11] fixup! feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/enterprise_rules.go | 18 ++++++------- github/orgs_rules.go | 18 ++++++------- github/repos_rules.go | 54 ++++++++++++++++++-------------------- github/repos_rules_test.go | 4 +-- 4 files changed, 45 insertions(+), 49 deletions(-) diff --git a/github/enterprise_rules.go b/github/enterprise_rules.go index 04e93a662c6..32c19d0d1e5 100644 --- a/github/enterprise_rules.go +++ b/github/enterprise_rules.go @@ -15,21 +15,21 @@ import ( // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#create-an-enterprise-repository-ruleset // //meta:operation POST /enterprises/{enterprise}/rulesets -func (s *EnterpriseService) CreateEnterpriseRuleset(ctx context.Context, enterprise string, rs Ruleset) (*Ruleset, *Response, error) { +func (s *EnterpriseService) CreateEnterpriseRuleset(ctx context.Context, enterprise string, ruleset Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("enterprises/%v/rulesets", enterprise) - req, err := s.client.NewRequest("POST", u, rs) + req, err := s.client.NewRequest("POST", u, ruleset) if err != nil { return nil, nil, err } - var ruleset *Ruleset + var rs *Ruleset resp, err := s.client.Do(ctx, req, &ruleset) if err != nil { return nil, resp, err } - return ruleset, resp, nil + return rs, resp, nil } // GetEnterpriseRuleset gets a ruleset from the specified enterprise. @@ -59,26 +59,26 @@ func (s *EnterpriseService) GetEnterpriseRuleset(ctx context.Context, enterprise // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#update-an-enterprise-repository-ruleset // //meta:operation PUT /enterprises/{enterprise}/rulesets/{ruleset_id} -func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64, rs Ruleset) (*Ruleset, *Response, error) { +func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterprise string, rulesetID int64, ruleset Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("enterprises/%v/rulesets/%v", enterprise, rulesetID) - req, err := s.client.NewRequest("PUT", u, rs) + req, err := s.client.NewRequest("PUT", u, ruleset) if err != nil { return nil, nil, err } - var ruleset *Ruleset + var rs *Ruleset resp, err := s.client.Do(ctx, req, &ruleset) if err != nil { return nil, resp, err } - return ruleset, resp, nil + return rs, resp, nil } // UpdateEnterpriseRulesetClearBypassActor clears the ruleset bypass actors for a ruleset for the specified repository. // -// This function is necessary as the UpdateEnterpriseRuleset function does not marshal ByPassActor if passed as nil or an empty array. +// This function is necessary as the UpdateEnterpriseRuleset function does not marshal ByPassActor if passed as an empty array. // // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#update-an-enterprise-repository-ruleset // diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 5438a1d6fb3..7afab24dcac 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -37,21 +37,21 @@ func (s *OrganizationsService) GetAllOrganizationRulesets(ctx context.Context, o // GitHub API docs: https://docs.github.com/rest/orgs/rules#create-an-organization-repository-ruleset // //meta:operation POST /orgs/{org}/rulesets -func (s *OrganizationsService) CreateOrganizationRuleset(ctx context.Context, org string, rs Ruleset) (*Ruleset, *Response, error) { +func (s *OrganizationsService) CreateOrganizationRuleset(ctx context.Context, org string, ruleset Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("orgs/%v/rulesets", org) - req, err := s.client.NewRequest("POST", u, rs) + req, err := s.client.NewRequest("POST", u, ruleset) if err != nil { return nil, nil, err } - var ruleset *Ruleset + var rs *Ruleset resp, err := s.client.Do(ctx, req, &ruleset) if err != nil { return nil, resp, err } - return ruleset, resp, nil + return rs, resp, nil } // GetOrganizationRuleset gets a ruleset from the specified organization. @@ -81,26 +81,26 @@ func (s *OrganizationsService) GetOrganizationRuleset(ctx context.Context, org s // GitHub API docs: https://docs.github.com/rest/orgs/rules#update-an-organization-repository-ruleset // //meta:operation PUT /orgs/{org}/rulesets/{ruleset_id} -func (s *OrganizationsService) UpdateOrganizationRuleset(ctx context.Context, org string, rulesetID int64, rs Ruleset) (*Ruleset, *Response, error) { +func (s *OrganizationsService) UpdateOrganizationRuleset(ctx context.Context, org string, rulesetID int64, ruleset Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID) - req, err := s.client.NewRequest("PUT", u, rs) + req, err := s.client.NewRequest("PUT", u, ruleset) if err != nil { return nil, nil, err } - var ruleset *Ruleset + var rs *Ruleset resp, err := s.client.Do(ctx, req, &ruleset) if err != nil { return nil, resp, err } - return ruleset, resp, nil + return rs, resp, nil } // UpdateOrganizationRulesetClearBypassActor clears the ruleset bypass actors for a ruleset for the specified repository. // -// This function is necessary as the UpdateOrganizationRuleset function does not marshal ByPassActor if passed as nil or an empty array. +// This function is necessary as the UpdateOrganizationRuleset function does not marshal ByPassActor if passed as an empty array. // // GitHub API docs: https://docs.github.com/rest/orgs/rules#update-an-organization-repository-ruleset // diff --git a/github/repos_rules.go b/github/repos_rules.go index 7af057e4f0c..25fec174499 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -903,21 +903,21 @@ func (s *RepositoriesService) GetAllRulesets(ctx context.Context, owner, repo st // GitHub API docs: https://docs.github.com/rest/repos/rules#create-a-repository-ruleset // //meta:operation POST /repos/{owner}/{repo}/rulesets -func (s *RepositoriesService) CreateRuleset(ctx context.Context, owner, repo string, rs Ruleset) (*Ruleset, *Response, error) { +func (s *RepositoriesService) CreateRuleset(ctx context.Context, owner, repo string, ruleset Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("repos/%v/%v/rulesets", owner, repo) - req, err := s.client.NewRequest("POST", u, rs) + req, err := s.client.NewRequest("POST", u, ruleset) if err != nil { return nil, nil, err } - var ruleset *Ruleset + var rs *Ruleset resp, err := s.client.Do(ctx, req, &ruleset) if err != nil { return nil, resp, err } - return ruleset, resp, nil + return rs, resp, nil } // GetRuleset gets a ruleset for the specified repository. @@ -948,26 +948,26 @@ func (s *RepositoriesService) GetRuleset(ctx context.Context, owner, repo string // GitHub API docs: https://docs.github.com/rest/repos/rules#update-a-repository-ruleset // //meta:operation PUT /repos/{owner}/{repo}/rulesets/{ruleset_id} -func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo string, rulesetID int64, rs Ruleset) (*Ruleset, *Response, error) { +func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo string, rulesetID int64, ruleset Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("repos/%v/%v/rulesets/%v", owner, repo, rulesetID) - req, err := s.client.NewRequest("PUT", u, rs) + req, err := s.client.NewRequest("PUT", u, ruleset) if err != nil { return nil, nil, err } - var ruleset *Ruleset + var rs *Ruleset resp, err := s.client.Do(ctx, req, &ruleset) if err != nil { return nil, resp, err } - return ruleset, resp, nil + return rs, resp, nil } // UpdateRulesetClearBypassActor clears the ruleset bypass actors for a ruleset for the specified repository. // -// This function is necessary as the UpdateRuleset function does not marshal ByPassActor if passed as nil or an empty array. +// This function is necessary as the UpdateRuleset function does not marshal ByPassActor if passed as an empty array. // // GitHub API docs: https://docs.github.com/rest/repos/rules#update-a-repository-ruleset // @@ -992,32 +992,28 @@ func (s *RepositoriesService) UpdateRulesetClearBypassActor(ctx context.Context, // UpdateRulesetNoBypassActor updates a ruleset for the specified repository. // -// This function is necessary as the UpdateRuleset function does not marshal ByPassActor if passed as nil or an empty array. +// This function is necessary as the UpdateRuleset function does not marshal ByPassActor if passed as an empty array. // // Deprecated: Use UpdateRulesetClearBypassActor instead. // // GitHub API docs: https://docs.github.com/rest/repos/rules#update-a-repository-ruleset // //meta:operation PUT /repos/{owner}/{repo}/rulesets/{ruleset_id} -func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, owner, repo string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { +func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, owner, repo string, rulesetID int64, ruleSet Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("repos/%v/%v/rulesets/%v", owner, repo, rulesetID) - rsNoBypassActor := &rulesetNoOmitBypassActors{} - - if rs != nil { - rsNoBypassActor = &rulesetNoOmitBypassActors{ - ID: rs.ID, - Name: rs.Name, - Target: rs.Target, - SourceType: rs.SourceType, - Source: rs.Source, - Enforcement: rs.Enforcement, - BypassActors: rs.BypassActors, - NodeID: rs.NodeID, - Links: rs.Links, - Conditions: rs.Conditions, - Rules: rs.Rules, - } + rsNoBypassActor := rulesetNoOmitBypassActors{ + ID: ruleSet.ID, + Name: ruleSet.Name, + Target: ruleSet.Target, + SourceType: ruleSet.SourceType, + Source: ruleSet.Source, + Enforcement: ruleSet.Enforcement, + BypassActors: ruleSet.BypassActors, + NodeID: ruleSet.NodeID, + Links: ruleSet.Links, + Conditions: ruleSet.Conditions, + Rules: ruleSet.Rules, } req, err := s.client.NewRequest("PUT", u, rsNoBypassActor) @@ -1025,13 +1021,13 @@ func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, ow return nil, nil, err } - var ruleSet *Ruleset + var rs *Ruleset resp, err := s.client.Do(ctx, req, &ruleSet) if err != nil { return nil, resp, err } - return ruleSet, resp, nil + return rs, resp, nil } // DeleteRuleset deletes a ruleset for the specified repository. diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index a01ad1baf33..8ee8b9749ec 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -872,7 +872,7 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { ctx := context.Background() - ruleSet, _, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, &rs) + ruleSet, _, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, rs) if err != nil { t.Errorf("Repositories.UpdateRulesetNoBypassActor returned error: %v \n", err) } @@ -892,7 +892,7 @@ func TestRepositoriesService_UpdateRulesetNoBypassActor(t *testing.T) { const methodName = "UpdateRulesetNoBypassActor" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, &Ruleset{}) + got, resp, err := client.Repositories.UpdateRulesetNoBypassActor(ctx, "o", "repo", 42, Ruleset{}) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } From 0e2ee695493adf39b537c6f99283c1464c3c4a99 Mon Sep 17 00:00:00 2001 From: Steve Hipwell Date: Tue, 7 Jan 2025 19:19:28 +0000 Subject: [PATCH 11/11] fixup! feat: Added enterprise rules Signed-off-by: Steve Hipwell --- github/enterprise_rules.go | 4 ++-- github/orgs_rules.go | 4 ++-- github/repos_rules.go | 30 +++++++++++++++--------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/github/enterprise_rules.go b/github/enterprise_rules.go index 32c19d0d1e5..29e3e4a568f 100644 --- a/github/enterprise_rules.go +++ b/github/enterprise_rules.go @@ -24,7 +24,7 @@ func (s *EnterpriseService) CreateEnterpriseRuleset(ctx context.Context, enterpr } var rs *Ruleset - resp, err := s.client.Do(ctx, req, &ruleset) + resp, err := s.client.Do(ctx, req, &rs) if err != nil { return nil, resp, err } @@ -68,7 +68,7 @@ func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterpr } var rs *Ruleset - resp, err := s.client.Do(ctx, req, &ruleset) + resp, err := s.client.Do(ctx, req, &rs) if err != nil { return nil, resp, err } diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 7afab24dcac..b0773fab917 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -46,7 +46,7 @@ func (s *OrganizationsService) CreateOrganizationRuleset(ctx context.Context, or } var rs *Ruleset - resp, err := s.client.Do(ctx, req, &ruleset) + resp, err := s.client.Do(ctx, req, &rs) if err != nil { return nil, resp, err } @@ -90,7 +90,7 @@ func (s *OrganizationsService) UpdateOrganizationRuleset(ctx context.Context, or } var rs *Ruleset - resp, err := s.client.Do(ctx, req, &ruleset) + resp, err := s.client.Do(ctx, req, &rs) if err != nil { return nil, resp, err } diff --git a/github/repos_rules.go b/github/repos_rules.go index 25fec174499..60e9739cdf7 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -912,7 +912,7 @@ func (s *RepositoriesService) CreateRuleset(ctx context.Context, owner, repo str } var rs *Ruleset - resp, err := s.client.Do(ctx, req, &ruleset) + resp, err := s.client.Do(ctx, req, &rs) if err != nil { return nil, resp, err } @@ -957,7 +957,7 @@ func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo str } var rs *Ruleset - resp, err := s.client.Do(ctx, req, &ruleset) + resp, err := s.client.Do(ctx, req, &rs) if err != nil { return nil, resp, err } @@ -999,21 +999,21 @@ func (s *RepositoriesService) UpdateRulesetClearBypassActor(ctx context.Context, // GitHub API docs: https://docs.github.com/rest/repos/rules#update-a-repository-ruleset // //meta:operation PUT /repos/{owner}/{repo}/rulesets/{ruleset_id} -func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, owner, repo string, rulesetID int64, ruleSet Ruleset) (*Ruleset, *Response, error) { +func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, owner, repo string, rulesetID int64, ruleset Ruleset) (*Ruleset, *Response, error) { u := fmt.Sprintf("repos/%v/%v/rulesets/%v", owner, repo, rulesetID) rsNoBypassActor := rulesetNoOmitBypassActors{ - ID: ruleSet.ID, - Name: ruleSet.Name, - Target: ruleSet.Target, - SourceType: ruleSet.SourceType, - Source: ruleSet.Source, - Enforcement: ruleSet.Enforcement, - BypassActors: ruleSet.BypassActors, - NodeID: ruleSet.NodeID, - Links: ruleSet.Links, - Conditions: ruleSet.Conditions, - Rules: ruleSet.Rules, + ID: ruleset.ID, + Name: ruleset.Name, + Target: ruleset.Target, + SourceType: ruleset.SourceType, + Source: ruleset.Source, + Enforcement: ruleset.Enforcement, + BypassActors: ruleset.BypassActors, + NodeID: ruleset.NodeID, + Links: ruleset.Links, + Conditions: ruleset.Conditions, + Rules: ruleset.Rules, } req, err := s.client.NewRequest("PUT", u, rsNoBypassActor) @@ -1022,7 +1022,7 @@ func (s *RepositoriesService) UpdateRulesetNoBypassActor(ctx context.Context, ow } var rs *Ruleset - resp, err := s.client.Do(ctx, req, &ruleSet) + resp, err := s.client.Do(ctx, req, &rs) if err != nil { return nil, resp, err }