Skip to content

Commit fe726ea

Browse files
authored
Merge branch 'main' into dependabot-alert
2 parents 0e9988e + e47c153 commit fe726ea

11 files changed

+153
-7
lines changed

github/Branch.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ def edit_protection(
149149
teams_bypass_pull_request_allowances: Opt[list[str]] = NotSet,
150150
apps_bypass_pull_request_allowances: Opt[list[str]] = NotSet,
151151
block_creations: Opt[bool] = NotSet,
152+
require_last_push_approval: Opt[bool] = NotSet,
153+
allow_deletions: Opt[bool] = NotSet,
152154
) -> BranchProtection:
153155
"""
154156
:calls: `PUT /repos/{owner}/{repo}/branches/{branch}/protection <https://docs.github.com/en/rest/reference/repos#get-branch-protection>`_
@@ -174,6 +176,8 @@ def edit_protection(
174176
assert is_optional_list(users_bypass_pull_request_allowances, str), users_bypass_pull_request_allowances
175177
assert is_optional_list(teams_bypass_pull_request_allowances, str), teams_bypass_pull_request_allowances
176178
assert is_optional_list(apps_bypass_pull_request_allowances, str), apps_bypass_pull_request_allowances
179+
assert is_optional(require_last_push_approval, bool), require_last_push_approval
180+
assert is_optional(allow_deletions, bool), allow_deletions
177181

178182
post_parameters: dict[str, Any] = {}
179183
if is_defined(strict) or is_defined(contexts):
@@ -203,6 +207,7 @@ def edit_protection(
203207
or is_defined(users_bypass_pull_request_allowances)
204208
or is_defined(teams_bypass_pull_request_allowances)
205209
or is_defined(apps_bypass_pull_request_allowances)
210+
or is_defined(require_last_push_approval)
206211
):
207212
post_parameters["required_pull_request_reviews"] = {}
208213
if is_defined(dismiss_stale_reviews):
@@ -215,6 +220,10 @@ def edit_protection(
215220
post_parameters["required_pull_request_reviews"][
216221
"required_approving_review_count"
217222
] = required_approving_review_count
223+
if is_defined(require_last_push_approval):
224+
post_parameters["required_pull_request_reviews"][
225+
"require_last_push_approval"
226+
] = require_last_push_approval
218227

219228
dismissal_restrictions = {}
220229
if is_defined(dismissal_users):
@@ -283,6 +292,10 @@ def edit_protection(
283292
post_parameters["block_creations"] = block_creations
284293
else:
285294
post_parameters["block_creations"] = None
295+
if is_defined(allow_deletions):
296+
post_parameters["allow_deletions"] = allow_deletions
297+
else:
298+
post_parameters["allow_deletions"] = None
286299

287300
headers, data = self._requester.requestJsonAndCheck(
288301
"PUT",
@@ -360,6 +373,7 @@ def edit_required_pull_request_reviews(
360373
dismiss_stale_reviews: Opt[bool] = NotSet,
361374
require_code_owner_reviews: Opt[bool] = NotSet,
362375
required_approving_review_count: Opt[int] = NotSet,
376+
require_last_push_approval: Opt[bool] = NotSet,
363377
) -> RequiredStatusChecks:
364378
"""
365379
:calls: `PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews <https://docs.github.com/en/rest/reference/repos#branches>`_
@@ -369,12 +383,14 @@ def edit_required_pull_request_reviews(
369383
assert is_optional(dismiss_stale_reviews, bool), dismiss_stale_reviews
370384
assert is_optional(require_code_owner_reviews, bool), require_code_owner_reviews
371385
assert is_optional(required_approving_review_count, int), required_approving_review_count
386+
assert is_optional(require_last_push_approval, bool), require_last_push_approval
372387

373388
post_parameters: dict[str, Any] = NotSet.remove_unset_items(
374389
{
375390
"dismiss_stale_reviews": dismiss_stale_reviews,
376391
"require_code_owner_reviews": require_code_owner_reviews,
377392
"required_approving_review_count": required_approving_review_count,
393+
"require_last_push_approval": require_last_push_approval,
378394
}
379395
)
380396

@@ -546,3 +562,22 @@ def remove_required_signatures(self) -> None:
546562
f"{self.protection_url}/required_signatures",
547563
headers={"Accept": Consts.signaturesProtectedBranchesPreview},
548564
)
565+
566+
def get_allow_deletions(self) -> bool:
567+
"""
568+
:calls: `GET /repos/{owner}/{repo}/branches/{branch}/protection/allow_deletions <https://docs.github.com/en/rest/reference/repos#branches>`_
569+
"""
570+
headers, data = self._requester.requestJsonAndCheck("GET", f"{self.protection_url}/allow_deletions")
571+
return data["enabled"]
572+
573+
def set_allow_deletions(self) -> None:
574+
"""
575+
:calls: `POST /repos/{owner}/{repo}/branches/{branch}/protection/allow_deletions <https://docs.github.com/en/rest/reference/repos#branches>`_
576+
"""
577+
headers, data = self._requester.requestJsonAndCheck("POST", f"{self.protection_url}/allow_deletions")
578+
579+
def remove_allow_deletions(self) -> None:
580+
"""
581+
:calls: `DELETE /repos/{owner}/{repo}/branches/{branch}/protection/allow_deletions <https://docs.github.com/en/rest/reference/repos#branches>`_
582+
"""
583+
headers, data = self._requester.requestJsonAndCheck("DELETE", f"{self.protection_url}/allow_deletions")

