Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[tool.ruff]
# CONTRIBUTING.md has documented this selection since the lint gate was introduced,
# but no config file ever enforced it, so `ruff check .` ran with whatever the
# installed ruff version defaults to. With `ruff>=0.6` in requirements-dev.txt, a new
# ruff release can therefore start failing CI on untouched code — which is exactly
# what happened: main was green, and the next PR (docs only) went red on SIM102 and
# PLW1510 findings in scripts/apply-settings.py.
#
# Pinning the rule selection instead of pinning ruff keeps the `>=` minimums policy
# in section "Dependencies" intact while making the gate deterministic. Widening this
# list is a deliberate policy change: do it in a PR that also fixes the findings.
lint.select = ["E", "F", "I", "W"]
21 changes: 14 additions & 7 deletions scripts/apply-settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ def delete_legacy_protection(repo: str, branch: str) -> None:
capture_output=True, text=True,
)
if result.returncode == 0:
print(f" OK removed legacy branch protection on '{branch}' (superseded by ruleset)")
print(f" OK removed legacy branch protection on '{branch}' "
f"(superseded by ruleset)")


def apply_branch_protection(repo: str, branch: str, protection: dict) -> None:
Expand Down Expand Up @@ -190,7 +191,9 @@ def verify_branch_protection(repo: str, branch: str, protection: dict) -> bool:
continue
got = actual_flat.get(key)
if isinstance(expected, dict) and isinstance(got, dict):
mismatch = {k: (got.get(k), v) for k, v in expected.items() if got.get(k) != v}
mismatch = {
k: (got.get(k), v) for k, v in expected.items() if got.get(k) != v
}
sub_ok = not mismatch
marker = "OK " if sub_ok else "FAIL"
print(f" {marker} branches.{branch}.{key}: "
Expand All @@ -200,7 +203,8 @@ def verify_branch_protection(repo: str, branch: str, protection: dict) -> bool:
else:
sub_ok = got == expected
marker = "OK " if sub_ok else "FAIL"
print(f" {marker} branches.{branch}.{key}: {got!r} (expected {expected!r})")
print(f" {marker} branches.{branch}.{key}: {got!r} "
f"(expected {expected!r})")
if not sub_ok:
ok = False
return ok
Expand Down Expand Up @@ -232,8 +236,9 @@ def main(argv: list[str]) -> int:
is_public = get_repo_visibility(repo) == "public"

if is_public and rulesets_block:
# Public repos: rulesets with bypass actors for admin force-push break-glass.
# Legacy branch protection is removed so it can't silently override the ruleset.
# Public repos: rulesets with bypass actors for admin force-push
# break-glass. Legacy branch protection is removed so it can't
# silently override the ruleset.
for ruleset in rulesets_block:
try:
apply_ruleset(repo, ruleset)
Expand All @@ -250,7 +255,8 @@ def main(argv: list[str]) -> int:
if branch:
delete_legacy_protection(repo, branch)
else:
# Private repos: attempt legacy branch protection (expected to fail on Free plan).
# Private repos: attempt legacy branch protection (expected to fail
# on the Free plan).
for entry in branches_block:
branch = entry.get("name")
protection = entry.get("protection") or {}
Expand All @@ -264,7 +270,8 @@ def main(argv: list[str]) -> int:
# failure — the repo stays aligned on every merge-method
# field. Skip without failing the run. (If the plan is later
# upgraded, the PUT succeeds and verify below applies.)
print(f" SKIP branches.{branch}: PUT failed (exit {e.returncode}). "
print(f" SKIP branches.{branch}: PUT failed "
f"(exit {e.returncode}). "
f"Expected for a private repo on a plan without branch "
f"protection; merge-method settings above still applied.")
continue
Expand Down
5 changes: 4 additions & 1 deletion tests/test_apply_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,10 @@ def test_missing_key_becomes_none(self):
assert apply_settings._flatten_protection({})["enforce_admins"] is None

def test_non_wrapper_dict_passes_through_unchanged(self):
reviews = {"required_approving_review_count": 1, "require_code_owner_reviews": True}
reviews = {
"required_approving_review_count": 1,
"require_code_owner_reviews": True,
}
actual = {"required_pull_request_reviews": reviews}
flat = apply_settings._flatten_protection(actual)
assert flat["required_pull_request_reviews"] == reviews
Expand Down
Loading