Skip to content

Commit 34bb848

Browse files
feat!: Use omitzero for BypassActors to support handling empty arrays (#3891)
BREAKING CHANGE: `UpdateRepositoryRulesetClearBypassActor`, `UpdateRepositoryRulesetClearBypassActor`, `UpdateRulesetClearBypassActor`, and `UpdateRulesetNoBypassActor` have been removed as they are no longer needed.
1 parent e85e1dc commit 34bb848

File tree

7 files changed

+176
-345
lines changed

7 files changed

+176
-345
lines changed

github/enterprise_rules.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -76,33 +76,6 @@ func (s *EnterpriseService) UpdateRepositoryRuleset(ctx context.Context, enterpr
7676
return rs, resp, nil
7777
}
7878

79-
// UpdateRepositoryRulesetClearBypassActor clears the bypass actors for a repository ruleset for the specified enterprise.
80-
//
81-
// This function is necessary as the UpdateRepositoryRuleset function does not marshal ByPassActor if passed as an empty array.
82-
//
83-
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#update-an-enterprise-repository-ruleset
84-
//
85-
//meta:operation PUT /enterprises/{enterprise}/rulesets/{ruleset_id}
86-
func (s *EnterpriseService) UpdateRepositoryRulesetClearBypassActor(ctx context.Context, enterprise string, rulesetID int64) (*Response, error) {
87-
u := fmt.Sprintf("enterprises/%v/rulesets/%v", enterprise, rulesetID)
88-
89-
rsClearBypassActor := rulesetClearBypassActors{
90-
BypassActors: []*BypassActor{},
91-
}
92-
93-
req, err := s.client.NewRequest("PUT", u, rsClearBypassActor)
94-
if err != nil {
95-
return nil, err
96-
}
97-
98-
resp, err := s.client.Do(ctx, req, nil)
99-
if err != nil {
100-
return resp, err
101-
}
102-
103-
return resp, nil
104-
}
105-
10679
// DeleteRepositoryRuleset deletes a repository ruleset from the specified enterprise.
10780
//
10881
// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/enterprise-admin/rules#delete-an-enterprise-repository-ruleset

github/enterprise_rules_test.go

Lines changed: 56 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package github
77

88
import (
9+
"encoding/json"
910
"fmt"
1011
"net/http"
1112
"testing"
@@ -384,6 +385,61 @@ func TestEnterpriseService_CreateRepositoryRuleset_OrgNameRepoName(t *testing.T)
384385
})
385386
}
386387

388+
func TestEnterpriseService_UpdateRepositoryRuleset_OmitZero_Nil(t *testing.T) {
389+
t.Parallel()
390+
client, mux, _ := setup(t)
391+
392+
mux.HandleFunc("/enterprises/e/rulesets/84", func(w http.ResponseWriter, r *http.Request) {
393+
testMethod(t, r, "PUT")
394+
395+
var v map[string]any
396+
if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
397+
t.Errorf("could not decode body: %v", err)
398+
}
399+
400+
if _, ok := v["bypass_actors"]; ok {
401+
t.Error("Request body contained 'bypass_actors', expected it to be omitted")
402+
}
403+
404+
fmt.Fprint(w, `{"id": 84, "name": "test ruleset"}`)
405+
})
406+
407+
ctx := t.Context()
408+
input := RepositoryRuleset{
409+
Name: "test ruleset",
410+
BypassActors: nil,
411+
}
412+
413+
_, _, err := client.Enterprise.UpdateRepositoryRuleset(ctx, "e", 84, input)
414+
if err != nil {
415+
t.Errorf("Enterprise.UpdateRepositoryRuleset returned error: %v", err)
416+
}
417+
}
418+
419+
func TestEnterpriseService_UpdateRepositoryRuleset_OmitZero_EmptySlice(t *testing.T) {
420+
t.Parallel()
421+
client, mux, _ := setup(t)
422+
423+
mux.HandleFunc("/enterprises/e/rulesets/84", func(w http.ResponseWriter, r *http.Request) {
424+
testMethod(t, r, "PUT")
425+
426+
testBody(t, r, `{"name":"test ruleset","source":"","enforcement":"","bypass_actors":[]}`+"\n")
427+
428+
fmt.Fprint(w, `{"id": 84, "name": "test ruleset", "bypass_actors": []}`)
429+
})
430+
431+
ctx := t.Context()
432+
input := RepositoryRuleset{
433+
Name: "test ruleset",
434+
BypassActors: []*BypassActor{},
435+
}
436+
437+
_, _, err := client.Enterprise.UpdateRepositoryRuleset(ctx, "e", 84, input)
438+
if err != nil {
439+
t.Errorf("Enterprise.UpdateRepositoryRuleset returned error: %v", err)
440+
}
441+
}
442+
387443
func TestEnterpriseService_CreateRepositoryRuleset_OrgNameRepoProperty(t *testing.T) {
388444
t.Parallel()
389445
client, mux, _ := setup(t)
@@ -1769,73 +1825,6 @@ func TestEnterpriseService_UpdateRepositoryRuleset(t *testing.T) {
17691825
})
17701826
}
17711827