github/BranchProtection.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,43 @@ def __repr__(self) -> str:
5656

5757
def _initAttributes(self) -> None:
5858
self._url: Attribute[str] = NotSet
59+
self._allow_deletions: Attribute[bool] = NotSet
60+
self._allow_force_pushes: Attribute[bool] = NotSet
61+
self._allow_fork_syncing: Attribute[bool] = NotSet
62+
self._lock_branch: Attribute[bool] = NotSet
63+
self._required_conversation_resolution: Attribute[bool] = NotSet
5964
self._required_status_checks: Attribute[RequiredStatusChecks] = NotSet
6065
self._enforce_admins: Attribute[bool] = NotSet
6166
self._required_linear_history: Attribute[bool] = github.GithubObject.NotSet
6267
self._required_pull_request_reviews: Attribute[RequiredPullRequestReviews] = NotSet
6368
self._user_push_restrictions: Opt[str] = NotSet
6469
self._team_push_restrictions: Opt[str] = NotSet
6570

71+
@property
72+
def allow_deletions(self) -> bool:
73+
self._completeIfNotSet(self._allow_deletions)
74+
return self._allow_deletions.value
75+
76+
@property
77+
def allow_force_pushes(self) -> bool:
78+
self._completeIfNotSet(self._allow_force_pushes)
79+
return self._allow_force_pushes.value
80+
81+
@property
82+
def allow_fork_syncing(self) -> bool:
83+
self._completeIfNotSet(self._allow_fork_syncing)
84+
return self._allow_fork_syncing.value
85+
86+
@property
87+
def lock_branch(self) -> bool:
88+
self._completeIfNotSet(self._lock_branch)
89+
return self._lock_branch.value
90+
91+
@property
92+
def required_conversation_resolution(self) -> bool:
93+
self._completeIfNotSet(self._required_conversation_resolution)
94+
return self._required_conversation_resolution.value
95+
6696
@property
6797
def url(self) -> str:
6898
self._completeIfNotSet(self._url)
@@ -104,6 +134,18 @@ def get_team_push_restrictions(self) -> PaginatedList[Team] | None:
104134
return github.PaginatedList.PaginatedList(github.Team.Team, self._requester, self._team_push_restrictions, None)
105135

106136
def _useAttributes(self, attributes: dict[str, Any]) -> None:
137+
if "allow_deletions" in attributes: # pragma no branch
138+
self._allow_deletions = self._makeBoolAttribute(attributes["allow_deletions"]["enabled"])
139+
if "allow_force_pushes" in attributes: # pragma no branch
140+
self._allow_force_pushes = self._makeBoolAttribute(attributes["allow_force_pushes"]["enabled"])
141+
if "allow_fork_syncing" in attributes: # pragma no branch
142+
self._allow_fork_syncing = self._makeBoolAttribute(attributes["allow_fork_syncing"]["enabled"])
143+
if "lock_branch" in attributes: # pragma no branch
144+
self._lock_branch = self._makeBoolAttribute(attributes["lock_branch"]["enabled"])
145+
if "required_conversation_resolution" in attributes: # pragma no branch
146+
self._required_conversation_resolution = self._makeBoolAttribute(
147+
attributes["required_conversation_resolution"]["enabled"]
148+
)
107149
if "url" in attributes: # pragma no branch
108150
self._url = self._makeStringAttribute(attributes["url"])
109151
if "required_status_checks" in attributes: # pragma no branch

github/RequiredPullRequestReviews.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,15 @@ def _initAttributes(self) -> None:
6262
self._required_approving_review_count: Attribute[int] = NotSet
6363
self._users: Attribute[list[NamedUser]] = NotSet
6464
self._teams: Attribute[list[Team]] = NotSet
65+
self._require_last_push_approval: Attribute[bool] = NotSet
6566

