From 958a8a070f2b5e7e05601da007a7f8b464934d20 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Wed, 31 May 2023 17:00:46 +1000 Subject: [PATCH 01/29] Add repository ruleset and related structs Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/github-accessors.go | 80 ++++++++++++++++++++++++++++ github/github-accessors_test.go | 94 +++++++++++++++++++++++++++++++++ github/repos.go | 35 ++++++++++++ 3 files changed, 209 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index c2d9061c174..91b997c949d 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -2222,6 +2222,22 @@ func (b *BranchProtectionRuleEvent) GetSender() *User { return b.Sender } +// GetActorID returns the ActorID field if it's non-nil, zero value otherwise. +func (b *BypassActor) GetActorID() int { + if b == nil || b.ActorID == nil { + return 0 + } + return *b.ActorID +} + +// GetActorType returns the ActorType field if it's non-nil, zero value otherwise. +func (b *BypassActor) GetActorType() string { + if b == nil || b.ActorType == nil { + return "" + } + return *b.ActorType +} + // GetApp returns the App field. func (c *CheckRun) GetApp() *App { if c == nil { @@ -18366,6 +18382,70 @@ func (r *Rule) GetSeverity() string { return *r.Severity } +// GetBypassActors returns the BypassActors field if it's non-nil, zero value otherwise. +func (r *Ruleset) GetBypassActors() []BypassActor { + if r == nil || r.BypassActors == nil { + return nil + } + return *r.BypassActors +} + +// GetBypassMode returns the BypassMode field if it's non-nil, zero value otherwise. +func (r *Ruleset) GetBypassMode() string { + if r == nil || r.BypassMode == nil { + return "" + } + return *r.BypassMode +} + +// GetLinks returns the Links field. +func (r *Ruleset) GetLinks() *RulesetLinks { + if r == nil { + return nil + } + return r.Links +} + +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (r *Ruleset) GetNodeID() string { + if r == nil || r.NodeID == nil { + return "" + } + return *r.NodeID +} + +// GetSourceType returns the SourceType field if it's non-nil, zero value otherwise. +func (r *Ruleset) GetSourceType() string { + if r == nil || r.SourceType == nil { + return "" + } + return *r.SourceType +} + +// GetTarget returns the Target field if it's non-nil, zero value otherwise. +func (r *Ruleset) GetTarget() string { + if r == nil || r.Target == nil { + return "" + } + return *r.Target +} + +// GetHRef returns the HRef field if it's non-nil, zero value otherwise. +func (r *RulesetLink) GetHRef() string { + if r == nil || r.HRef == nil { + return "" + } + return *r.HRef +} + +// GetSelf returns the Self field. +func (r *RulesetLinks) GetSelf() *RulesetLink { + if r == nil { + return nil + } + return r.Self +} + // GetBusy returns the Busy field if it's non-nil, zero value otherwise. func (r *Runner) GetBusy() bool { if r == nil || r.Busy == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index eb0a0db42c6..d18bae61e2d 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -2664,6 +2664,26 @@ func TestBranchProtectionRuleEvent_GetSender(tt *testing.T) { b.GetSender() } +func TestBypassActor_GetActorID(tt *testing.T) { + var zeroValue int + b := &BypassActor{ActorID: &zeroValue} + b.GetActorID() + b = &BypassActor{} + b.GetActorID() + b = nil + b.GetActorID() +} + +func TestBypassActor_GetActorType(tt *testing.T) { + var zeroValue string + b := &BypassActor{ActorType: &zeroValue} + b.GetActorType() + b = &BypassActor{} + b.GetActorType() + b = nil + b.GetActorType() +} + func TestCheckRun_GetApp(tt *testing.T) { c := &CheckRun{} c.GetApp() @@ -21404,6 +21424,80 @@ func TestRule_GetSeverity(tt *testing.T) { r.GetSeverity() } +func TestRuleset_GetBypassActors(tt *testing.T) { + var zeroValue []BypassActor + r := &Ruleset{BypassActors: &zeroValue} + r.GetBypassActors() + r = &Ruleset{} + r.GetBypassActors() + r = nil + r.GetBypassActors() +} + +func TestRuleset_GetBypassMode(tt *testing.T) { + var zeroValue string + r := &Ruleset{BypassMode: &zeroValue} + r.GetBypassMode() + r = &Ruleset{} + r.GetBypassMode() + r = nil + r.GetBypassMode() +} + +func TestRuleset_GetLinks(tt *testing.T) { + r := &Ruleset{} + r.GetLinks() + r = nil + r.GetLinks() +} + +func TestRuleset_GetNodeID(tt *testing.T) { + var zeroValue string + r := &Ruleset{NodeID: &zeroValue} + r.GetNodeID() + r = &Ruleset{} + r.GetNodeID() + r = nil + r.GetNodeID() +} + +func TestRuleset_GetSourceType(tt *testing.T) { + var zeroValue string + r := &Ruleset{SourceType: &zeroValue} + r.GetSourceType() + r = &Ruleset{} + r.GetSourceType() + r = nil + r.GetSourceType() +} + +func TestRuleset_GetTarget(tt *testing.T) { + var zeroValue string + r := &Ruleset{Target: &zeroValue} + r.GetTarget() + r = &Ruleset{} + r.GetTarget() + r = nil + r.GetTarget() +} + +func TestRulesetLink_GetHRef(tt *testing.T) { + var zeroValue string + r := &RulesetLink{HRef: &zeroValue} + r.GetHRef() + r = &RulesetLink{} + r.GetHRef() + r = nil + r.GetHRef() +} + +func TestRulesetLinks_GetSelf(tt *testing.T) { + r := &RulesetLinks{} + r.GetSelf() + r = nil + r.GetSelf() +} + func TestRunner_GetBusy(tt *testing.T) { var zeroValue bool r := &Runner{Busy: &zeroValue} diff --git a/github/repos.go b/github/repos.go index 5ffad6dd3c4..32df08dc869 100644 --- a/github/repos.go +++ b/github/repos.go @@ -2034,3 +2034,38 @@ func isBranchNotProtected(err error) bool { errorResponse, ok := err.(*ErrorResponse) return ok && errorResponse.Message == githubBranchNotProtected } + +// BypassActor represents the bypass actors from a repository ruleset. +type BypassActor struct { + ActorID *int `json:"actor_id,omitempty"` + // Possible values for ActorType are: Team, Integration + ActorType *string `json:"actor_type,omitempty"` +} + +// RulesetLink represents a single link object from GitHub ruleset request _links. +type RulesetLink struct { + HRef *string `json:"href,omitempty"` +} + +// RulesetLinks represents the "_links" object in a Ruleset. +type RulesetLinks struct { + Self *RulesetLink `json:"self,omitempty"` +} + +// Ruleset represents a GitHub ruleset request. +type Ruleset struct { + ID int `json:"id"` + Name string `json:"name"` + // Possible values for Target are branch, tag + Target *string `json:"target,omitempty"` + // Possible values for SourceType are: Repository, Organization + SourceType *string `json:"source_type,omitempty"` + Source string `json:"source"` + // Possible values for Enforcement are: disabled, active, evaluate + Enforcement string `json:"enforcement"` + // Possible values for BypassMode are: none, repository, organization + BypassMode *string `json:"bypass_mode,omitempty"` + BypassActors *[]BypassActor `json:"bypass_actors,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Links *RulesetLinks `json:"_links,omitempty"` +} From 1e2554c2b83cbb6c3abef5a0b0cfa5eae6250e82 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Wed, 31 May 2023 18:02:20 +1000 Subject: [PATCH 02/29] Add GetAllOrganizationRepositoryRulesets Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 31 ++++++++++++++++++ github/orgs_rules_test.go | 68 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 github/orgs_rules.go create mode 100644 github/orgs_rules_test.go diff --git a/github/orgs_rules.go b/github/orgs_rules.go new file mode 100644 index 00000000000..1dd7ac06695 --- /dev/null +++ b/github/orgs_rules.go @@ -0,0 +1,31 @@ +// Copyright 2017 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" +) + +// GetAllOrganizationRepositoryRulesets gets all the repository rulesets for the specified organization. +// +// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#get-all-organization-repository-rulesets +func (s *OrganizationsService) GetAllOrganizationRepositoryRulesets(ctx context.Context, org string) ([]*Ruleset, *Response, error) { + u := fmt.Sprintf("orgs/%v/rulesets", org) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var rulesets []*Ruleset + resp, err := s.client.Do(ctx, req, &rulesets) + if err != nil { + return nil, resp, err + } + + return rulesets, resp, nil +} diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go new file mode 100644 index 00000000000..05e562225ff --- /dev/null +++ b/github/orgs_rules_test.go @@ -0,0 +1,68 @@ +package github + +import ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestOrganizationsService_GetAllOrganizationRepositoryRulesets(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{}) + fmt.Fprint(w, `[{ + "id": 26110, + "name": "test ruleset", + "target": "branch", + "source_type": "Organization", + "source": "my-org", + "enforcement": "active", + "bypass_mode": "none", + "node_id": "nid", + "_links": { + "self": { + "href": "https://api.github.com/orgs/o/rulesets/26110" + } + } + }]`) + }) + + ctx := context.Background() + rulesets, _, err := client.Organizations.GetAllOrganizationRepositoryRulesets(ctx, "o") + if err != nil { + t.Errorf("Organizations.GetAllOrganizationRepositoryRulesets returned error: %v", err) + } + + want := []*Ruleset{{ + ID: 26110, + Name: "test ruleset", + Target: String("branch"), + SourceType: String("Organization"), + Source: "my-org", + Enforcement: "active", + BypassMode: String("none"), + NodeID: String("nid"), + Links: &RulesetLinks{ + Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, + }, + }} + if !cmp.Equal(rulesets, want) { + t.Errorf("Organizations.GetAllOrganizationRepositoryRulesets returned %+v, want %+v", rulesets, want) + } + + const methodName = "GetAllOrganizationRepositoryRulesets" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.GetAllOrganizationRepositoryRulesets(ctx, "o") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 6a93946223e684be9f7fe4481563e4b5f773b567 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Wed, 31 May 2023 18:36:14 +1000 Subject: [PATCH 03/29] Extend ruleset struct with conditions Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/github-accessors.go | 48 +++++++++++++++++++---------- github/github-accessors_test.go | 54 +++++++++++++++++++++------------ github/repos.go | 24 +++++++++++---- 3 files changed, 84 insertions(+), 42 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 91b997c949d..1ab6757f7da 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -2222,22 +2222,6 @@ func (b *BranchProtectionRuleEvent) GetSender() *User { return b.Sender } -// GetActorID returns the ActorID field if it's non-nil, zero value otherwise. -func (b *BypassActor) GetActorID() int { - if b == nil || b.ActorID == nil { - return 0 - } - return *b.ActorID -} - -// GetActorType returns the ActorType field if it's non-nil, zero value otherwise. -func (b *BypassActor) GetActorType() string { - if b == nil || b.ActorType == nil { - return "" - } - return *b.ActorType -} - // GetApp returns the App field. func (c *CheckRun) GetApp() *App { if c == nil { @@ -18398,6 +18382,14 @@ func (r *Ruleset) GetBypassMode() string { return *r.BypassMode } +// GetConditions returns the Conditions field if it's non-nil, zero value otherwise. +func (r *Ruleset) GetConditions() []RulesetCondition { + if r == nil || r.Conditions == nil { + return nil + } + return *r.Conditions +} + // GetLinks returns the Links field. func (r *Ruleset) GetLinks() *RulesetLinks { if r == nil { @@ -18430,6 +18422,30 @@ func (r *Ruleset) GetTarget() string { return *r.Target } +// GetRefName returns the RefName field. +func (r *RulesetCondition) GetRefName() *RulesetConditionRefName { + if r == nil { + return nil + } + return r.RefName +} + +// GetRepositoryName returns the RepositoryName field. +func (r *RulesetCondition) GetRepositoryName() *RulesetConditionRefName { + if r == nil { + return nil + } + return r.RepositoryName +} + +// GetProtected returns the Protected field if it's non-nil, zero value otherwise. +func (r *RulesetConditionRefName) GetProtected() bool { + if r == nil || r.Protected == nil { + return false + } + return *r.Protected +} + // GetHRef returns the HRef field if it's non-nil, zero value otherwise. func (r *RulesetLink) GetHRef() string { if r == nil || r.HRef == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index d18bae61e2d..703ccb02531 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -2664,26 +2664,6 @@ func TestBranchProtectionRuleEvent_GetSender(tt *testing.T) { b.GetSender() } -func TestBypassActor_GetActorID(tt *testing.T) { - var zeroValue int - b := &BypassActor{ActorID: &zeroValue} - b.GetActorID() - b = &BypassActor{} - b.GetActorID() - b = nil - b.GetActorID() -} - -func TestBypassActor_GetActorType(tt *testing.T) { - var zeroValue string - b := &BypassActor{ActorType: &zeroValue} - b.GetActorType() - b = &BypassActor{} - b.GetActorType() - b = nil - b.GetActorType() -} - func TestCheckRun_GetApp(tt *testing.T) { c := &CheckRun{} c.GetApp() @@ -21444,6 +21424,16 @@ func TestRuleset_GetBypassMode(tt *testing.T) { r.GetBypassMode() } +func TestRuleset_GetConditions(tt *testing.T) { + var zeroValue []RulesetCondition + r := &Ruleset{Conditions: &zeroValue} + r.GetConditions() + r = &Ruleset{} + r.GetConditions() + r = nil + r.GetConditions() +} + func TestRuleset_GetLinks(tt *testing.T) { r := &Ruleset{} r.GetLinks() @@ -21481,6 +21471,30 @@ func TestRuleset_GetTarget(tt *testing.T) { r.GetTarget() } +func TestRulesetCondition_GetRefName(tt *testing.T) { + r := &RulesetCondition{} + r.GetRefName() + r = nil + r.GetRefName() +} + +func TestRulesetCondition_GetRepositoryName(tt *testing.T) { + r := &RulesetCondition{} + r.GetRepositoryName() + r = nil + r.GetRepositoryName() +} + +func TestRulesetConditionRefName_GetProtected(tt *testing.T) { + var zeroValue bool + r := &RulesetConditionRefName{Protected: &zeroValue} + r.GetProtected() + r = &RulesetConditionRefName{} + r.GetProtected() + r = nil + r.GetProtected() +} + func TestRulesetLink_GetHRef(tt *testing.T) { var zeroValue string r := &RulesetLink{HRef: &zeroValue} diff --git a/github/repos.go b/github/repos.go index 32df08dc869..963e1bef421 100644 --- a/github/repos.go +++ b/github/repos.go @@ -2037,9 +2037,9 @@ func isBranchNotProtected(err error) bool { // BypassActor represents the bypass actors from a repository ruleset. type BypassActor struct { - ActorID *int `json:"actor_id,omitempty"` + ActorID int `json:"actor_id,omitempty"` // Possible values for ActorType are: Team, Integration - ActorType *string `json:"actor_type,omitempty"` + ActorType string `json:"actor_type,omitempty"` } // RulesetLink represents a single link object from GitHub ruleset request _links. @@ -2052,6 +2052,17 @@ type RulesetLinks struct { Self *RulesetLink `json:"self,omitempty"` } +type RulesetConditionRefName struct { + Include []string `json:"include"` + Exclude []string `json:"exclude"` + Protected *bool `json:"protected,omitempty"` +} + +type RulesetCondition struct { + RefName *RulesetConditionRefName `json:"ref_name,omitempty"` + RepositoryName *RulesetConditionRefName `json:"repository_name,omitempty"` +} + // Ruleset represents a GitHub ruleset request. type Ruleset struct { ID int `json:"id"` @@ -2064,8 +2075,9 @@ type Ruleset struct { // Possible values for Enforcement are: disabled, active, evaluate Enforcement string `json:"enforcement"` // Possible values for BypassMode are: none, repository, organization - BypassMode *string `json:"bypass_mode,omitempty"` - BypassActors *[]BypassActor `json:"bypass_actors,omitempty"` - NodeID *string `json:"node_id,omitempty"` - Links *RulesetLinks `json:"_links,omitempty"` + BypassMode *string `json:"bypass_mode,omitempty"` + BypassActors *[]BypassActor `json:"bypass_actors,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Links *RulesetLinks `json:"_links,omitempty"` + Conditions *[]RulesetCondition `json:"conditions,omitempty"` } From 5b15d81ab00f91ccc7749c42fe0dee0852380227 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Wed, 31 May 2023 21:18:03 +1000 Subject: [PATCH 04/29] Create all the different rules Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/github-accessors.go | 86 ++++++++++- github/github-accessors_test.go | 101 ++++++++++++- github/repos.go | 47 ------ github/repos_rules.go | 246 ++++++++++++++++++++++++++++++++ 4 files changed, 419 insertions(+), 61 deletions(-) create mode 100644 github/repos_rules.go diff --git a/github/github-accessors.go b/github/github-accessors.go index 1ab6757f7da..483c976fe3e 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -15062,6 +15062,46 @@ func (p *PullRequestReviewThreadEvent) GetThread() *PullRequestThread { return p.Thread } +// GetDismissStaleReviewsOnPush returns the DismissStaleReviewsOnPush field if it's non-nil, zero value otherwise. +func (p *PullRequestRuleParameters) GetDismissStaleReviewsOnPush() bool { + if p == nil || p.DismissStaleReviewsOnPush == nil { + return false + } + return *p.DismissStaleReviewsOnPush +} + +// GetRequireCodeOwnerReview returns the RequireCodeOwnerReview field if it's non-nil, zero value otherwise. +func (p *PullRequestRuleParameters) GetRequireCodeOwnerReview() bool { + if p == nil || p.RequireCodeOwnerReview == nil { + return false + } + return *p.RequireCodeOwnerReview +} + +// GetRequiredApprovingReviewCount returns the RequiredApprovingReviewCount field if it's non-nil, zero value otherwise. +func (p *PullRequestRuleParameters) GetRequiredApprovingReviewCount() int { + if p == nil || p.RequiredApprovingReviewCount == nil { + return 0 + } + return *p.RequiredApprovingReviewCount +} + +// GetRequiredReviewThreadResolution returns the RequiredReviewThreadResolution field if it's non-nil, zero value otherwise. +func (p *PullRequestRuleParameters) GetRequiredReviewThreadResolution() bool { + if p == nil || p.RequiredReviewThreadResolution == nil { + return false + } + return *p.RequiredReviewThreadResolution +} + +// GetRequireLastPushApproval returns the RequireLastPushApproval field if it's non-nil, zero value otherwise. +func (p *PullRequestRuleParameters) GetRequireLastPushApproval() bool { + if p == nil || p.RequireLastPushApproval == nil { + return false + } + return *p.RequireLastPushApproval +} + // GetAction returns the Action field if it's non-nil, zero value otherwise. func (p *PullRequestTargetEvent) GetAction() string { if p == nil || p.Action == nil { @@ -18294,6 +18334,14 @@ func (r *RequiredStatusChecksRequest) GetStrict() bool { return *r.Strict } +// GetIntegrationID returns the IntegrationID field if it's non-nil, zero value otherwise. +func (r *RequiredStatusChecksRuleParameters) GetIntegrationID() int64 { + if r == nil || r.IntegrationID == nil { + return 0 + } + return *r.IntegrationID +} + // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (r *RequiredWorkflowSelectedRepos) GetTotalCount() int { if r == nil || r.TotalCount == nil { @@ -18366,6 +18414,22 @@ func (r *Rule) GetSeverity() string { return *r.Severity } +// GetName returns the Name field if it's non-nil, zero value otherwise. +func (r *RulePatternParameters) GetName() string { + if r == nil || r.Name == nil { + return "" + } + return *r.Name +} + +// GetNegate returns the Negate field if it's non-nil, zero value otherwise. +func (r *RulePatternParameters) GetNegate() bool { + if r == nil || r.Negate == nil { + return false + } + return *r.Negate +} + // GetBypassActors returns the BypassActors field if it's non-nil, zero value otherwise. func (r *Ruleset) GetBypassActors() []BypassActor { if r == nil || r.BypassActors == nil { @@ -18382,12 +18446,12 @@ func (r *Ruleset) GetBypassMode() string { return *r.BypassMode } -// GetConditions returns the Conditions field if it's non-nil, zero value otherwise. -func (r *Ruleset) GetConditions() []RulesetCondition { - if r == nil || r.Conditions == nil { +// GetConditions returns the Conditions field. +func (r *Ruleset) GetConditions() *RulesetCondition { + if r == nil { return nil } - return *r.Conditions + return r.Conditions } // GetLinks returns the Links field. @@ -18406,6 +18470,14 @@ func (r *Ruleset) GetNodeID() string { return *r.NodeID } +// GetRules returns the Rules field if it's non-nil, zero value otherwise. +func (r *Ruleset) GetRules() []RulesetRule { + if r == nil || r.Rules == nil { + return nil + } + return *r.Rules +} + // GetSourceType returns the SourceType field if it's non-nil, zero value otherwise. func (r *Ruleset) GetSourceType() string { if r == nil || r.SourceType == nil { @@ -18423,7 +18495,7 @@ func (r *Ruleset) GetTarget() string { } // GetRefName returns the RefName field. -func (r *RulesetCondition) GetRefName() *RulesetConditionRefName { +func (r *RulesetCondition) GetRefName() *RulesetConditionParameters { if r == nil { return nil } @@ -18431,7 +18503,7 @@ func (r *RulesetCondition) GetRefName() *RulesetConditionRefName { } // GetRepositoryName returns the RepositoryName field. -func (r *RulesetCondition) GetRepositoryName() *RulesetConditionRefName { +func (r *RulesetCondition) GetRepositoryName() *RulesetConditionParameters { if r == nil { return nil } @@ -18439,7 +18511,7 @@ func (r *RulesetCondition) GetRepositoryName() *RulesetConditionRefName { } // GetProtected returns the Protected field if it's non-nil, zero value otherwise. -func (r *RulesetConditionRefName) GetProtected() bool { +func (r *RulesetConditionParameters) GetProtected() bool { if r == nil || r.Protected == nil { return false } diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 703ccb02531..e4b409468eb 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -17499,6 +17499,56 @@ func TestPullRequestReviewThreadEvent_GetThread(tt *testing.T) { p.GetThread() } +func TestPullRequestRuleParameters_GetDismissStaleReviewsOnPush(tt *testing.T) { + var zeroValue bool + p := &PullRequestRuleParameters{DismissStaleReviewsOnPush: &zeroValue} + p.GetDismissStaleReviewsOnPush() + p = &PullRequestRuleParameters{} + p.GetDismissStaleReviewsOnPush() + p = nil + p.GetDismissStaleReviewsOnPush() +} + +func TestPullRequestRuleParameters_GetRequireCodeOwnerReview(tt *testing.T) { + var zeroValue bool + p := &PullRequestRuleParameters{RequireCodeOwnerReview: &zeroValue} + p.GetRequireCodeOwnerReview() + p = &PullRequestRuleParameters{} + p.GetRequireCodeOwnerReview() + p = nil + p.GetRequireCodeOwnerReview() +} + +func TestPullRequestRuleParameters_GetRequiredApprovingReviewCount(tt *testing.T) { + var zeroValue int + p := &PullRequestRuleParameters{RequiredApprovingReviewCount: &zeroValue} + p.GetRequiredApprovingReviewCount() + p = &PullRequestRuleParameters{} + p.GetRequiredApprovingReviewCount() + p = nil + p.GetRequiredApprovingReviewCount() +} + +func TestPullRequestRuleParameters_GetRequiredReviewThreadResolution(tt *testing.T) { + var zeroValue bool + p := &PullRequestRuleParameters{RequiredReviewThreadResolution: &zeroValue} + p.GetRequiredReviewThreadResolution() + p = &PullRequestRuleParameters{} + p.GetRequiredReviewThreadResolution() + p = nil + p.GetRequiredReviewThreadResolution() +} + +func TestPullRequestRuleParameters_GetRequireLastPushApproval(tt *testing.T) { + var zeroValue bool + p := &PullRequestRuleParameters{RequireLastPushApproval: &zeroValue} + p.GetRequireLastPushApproval() + p = &PullRequestRuleParameters{} + p.GetRequireLastPushApproval() + p = nil + p.GetRequireLastPushApproval() +} + func TestPullRequestTargetEvent_GetAction(tt *testing.T) { var zeroValue string p := &PullRequestTargetEvent{Action: &zeroValue} @@ -21314,6 +21364,16 @@ func TestRequiredStatusChecksRequest_GetStrict(tt *testing.T) { r.GetStrict() } +func TestRequiredStatusChecksRuleParameters_GetIntegrationID(tt *testing.T) { + var zeroValue int64 + r := &RequiredStatusChecksRuleParameters{IntegrationID: &zeroValue} + r.GetIntegrationID() + r = &RequiredStatusChecksRuleParameters{} + r.GetIntegrationID() + r = nil + r.GetIntegrationID() +} + func TestRequiredWorkflowSelectedRepos_GetTotalCount(tt *testing.T) { var zeroValue int r := &RequiredWorkflowSelectedRepos{TotalCount: &zeroValue} @@ -21404,6 +21464,26 @@ func TestRule_GetSeverity(tt *testing.T) { r.GetSeverity() } +func TestRulePatternParameters_GetName(tt *testing.T) { + var zeroValue string + r := &RulePatternParameters{Name: &zeroValue} + r.GetName() + r = &RulePatternParameters{} + r.GetName() + r = nil + r.GetName() +} + +func TestRulePatternParameters_GetNegate(tt *testing.T) { + var zeroValue bool + r := &RulePatternParameters{Negate: &zeroValue} + r.GetNegate() + r = &RulePatternParameters{} + r.GetNegate() + r = nil + r.GetNegate() +} + func TestRuleset_GetBypassActors(tt *testing.T) { var zeroValue []BypassActor r := &Ruleset{BypassActors: &zeroValue} @@ -21425,10 +21505,7 @@ func TestRuleset_GetBypassMode(tt *testing.T) { } func TestRuleset_GetConditions(tt *testing.T) { - var zeroValue []RulesetCondition - r := &Ruleset{Conditions: &zeroValue} - r.GetConditions() - r = &Ruleset{} + r := &Ruleset{} r.GetConditions() r = nil r.GetConditions() @@ -21451,6 +21528,16 @@ func TestRuleset_GetNodeID(tt *testing.T) { r.GetNodeID() } +func TestRuleset_GetRules(tt *testing.T) { + var zeroValue []RulesetRule + r := &Ruleset{Rules: &zeroValue} + r.GetRules() + r = &Ruleset{} + r.GetRules() + r = nil + r.GetRules() +} + func TestRuleset_GetSourceType(tt *testing.T) { var zeroValue string r := &Ruleset{SourceType: &zeroValue} @@ -21485,11 +21572,11 @@ func TestRulesetCondition_GetRepositoryName(tt *testing.T) { r.GetRepositoryName() } -func TestRulesetConditionRefName_GetProtected(tt *testing.T) { +func TestRulesetConditionParameters_GetProtected(tt *testing.T) { var zeroValue bool - r := &RulesetConditionRefName{Protected: &zeroValue} + r := &RulesetConditionParameters{Protected: &zeroValue} r.GetProtected() - r = &RulesetConditionRefName{} + r = &RulesetConditionParameters{} r.GetProtected() r = nil r.GetProtected() diff --git a/github/repos.go b/github/repos.go index 963e1bef421..5ffad6dd3c4 100644 --- a/github/repos.go +++ b/github/repos.go @@ -2034,50 +2034,3 @@ func isBranchNotProtected(err error) bool { errorResponse, ok := err.(*ErrorResponse) return ok && errorResponse.Message == githubBranchNotProtected } - -// BypassActor represents the bypass actors from a repository ruleset. -type BypassActor struct { - ActorID int `json:"actor_id,omitempty"` - // Possible values for ActorType are: Team, Integration - ActorType string `json:"actor_type,omitempty"` -} - -// RulesetLink represents a single link object from GitHub ruleset request _links. -type RulesetLink struct { - HRef *string `json:"href,omitempty"` -} - -// RulesetLinks represents the "_links" object in a Ruleset. -type RulesetLinks struct { - Self *RulesetLink `json:"self,omitempty"` -} - -type RulesetConditionRefName struct { - Include []string `json:"include"` - Exclude []string `json:"exclude"` - Protected *bool `json:"protected,omitempty"` -} - -type RulesetCondition struct { - RefName *RulesetConditionRefName `json:"ref_name,omitempty"` - RepositoryName *RulesetConditionRefName `json:"repository_name,omitempty"` -} - -// Ruleset represents a GitHub ruleset request. -type Ruleset struct { - ID int `json:"id"` - Name string `json:"name"` - // Possible values for Target are branch, tag - Target *string `json:"target,omitempty"` - // Possible values for SourceType are: Repository, Organization - SourceType *string `json:"source_type,omitempty"` - Source string `json:"source"` - // Possible values for Enforcement are: disabled, active, evaluate - Enforcement string `json:"enforcement"` - // Possible values for BypassMode are: none, repository, organization - BypassMode *string `json:"bypass_mode,omitempty"` - BypassActors *[]BypassActor `json:"bypass_actors,omitempty"` - NodeID *string `json:"node_id,omitempty"` - Links *RulesetLinks `json:"_links,omitempty"` - Conditions *[]RulesetCondition `json:"conditions,omitempty"` -} diff --git a/github/repos_rules.go b/github/repos_rules.go new file mode 100644 index 00000000000..62034e1a6bc --- /dev/null +++ b/github/repos_rules.go @@ -0,0 +1,246 @@ +// Copyright 2013 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 ( + "encoding/json" + "fmt" +) + +// BypassActor represents the bypass actors from a repository ruleset. +type BypassActor struct { + ActorID int64 `json:"actor_id,omitempty"` + // Possible values for ActorType are: Team, Integration + ActorType string `json:"actor_type,omitempty"` +} + +// RulesetLink represents a single link object from GitHub ruleset request _links. +type RulesetLink struct { + HRef *string `json:"href,omitempty"` +} + +// RulesetLinks represents the "_links" object in a Ruleset. +type RulesetLinks struct { + Self *RulesetLink `json:"self,omitempty"` +} + +type RulesetConditionParameters struct { + Include []string `json:"include"` + Exclude []string `json:"exclude"` + Protected *bool `json:"protected,omitempty"` +} + +type RulesetCondition struct { + RefName *RulesetConditionParameters `json:"ref_name,omitempty"` + RepositoryName *RulesetConditionParameters `json:"repository_name,omitempty"` +} + +type RulePatternParameters struct { + Name *string `json:"name,omitempty"` + Negate *bool `json:"negate,omitempty"` + // Possible values for Operator are: starts_with, ends_with, contains, regex + Operator string `json:"operator"` + Pattern string `json:"pattern"` +} + +// UpdateAllowsFetchAndMergeRuleParameters represents the update rule parameters. +type UpdateAllowsFetchAndMergeRuleParameters struct { + UpdateAllowsFetchAndMerge bool `json:"update_allows_fetch_and_merge"` +} + +// RequiredDeploymentEnvironmentsRuleParameters represents the required_deployments rule parameters. +type RequiredDeploymentEnvironmentsRuleParameters struct { + RequiredDeploymentEnvironments bool `json:"required_deployment_environments"` +} + +// 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"` +} + +// RequiredStatusChecksRuleParameters represents the required_status_checks rule parameters. +type RequiredStatusChecksRuleParameters struct { + Context string `json:"context"` + IntegrationID *int64 `json:"integration_id,omitempty"` + StrictRequiredStatusChecksPolicy bool `json:"strict_required_status_checks_policy"` +} + +// RulesetRule represents a GitHub Rule within a Ruleset. +type RulesetRule struct { + Type string `json:"type"` + Parameters interface{} `json:"parameters,omitempty"` +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +// This helps us handle the fact that RulesetRule can by either a RuleParameterPattern or RuleParameterPattern type parameters field. +func (rsr *RulesetRule) UnmarshalJSON(data []byte) error { + type rule RulesetRule + var rulesetRule rule + if err := json.Unmarshal(data, &rulesetRule); err != nil { + return err + } + + rsr.Type = rulesetRule.Type + + switch rulesetRule.Type { + case "creation", "deletion", "required_linear_history", "required_signatures", "non_fast_forward": + rsr.Parameters = nil + case "update": + rulesetRule.Parameters = &UpdateAllowsFetchAndMergeRuleParameters{} + if err := json.Unmarshal(data, &rulesetRule); err != nil { + return err + } + rsr.Parameters = rulesetRule.Parameters + case "required_deployment_environments": + rulesetRule.Parameters = &RequiredDeploymentEnvironmentsRuleParameters{} + if err := json.Unmarshal(data, &rulesetRule); err != nil { + return err + } + rsr.Parameters = rulesetRule.Parameters + case "commit_message_pattern", "commit_author_email_pattern", "committer_email_pattern", "branch_name_pattern", "tag_name_pattern": + rulesetRule.Parameters = &RulePatternParameters{} + if err := json.Unmarshal(data, &rulesetRule); err != nil { + return err + } + rsr.Parameters = rulesetRule.Parameters + case "pull_request": + rulesetRule.Parameters = &PullRequestRuleParameters{} + if err := json.Unmarshal(data, &rulesetRule); err != nil { + return err + } + rsr.Parameters = rulesetRule.Parameters + case "required_status_checks": + rulesetRule.Parameters = &RequiredStatusChecksRuleParameters{} + if err := json.Unmarshal(data, &rulesetRule); err != nil { + return err + } + rsr.Parameters = rulesetRule.Parameters + default: + rsr.Type = "" + rsr.Parameters = nil + return fmt.Errorf("rulesetRule.Type is %T, not a string of 'User' or 'Team', unable to unmarshal", rulesetRule.Type) + } + + return nil +} + +func NewCreationRule() (rule RulesetRule) { + return RulesetRule{ + Type: "creation", + } +} + +func NewUpdateRule(params *UpdateAllowsFetchAndMergeRuleParameters) (rule RulesetRule) { + return RulesetRule{ + Type: "update", + Parameters: params, + } +} + +func NewDeletionRule() (rule RulesetRule) { + return RulesetRule{ + Type: "deletion", + } +} + +func NewRequiredLinearHistoryRule() (rule RulesetRule) { + return RulesetRule{ + Type: "required_linear_history", + } +} + +func NewRequiredDeploymentsRule(params *RequiredDeploymentEnvironmentsRuleParameters) (rule RulesetRule) { + return RulesetRule{ + Type: "required_deployments", + Parameters: params, + } +} + +func NewRequiredSignaturesRule() (rule RulesetRule) { + return RulesetRule{ + Type: "required_signatures", + } +} + +func NewPullRequestRule(params *PullRequestRuleParameters) ( + rule RulesetRule) { + return RulesetRule{ + Type: "pull_request", + Parameters: params, + } +} + +func NewRequiredStatusChecksRule(params *RequiredStatusChecksRuleParameters) (rule RulesetRule) { + return RulesetRule{ + Type: "required_status_checks", + Parameters: params, + } +} + +func NewNonFastForwardRule() (rule RulesetRule) { + return RulesetRule{ + Type: "non_fast_forward", + } +} + +func NewCommitMessagePatternRule(pattern *RulePatternParameters) (rule RulesetRule) { + return RulesetRule{ + Type: "commit_message_pattern", + Parameters: pattern, + } +} + +func NewCommitAuthorEmailPatternRule(pattern *RulePatternParameters) (rule RulesetRule) { + return RulesetRule{ + Type: "commit_author_email_pattern", + Parameters: pattern, + } +} + +func NewCommitterEmailPatternRule(pattern *RulePatternParameters) (rule RulesetRule) { + return RulesetRule{ + Type: "committer_email_pattern", + Parameters: pattern, + } +} + +func NewBranchNamePatternRule(pattern *RulePatternParameters) (rule RulesetRule) { + return RulesetRule{ + Type: "branch_name_pattern", + Parameters: pattern, + } +} + +func NewTagNamePatternRule(pattern *RulePatternParameters) (rule RulesetRule) { + return RulesetRule{ + Type: "tag_name_pattern", + Parameters: pattern, + } +} + +// Ruleset represents a GitHub rules request. +type Ruleset struct { + ID int64 `json:"id"` + Name string `json:"name"` + // Possible values for Target are branch, tag + Target *string `json:"target,omitempty"` + // Possible values for SourceType are: Repository, Organization + SourceType *string `json:"source_type,omitempty"` + Source string `json:"source"` + // Possible values for Enforcement are: disabled, active, evaluate + Enforcement string `json:"enforcement"` + // Possible values for BypassMode are: none, repository, organization + BypassMode *string `json:"bypass_mode,omitempty"` + BypassActors *[]BypassActor `json:"bypass_actors,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Links *RulesetLinks `json:"_links,omitempty"` + Conditions *RulesetCondition `json:"conditions,omitempty"` + Rules *[]RulesetRule `json:"rules,omitempty"` +} From dc199b508aa4b54908a99c924dbe9ceefeecd521 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 01:36:00 +1000 Subject: [PATCH 05/29] Spilt out ruleset conditions in different types Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/github-accessors.go | 20 ++++++++++---------- github/github-accessors_test.go | 20 ++++++++++---------- github/repos_rules.go | 15 ++++++++++++--- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 483c976fe3e..162c75c5f5c 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -18495,7 +18495,7 @@ func (r *Ruleset) GetTarget() string { } // GetRefName returns the RefName field. -func (r *RulesetCondition) GetRefName() *RulesetConditionParameters { +func (r *RulesetCondition) GetRefName() *RulesetRefConditionParameters { if r == nil { return nil } @@ -18503,21 +18503,13 @@ func (r *RulesetCondition) GetRefName() *RulesetConditionParameters { } // GetRepositoryName returns the RepositoryName field. -func (r *RulesetCondition) GetRepositoryName() *RulesetConditionParameters { +func (r *RulesetCondition) GetRepositoryName() *RulesetRepositoryConditionParameters { if r == nil { return nil } return r.RepositoryName } -// GetProtected returns the Protected field if it's non-nil, zero value otherwise. -func (r *RulesetConditionParameters) GetProtected() bool { - if r == nil || r.Protected == nil { - return false - } - return *r.Protected -} - // GetHRef returns the HRef field if it's non-nil, zero value otherwise. func (r *RulesetLink) GetHRef() string { if r == nil || r.HRef == nil { @@ -18534,6 +18526,14 @@ func (r *RulesetLinks) GetSelf() *RulesetLink { return r.Self } +// GetProtected returns the Protected field if it's non-nil, zero value otherwise. +func (r *RulesetRepositoryConditionParameters) GetProtected() bool { + if r == nil || r.Protected == nil { + return false + } + return *r.Protected +} + // GetBusy returns the Busy field if it's non-nil, zero value otherwise. func (r *Runner) GetBusy() bool { if r == nil || r.Busy == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index e4b409468eb..1ae1344dfb0 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -21572,16 +21572,6 @@ func TestRulesetCondition_GetRepositoryName(tt *testing.T) { r.GetRepositoryName() } -func TestRulesetConditionParameters_GetProtected(tt *testing.T) { - var zeroValue bool - r := &RulesetConditionParameters{Protected: &zeroValue} - r.GetProtected() - r = &RulesetConditionParameters{} - r.GetProtected() - r = nil - r.GetProtected() -} - func TestRulesetLink_GetHRef(tt *testing.T) { var zeroValue string r := &RulesetLink{HRef: &zeroValue} @@ -21599,6 +21589,16 @@ func TestRulesetLinks_GetSelf(tt *testing.T) { r.GetSelf() } +func TestRulesetRepositoryConditionParameters_GetProtected(tt *testing.T) { + var zeroValue bool + r := &RulesetRepositoryConditionParameters{Protected: &zeroValue} + r.GetProtected() + r = &RulesetRepositoryConditionParameters{} + r.GetProtected() + r = nil + r.GetProtected() +} + func TestRunner_GetBusy(tt *testing.T) { var zeroValue bool r := &Runner{Busy: &zeroValue} diff --git a/github/repos_rules.go b/github/repos_rules.go index 62034e1a6bc..669e1c9ff5b 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -27,17 +27,26 @@ type RulesetLinks struct { Self *RulesetLink `json:"self,omitempty"` } -type RulesetConditionParameters struct { +// RulesetRefConditionParameters represents the conditions object for ref_names. +type RulesetRefConditionParameters struct { + Include []string `json:"include"` + Exclude []string `json:"exclude"` +} + +// RulesetRepositoryConditionParameters represents the conditions object for repository_names. +type RulesetRepositoryConditionParameters struct { Include []string `json:"include"` Exclude []string `json:"exclude"` Protected *bool `json:"protected,omitempty"` } +// RulesetCondition represents the conditions object in a ruleset. type RulesetCondition struct { - RefName *RulesetConditionParameters `json:"ref_name,omitempty"` - RepositoryName *RulesetConditionParameters `json:"repository_name,omitempty"` + RefName *RulesetRefConditionParameters `json:"ref_name,omitempty"` + RepositoryName *RulesetRepositoryConditionParameters `json:"repository_name,omitempty"` } +// RulePatternParameters represents the rule pattern parameter. type RulePatternParameters struct { Name *string `json:"name,omitempty"` Negate *bool `json:"negate,omitempty"` From 90d803f7eb989f2aeb24a133c79b2d0b09d9e983 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 12:32:50 +1000 Subject: [PATCH 06/29] Add missing requiredStatusChecks struct Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/github-accessors.go | 56 ++++---------------------- github/github-accessors_test.go | 70 +++++---------------------------- github/repos_rules.go | 30 ++++++++------ 3 files changed, 36 insertions(+), 120 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 162c75c5f5c..0289e0d3ea5 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -15062,46 +15062,6 @@ func (p *PullRequestReviewThreadEvent) GetThread() *PullRequestThread { return p.Thread } -// GetDismissStaleReviewsOnPush returns the DismissStaleReviewsOnPush field if it's non-nil, zero value otherwise. -func (p *PullRequestRuleParameters) GetDismissStaleReviewsOnPush() bool { - if p == nil || p.DismissStaleReviewsOnPush == nil { - return false - } - return *p.DismissStaleReviewsOnPush -} - -// GetRequireCodeOwnerReview returns the RequireCodeOwnerReview field if it's non-nil, zero value otherwise. -func (p *PullRequestRuleParameters) GetRequireCodeOwnerReview() bool { - if p == nil || p.RequireCodeOwnerReview == nil { - return false - } - return *p.RequireCodeOwnerReview -} - -// GetRequiredApprovingReviewCount returns the RequiredApprovingReviewCount field if it's non-nil, zero value otherwise. -func (p *PullRequestRuleParameters) GetRequiredApprovingReviewCount() int { - if p == nil || p.RequiredApprovingReviewCount == nil { - return 0 - } - return *p.RequiredApprovingReviewCount -} - -// GetRequiredReviewThreadResolution returns the RequiredReviewThreadResolution field if it's non-nil, zero value otherwise. -func (p *PullRequestRuleParameters) GetRequiredReviewThreadResolution() bool { - if p == nil || p.RequiredReviewThreadResolution == nil { - return false - } - return *p.RequiredReviewThreadResolution -} - -// GetRequireLastPushApproval returns the RequireLastPushApproval field if it's non-nil, zero value otherwise. -func (p *PullRequestRuleParameters) GetRequireLastPushApproval() bool { - if p == nil || p.RequireLastPushApproval == nil { - return false - } - return *p.RequireLastPushApproval -} - // GetAction returns the Action field if it's non-nil, zero value otherwise. func (p *PullRequestTargetEvent) GetAction() string { if p == nil || p.Action == nil { @@ -18334,14 +18294,6 @@ func (r *RequiredStatusChecksRequest) GetStrict() bool { return *r.Strict } -// GetIntegrationID returns the IntegrationID field if it's non-nil, zero value otherwise. -func (r *RequiredStatusChecksRuleParameters) GetIntegrationID() int64 { - if r == nil || r.IntegrationID == nil { - return 0 - } - return *r.IntegrationID -} - // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise. func (r *RequiredWorkflowSelectedRepos) GetTotalCount() int { if r == nil || r.TotalCount == nil { @@ -18430,6 +18382,14 @@ func (r *RulePatternParameters) GetNegate() bool { return *r.Negate } +// GetIntegrationID returns the IntegrationID field if it's non-nil, zero value otherwise. +func (r *RuleRequiredStatusChecks) GetIntegrationID() int64 { + if r == nil || r.IntegrationID == nil { + return 0 + } + return *r.IntegrationID +} + // GetBypassActors returns the BypassActors field if it's non-nil, zero value otherwise. func (r *Ruleset) GetBypassActors() []BypassActor { if r == nil || r.BypassActors == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 1ae1344dfb0..795a4201748 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -17499,56 +17499,6 @@ func TestPullRequestReviewThreadEvent_GetThread(tt *testing.T) { p.GetThread() } -func TestPullRequestRuleParameters_GetDismissStaleReviewsOnPush(tt *testing.T) { - var zeroValue bool - p := &PullRequestRuleParameters{DismissStaleReviewsOnPush: &zeroValue} - p.GetDismissStaleReviewsOnPush() - p = &PullRequestRuleParameters{} - p.GetDismissStaleReviewsOnPush() - p = nil - p.GetDismissStaleReviewsOnPush() -} - -func TestPullRequestRuleParameters_GetRequireCodeOwnerReview(tt *testing.T) { - var zeroValue bool - p := &PullRequestRuleParameters{RequireCodeOwnerReview: &zeroValue} - p.GetRequireCodeOwnerReview() - p = &PullRequestRuleParameters{} - p.GetRequireCodeOwnerReview() - p = nil - p.GetRequireCodeOwnerReview() -} - -func TestPullRequestRuleParameters_GetRequiredApprovingReviewCount(tt *testing.T) { - var zeroValue int - p := &PullRequestRuleParameters{RequiredApprovingReviewCount: &zeroValue} - p.GetRequiredApprovingReviewCount() - p = &PullRequestRuleParameters{} - p.GetRequiredApprovingReviewCount() - p = nil - p.GetRequiredApprovingReviewCount() -} - -func TestPullRequestRuleParameters_GetRequiredReviewThreadResolution(tt *testing.T) { - var zeroValue bool - p := &PullRequestRuleParameters{RequiredReviewThreadResolution: &zeroValue} - p.GetRequiredReviewThreadResolution() - p = &PullRequestRuleParameters{} - p.GetRequiredReviewThreadResolution() - p = nil - p.GetRequiredReviewThreadResolution() -} - -func TestPullRequestRuleParameters_GetRequireLastPushApproval(tt *testing.T) { - var zeroValue bool - p := &PullRequestRuleParameters{RequireLastPushApproval: &zeroValue} - p.GetRequireLastPushApproval() - p = &PullRequestRuleParameters{} - p.GetRequireLastPushApproval() - p = nil - p.GetRequireLastPushApproval() -} - func TestPullRequestTargetEvent_GetAction(tt *testing.T) { var zeroValue string p := &PullRequestTargetEvent{Action: &zeroValue} @@ -21364,16 +21314,6 @@ func TestRequiredStatusChecksRequest_GetStrict(tt *testing.T) { r.GetStrict() } -func TestRequiredStatusChecksRuleParameters_GetIntegrationID(tt *testing.T) { - var zeroValue int64 - r := &RequiredStatusChecksRuleParameters{IntegrationID: &zeroValue} - r.GetIntegrationID() - r = &RequiredStatusChecksRuleParameters{} - r.GetIntegrationID() - r = nil - r.GetIntegrationID() -} - func TestRequiredWorkflowSelectedRepos_GetTotalCount(tt *testing.T) { var zeroValue int r := &RequiredWorkflowSelectedRepos{TotalCount: &zeroValue} @@ -21484,6 +21424,16 @@ func TestRulePatternParameters_GetNegate(tt *testing.T) { r.GetNegate() } +func TestRuleRequiredStatusChecks_GetIntegrationID(tt *testing.T) { + var zeroValue int64 + r := &RuleRequiredStatusChecks{IntegrationID: &zeroValue} + r.GetIntegrationID() + r = &RuleRequiredStatusChecks{} + r.GetIntegrationID() + r = nil + r.GetIntegrationID() +} + func TestRuleset_GetBypassActors(tt *testing.T) { var zeroValue []BypassActor r := &Ruleset{BypassActors: &zeroValue} diff --git a/github/repos_rules.go b/github/repos_rules.go index 669e1c9ff5b..f941fe3f62a 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -48,8 +48,9 @@ type RulesetCondition struct { // RulePatternParameters represents the rule pattern parameter. type RulePatternParameters struct { - Name *string `json:"name,omitempty"` - Negate *bool `json:"negate,omitempty"` + Name *string `json:"name,omitempty"` + // If Negate is true, the rule will fail if the pattern matches. + Negate *bool `json:"negate,omitempty"` // Possible values for Operator are: starts_with, ends_with, contains, regex Operator string `json:"operator"` Pattern string `json:"pattern"` @@ -62,23 +63,28 @@ type UpdateAllowsFetchAndMergeRuleParameters struct { // RequiredDeploymentEnvironmentsRuleParameters represents the required_deployments rule parameters. type RequiredDeploymentEnvironmentsRuleParameters struct { - RequiredDeploymentEnvironments bool `json:"required_deployment_environments"` + RequiredDeploymentEnvironments []string `json:"required_deployment_environments"` } // 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"` + 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. +type RuleRequiredStatusChecks struct { + Context string `json:"context"` + IntegrationID *int64 `json:"integration_id,omitempty"` } // RequiredStatusChecksRuleParameters represents the required_status_checks rule parameters. type RequiredStatusChecksRuleParameters struct { - Context string `json:"context"` - IntegrationID *int64 `json:"integration_id,omitempty"` - StrictRequiredStatusChecksPolicy bool `json:"strict_required_status_checks_policy"` + RequiredStatusChecks []RuleRequiredStatusChecks `json:"required_status_checks"` + StrictRequiredStatusChecksPolicy bool `json:"strict_required_status_checks_policy"` } // RulesetRule represents a GitHub Rule within a Ruleset. @@ -107,7 +113,7 @@ func (rsr *RulesetRule) UnmarshalJSON(data []byte) error { return err } rsr.Parameters = rulesetRule.Parameters - case "required_deployment_environments": + case "required_deployments": rulesetRule.Parameters = &RequiredDeploymentEnvironmentsRuleParameters{} if err := json.Unmarshal(data, &rulesetRule); err != nil { return err From 8b3f493bc26dc75c42db4a0bce7ce21ad33ffba4 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 12:34:38 +1000 Subject: [PATCH 07/29] Add CreateOrganizationRepositoryRuleset Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 20 +++ github/orgs_rules_test.go | 326 +++++++++++++++++++++++++++++++++++++- 2 files changed, 343 insertions(+), 3 deletions(-) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 1dd7ac06695..a8b1400ce03 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -29,3 +29,23 @@ func (s *OrganizationsService) GetAllOrganizationRepositoryRulesets(ctx context. return rulesets, resp, nil } + +// CreateOrganizationRepositoryRuleset creates a repository ruleset for the specified organization. +// +// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#create-an-organization-repository-ruleset +func (s *OrganizationsService) CreateOrganizationRepositoryRuleset(ctx context.Context, org string, rs *Ruleset) (*Ruleset, *Response, error) { + u := fmt.Sprintf("orgs/%v/rulesets", org) + + req, err := s.client.NewRequest("POST", u, rs) + if err != nil { + return nil, nil, err + } + + var ruleset *Ruleset + resp, err := s.client.Do(ctx, req, &ruleset) + if err != nil { + return nil, resp, err + } + + return ruleset, resp, nil +} diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index 05e562225ff..a2d8ff704db 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -15,13 +15,12 @@ func TestOrganizationsService_GetAllOrganizationRepositoryRulesets(t *testing.T) mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - testFormValues(t, r, values{}) fmt.Fprint(w, `[{ "id": 26110, "name": "test ruleset", "target": "branch", "source_type": "Organization", - "source": "my-org", + "source": "o", "enforcement": "active", "bypass_mode": "none", "node_id": "nid", @@ -44,7 +43,7 @@ func TestOrganizationsService_GetAllOrganizationRepositoryRulesets(t *testing.T) Name: "test ruleset", Target: String("branch"), SourceType: String("Organization"), - Source: "my-org", + Source: "o", Enforcement: "active", BypassMode: String("none"), NodeID: String("nid"), @@ -66,3 +65,324 @@ func TestOrganizationsService_GetAllOrganizationRepositoryRulesets(t *testing.T) return resp, err }) } + +func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/rulesets", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `{ + "id": 21, + "name": "ruleset", + "target": "branch", + "source_type": "Organization", + "source": "o", + "enforcement": "active", + "bypass_actors": [ + { + "actor_id": 234, + "actor_type": "Team" + } + ], + "conditions": { + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + }, + "repository_name": { + "include": [ + "important_repository", + "another_important_repository" + ], + "exclude": [ + "unimportant_repository" + ], + "protected": true + } + }, + "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" + } + } + ] + }`) + }) + + ctx := context.Background() + ruleset, _, err := client.Organizations.CreateOrganizationRepositoryRuleset(ctx, "o", &Ruleset{ + ID: 21, + Name: "ruleset", + Target: String("branch"), + SourceType: String("Organization"), + Source: "o", + Enforcement: "active", + BypassActors: &[]BypassActor{ + { + ActorID: 234, + ActorType: "Team", + }, + }, + Conditions: &RulesetCondition{ + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + RepositoryName: &RulesetRepositoryConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Bool(true), + }, + }, + Rules: &[]RulesetRule{ + 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: Int64(1), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: String("avoid test commits"), + Negate: Bool(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: String("avoid commit emails"), + Negate: Bool(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: String("avoid branch names"), + Negate: Bool(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: String("avoid tag names"), + Negate: Bool(true), + Operator: "contains", + Pattern: "github", + }), + }, + }) + if err != nil { + t.Errorf("Organizations.CreateOrganizationRepositoryRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: 21, + Name: "ruleset", + Target: String("branch"), + SourceType: String("Organization"), + Source: "o", + Enforcement: "active", + BypassActors: &[]BypassActor{ + { + ActorID: 234, + ActorType: "Team", + }, + }, + Conditions: &RulesetCondition{ + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + RepositoryName: &RulesetRepositoryConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Bool(true), + }, + }, + Rules: &[]RulesetRule{ + 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: Int64(1), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }), + NewNonFastForwardRule(), + NewCommitMessagePatternRule(&RulePatternParameters{ + Name: String("avoid test commits"), + Negate: Bool(true), + Operator: "starts_with", + Pattern: "[test]", + }), + NewCommitAuthorEmailPatternRule(&RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }), + NewCommitterEmailPatternRule(&RulePatternParameters{ + Name: String("avoid commit emails"), + Negate: Bool(true), + Operator: "ends_with", + Pattern: "abc", + }), + NewBranchNamePatternRule(&RulePatternParameters{ + Name: String("avoid branch names"), + Negate: Bool(true), + Operator: "regex", + Pattern: "github$", + }), + NewTagNamePatternRule(&RulePatternParameters{ + Name: String("avoid tag names"), + Negate: Bool(true), + Operator: "contains", + Pattern: "github", + }), + }, + } + if !cmp.Equal(ruleset, want) { + t.Errorf("Organizations.CreateOrganizationRepositoryRuleset returned %+v, want %+v", ruleset, want) + } + + const methodName = "CreateOrganizationRepositoryRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.CreateOrganizationRepositoryRuleset(ctx, "o", nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From f2b462f8da793e1ce29f478517d4462c8627b0d8 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 12:42:22 +1000 Subject: [PATCH 08/29] Fix unhandled rulesetRule type message Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github/repos_rules.go b/github/repos_rules.go index f941fe3f62a..e6da35d1723 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -94,7 +94,7 @@ type RulesetRule struct { } // UnmarshalJSON implements the json.Unmarshaler interface. -// This helps us handle the fact that RulesetRule can by either a RuleParameterPattern or RuleParameterPattern type parameters field. +// This helps us handle the fact that RulesetRule parameter field can be of numerous types. func (rsr *RulesetRule) UnmarshalJSON(data []byte) error { type rule RulesetRule var rulesetRule rule @@ -140,7 +140,7 @@ func (rsr *RulesetRule) UnmarshalJSON(data []byte) error { default: rsr.Type = "" rsr.Parameters = nil - return fmt.Errorf("rulesetRule.Type is %T, not a string of 'User' or 'Team', unable to unmarshal", rulesetRule.Type) + return fmt.Errorf("rulesetRule.Type %T is not yet implemented, unable to unmarshal", rulesetRule.Type) } return nil From 113d39f4a40398cd32354597eb04f71dcd5687dd Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:33:56 +1000 Subject: [PATCH 09/29] Add comments on the rule creations Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/github/repos_rules.go b/github/repos_rules.go index e6da35d1723..a7db66d6138 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -146,12 +146,14 @@ func (rsr *RulesetRule) UnmarshalJSON(data []byte) error { return nil } +// NewCreationRule creates a rule as part of a GitHub ruleset to only allow users with bypass permission to create matching refs. func NewCreationRule() (rule RulesetRule) { return RulesetRule{ Type: "creation", } } +// NewUpdateRule creates a rule as part of a GitHub ruleset to only allow users with bypass permission to update matching refs. func NewUpdateRule(params *UpdateAllowsFetchAndMergeRuleParameters) (rule RulesetRule) { return RulesetRule{ Type: "update", @@ -159,18 +161,21 @@ func NewUpdateRule(params *UpdateAllowsFetchAndMergeRuleParameters) (rule Rulese } } +// NewDeletionRule creates a rule as part of a GitHub ruleset to only allow users with bypass permissions to delete matching refs. func NewDeletionRule() (rule RulesetRule) { return RulesetRule{ Type: "deletion", } } +// NewRequiredLinearHistoryRule creates a rule as part of a GitHub ruleset to prevent merge commits from being pushed to matching branches. func NewRequiredLinearHistoryRule() (rule RulesetRule) { return RulesetRule{ Type: "required_linear_history", } } +// NewRequiredDeploymentsRule creates a rule as part of a GitHub ruleset to require environments to be successfully deployed before they can be merged into the matching branches. func NewRequiredDeploymentsRule(params *RequiredDeploymentEnvironmentsRuleParameters) (rule RulesetRule) { return RulesetRule{ Type: "required_deployments", @@ -178,12 +183,14 @@ func NewRequiredDeploymentsRule(params *RequiredDeploymentEnvironmentsRuleParame } } +// NewRequiredSignaturesRule creates a rule as part of a GitHub ruleset to require commits pushed to matching branches to have verified signatures. func NewRequiredSignaturesRule() (rule RulesetRule) { return RulesetRule{ Type: "required_signatures", } } +// NewPullRequestRule creates a rule as part of a GitHub ruleset to require all commits be made to a non-target branch and submitted via a pull request before they can be merged. func NewPullRequestRule(params *PullRequestRuleParameters) ( rule RulesetRule) { return RulesetRule{ @@ -192,6 +199,7 @@ func NewPullRequestRule(params *PullRequestRuleParameters) ( } } +// NewRequiredStatusChecksRule creates a rule as part of a GitHub ruleset to require which status checks must pass before branches can be merged into a branch rule. func NewRequiredStatusChecksRule(params *RequiredStatusChecksRuleParameters) (rule RulesetRule) { return RulesetRule{ Type: "required_status_checks", @@ -199,12 +207,14 @@ func NewRequiredStatusChecksRule(params *RequiredStatusChecksRuleParameters) (ru } } +// NewNonFastForwardRule creates a rule as part of a GitHub ruleset to prevent users with push access from force pushing to matching branches. func NewNonFastForwardRule() (rule RulesetRule) { return RulesetRule{ Type: "non_fast_forward", } } +// NewCommitMessagePatternRule creates a rule as part of a GitHub ruleset to restrict commit message patterns being pushed to matching branches. func NewCommitMessagePatternRule(pattern *RulePatternParameters) (rule RulesetRule) { return RulesetRule{ Type: "commit_message_pattern", @@ -212,6 +222,7 @@ func NewCommitMessagePatternRule(pattern *RulePatternParameters) (rule RulesetRu } } +// NewCommitAuthorEmailPatternRule creates a rule as part of a GitHub ruleset to restrict commits with author email patterns being merged into matching branches. func NewCommitAuthorEmailPatternRule(pattern *RulePatternParameters) (rule RulesetRule) { return RulesetRule{ Type: "commit_author_email_pattern", @@ -219,6 +230,7 @@ func NewCommitAuthorEmailPatternRule(pattern *RulePatternParameters) (rule Rules } } +// NewCommitterEmailPatternRule creates a rule as part of a GitHub ruleset to restrict commits with committer email patterns being merged into matching branches. func NewCommitterEmailPatternRule(pattern *RulePatternParameters) (rule RulesetRule) { return RulesetRule{ Type: "committer_email_pattern", From 93e2a9043306451179ca2f6a5b43e6e1c7ea321c Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:40:27 +1000 Subject: [PATCH 10/29] Add GetOrganizationRepositoryRuleset Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 20 ++++++++ github/orgs_rules_test.go | 97 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index a8b1400ce03..6fd659386bf 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -49,3 +49,23 @@ func (s *OrganizationsService) CreateOrganizationRepositoryRuleset(ctx context.C return ruleset, resp, nil } + +// GetOrganizationRepositoryRuleset gets a repository ruleset from the specified organization. +// +// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#get-an-organization-repository-ruleset +func (s *OrganizationsService) GetOrganizationRepositoryRuleset(ctx context.Context, org string, ruleset_id int64) (*Ruleset, *Response, error) { + u := fmt.Sprintf("orgs/%v/rulesets/%v", org, ruleset_id) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var rulesets *Ruleset + resp, err := s.client.Do(ctx, req, &rulesets) + if err != nil { + return nil, resp, err + } + + return rulesets, resp, nil +} diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index a2d8ff704db..f4ccacc9e15 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -386,3 +386,100 @@ func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) return resp, err }) } + +func TestOrganizationsService_GetOrganizationRepositoryRuleset(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "id": 26110, + "name": "test ruleset", + "target": "branch", + "source_type": "Organization", + "source": "o", + "enforcement": "active", + "bypass_mode": "none", + "node_id": "nid", + "_links": { + "self": { + "href": "https://api.github.com/orgs/o/rulesets/26110" + } + }, + "conditions": { + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + }, + "repository_name": { + "include": [ + "important_repository", + "another_important_repository" + ], + "exclude": [ + "unimportant_repository" + ], + "protected": true + } + }, + "rules": [ + { + "type": "creation" + } + ] + }`) + }) + + ctx := context.Background() + rulesets, _, err := client.Organizations.GetOrganizationRepositoryRuleset(ctx, "o", 26110) + if err != nil { + t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: 26110, + Name: "test ruleset", + Target: String("branch"), + SourceType: String("Organization"), + Source: "o", + Enforcement: "active", + BypassMode: String("none"), + NodeID: String("nid"), + Links: &RulesetLinks{ + Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, + }, + Conditions: &RulesetCondition{ + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + RepositoryName: &RulesetRepositoryConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Bool(true), + }, + }, + Rules: &[]RulesetRule{ + NewCreationRule(), + }, + } + if !cmp.Equal(rulesets, want) { + t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned %+v, want %+v", rulesets, want) + } + + const methodName = "GetOrganizationRepositoryRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.GetOrganizationRepositoryRuleset(ctx, "o", 26110) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 3208f5c577cfd7e6913415cb2c635e9ff957b09f Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 13:41:25 +1000 Subject: [PATCH 11/29] Add copyright metadata Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 2 +- github/orgs_rules_test.go | 5 +++++ github/repos_rules.go | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 6fd659386bf..1db3891e18f 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -1,4 +1,4 @@ -// Copyright 2017 The go-github AUTHORS. All rights reserved. +// Copyright 2023 The go-github AUTHORS. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index f4ccacc9e15..de633fd4585 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -1,3 +1,8 @@ +// Copyright 2023 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + package github import ( diff --git a/github/repos_rules.go b/github/repos_rules.go index a7db66d6138..ede1f6b0aa4 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -1,4 +1,4 @@ -// Copyright 2013 The go-github AUTHORS. All rights reserved. +// Copyright 2023 The go-github AUTHORS. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. From f58936c919c202b9c3749b4adc2aa226f0d38c57 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:07:21 +1000 Subject: [PATCH 12/29] Add UpdateOrganizationRepositoryRuleset Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 20 +++++++ github/orgs_rules_test.go | 117 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 1db3891e18f..16111cef02a 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -69,3 +69,23 @@ func (s *OrganizationsService) GetOrganizationRepositoryRuleset(ctx context.Cont return rulesets, resp, nil } + +// UpdateOrganizationRepositoryRuleset updates a repository ruleset from the specified organization. +// +// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#update-a-repository-ruleset +func (s *OrganizationsService) UpdateOrganizationRepositoryRuleset(ctx context.Context, org string, ruleset_id int64, rs *Ruleset) (*Ruleset, *Response, error) { + u := fmt.Sprintf("orgs/%v/rulesets/%v", org, ruleset_id) + + req, err := s.client.NewRequest("POST", u, rs) + if err != nil { + return nil, nil, err + } + + var rulesets *Ruleset + resp, err := s.client.Do(ctx, req, &rulesets) + if err != nil { + return nil, resp, err + } + + return rulesets, resp, nil +} diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index de633fd4585..fed88b46106 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -488,3 +488,120 @@ func TestOrganizationsService_GetOrganizationRepositoryRuleset(t *testing.T) { return resp, err }) } + +func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `{ + "id": 26110, + "name": "test ruleset", + "target": "branch", + "source_type": "Organization", + "source": "o", + "enforcement": "active", + "bypass_mode": "none", + "node_id": "nid", + "_links": { + "self": { + "href": "https://api.github.com/orgs/o/rulesets/26110" + } + }, + "conditions": { + "ref_name": { + "include": [ + "refs/heads/main", + "refs/heads/master" + ], + "exclude": [ + "refs/heads/dev*" + ] + }, + "repository_name": { + "include": [ + "important_repository", + "another_important_repository" + ], + "exclude": [ + "unimportant_repository" + ], + "protected": true + } + }, + "rules": [ + { + "type": "creation" + } + ] + }`) + }) + + ctx := context.Background() + rulesets, _, err := client.Organizations.UpdateOrganizationRepositoryRuleset(ctx, "o", 26110, &Ruleset{ + Name: "test ruleset", + Target: String("branch"), + Enforcement: "active", + BypassMode: String("none"), + Conditions: &RulesetCondition{ + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + RepositoryName: &RulesetRepositoryConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Bool(true), + }, + }, + Rules: &[]RulesetRule{ + NewCreationRule(), + }, + }) + + if err != nil { + t.Errorf("Organizations.UpdateOrganizationRepositoryRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: 26110, + Name: "test ruleset", + Target: String("branch"), + SourceType: String("Organization"), + Source: "o", + Enforcement: "active", + BypassMode: String("none"), + NodeID: String("nid"), + Links: &RulesetLinks{ + Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, + }, + Conditions: &RulesetCondition{ + RefName: &RulesetRefConditionParameters{ + Include: []string{"refs/heads/main", "refs/heads/master"}, + Exclude: []string{"refs/heads/dev*"}, + }, + RepositoryName: &RulesetRepositoryConditionParameters{ + Include: []string{"important_repository", "another_important_repository"}, + Exclude: []string{"unimportant_repository"}, + Protected: Bool(true), + }, + }, + Rules: &[]RulesetRule{ + NewCreationRule(), + }, + } + if !cmp.Equal(rulesets, want) { + t.Errorf("Organizations.UpdateOrganizationRepositoryRuleset returned %+v, want %+v", rulesets, want) + } + + const methodName = "UpdateOrganizationRepositoryRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Organizations.UpdateOrganizationRepositoryRuleset(ctx, "o", 26110, nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 879e3e0e0033db928b08914d53c5f243d6b95ca8 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:15:11 +1000 Subject: [PATCH 13/29] Add DeleteOrganizationRepositoryRuleset Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 19 +++++++++++++++++++ github/orgs_rules_test.go | 21 +++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 16111cef02a..71924e3598a 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -89,3 +89,22 @@ func (s *OrganizationsService) UpdateOrganizationRepositoryRuleset(ctx context.C return rulesets, resp, nil } + +// DeleteOrganizationRepositoryRuleset deletes a repository ruleset from the specified organization. +// +// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#delete-a-repository-ruleset +func (s *OrganizationsService) DeleteOrganizationRepositoryRuleset(ctx context.Context, org string, ruleset_id int64) (*Response, error) { + u := fmt.Sprintf("orgs/%v/rulesets/%v", org, ruleset_id) + + req, err := s.client.NewRequest("DELETE", u, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index fed88b46106..8b34b6e8674 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -605,3 +605,24 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) return resp, err }) } + +func TestOrganizationsService_DeleteOrganizationRepositoryRuleset(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + ctx := context.Background() + _, err := client.Organizations.DeleteOrganizationRepositoryRuleset(ctx, "o", 26110) + if err != nil { + t.Errorf("Organizations.DeleteOrganizationRepositoryRuleset returned error: %v", err) + } + + const methodName = "DeleteOrganizationRepositoryRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Organizations.DeleteOrganizationRepositoryRuleset(ctx, "0", 26110) + }) +} From d89d75a87d27f0e5845e97ffa13f68879e02c367 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:39:00 +1000 Subject: [PATCH 14/29] Add comment on ruleset Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github/repos_rules.go b/github/repos_rules.go index ede1f6b0aa4..0b5c86ed7d6 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -252,7 +252,7 @@ func NewTagNamePatternRule(pattern *RulePatternParameters) (rule RulesetRule) { } } -// Ruleset represents a GitHub rules request. +// Ruleset represents a GitHub ruleset object. type Ruleset struct { ID int64 `json:"id"` Name string `json:"name"` From 51f34d4734a296602cc399e1136b7823fd2fb6ce Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:43:43 +1000 Subject: [PATCH 15/29] Fix linting Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 71924e3598a..4bfbe2aefcc 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -53,8 +53,8 @@ func (s *OrganizationsService) CreateOrganizationRepositoryRuleset(ctx context.C // GetOrganizationRepositoryRuleset gets a repository ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#get-an-organization-repository-ruleset -func (s *OrganizationsService) GetOrganizationRepositoryRuleset(ctx context.Context, org string, ruleset_id int64) (*Ruleset, *Response, error) { - u := fmt.Sprintf("orgs/%v/rulesets/%v", org, ruleset_id) +func (s *OrganizationsService) GetOrganizationRepositoryRuleset(ctx context.Context, org string, rulesetID int64) (*Ruleset, *Response, error) { + u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -73,8 +73,8 @@ func (s *OrganizationsService) GetOrganizationRepositoryRuleset(ctx context.Cont // UpdateOrganizationRepositoryRuleset updates a repository ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#update-a-repository-ruleset -func (s *OrganizationsService) UpdateOrganizationRepositoryRuleset(ctx context.Context, org string, ruleset_id int64, rs *Ruleset) (*Ruleset, *Response, error) { - u := fmt.Sprintf("orgs/%v/rulesets/%v", org, ruleset_id) +func (s *OrganizationsService) UpdateOrganizationRepositoryRuleset(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("POST", u, rs) if err != nil { @@ -93,8 +93,8 @@ func (s *OrganizationsService) UpdateOrganizationRepositoryRuleset(ctx context.C // DeleteOrganizationRepositoryRuleset deletes a repository ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#delete-a-repository-ruleset -func (s *OrganizationsService) DeleteOrganizationRepositoryRuleset(ctx context.Context, org string, ruleset_id int64) (*Response, error) { - u := fmt.Sprintf("orgs/%v/rulesets/%v", org, ruleset_id) +func (s *OrganizationsService) DeleteOrganizationRepositoryRuleset(ctx context.Context, org string, rulesetID int64) (*Response, error) { + u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { From 8d47d85e8885d5cd7f34e5b99786fdf472a6bdd9 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 17:59:39 +1000 Subject: [PATCH 16/29] Add tests for Rule_UnmarshalJSON Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules_test.go | 151 +++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 github/repos_rules_test.go diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go new file mode 100644 index 00000000000..bc30ea724f2 --- /dev/null +++ b/github/repos_rules_test.go @@ -0,0 +1,151 @@ +// Copyright 2023 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "encoding/json" + "testing" +) + +func TestRulesetRule_UnmarshalJSON(t *testing.T) { + tests := []struct { + in *RulesetRule + want string + wantErr bool + }{ + { + in: &RulesetRule{ + Type: "update", + Parameters: &UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }, + }, + want: `{`, + wantErr: true, + }, + { + in: &RulesetRule{ + Type: "required_deployments", + Parameters: &RequiredDeploymentEnvironmentsRuleParameters{ + RequiredDeploymentEnvironments: []string{"test"}, + }, + }, + want: `{`, + wantErr: true, + }, + { + in: &RulesetRule{ + Type: "commit_message_pattern", + Parameters: &RulePatternParameters{ + Name: String("avoid test commits"), + Negate: Bool(true), + Operator: "starts_with", + Pattern: "[test]", + }, + }, + want: `{`, + wantErr: true, + }, + { + in: &RulesetRule{ + Type: "commit_author_email_pattern", + Parameters: &RulePatternParameters{ + Operator: "contains", + Pattern: "github", + }, + }, + want: `{`, + wantErr: true, + }, + { + in: &RulesetRule{ + Type: "committer_email_pattern", + Parameters: &RulePatternParameters{ + Name: String("avoid commit emails"), + Negate: Bool(true), + Operator: "ends_with", + Pattern: "abc", + }, + }, + want: `{`, + wantErr: true, + }, + { + in: &RulesetRule{ + Type: "branch_name_pattern", + Parameters: &RulePatternParameters{ + Name: String("avoid branch names"), + Negate: Bool(true), + Operator: "regex", + Pattern: "github$", + }, + }, + want: `{`, + wantErr: true, + }, + { + in: &RulesetRule{ + Type: "tag_name_pattern", + Parameters: &RulePatternParameters{ + Name: String("avoid tag names"), + Negate: Bool(true), + Operator: "contains", + Pattern: "github", + }, + }, + want: `{`, + wantErr: true, + }, + { + in: &RulesetRule{ + Type: "pull_request", + Parameters: &PullRequestRuleParameters{ + RequireCodeOwnerReview: true, + RequireLastPushApproval: true, + RequiredApprovingReviewCount: 1, + RequiredReviewThreadResolution: true, + DismissStaleReviewsOnPush: true, + }, + }, + want: `{`, + wantErr: true, + }, + { + in: &RulesetRule{ + Type: "required_status_checks", + Parameters: &RequiredStatusChecksRuleParameters{ + RequiredStatusChecks: []RuleRequiredStatusChecks{ + { + Context: "test", + IntegrationID: Int64(1), + }, + }, + StrictRequiredStatusChecksPolicy: true, + }, + }, + want: `{`, + wantErr: true, + }, + { + in: &RulesetRule{ + Type: "unknown", + }, + want: `{`, + wantErr: true, + }, + } + + for _, tc := range tests { + err := json.Unmarshal([]byte(tc.want), tc.in) + if err == nil && tc.wantErr { + t.Errorf("RulesetRule.UnmarshalJSON returned nil instead of an error") + } + if err != nil && !tc.wantErr { + t.Errorf("RulesetRule.UnmarshalJSON returned an unexpected error: %+v", err) + } + } + +} From 5439e29d462d114d05642ac2111e25afee13ec4c Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 18:04:35 +1000 Subject: [PATCH 17/29] Fix newline linting Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index bc30ea724f2..51c6f748102 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -147,5 +147,4 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { t.Errorf("RulesetRule.UnmarshalJSON returned an unexpected error: %+v", err) } } - } From 3f1a6b4e18b6afb2d731221025ce7ac0e4eca60d Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Thu, 1 Jun 2023 20:39:08 +1000 Subject: [PATCH 18/29] Rename RuleSetRule to RepositoryRule Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/github-accessors.go | 8 +- github/github-accessors_test.go | 10 +-- github/orgs_rules_test.go | 20 ++--- github/repos_rules.go | 126 ++++++++++++++++---------------- github/repos_rules_test.go | 28 +++---- 5 files changed, 96 insertions(+), 96 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 0289e0d3ea5..9f81d3c520b 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -18407,7 +18407,7 @@ func (r *Ruleset) GetBypassMode() string { } // GetConditions returns the Conditions field. -func (r *Ruleset) GetConditions() *RulesetCondition { +func (r *Ruleset) GetConditions() *RulesetConditions { if r == nil { return nil } @@ -18431,7 +18431,7 @@ func (r *Ruleset) GetNodeID() string { } // GetRules returns the Rules field if it's non-nil, zero value otherwise. -func (r *Ruleset) GetRules() []RulesetRule { +func (r *Ruleset) GetRules() []RepositoryRule { if r == nil || r.Rules == nil { return nil } @@ -18455,7 +18455,7 @@ func (r *Ruleset) GetTarget() string { } // GetRefName returns the RefName field. -func (r *RulesetCondition) GetRefName() *RulesetRefConditionParameters { +func (r *RulesetConditions) GetRefName() *RulesetRefConditionParameters { if r == nil { return nil } @@ -18463,7 +18463,7 @@ func (r *RulesetCondition) GetRefName() *RulesetRefConditionParameters { } // GetRepositoryName returns the RepositoryName field. -func (r *RulesetCondition) GetRepositoryName() *RulesetRepositoryConditionParameters { +func (r *RulesetConditions) GetRepositoryName() *RulesetRepositoryConditionParameters { if r == nil { return nil } diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 795a4201748..bb43916d1c0 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -21479,7 +21479,7 @@ func TestRuleset_GetNodeID(tt *testing.T) { } func TestRuleset_GetRules(tt *testing.T) { - var zeroValue []RulesetRule + var zeroValue []RepositoryRule r := &Ruleset{Rules: &zeroValue} r.GetRules() r = &Ruleset{} @@ -21508,15 +21508,15 @@ func TestRuleset_GetTarget(tt *testing.T) { r.GetTarget() } -func TestRulesetCondition_GetRefName(tt *testing.T) { - r := &RulesetCondition{} +func TestRulesetConditions_GetRefName(tt *testing.T) { + r := &RulesetConditions{} r.GetRefName() r = nil r.GetRefName() } -func TestRulesetCondition_GetRepositoryName(tt *testing.T) { - r := &RulesetCondition{} +func TestRulesetConditions_GetRepositoryName(tt *testing.T) { + r := &RulesetConditions{} r.GetRepositoryName() r = nil r.GetRepositoryName() diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index 8b34b6e8674..c1576c675a0 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -222,7 +222,7 @@ func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) ActorType: "Team", }, }, - Conditions: &RulesetCondition{ + Conditions: &RulesetConditions{ RefName: &RulesetRefConditionParameters{ Include: []string{"refs/heads/main", "refs/heads/master"}, Exclude: []string{"refs/heads/dev*"}, @@ -233,7 +233,7 @@ func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) Protected: Bool(true), }, }, - Rules: &[]RulesetRule{ + Rules: &[]RepositoryRule{ NewCreationRule(), NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ UpdateAllowsFetchAndMerge: true, @@ -308,7 +308,7 @@ func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) ActorType: "Team", }, }, - Conditions: &RulesetCondition{ + Conditions: &RulesetConditions{ RefName: &RulesetRefConditionParameters{ Include: []string{"refs/heads/main", "refs/heads/master"}, Exclude: []string{"refs/heads/dev*"}, @@ -319,7 +319,7 @@ func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) Protected: Bool(true), }, }, - Rules: &[]RulesetRule{ + Rules: &[]RepositoryRule{ NewCreationRule(), NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ UpdateAllowsFetchAndMerge: true, @@ -459,7 +459,7 @@ func TestOrganizationsService_GetOrganizationRepositoryRuleset(t *testing.T) { Links: &RulesetLinks{ Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, }, - Conditions: &RulesetCondition{ + Conditions: &RulesetConditions{ RefName: &RulesetRefConditionParameters{ Include: []string{"refs/heads/main", "refs/heads/master"}, Exclude: []string{"refs/heads/dev*"}, @@ -470,7 +470,7 @@ func TestOrganizationsService_GetOrganizationRepositoryRuleset(t *testing.T) { Protected: Bool(true), }, }, - Rules: &[]RulesetRule{ + Rules: &[]RepositoryRule{ NewCreationRule(), }, } @@ -544,7 +544,7 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) Target: String("branch"), Enforcement: "active", BypassMode: String("none"), - Conditions: &RulesetCondition{ + Conditions: &RulesetConditions{ RefName: &RulesetRefConditionParameters{ Include: []string{"refs/heads/main", "refs/heads/master"}, Exclude: []string{"refs/heads/dev*"}, @@ -555,7 +555,7 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) Protected: Bool(true), }, }, - Rules: &[]RulesetRule{ + Rules: &[]RepositoryRule{ NewCreationRule(), }, }) @@ -576,7 +576,7 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) Links: &RulesetLinks{ Self: &RulesetLink{HRef: String("https://api.github.com/orgs/o/rulesets/26110")}, }, - Conditions: &RulesetCondition{ + Conditions: &RulesetConditions{ RefName: &RulesetRefConditionParameters{ Include: []string{"refs/heads/main", "refs/heads/master"}, Exclude: []string{"refs/heads/dev*"}, @@ -587,7 +587,7 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) Protected: Bool(true), }, }, - Rules: &[]RulesetRule{ + Rules: &[]RepositoryRule{ NewCreationRule(), }, } diff --git a/github/repos_rules.go b/github/repos_rules.go index 0b5c86ed7d6..72fc3a9abaa 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -41,7 +41,7 @@ type RulesetRepositoryConditionParameters struct { } // RulesetCondition represents the conditions object in a ruleset. -type RulesetCondition struct { +type RulesetConditions struct { RefName *RulesetRefConditionParameters `json:"ref_name,omitempty"` RepositoryName *RulesetRepositoryConditionParameters `json:"repository_name,omitempty"` } @@ -87,166 +87,166 @@ type RequiredStatusChecksRuleParameters struct { StrictRequiredStatusChecksPolicy bool `json:"strict_required_status_checks_policy"` } -// RulesetRule represents a GitHub Rule within a Ruleset. -type RulesetRule struct { +// RepositoryRule represents a GitHub Rule within a Ruleset. +type RepositoryRule struct { Type string `json:"type"` Parameters interface{} `json:"parameters,omitempty"` } // UnmarshalJSON implements the json.Unmarshaler interface. -// This helps us handle the fact that RulesetRule parameter field can be of numerous types. -func (rsr *RulesetRule) UnmarshalJSON(data []byte) error { - type rule RulesetRule - var rulesetRule rule - if err := json.Unmarshal(data, &rulesetRule); err != nil { +// This helps us handle the fact that RepositoryRule parameter field can be of numerous types. +func (r *RepositoryRule) UnmarshalJSON(data []byte) error { + type rule RepositoryRule + var RepositoryRule rule + if err := json.Unmarshal(data, &RepositoryRule); err != nil { return err } - rsr.Type = rulesetRule.Type + r.Type = RepositoryRule.Type - switch rulesetRule.Type { + switch RepositoryRule.Type { case "creation", "deletion", "required_linear_history", "required_signatures", "non_fast_forward": - rsr.Parameters = nil + r.Parameters = nil case "update": - rulesetRule.Parameters = &UpdateAllowsFetchAndMergeRuleParameters{} - if err := json.Unmarshal(data, &rulesetRule); err != nil { + RepositoryRule.Parameters = &UpdateAllowsFetchAndMergeRuleParameters{} + if err := json.Unmarshal(data, &RepositoryRule); err != nil { return err } - rsr.Parameters = rulesetRule.Parameters + r.Parameters = RepositoryRule.Parameters case "required_deployments": - rulesetRule.Parameters = &RequiredDeploymentEnvironmentsRuleParameters{} - if err := json.Unmarshal(data, &rulesetRule); err != nil { + RepositoryRule.Parameters = &RequiredDeploymentEnvironmentsRuleParameters{} + if err := json.Unmarshal(data, &RepositoryRule); err != nil { return err } - rsr.Parameters = rulesetRule.Parameters + r.Parameters = RepositoryRule.Parameters case "commit_message_pattern", "commit_author_email_pattern", "committer_email_pattern", "branch_name_pattern", "tag_name_pattern": - rulesetRule.Parameters = &RulePatternParameters{} - if err := json.Unmarshal(data, &rulesetRule); err != nil { + RepositoryRule.Parameters = &RulePatternParameters{} + if err := json.Unmarshal(data, &RepositoryRule); err != nil { return err } - rsr.Parameters = rulesetRule.Parameters + r.Parameters = RepositoryRule.Parameters case "pull_request": - rulesetRule.Parameters = &PullRequestRuleParameters{} - if err := json.Unmarshal(data, &rulesetRule); err != nil { + RepositoryRule.Parameters = &PullRequestRuleParameters{} + if err := json.Unmarshal(data, &RepositoryRule); err != nil { return err } - rsr.Parameters = rulesetRule.Parameters + r.Parameters = RepositoryRule.Parameters case "required_status_checks": - rulesetRule.Parameters = &RequiredStatusChecksRuleParameters{} - if err := json.Unmarshal(data, &rulesetRule); err != nil { + RepositoryRule.Parameters = &RequiredStatusChecksRuleParameters{} + if err := json.Unmarshal(data, &RepositoryRule); err != nil { return err } - rsr.Parameters = rulesetRule.Parameters + r.Parameters = RepositoryRule.Parameters default: - rsr.Type = "" - rsr.Parameters = nil - return fmt.Errorf("rulesetRule.Type %T is not yet implemented, unable to unmarshal", rulesetRule.Type) + r.Type = "" + r.Parameters = nil + return fmt.Errorf("RepositoryRule.Type %T is not yet implemented, unable to unmarshal", RepositoryRule.Type) } return nil } // NewCreationRule creates a rule as part of a GitHub ruleset to only allow users with bypass permission to create matching refs. -func NewCreationRule() (rule RulesetRule) { - return RulesetRule{ +func NewCreationRule() (rule RepositoryRule) { + return RepositoryRule{ Type: "creation", } } // NewUpdateRule creates a rule as part of a GitHub ruleset to only allow users with bypass permission to update matching refs. -func NewUpdateRule(params *UpdateAllowsFetchAndMergeRuleParameters) (rule RulesetRule) { - return RulesetRule{ +func NewUpdateRule(params *UpdateAllowsFetchAndMergeRuleParameters) (rule RepositoryRule) { + return RepositoryRule{ Type: "update", Parameters: params, } } // NewDeletionRule creates a rule as part of a GitHub ruleset to only allow users with bypass permissions to delete matching refs. -func NewDeletionRule() (rule RulesetRule) { - return RulesetRule{ +func NewDeletionRule() (rule RepositoryRule) { + return RepositoryRule{ Type: "deletion", } } // NewRequiredLinearHistoryRule creates a rule as part of a GitHub ruleset to prevent merge commits from being pushed to matching branches. -func NewRequiredLinearHistoryRule() (rule RulesetRule) { - return RulesetRule{ +func NewRequiredLinearHistoryRule() (rule RepositoryRule) { + return RepositoryRule{ Type: "required_linear_history", } } // NewRequiredDeploymentsRule creates a rule as part of a GitHub ruleset to require environments to be successfully deployed before they can be merged into the matching branches. -func NewRequiredDeploymentsRule(params *RequiredDeploymentEnvironmentsRuleParameters) (rule RulesetRule) { - return RulesetRule{ +func NewRequiredDeploymentsRule(params *RequiredDeploymentEnvironmentsRuleParameters) (rule RepositoryRule) { + return RepositoryRule{ Type: "required_deployments", Parameters: params, } } // NewRequiredSignaturesRule creates a rule as part of a GitHub ruleset to require commits pushed to matching branches to have verified signatures. -func NewRequiredSignaturesRule() (rule RulesetRule) { - return RulesetRule{ +func NewRequiredSignaturesRule() (rule RepositoryRule) { + return RepositoryRule{ Type: "required_signatures", } } // NewPullRequestRule creates a rule as part of a GitHub ruleset to require all commits be made to a non-target branch and submitted via a pull request before they can be merged. func NewPullRequestRule(params *PullRequestRuleParameters) ( - rule RulesetRule) { - return RulesetRule{ + rule RepositoryRule) { + return RepositoryRule{ Type: "pull_request", Parameters: params, } } // NewRequiredStatusChecksRule creates a rule as part of a GitHub ruleset to require which status checks must pass before branches can be merged into a branch rule. -func NewRequiredStatusChecksRule(params *RequiredStatusChecksRuleParameters) (rule RulesetRule) { - return RulesetRule{ +func NewRequiredStatusChecksRule(params *RequiredStatusChecksRuleParameters) (rule RepositoryRule) { + return RepositoryRule{ Type: "required_status_checks", Parameters: params, } } // NewNonFastForwardRule creates a rule as part of a GitHub ruleset to prevent users with push access from force pushing to matching branches. -func NewNonFastForwardRule() (rule RulesetRule) { - return RulesetRule{ +func NewNonFastForwardRule() (rule RepositoryRule) { + return RepositoryRule{ Type: "non_fast_forward", } } // NewCommitMessagePatternRule creates a rule as part of a GitHub ruleset to restrict commit message patterns being pushed to matching branches. -func NewCommitMessagePatternRule(pattern *RulePatternParameters) (rule RulesetRule) { - return RulesetRule{ +func NewCommitMessagePatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { + return RepositoryRule{ Type: "commit_message_pattern", Parameters: pattern, } } // NewCommitAuthorEmailPatternRule creates a rule as part of a GitHub ruleset to restrict commits with author email patterns being merged into matching branches. -func NewCommitAuthorEmailPatternRule(pattern *RulePatternParameters) (rule RulesetRule) { - return RulesetRule{ +func NewCommitAuthorEmailPatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { + return RepositoryRule{ Type: "commit_author_email_pattern", Parameters: pattern, } } // NewCommitterEmailPatternRule creates a rule as part of a GitHub ruleset to restrict commits with committer email patterns being merged into matching branches. -func NewCommitterEmailPatternRule(pattern *RulePatternParameters) (rule RulesetRule) { - return RulesetRule{ +func NewCommitterEmailPatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { + return RepositoryRule{ Type: "committer_email_pattern", Parameters: pattern, } } -func NewBranchNamePatternRule(pattern *RulePatternParameters) (rule RulesetRule) { - return RulesetRule{ +func NewBranchNamePatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { + return RepositoryRule{ Type: "branch_name_pattern", Parameters: pattern, } } -func NewTagNamePatternRule(pattern *RulePatternParameters) (rule RulesetRule) { - return RulesetRule{ +func NewTagNamePatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { + return RepositoryRule{ Type: "tag_name_pattern", Parameters: pattern, } @@ -264,10 +264,10 @@ type Ruleset struct { // Possible values for Enforcement are: disabled, active, evaluate Enforcement string `json:"enforcement"` // Possible values for BypassMode are: none, repository, organization - BypassMode *string `json:"bypass_mode,omitempty"` - BypassActors *[]BypassActor `json:"bypass_actors,omitempty"` - NodeID *string `json:"node_id,omitempty"` - Links *RulesetLinks `json:"_links,omitempty"` - Conditions *RulesetCondition `json:"conditions,omitempty"` - Rules *[]RulesetRule `json:"rules,omitempty"` + BypassMode *string `json:"bypass_mode,omitempty"` + BypassActors *[]BypassActor `json:"bypass_actors,omitempty"` + NodeID *string `json:"node_id,omitempty"` + Links *RulesetLinks `json:"_links,omitempty"` + Conditions *RulesetConditions `json:"conditions,omitempty"` + Rules *[]RepositoryRule `json:"rules,omitempty"` } diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index 51c6f748102..e1e65bc6329 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -10,14 +10,14 @@ import ( "testing" ) -func TestRulesetRule_UnmarshalJSON(t *testing.T) { +func TestRepositoryRule_UnmarshalJSON(t *testing.T) { tests := []struct { - in *RulesetRule + in *RepositoryRule want string wantErr bool }{ { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "update", Parameters: &UpdateAllowsFetchAndMergeRuleParameters{ UpdateAllowsFetchAndMerge: true, @@ -27,7 +27,7 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { wantErr: true, }, { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "required_deployments", Parameters: &RequiredDeploymentEnvironmentsRuleParameters{ RequiredDeploymentEnvironments: []string{"test"}, @@ -37,7 +37,7 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { wantErr: true, }, { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "commit_message_pattern", Parameters: &RulePatternParameters{ Name: String("avoid test commits"), @@ -50,7 +50,7 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { wantErr: true, }, { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "commit_author_email_pattern", Parameters: &RulePatternParameters{ Operator: "contains", @@ -61,7 +61,7 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { wantErr: true, }, { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "committer_email_pattern", Parameters: &RulePatternParameters{ Name: String("avoid commit emails"), @@ -74,7 +74,7 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { wantErr: true, }, { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "branch_name_pattern", Parameters: &RulePatternParameters{ Name: String("avoid branch names"), @@ -87,7 +87,7 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { wantErr: true, }, { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "tag_name_pattern", Parameters: &RulePatternParameters{ Name: String("avoid tag names"), @@ -100,7 +100,7 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { wantErr: true, }, { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "pull_request", Parameters: &PullRequestRuleParameters{ RequireCodeOwnerReview: true, @@ -114,7 +114,7 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { wantErr: true, }, { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "required_status_checks", Parameters: &RequiredStatusChecksRuleParameters{ RequiredStatusChecks: []RuleRequiredStatusChecks{ @@ -130,7 +130,7 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { wantErr: true, }, { - in: &RulesetRule{ + in: &RepositoryRule{ Type: "unknown", }, want: `{`, @@ -141,10 +141,10 @@ func TestRulesetRule_UnmarshalJSON(t *testing.T) { for _, tc := range tests { err := json.Unmarshal([]byte(tc.want), tc.in) if err == nil && tc.wantErr { - t.Errorf("RulesetRule.UnmarshalJSON returned nil instead of an error") + t.Errorf("RepositoryRule.UnmarshalJSON returned nil instead of an error") } if err != nil && !tc.wantErr { - t.Errorf("RulesetRule.UnmarshalJSON returned an unexpected error: %+v", err) + t.Errorf("RepositoryRule.UnmarshalJSON returned an unexpected error: %+v", err) } } } From 90c2a8d06103d92c12ddafd13d3010432588facc Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 09:44:56 +1000 Subject: [PATCH 19/29] Add GetRulesForBranch Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 21 +++++++++++++++ github/repos_rules_test.go | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/github/repos_rules.go b/github/repos_rules.go index 72fc3a9abaa..1f706a38ce9 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -6,6 +6,7 @@ package github import ( + "context" "encoding/json" "fmt" ) @@ -271,3 +272,23 @@ type Ruleset struct { Conditions *RulesetConditions `json:"conditions,omitempty"` Rules *[]RepositoryRule `json:"rules,omitempty"` } + +// GetRulesForBranch gets all the repository rules that apply to the specified branch. +// +// GitHub API docs: https://docs.github.com/en/rest/repos/rules#get-rules-for-a-branch +func (s *RepositoriesService) GetRulesForBranch(ctx context.Context, owner, repo, branch string) ([]*RepositoryRule, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/rules/branches/%v", owner, repo, branch) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var rules []*RepositoryRule + resp, err := s.client.Do(ctx, req, &rules) + if err != nil { + return nil, resp, err + } + + return rules, resp, nil +} diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index e1e65bc6329..70d7e59f4d5 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -6,8 +6,13 @@ package github import ( + "context" "encoding/json" + "fmt" + "net/http" "testing" + + "github.com/google/go-cmp/cmp" ) func TestRepositoryRule_UnmarshalJSON(t *testing.T) { @@ -148,3 +153,52 @@ func TestRepositoryRule_UnmarshalJSON(t *testing.T) { } } } + +func TestRepositoriesService_GetRulesForBranch(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/repo/rules/branches/branch", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[ + { + "type": "creation" + }, + { + "type": "update", + "parameters": { + "update_allows_fetch_and_merge": true + } + } + ]`) + }) + + ctx := context.Background() + rules, _, err := client.Repositories.GetRulesForBranch(ctx, "o", "repo", "branch") + if err != nil { + t.Errorf("Repositories.GetRulesForBranch returned error: %v", err) + } + + creationRule := NewCreationRule() + updateRule := NewUpdateRule(&UpdateAllowsFetchAndMergeRuleParameters{ + UpdateAllowsFetchAndMerge: true, + }) + + want := []*RepositoryRule{ + &creationRule, + &updateRule, + } + if !cmp.Equal(rules, want) { + t.Errorf("Repositories.GetRulesForBranch returned %+v, want %+v", rules, want) + } + + const methodName = "GetRulesForBranch" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Repositories.GetRulesForBranch(ctx, "o", "repo", "branch") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 0e828ee8cbe620af35a2403e334482b0f8286992 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 10:01:39 +1000 Subject: [PATCH 20/29] Add GetAllRulesets Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 20 +++++++++++++ github/repos_rules_test.go | 61 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/github/repos_rules.go b/github/repos_rules.go index 1f706a38ce9..60bf5a16e07 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -292,3 +292,23 @@ func (s *RepositoriesService) GetRulesForBranch(ctx context.Context, owner, repo return rules, resp, nil } + +// GetAllRepositoryRulesets gets all the repository rules that apply to the specified repository. +// +// GitHub API docs: https://docs.github.com/en/rest/repos/rules#get-all-repository-rulesets +func (s *RepositoriesService) GetAllRulesets(ctx context.Context, owner, repo string) ([]*Ruleset, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/rulesets", owner, repo) + + 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 +} diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index 70d7e59f4d5..751599856db 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -202,3 +202,64 @@ func TestRepositoriesService_GetRulesForBranch(t *testing.T) { return resp, err }) } + +func TestRepositoriesService_GetAllRulesets(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/repo/rulesets", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[ + { + "id": 42, + "name": "ruleset", + "source_type": "Repository", + "source": "monalisa/my-repo", + "enforcement": "enabled" + }, + { + "id": 314, + "name": "Another ruleset", + "source_type": "Repository", + "source": "monalisa/my-repo", + "enforcement": "enabled" + } + ]`) + }) + + ctx := context.Background() + ruleSet, _, err := client.Repositories.GetAllRulesets(ctx, "o", "repo") + if err != nil { + t.Errorf("Repositories.GetAllRulesets returned error: %v", err) + } + + want := []*Ruleset{ + { + ID: 42, + Name: "ruleset", + SourceType: String("Repository"), + Source: "monalisa/my-repo", + Enforcement: "enabled", + }, + { + ID: 314, + Name: "Another ruleset", + SourceType: String("Repository"), + Source: "monalisa/my-repo", + Enforcement: "enabled", + }, + } + if !cmp.Equal(ruleSet, want) { + t.Errorf("Repositories.GetAllRulesets returned %+v, want %+v", ruleSet, want) + } + + const methodName = "GetAllRulesets" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Repositories.GetAllRulesets(ctx, "o", "repo") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 5589fc10adbb77d569a4287ddd4bff7b5795db95 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 10:20:19 +1000 Subject: [PATCH 21/29] Add CreateRuleset Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 26 +++++++++++++++--- github/repos_rules_test.go | 54 +++++++++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/github/repos_rules.go b/github/repos_rules.go index 60bf5a16e07..2f8e7387aee 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -304,11 +304,31 @@ func (s *RepositoriesService) GetAllRulesets(ctx context.Context, owner, repo st return nil, nil, err } - var ruleSet []*Ruleset - resp, err := s.client.Do(ctx, req, &ruleSet) + var ruleset []*Ruleset + resp, err := s.client.Do(ctx, req, &ruleset) if err != nil { return nil, resp, err } - return ruleSet, resp, nil + return ruleset, resp, nil +} + +// CreateRuleset creates a repository ruleset for the specified repository. +// +// GitHub API docs: https://docs.github.com/en/rest/repos/rules#create-a-repository-ruleset +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) + 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 } diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index 751599856db..f6c12fe9e18 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -214,14 +214,14 @@ func TestRepositoriesService_GetAllRulesets(t *testing.T) { "id": 42, "name": "ruleset", "source_type": "Repository", - "source": "monalisa/my-repo", + "source": "o/repo", "enforcement": "enabled" }, { "id": 314, "name": "Another ruleset", "source_type": "Repository", - "source": "monalisa/my-repo", + "source": "o/repo", "enforcement": "enabled" } ]`) @@ -238,14 +238,14 @@ func TestRepositoriesService_GetAllRulesets(t *testing.T) { ID: 42, Name: "ruleset", SourceType: String("Repository"), - Source: "monalisa/my-repo", + Source: "o/repo", Enforcement: "enabled", }, { ID: 314, Name: "Another ruleset", SourceType: String("Repository"), - Source: "monalisa/my-repo", + Source: "o/repo", Enforcement: "enabled", }, } @@ -263,3 +263,49 @@ func TestRepositoriesService_GetAllRulesets(t *testing.T) { return resp, err }) } + +func TestRepositoriesService_CreateRuleset(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/repo/rulesets", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `{ + "id": 42, + "name": "ruleset", + "source_type": "Repository", + "source": "o/repo", + "enforcement": "enabled" + }`) + }) + + ctx := context.Background() + ruleSet, _, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{ + Name: "ruleset", + Enforcement: "enabled", + }) + if err != nil { + t.Errorf("Repositories.CreateRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: 42, + Name: "ruleset", + SourceType: String("Repository"), + Source: "o/repo", + Enforcement: "enabled", + } + if !cmp.Equal(ruleSet, want) { + t.Errorf("Repositories.CreateRuleset returned %+v, want %+v", ruleSet, want) + } + + const methodName = "CreateRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{}) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 8c128a6f9f50d2dc1b7c533fefbc5b7fe8fe868e Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 10:49:10 +1000 Subject: [PATCH 22/29] Add GetRuleset Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 21 +++++++++++++++++++ github/repos_rules_test.go | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/github/repos_rules.go b/github/repos_rules.go index 2f8e7387aee..414f44b7e10 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -332,3 +332,24 @@ func (s *RepositoriesService) CreateRuleset(ctx context.Context, owner, repo str return ruleset, resp, nil } + +// GetRuleset gets a repository ruleset for the specified repository. +// If includesParent is true, rulesets configured at organisation level that apply to the repository can be retrieved. +// +// GitHub API docs: https://docs.github.com/en/rest/repos/rules#get-a-repository-ruleset +func (s *RepositoriesService) GetRuleset(ctx context.Context, owner, repo string, rulesetID int64, includesParent bool) (*Ruleset, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/rulesets/%v?includes_parents=%v", owner, repo, rulesetID, includesParent) + + 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 +} diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index f6c12fe9e18..98f5d4253c4 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -309,3 +309,46 @@ func TestRepositoriesService_CreateRuleset(t *testing.T) { return resp, err }) } + +func TestRepositoriesService_GetRuleset(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/repo/rulesets/42", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{ + "id": 42, + "name": "ruleset", + "source_type": "Organization", + "source": "o", + "enforcement": "enabled" + }`) + }) + + ctx := context.Background() + ruleSet, _, err := client.Repositories.GetRuleset(ctx, "o", "repo", 42, true) + if err != nil { + t.Errorf("Repositories.GetRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: 42, + Name: "ruleset", + SourceType: String("Organization"), + Source: "o", + Enforcement: "enabled", + } + if !cmp.Equal(ruleSet, want) { + t.Errorf("Repositories.GetRuleset returned %+v, want %+v", ruleSet, want) + } + + const methodName = "GetRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Repositories.GetRuleset(ctx, "o", "repo", 42, true) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 7696f527a63afc44e751c69e49290670e71cce98 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 11:08:36 +1000 Subject: [PATCH 23/29] Add UpdateRuleset Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 20 +++++++++++++++++ github/repos_rules_test.go | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/github/repos_rules.go b/github/repos_rules.go index 414f44b7e10..ff87e040ae6 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -353,3 +353,23 @@ func (s *RepositoriesService) GetRuleset(ctx context.Context, owner, repo string return ruleset, resp, nil } + +// UpdateRuleset updates a repository ruleset for the specified repository. +// +// GitHub API docs: https://docs.github.com/en/rest/repos/rules#update-a-repository-ruleset +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) + 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 +} diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index 98f5d4253c4..b42cb135df4 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -352,3 +352,49 @@ func TestRepositoriesService_GetRuleset(t *testing.T) { return resp, err }) } + +func TestRepositoriesService_UpdateRuleset(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + 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.UpdateRuleset(ctx, "o", "repo", 42, &Ruleset{ + Name: "ruleset", + Enforcement: "enabled", + }) + if err != nil { + t.Errorf("Repositories.UpdateRuleset returned error: %v", err) + } + + want := &Ruleset{ + ID: 42, + Name: "ruleset", + SourceType: String("Repository"), + Source: "o/repo", + Enforcement: "enabled", + } + if !cmp.Equal(ruleSet, want) { + t.Errorf("Repositories.UpdateRuleset returned %+v, want %+v", ruleSet, want) + } + + const methodName = "UpdateRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Repositories.UpdateRuleset(ctx, "o", "repo", 42, nil) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} From 9db004036062884fd76052aab903bbcc62f1a592 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 11:11:16 +1000 Subject: [PATCH 24/29] Fix http method for UpdateOrganizationRepositoryRuleset Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 6 +++--- github/orgs_rules_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 4bfbe2aefcc..945c9144f91 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -72,11 +72,11 @@ func (s *OrganizationsService) GetOrganizationRepositoryRuleset(ctx context.Cont // UpdateOrganizationRepositoryRuleset updates a repository ruleset from the specified organization. // -// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#update-a-repository-ruleset +// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#update-an-organization-repository-ruleset func (s *OrganizationsService) UpdateOrganizationRepositoryRuleset(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("POST", u, rs) + req, err := s.client.NewRequest("PUT", u, rs) if err != nil { return nil, nil, err } @@ -92,7 +92,7 @@ func (s *OrganizationsService) UpdateOrganizationRepositoryRuleset(ctx context.C // DeleteOrganizationRepositoryRuleset deletes a repository ruleset from the specified organization. // -// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#delete-a-repository-ruleset +// GitHub API docs: https://docs.github.com/en/rest/orgs/rules#delete-an-organization-repository-ruleset func (s *OrganizationsService) DeleteOrganizationRepositoryRuleset(ctx context.Context, org string, rulesetID int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID) diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index c1576c675a0..faebab125bf 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -494,7 +494,7 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) defer teardown() mux.HandleFunc("/orgs/o/rulesets/26110", func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, "POST") + testMethod(t, r, "PUT") fmt.Fprint(w, `{ "id": 26110, "name": "test ruleset", From fc0b2f1e3b23bdf8ee4af0029d55f71d3c95e107 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 11:27:07 +1000 Subject: [PATCH 25/29] Always return response when deleting rulesets Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 7 +------ github/repos_rules.go | 14 ++++++++++++++ github/repos_rules_test.go | 21 +++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 945c9144f91..4c733ebcad6 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -101,10 +101,5 @@ func (s *OrganizationsService) DeleteOrganizationRepositoryRuleset(ctx context.C return nil, err } - resp, err := s.client.Do(ctx, req, nil) - if err != nil { - return resp, err - } - - return resp, nil + return s.client.Do(ctx, req, nil) } diff --git a/github/repos_rules.go b/github/repos_rules.go index ff87e040ae6..6da33b9a348 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -373,3 +373,17 @@ func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo str return ruleset, resp, nil } + +// DeleteRuleset deletes a repository ruleset for the specified repository. +// +// GitHub API docs: https://docs.github.com/en/rest/repos/rules#delete-a-repository-ruleset +func (s *RepositoriesService) DeleteRuleset(ctx context.Context, owner, repo string, rulesetID int64) (*Response, error) { + u := fmt.Sprintf("repos/%v/%v/rulesets/%v", owner, repo, 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/repos_rules_test.go b/github/repos_rules_test.go index b42cb135df4..c28c252488a 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -398,3 +398,24 @@ func TestRepositoriesService_UpdateRuleset(t *testing.T) { return resp, err }) } + +func TestRepositoriesService_DeleteRuleset(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/repo/rulesets/42", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + }) + + ctx := context.Background() + _, err := client.Repositories.DeleteRuleset(ctx, "o", "repo", 42) + if err != nil { + t.Errorf("Repositories.DeleteRuleset returned error: %v", err) + } + + const methodName = "DeleteRuleset" + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Repositories.DeleteRuleset(ctx, "o", "repo", 42) + }) +} From 5a90752c7e46c6420d76828653f738c5ac257943 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 11:29:06 +1000 Subject: [PATCH 26/29] Update comments Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/github/repos_rules.go b/github/repos_rules.go index 6da33b9a348..a3bec70a48c 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -313,7 +313,7 @@ func (s *RepositoriesService) GetAllRulesets(ctx context.Context, owner, repo st return ruleset, resp, nil } -// CreateRuleset creates a repository ruleset for the specified repository. +// CreateRuleset creates a ruleset for the specified repository. // // GitHub API docs: https://docs.github.com/en/rest/repos/rules#create-a-repository-ruleset func (s *RepositoriesService) CreateRuleset(ctx context.Context, owner, repo string, rs *Ruleset) (*Ruleset, *Response, error) { @@ -333,7 +333,7 @@ func (s *RepositoriesService) CreateRuleset(ctx context.Context, owner, repo str return ruleset, resp, nil } -// GetRuleset gets a repository ruleset for the specified repository. +// GetRuleset gets a ruleset for the specified repository. // If includesParent is true, rulesets configured at organisation level that apply to the repository can be retrieved. // // GitHub API docs: https://docs.github.com/en/rest/repos/rules#get-a-repository-ruleset @@ -354,7 +354,7 @@ func (s *RepositoriesService) GetRuleset(ctx context.Context, owner, repo string return ruleset, resp, nil } -// UpdateRuleset updates a repository ruleset for the specified repository. +// UpdateRuleset updates a ruleset for the specified repository. // // GitHub API docs: https://docs.github.com/en/rest/repos/rules#update-a-repository-ruleset func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { @@ -374,7 +374,7 @@ func (s *RepositoriesService) UpdateRuleset(ctx context.Context, owner, repo str return ruleset, resp, nil } -// DeleteRuleset deletes a repository ruleset for the specified repository. +// DeleteRuleset deletes a ruleset for the specified repository. // // GitHub API docs: https://docs.github.com/en/rest/repos/rules#delete-a-repository-ruleset func (s *RepositoriesService) DeleteRuleset(ctx context.Context, owner, repo string, rulesetID int64) (*Response, error) { From 54921310bd42fd9786086cac35042a89cffc62e7 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 11:34:35 +1000 Subject: [PATCH 27/29] Small renaming and tidy up for consistency Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 20 +++++++------- github/orgs_rules_test.go | 56 +++++++++++++++++++-------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 4c733ebcad6..2d1975137a5 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -10,10 +10,10 @@ import ( "fmt" ) -// GetAllOrganizationRepositoryRulesets gets all the repository rulesets for the specified organization. +// GetAllOrganizationRulesets gets all the repository rulesets for the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#get-all-organization-repository-rulesets -func (s *OrganizationsService) GetAllOrganizationRepositoryRulesets(ctx context.Context, org string) ([]*Ruleset, *Response, error) { +func (s *OrganizationsService) GetAllOrganizationRulesets(ctx context.Context, org string) ([]*Ruleset, *Response, error) { u := fmt.Sprintf("orgs/%v/rulesets", org) req, err := s.client.NewRequest("GET", u, nil) @@ -30,10 +30,10 @@ func (s *OrganizationsService) GetAllOrganizationRepositoryRulesets(ctx context. return rulesets, resp, nil } -// CreateOrganizationRepositoryRuleset creates a repository ruleset for the specified organization. +// CreateOrganizationRuleset creates a repository ruleset for the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#create-an-organization-repository-ruleset -func (s *OrganizationsService) CreateOrganizationRepositoryRuleset(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) @@ -50,10 +50,10 @@ func (s *OrganizationsService) CreateOrganizationRepositoryRuleset(ctx context.C return ruleset, resp, nil } -// GetOrganizationRepositoryRuleset gets a repository ruleset from the specified organization. +// GetOrganizationRuleset gets a repository ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#get-an-organization-repository-ruleset -func (s *OrganizationsService) GetOrganizationRepositoryRuleset(ctx context.Context, org string, rulesetID int64) (*Ruleset, *Response, error) { +func (s *OrganizationsService) GetOrganizationRuleset(ctx context.Context, org string, rulesetID int64) (*Ruleset, *Response, error) { u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID) req, err := s.client.NewRequest("GET", u, nil) @@ -70,10 +70,10 @@ func (s *OrganizationsService) GetOrganizationRepositoryRuleset(ctx context.Cont return rulesets, resp, nil } -// UpdateOrganizationRepositoryRuleset updates a repository ruleset from the specified organization. +// UpdateOrganizationRuleset updates a repository ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#update-an-organization-repository-ruleset -func (s *OrganizationsService) UpdateOrganizationRepositoryRuleset(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) @@ -90,10 +90,10 @@ func (s *OrganizationsService) UpdateOrganizationRepositoryRuleset(ctx context.C return rulesets, resp, nil } -// DeleteOrganizationRepositoryRuleset deletes a repository ruleset from the specified organization. +// DeleteOrganizationRuleset deletes a repository ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#delete-an-organization-repository-ruleset -func (s *OrganizationsService) DeleteOrganizationRepositoryRuleset(ctx context.Context, org string, rulesetID int64) (*Response, error) { +func (s *OrganizationsService) DeleteOrganizationRuleset(ctx context.Context, org string, rulesetID int64) (*Response, error) { u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID) req, err := s.client.NewRequest("DELETE", u, nil) diff --git a/github/orgs_rules_test.go b/github/orgs_rules_test.go index faebab125bf..f7e3fb0b973 100644 --- a/github/orgs_rules_test.go +++ b/github/orgs_rules_test.go @@ -14,7 +14,7 @@ import ( "github.com/google/go-cmp/cmp" ) -func TestOrganizationsService_GetAllOrganizationRepositoryRulesets(t *testing.T) { +func TestOrganizationsService_GetAllOrganizationRulesets(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -38,9 +38,9 @@ func TestOrganizationsService_GetAllOrganizationRepositoryRulesets(t *testing.T) }) ctx := context.Background() - rulesets, _, err := client.Organizations.GetAllOrganizationRepositoryRulesets(ctx, "o") + rulesets, _, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") if err != nil { - t.Errorf("Organizations.GetAllOrganizationRepositoryRulesets returned error: %v", err) + t.Errorf("Organizations.GetAllOrganizationRulesets returned error: %v", err) } want := []*Ruleset{{ @@ -57,13 +57,13 @@ func TestOrganizationsService_GetAllOrganizationRepositoryRulesets(t *testing.T) }, }} if !cmp.Equal(rulesets, want) { - t.Errorf("Organizations.GetAllOrganizationRepositoryRulesets returned %+v, want %+v", rulesets, want) + t.Errorf("Organizations.GetAllOrganizationRulesets returned %+v, want %+v", rulesets, want) } - const methodName = "GetAllOrganizationRepositoryRulesets" + const methodName = "GetAllOrganizationRulesets" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetAllOrganizationRepositoryRulesets(ctx, "o") + got, resp, err := client.Organizations.GetAllOrganizationRulesets(ctx, "o") if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -71,7 +71,7 @@ func TestOrganizationsService_GetAllOrganizationRepositoryRulesets(t *testing.T) }) } -func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) { +func TestOrganizationsService_CreateOrganizationRuleset(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -209,7 +209,7 @@ func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) }) ctx := context.Background() - ruleset, _, err := client.Organizations.CreateOrganizationRepositoryRuleset(ctx, "o", &Ruleset{ + ruleset, _, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", &Ruleset{ ID: 21, Name: "ruleset", Target: String("branch"), @@ -292,7 +292,7 @@ func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) }, }) if err != nil { - t.Errorf("Organizations.CreateOrganizationRepositoryRuleset returned error: %v", err) + t.Errorf("Organizations.CreateOrganizationRuleset returned error: %v", err) } want := &Ruleset{ @@ -378,13 +378,13 @@ func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) }, } if !cmp.Equal(ruleset, want) { - t.Errorf("Organizations.CreateOrganizationRepositoryRuleset returned %+v, want %+v", ruleset, want) + t.Errorf("Organizations.CreateOrganizationRuleset returned %+v, want %+v", ruleset, want) } - const methodName = "CreateOrganizationRepositoryRuleset" + const methodName = "CreateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.CreateOrganizationRepositoryRuleset(ctx, "o", nil) + got, resp, err := client.Organizations.CreateOrganizationRuleset(ctx, "o", nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -392,7 +392,7 @@ func TestOrganizationsService_CreateOrganizationRepositoryRuleset(t *testing.T) }) } -func TestOrganizationsService_GetOrganizationRepositoryRuleset(t *testing.T) { +func TestOrganizationsService_GetOrganizationRuleset(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -442,7 +442,7 @@ func TestOrganizationsService_GetOrganizationRepositoryRuleset(t *testing.T) { }) ctx := context.Background() - rulesets, _, err := client.Organizations.GetOrganizationRepositoryRuleset(ctx, "o", 26110) + rulesets, _, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) if err != nil { t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned error: %v", err) } @@ -475,13 +475,13 @@ func TestOrganizationsService_GetOrganizationRepositoryRuleset(t *testing.T) { }, } if !cmp.Equal(rulesets, want) { - t.Errorf("Organizations.GetOrganizationRepositoryRuleset returned %+v, want %+v", rulesets, want) + t.Errorf("Organizations.GetOrganizationRuleset returned %+v, want %+v", rulesets, want) } - const methodName = "GetOrganizationRepositoryRuleset" + const methodName = "GetOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.GetOrganizationRepositoryRuleset(ctx, "o", 26110) + got, resp, err := client.Organizations.GetOrganizationRuleset(ctx, "o", 26110) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -489,7 +489,7 @@ func TestOrganizationsService_GetOrganizationRepositoryRuleset(t *testing.T) { }) } -func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) { +func TestOrganizationsService_UpdateOrganizationRuleset(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -539,7 +539,7 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) }) ctx := context.Background() - rulesets, _, err := client.Organizations.UpdateOrganizationRepositoryRuleset(ctx, "o", 26110, &Ruleset{ + rulesets, _, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, &Ruleset{ Name: "test ruleset", Target: String("branch"), Enforcement: "active", @@ -561,7 +561,7 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) }) if err != nil { - t.Errorf("Organizations.UpdateOrganizationRepositoryRuleset returned error: %v", err) + t.Errorf("Organizations.UpdateOrganizationRuleset returned error: %v", err) } want := &Ruleset{ @@ -592,13 +592,13 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) }, } if !cmp.Equal(rulesets, want) { - t.Errorf("Organizations.UpdateOrganizationRepositoryRuleset returned %+v, want %+v", rulesets, want) + t.Errorf("Organizations.UpdateOrganizationRuleset returned %+v, want %+v", rulesets, want) } - const methodName = "UpdateOrganizationRepositoryRuleset" + const methodName = "UpdateOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Organizations.UpdateOrganizationRepositoryRuleset(ctx, "o", 26110, nil) + got, resp, err := client.Organizations.UpdateOrganizationRuleset(ctx, "o", 26110, nil) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } @@ -606,7 +606,7 @@ func TestOrganizationsService_UpdateOrganizationRepositoryRuleset(t *testing.T) }) } -func TestOrganizationsService_DeleteOrganizationRepositoryRuleset(t *testing.T) { +func TestOrganizationsService_DeleteOrganizationRuleset(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -615,14 +615,14 @@ func TestOrganizationsService_DeleteOrganizationRepositoryRuleset(t *testing.T) }) ctx := context.Background() - _, err := client.Organizations.DeleteOrganizationRepositoryRuleset(ctx, "o", 26110) + _, err := client.Organizations.DeleteOrganizationRuleset(ctx, "o", 26110) if err != nil { - t.Errorf("Organizations.DeleteOrganizationRepositoryRuleset returned error: %v", err) + t.Errorf("Organizations.DeleteOrganizationRuleset returned error: %v", err) } - const methodName = "DeleteOrganizationRepositoryRuleset" + const methodName = "DeleteOrganizationRuleset" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - return client.Organizations.DeleteOrganizationRepositoryRuleset(ctx, "0", 26110) + return client.Organizations.DeleteOrganizationRuleset(ctx, "0", 26110) }) } From b814d7fe1f15dbcd8fc8d6537f1b092a8a5741af Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 13:31:20 +1000 Subject: [PATCH 28/29] Add includesParent query to GetAllRulesets Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/repos_rules.go | 4 ++-- github/repos_rules_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/github/repos_rules.go b/github/repos_rules.go index a3bec70a48c..cdb1a28304f 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -296,8 +296,8 @@ func (s *RepositoriesService) GetRulesForBranch(ctx context.Context, owner, repo // GetAllRepositoryRulesets gets all the repository rules that apply to the specified repository. // // GitHub API docs: https://docs.github.com/en/rest/repos/rules#get-all-repository-rulesets -func (s *RepositoriesService) GetAllRulesets(ctx context.Context, owner, repo string) ([]*Ruleset, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/rulesets", owner, repo) +func (s *RepositoriesService) GetAllRulesets(ctx context.Context, owner, repo string, includesParent bool) ([]*Ruleset, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/rulesets?includes_parents=%v", owner, repo, includesParent) req, err := s.client.NewRequest("GET", u, nil) if err != nil { diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go index c28c252488a..5c609cafb21 100644 --- a/github/repos_rules_test.go +++ b/github/repos_rules_test.go @@ -228,7 +228,7 @@ func TestRepositoriesService_GetAllRulesets(t *testing.T) { }) ctx := context.Background() - ruleSet, _, err := client.Repositories.GetAllRulesets(ctx, "o", "repo") + ruleSet, _, err := client.Repositories.GetAllRulesets(ctx, "o", "repo", false) if err != nil { t.Errorf("Repositories.GetAllRulesets returned error: %v", err) } @@ -256,7 +256,7 @@ func TestRepositoriesService_GetAllRulesets(t *testing.T) { const methodName = "GetAllRulesets" testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - got, resp, err := client.Repositories.GetAllRulesets(ctx, "o", "repo") + got, resp, err := client.Repositories.GetAllRulesets(ctx, "o", "repo", false) if got != nil { t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) } From c390b09c1ab6724df8053057f99d7ad0d6733492 Mon Sep 17 00:00:00 2001 From: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> Date: Fri, 2 Jun 2023 13:40:33 +1000 Subject: [PATCH 29/29] Further tidy up comments Signed-off-by: Daniel Liao <10663736+liaodaniel@users.noreply.github.com> --- github/orgs_rules.go | 10 ++++----- github/repos_rules.go | 47 +++++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/github/orgs_rules.go b/github/orgs_rules.go index 2d1975137a5..11be725eacd 100644 --- a/github/orgs_rules.go +++ b/github/orgs_rules.go @@ -10,7 +10,7 @@ import ( "fmt" ) -// GetAllOrganizationRulesets gets all the repository rulesets for the specified organization. +// GetAllOrganizationRulesets gets all the rulesets for the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#get-all-organization-repository-rulesets func (s *OrganizationsService) GetAllOrganizationRulesets(ctx context.Context, org string) ([]*Ruleset, *Response, error) { @@ -30,7 +30,7 @@ func (s *OrganizationsService) GetAllOrganizationRulesets(ctx context.Context, o return rulesets, resp, nil } -// CreateOrganizationRuleset creates a repository ruleset for the specified organization. +// CreateOrganizationRuleset creates a ruleset for the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#create-an-organization-repository-ruleset func (s *OrganizationsService) CreateOrganizationRuleset(ctx context.Context, org string, rs *Ruleset) (*Ruleset, *Response, error) { @@ -50,7 +50,7 @@ func (s *OrganizationsService) CreateOrganizationRuleset(ctx context.Context, or return ruleset, resp, nil } -// GetOrganizationRuleset gets a repository ruleset from the specified organization. +// GetOrganizationRuleset gets a ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#get-an-organization-repository-ruleset func (s *OrganizationsService) GetOrganizationRuleset(ctx context.Context, org string, rulesetID int64) (*Ruleset, *Response, error) { @@ -70,7 +70,7 @@ func (s *OrganizationsService) GetOrganizationRuleset(ctx context.Context, org s return rulesets, resp, nil } -// UpdateOrganizationRuleset updates a repository ruleset from the specified organization. +// UpdateOrganizationRuleset updates a ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#update-an-organization-repository-ruleset func (s *OrganizationsService) UpdateOrganizationRuleset(ctx context.Context, org string, rulesetID int64, rs *Ruleset) (*Ruleset, *Response, error) { @@ -90,7 +90,7 @@ func (s *OrganizationsService) UpdateOrganizationRuleset(ctx context.Context, or return rulesets, resp, nil } -// DeleteOrganizationRuleset deletes a repository ruleset from the specified organization. +// DeleteOrganizationRuleset deletes a ruleset from the specified organization. // // GitHub API docs: https://docs.github.com/en/rest/orgs/rules#delete-an-organization-repository-ruleset func (s *OrganizationsService) DeleteOrganizationRuleset(ctx context.Context, org string, rulesetID int64) (*Response, error) { diff --git a/github/repos_rules.go b/github/repos_rules.go index cdb1a28304f..83d7eacfe21 100644 --- a/github/repos_rules.go +++ b/github/repos_rules.go @@ -11,7 +11,7 @@ import ( "fmt" ) -// BypassActor represents the bypass actors from a repository ruleset. +// BypassActor represents the bypass actors from a ruleset. type BypassActor struct { ActorID int64 `json:"actor_id,omitempty"` // Possible values for ActorType are: Team, Integration @@ -47,7 +47,7 @@ type RulesetConditions struct { RepositoryName *RulesetRepositoryConditionParameters `json:"repository_name,omitempty"` } -// RulePatternParameters represents the rule pattern parameter. +// RulePatternParameters represents the rule pattern parameters. type RulePatternParameters struct { Name *string `json:"name,omitempty"` // If Negate is true, the rule will fail if the pattern matches. @@ -88,7 +88,7 @@ type RequiredStatusChecksRuleParameters struct { StrictRequiredStatusChecksPolicy bool `json:"strict_required_status_checks_policy"` } -// RepositoryRule represents a GitHub Rule within a Ruleset. +// RepositoryRule represents a GitHub Rule. type RepositoryRule struct { Type string `json:"type"` Parameters interface{} `json:"parameters,omitempty"` @@ -147,14 +147,14 @@ func (r *RepositoryRule) UnmarshalJSON(data []byte) error { return nil } -// NewCreationRule creates a rule as part of a GitHub ruleset to only allow users with bypass permission to create matching refs. +// NewCreationRule creates a rule to only allow users with bypass permission to create matching refs. func NewCreationRule() (rule RepositoryRule) { return RepositoryRule{ Type: "creation", } } -// NewUpdateRule creates a rule as part of a GitHub ruleset to only allow users with bypass permission to update matching refs. +// NewUpdateRule creates a rule to only allow users with bypass permission to update matching refs. func NewUpdateRule(params *UpdateAllowsFetchAndMergeRuleParameters) (rule RepositoryRule) { return RepositoryRule{ Type: "update", @@ -162,21 +162,21 @@ func NewUpdateRule(params *UpdateAllowsFetchAndMergeRuleParameters) (rule Reposi } } -// NewDeletionRule creates a rule as part of a GitHub ruleset to only allow users with bypass permissions to delete matching refs. +// NewDeletionRule creates a rule to only allow users with bypass permissions to delete matching refs. func NewDeletionRule() (rule RepositoryRule) { return RepositoryRule{ Type: "deletion", } } -// NewRequiredLinearHistoryRule creates a rule as part of a GitHub ruleset to prevent merge commits from being pushed to matching branches. +// NewRequiredLinearHistoryRule creates a rule to prevent merge commits from being pushed to matching branches. func NewRequiredLinearHistoryRule() (rule RepositoryRule) { return RepositoryRule{ Type: "required_linear_history", } } -// NewRequiredDeploymentsRule creates a rule as part of a GitHub ruleset to require environments to be successfully deployed before they can be merged into the matching branches. +// NewRequiredDeploymentsRule creates a rule to require environments to be successfully deployed before they can be merged into the matching branches. func NewRequiredDeploymentsRule(params *RequiredDeploymentEnvironmentsRuleParameters) (rule RepositoryRule) { return RepositoryRule{ Type: "required_deployments", @@ -184,14 +184,14 @@ func NewRequiredDeploymentsRule(params *RequiredDeploymentEnvironmentsRuleParame } } -// NewRequiredSignaturesRule creates a rule as part of a GitHub ruleset to require commits pushed to matching branches to have verified signatures. +// NewRequiredSignaturesRule creates a rule a to require commits pushed to matching branches to have verified signatures. func NewRequiredSignaturesRule() (rule RepositoryRule) { return RepositoryRule{ Type: "required_signatures", } } -// NewPullRequestRule creates a rule as part of a GitHub ruleset to require all commits be made to a non-target branch and submitted via a pull request before they can be merged. +// NewPullRequestRule creates a rule to require all commits be made to a non-target branch and submitted via a pull request before they can be merged. func NewPullRequestRule(params *PullRequestRuleParameters) ( rule RepositoryRule) { return RepositoryRule{ @@ -200,7 +200,7 @@ func NewPullRequestRule(params *PullRequestRuleParameters) ( } } -// NewRequiredStatusChecksRule creates a rule as part of a GitHub ruleset to require which status checks must pass before branches can be merged into a branch rule. +// NewRequiredStatusChecksRule creates a rule to require which status checks must pass before branches can be merged into a branch rule. func NewRequiredStatusChecksRule(params *RequiredStatusChecksRuleParameters) (rule RepositoryRule) { return RepositoryRule{ Type: "required_status_checks", @@ -208,14 +208,14 @@ func NewRequiredStatusChecksRule(params *RequiredStatusChecksRuleParameters) (ru } } -// NewNonFastForwardRule creates a rule as part of a GitHub ruleset to prevent users with push access from force pushing to matching branches. +// NewNonFastForwardRule creates a rule as part to prevent users with push access from force pushing to matching branches. func NewNonFastForwardRule() (rule RepositoryRule) { return RepositoryRule{ Type: "non_fast_forward", } } -// NewCommitMessagePatternRule creates a rule as part of a GitHub ruleset to restrict commit message patterns being pushed to matching branches. +// NewCommitMessagePatternRule creates a rule to restrict commit message patterns being pushed to matching branches. func NewCommitMessagePatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { return RepositoryRule{ Type: "commit_message_pattern", @@ -223,7 +223,7 @@ func NewCommitMessagePatternRule(pattern *RulePatternParameters) (rule Repositor } } -// NewCommitAuthorEmailPatternRule creates a rule as part of a GitHub ruleset to restrict commits with author email patterns being merged into matching branches. +// NewCommitAuthorEmailPatternRule creates a rule to restrict commits with author email patterns being merged into matching branches. func NewCommitAuthorEmailPatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { return RepositoryRule{ Type: "commit_author_email_pattern", @@ -231,7 +231,7 @@ func NewCommitAuthorEmailPatternRule(pattern *RulePatternParameters) (rule Repos } } -// NewCommitterEmailPatternRule creates a rule as part of a GitHub ruleset to restrict commits with committer email patterns being merged into matching branches. +// NewCommitterEmailPatternRule creates a rule to restrict commits with committer email patterns being merged into matching branches. func NewCommitterEmailPatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { return RepositoryRule{ Type: "committer_email_pattern", @@ -239,6 +239,7 @@ func NewCommitterEmailPatternRule(pattern *RulePatternParameters) (rule Reposito } } +// NewBranchNamePatternRule creates a rule to restrict branch patterns from being merged into matching branches. func NewBranchNamePatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { return RepositoryRule{ Type: "branch_name_pattern", @@ -246,6 +247,7 @@ func NewBranchNamePatternRule(pattern *RulePatternParameters) (rule RepositoryRu } } +// NewTagNamePatternRule creates a rule to restrict tag patterns contained in non-target branches from being merged into matching branches. func NewTagNamePatternRule(pattern *RulePatternParameters) (rule RepositoryRule) { return RepositoryRule{ Type: "tag_name_pattern", @@ -273,7 +275,7 @@ type Ruleset struct { Rules *[]RepositoryRule `json:"rules,omitempty"` } -// GetRulesForBranch gets all the repository rules that apply to the specified branch. +// GetRulesForBranch gets all the rules that apply to the specified branch. // // GitHub API docs: https://docs.github.com/en/rest/repos/rules#get-rules-for-a-branch func (s *RepositoriesService) GetRulesForBranch(ctx context.Context, owner, repo, branch string) ([]*RepositoryRule, *Response, error) { @@ -293,11 +295,12 @@ func (s *RepositoriesService) GetRulesForBranch(ctx context.Context, owner, repo return rules, resp, nil } -// GetAllRepositoryRulesets gets all the repository rules that apply to the specified repository. +// GetAllRulesets gets all the rules that apply to the specified repository. +// If includesParents is true, rulesets configured at the organisation level that apply to the repository will be returned. // // GitHub API docs: https://docs.github.com/en/rest/repos/rules#get-all-repository-rulesets -func (s *RepositoriesService) GetAllRulesets(ctx context.Context, owner, repo string, includesParent bool) ([]*Ruleset, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/rulesets?includes_parents=%v", owner, repo, includesParent) +func (s *RepositoriesService) GetAllRulesets(ctx context.Context, owner, repo string, includesParents bool) ([]*Ruleset, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/rulesets?includes_parents=%v", owner, repo, includesParents) req, err := s.client.NewRequest("GET", u, nil) if err != nil { @@ -334,11 +337,11 @@ func (s *RepositoriesService) CreateRuleset(ctx context.Context, owner, repo str } // GetRuleset gets a ruleset for the specified repository. -// If includesParent is true, rulesets configured at organisation level that apply to the repository can be retrieved. +// If includesParents is true, rulesets configured at the organisation level that apply to the repository will be returned. // // GitHub API docs: https://docs.github.com/en/rest/repos/rules#get-a-repository-ruleset -func (s *RepositoriesService) GetRuleset(ctx context.Context, owner, repo string, rulesetID int64, includesParent bool) (*Ruleset, *Response, error) { - u := fmt.Sprintf("repos/%v/%v/rulesets/%v?includes_parents=%v", owner, repo, rulesetID, includesParent) +func (s *RepositoriesService) GetRuleset(ctx context.Context, owner, repo string, rulesetID int64, includesParents bool) (*Ruleset, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/rulesets/%v?includes_parents=%v", owner, repo, rulesetID, includesParents) req, err := s.client.NewRequest("GET", u, nil) if err != nil {