1772-
func TestEnterpriseService_UpdateRepositoryRulesetClearBypassActor(t *testing.T) {
1773-
t.Parallel()
1774-
client, mux, _ := setup(t)
1775-
1776-
mux.HandleFunc("/enterprises/e/rulesets/84", func(w http.ResponseWriter, r *http.Request) {
1777-
testMethod(t, r, "PUT")
1778-
testBody(t, r, `{"bypass_actors":[]}`+"\n")
1779-
fmt.Fprint(w, `{
1780-
"id": 84,
1781-
"name": "test ruleset",
1782-
"target": "branch",
1783-
"source_type": "Enterprise",
1784-
"source": "e",
1785-
"enforcement": "active",
1786-
"bypass_mode": "none",
1787-
"conditions": {
1788-
"organization_name": {
1789-
"include": [
1790-
"important_organization",
1791-
"another_important_organization"
1792-
],
1793-
"exclude": [
1794-
"unimportant_organization"
1795-
]
1796-
},
1797-
"repository_name": {
1798-
"include": [
1799-
"important_repository",
1800-
"another_important_repository"
1801-
],
1802-
"exclude": [
1803-
"unimportant_repository"
1804-
],
1805-
"protected": true
1806-
},
1807-
"ref_name": {
1808-
"include": [
1809-
"refs/heads/main",
1810-
"refs/heads/master"
1811-
],
1812-
"exclude": [
1813-
"refs/heads/dev*"
1814-
]
1815-
}
1816-
},
1817-
"rules": [
1818-
{
1819-
"type": "creation"
1820-
}
1821-
]
1822-
}`)
1823-
})
1824-
1825-
ctx := t.Context()
1826-
1827-
_, err := client.Enterprise.UpdateRepositoryRulesetClearBypassActor(ctx, "e", 84)
1828-
if err != nil {
1829-
t.Errorf("Enterprise.UpdateRepositoryRulesetClearBypassActor returned error: %v \n", err)
1830-
}
1831-
1832-
const methodName = "UpdateRepositoryRulesetClearBypassActor"
1833-
1834-
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
1835-
return client.Enterprise.UpdateRepositoryRulesetClearBypassActor(ctx, "e", 84)
1836-
})
1837-
}
1838-
18391828
func TestEnterpriseService_DeleteRepositoryRuleset(t *testing.T) {
18401829
t.Parallel()
18411830
client, mux, _ := setup(t)

github/orgs_rules.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -103,33 +103,6 @@ func (s *OrganizationsService) UpdateRepositoryRuleset(ctx context.Context, org
103103
return rs, resp, nil
104104
}
105105

106-
// UpdateRepositoryRulesetClearBypassActor clears the bypass actors for a repository ruleset for the specified organization.
107-
//
108-
// This function is necessary as the UpdateRepositoryRuleset function does not marshal ByPassActor if passed as an empty array.
109-
//
110-
// GitHub API docs: https://docs.github.com/rest/orgs/rules#update-an-organization-repository-ruleset
111-
//
112-
//meta:operation PUT /orgs/{org}/rulesets/{ruleset_id}
113-
func (s *OrganizationsService) UpdateRepositoryRulesetClearBypassActor(ctx context.Context, org string, rulesetID int64) (*Response, error) {
114-
u := fmt.Sprintf("orgs/%v/rulesets/%v", org, rulesetID)
115-
116-
rsClearBypassActor := rulesetClearBypassActors{
117-
BypassActors: []*BypassActor{},
118-
}
119-
120-
req, err := s.client.NewRequest("PUT", u, rsClearBypassActor)
121-
if err != nil {
122-
return nil, err
123-
}
124-
125-
resp, err := s.client.Do(ctx, req, nil)
126-
if err != nil {
127-
return resp, err
128-
}
129-
130-
return resp, nil
131-
}
132-
133106
// DeleteRepositoryRuleset deletes a repository ruleset from the specified organization.
134107
//
135108
// GitHub API docs: https://docs.github.com/rest/orgs/rules#delete-an-organization-repository-ruleset

github/orgs_rules_test.go

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package github
77

88
import (
9+
"encoding/json"
910
"fmt"
1011
"net/http"
1112
"testing"
@@ -1587,62 +1588,74 @@ func TestOrganizationsService_UpdateRepositoryRulesetWithRepoProp(t *testing.T)
15871588
})
15881589
}
15891590