6667
def __repr__(self) -> str:
6768
return self.get__repr__(
6869
{
6970
"url": self._url.value,
7071
"dismiss_stale_reviews": self._dismiss_stale_reviews.value,
7172
"require_code_owner_reviews": self._require_code_owner_reviews.value,
73+
"require_last_push_approval": self._require_last_push_approval.value,
7274
}
7375
)
7476

@@ -87,6 +89,11 @@ def required_approving_review_count(self) -> int:
8789
self._completeIfNotSet(self._required_approving_review_count)
8890
return self._required_approving_review_count.value
8991

92+
@property
93+
def require_last_push_approval(self) -> bool:
94+
self._completeIfNotSet(self._require_last_push_approval)
95+
return self._require_last_push_approval.value
96+
9097
@property
9198
def url(self) -> str:
9299
self._completeIfNotSet(self._url)
@@ -121,5 +128,7 @@ def _useAttributes(self, attributes: dict[str, Any]) -> None:
121128
self._required_approving_review_count = self._makeIntAttribute(
122129
attributes["required_approving_review_count"]
123130
)
131+
if "require_last_push_approval" in attributes: # pragma no branch
132+
self._require_last_push_approval = self._makeBoolAttribute(attributes["require_last_push_approval"])
124133
if "url" in attributes: # pragma no branch
125134
self._url = self._makeStringAttribute(attributes["url"])

tests/Branch.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,21 @@ def testEditProtection(self):
6464
strict=True,
6565
require_code_owner_reviews=True,
6666
required_approving_review_count=2,
67+
require_last_push_approval=True,
6768
)
6869
branch_protection = self.protected_branch.get_protection()
6970
self.assertTrue(branch_protection.required_status_checks.strict)
7071
self.assertEqual(branch_protection.required_status_checks.contexts, [])
7172
self.assertTrue(branch_protection.enforce_admins)
7273
self.assertFalse(branch_protection.required_linear_history)
74+
self.assertFalse(branch_protection.allow_deletions)
7375
self.assertFalse(branch_protection.required_pull_request_reviews.dismiss_stale_reviews)
7476
self.assertTrue(branch_protection.required_pull_request_reviews.require_code_owner_reviews)
7577
self.assertEqual(
7678
branch_protection.required_pull_request_reviews.required_approving_review_count,
7779
2,
7880
)
81+
self.assertTrue(branch_protection.required_pull_request_reviews.require_last_push_approval)
7982

8083
def testEditProtectionDismissalUsersWithUserOwnedBranch(self):
8184
with self.assertRaises(github.GithubException) as raisedexp:
@@ -160,7 +163,8 @@ def testRemoveRequiredStatusChecks(self):
160163

161164
def testEditRequiredPullRequestReviews(self):
162165
self.protected_branch.edit_required_pull_request_reviews(
163-
dismiss_stale_reviews=True, required_approving_review_count=2
166+
dismiss_stale_reviews=True,
167+
required_approving_review_count=2,
164168
)
165169
required_pull_request_reviews = self.protected_branch.get_required_pull_request_reviews()
166170
self.assertTrue(required_pull_request_reviews.dismiss_stale_reviews)
@@ -197,13 +201,20 @@ def testRemoveRequiredPullRequestReviews(self):
197201
self.assertFalse(required_pull_request_reviews.dismiss_stale_reviews)
198202
self.assertFalse(required_pull_request_reviews.require_code_owner_reviews)
199203
self.assertEqual(required_pull_request_reviews.required_approving_review_count, 1)
204+
self.assertFalse(required_pull_request_reviews.require_last_push_approval)
200205

201206
def testAdminEnforcement(self):
202207
self.protected_branch.remove_admin_enforcement()
203208
self.assertFalse(self.protected_branch.get_admin_enforcement())
204209
self.protected_branch.set_admin_enforcement()
205210
self.assertTrue(self.protected_branch.get_admin_enforcement())
206211