1590-
func TestOrganizationsService_UpdateRepositoryRulesetClearBypassActor(t *testing.T) {
1591+
func TestOrganizationsService_UpdateRepositoryRuleset_OmitZero_Nil(t *testing.T) {
15911592
t.Parallel()
15921593
client, mux, _ := setup(t)
15931594

15941595
mux.HandleFunc("/orgs/o/rulesets/21", func(w http.ResponseWriter, r *http.Request) {
15951596
testMethod(t, r, "PUT")
1596-
testBody(t, r, `{"bypass_actors":[]}`+"\n")
1597+
1598+
var v map[string]any
1599+
if err := json.NewDecoder(r.Body).Decode(&v); err != nil {
1600+
t.Errorf("could not decode body: %v", err)
1601+
}
1602+
1603+
if _, ok := v["bypass_actors"]; ok {
1604+
t.Error("Request body contained 'bypass_actors', expected it to be omitted for nil input")
1605+
}
1606+
15971607
fmt.Fprint(w, `{
15981608
"id": 21,
15991609
"name": "test ruleset",
1600-
"target": "branch",
16011610
"source_type": "Organization",
16021611
"source": "o",
1603-
"enforcement": "active",
1604-
"bypass_mode": "none",
1605-
"conditions": {
1606-
"repository_name": {
1607-
"include": [
1608-
"important_repository",
1609-
"another_important_repository"
1610-
],
1611-
"exclude": [
1612-
"unimportant_repository"
1613-
],
1614-
"protected": true
1615-
},
1616-
"ref_name": {
1617-
"include": [
1618-
"refs/heads/main",
1619-
"refs/heads/master"
1620-
],
1621-
"exclude": [
1622-
"refs/heads/dev*"
1623-
]
1624-
}
1625-
},
1626-
"rules": [
1627-
{
1628-
"type": "creation"
1629-
}
1630-
]
1612+
"enforcement": "active"
16311613
}`)
16321614
})
16331615

16341616
ctx := t.Context()
1617+
input := RepositoryRuleset{
1618+
Name: "test ruleset",
1619+
Enforcement: RulesetEnforcementActive,
1620+
BypassActors: nil,
1621+
}
16351622

1636-
_, err := client.Organizations.UpdateRepositoryRulesetClearBypassActor(ctx, "o", 21)
1623+
_, _, err := client.Organizations.UpdateRepositoryRuleset(ctx, "o", 21, input)
16371624
if err != nil {
1638-
t.Errorf("Organizations.UpdateRepositoryRulesetClearBypassActor returned error: %v \n", err)
1625+
t.Errorf("Organizations.UpdateRepositoryRuleset returned error: %v", err)
16391626
}
1627+
}
16401628

1641-
const methodName = "UpdateRepositoryRulesetClearBypassActor"
1629+
func TestOrganizationsService_UpdateRepositoryRuleset_OmitZero_EmptySlice(t *testing.T) {
1630+
t.Parallel()
1631+
client, mux, _ := setup(t)
16421632

1643-
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
1644-
return client.Organizations.UpdateRepositoryRulesetClearBypassActor(ctx, "o", 21)
1633+
mux.HandleFunc("/orgs/o/rulesets/21", func(w http.ResponseWriter, r *http.Request) {
1634+
testMethod(t, r, "PUT")
1635+
1636+
testBody(t, r, `{"name":"test ruleset","source":"","enforcement":"active","bypass_actors":[]}`+"\n")
1637+
1638+
fmt.Fprint(w, `{
1639+
"id": 21,
1640+
"name": "test ruleset",
1641+
"source_type": "Organization",
1642+
"source": "o",
1643+
"enforcement": "active",
1644+
"bypass_actors": []
1645+
}`)
16451646
})
1647+
1648+
ctx := t.Context()
1649+
input := RepositoryRuleset{
1650+
Name: "test ruleset",
1651+
Enforcement: RulesetEnforcementActive,
1652+
BypassActors: []*BypassActor{},
1653+
}
1654+
1655+
_, _, err := client.Organizations.UpdateRepositoryRuleset(ctx, "o", 21, input)
1656+
if err != nil {
1657+
t.Errorf("Organizations.UpdateRepositoryRuleset returned error: %v", err)
1658+
}
16461659
}
16471660

16481661
func TestOrganizationsService_DeleteRepositoryRuleset(t *testing.T) {

0 commit comments

Comments
 (0)