212+
def testAllowDeletions(self):
213+
self.protected_branch.set_allow_deletions()
214+
self.assertTrue(self.protected_branch.get_allow_deletions())
215+
self.protected_branch.remove_allow_deletions()
216+
self.assertFalse(self.protected_branch.get_allow_deletions())
217+
207218
def testAddUserPushRestrictions(self):
208219
self.organization_branch.add_user_push_restrictions("sfdye")
209220
self.assertListKeyEqual(

tests/BranchProtection.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,8 @@ def testAttributes(self):
5252
self.branch_protection.__repr__(),
5353
'BranchProtection(url="https://api.github.com/repos/curvewise-forks/PyGithub/branches/master/protection")',
5454
)
55+
self.assertFalse(self.branch_protection.allow_force_pushes)
56+
self.assertFalse(self.branch_protection.allow_deletions)
57+
self.assertFalse(self.branch_protection.required_conversation_resolution)
58+
self.assertFalse(self.branch_protection.lock_branch)
59+
self.assertFalse(self.branch_protection.allow_fork_syncing)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
https
2+
POST
3+
api.github.com
4+
None
5+
/repos/jacquev6/PyGithub/branches/integrations/protection/allow_deletions
6+
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
7+
None
8+
200
9+
[('strict-transport-security', 'max-age=31536000; includeSubdomains; preload'), ('vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('x-oauth-scopes', 'public_repo, repo:status'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('x-accepted-oauth-scopes', ''), ('etag', 'W/"5ebb2cbbb268262fba4eade23df2ed85"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('referrer-policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('status', '200 OK'), ('x-ratelimit-remaining', '4975'), ('x-github-media-type', 'github.v3; format=json'), ('access-control-expose-headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('transfer-encoding', 'chunked'), ('x-github-request-id', '935C:2DD6:186AD1F:1F9B1CD:5AF58E17'), ('date', 'Fri, 11 May 2018 12:35:51 GMT'), ('access-control-allow-origin', '*'), ('content-security-policy', "default-src 'none'"), ('content-encoding', 'gzip'), ('x-runtime-rack', '0.035550'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('x-frame-options', 'deny'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1526042267')]
10+
''
11+
12+
https
13+
GET
14+
api.github.com
15+
None
16+
/repos/jacquev6/PyGithub/branches/integrations/protection/allow_deletions
17+
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
18+
None
19+
200
20+
[('strict-transport-security', 'max-age=31536000; includeSubdomains; preload'), ('vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('x-oauth-scopes', 'public_repo, repo:status'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('x-accepted-oauth-scopes', ''), ('etag', 'W/"7e30c47ab395fea0aa2cb8f9c487c7be"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('referrer-policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('status', '200 OK'), ('x-ratelimit-remaining', '4998'), ('x-github-media-type', 'github.v3; format=json'), ('access-control-expose-headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('transfer-encoding', 'chunked'), ('x-github-request-id', '92CC:2DD0:1360C19:194AF93:5AF58EA4'), ('date', 'Fri, 11 May 2018 12:38:01 GMT'), ('access-control-allow-origin', '*'), ('content-security-policy', "default-src 'none'"), ('content-encoding', 'gzip'), ('x-runtime-rack', '0.038876'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('x-frame-options', 'deny'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1526045876')]
21+
{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/add-pr-review-request/protection/allow_deletions","enabled":true}
22+
23+
https
24+
DELETE
25+
api.github.com
26+
None
27+
/repos/jacquev6/PyGithub/branches/integrations/protection/allow_deletions
28+
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
29+
None
30+
204
31+
[('status', '204 No Content'), ('x-ratelimit-remaining', '4994'), ('content-length', '330'), ('server', 'nginx/1.0.13'), ('connection', 'keep-alive'), ('x-ratelimit-limit', '5000'), ('etag', '"2dada6dafd332016bcdf06e42487e520"'), ('date', 'Thu, 10 May 2012 13:56:55 GMT'), ('content-type', 'application/json; charset=utf-8')]
32+
33+
34+
https
35+
GET
36+
api.github.com
37+
None
38+
/repos/jacquev6/PyGithub/branches/integrations/protection/allow_deletions
39+
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
40+
None
41+
200
42+
[('strict-transport-security', 'max-age=31536000; includeSubdomains; preload'), ('vary', 'Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding'), ('x-oauth-scopes', 'public_repo, repo:status'), ('x-xss-protection', '1; mode=block'), ('x-content-type-options', 'nosniff'), ('x-accepted-oauth-scopes', ''), ('etag', 'W/"5ebb2cbbb268262fba4eade23df2ed85"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('referrer-policy', 'origin-when-cross-origin, strict-origin-when-cross-origin'), ('status', '200 OK'), ('x-ratelimit-remaining', '4975'), ('x-github-media-type', 'github.v3; format=json'), ('access-control-expose-headers', 'ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval'), ('transfer-encoding', 'chunked'), ('x-github-request-id', '935C:2DD6:186AD1F:1F9B1CD:5AF58E17'), ('date', 'Fri, 11 May 2018 12:35:41 GMT'), ('access-control-allow-origin', '*'), ('content-security-policy', "default-src 'none'"), ('content-encoding', 'gzip'), ('x-runtime-rack', '0.035550'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('x-frame-options', 'deny'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1526042267')]
43+
{"url":"https://api.github.com/repos/jacquev6/PyGithub/branches/add-pr-review-request/protection/allow_deletion","enabled":false}

0 commit comments

Comments
 (0)