Skip to content

Commit 07a464a

Browse files
committed
migrate: Fix version ruleset copilot removal
The v0.15.0 migration for the Protect version branches ruleset did not properly remove the Copilot review rule in existing repositories. Add a dedicated migration step to detect and remove the `copilot_code_review` rule. Signed-off-by: Leandro Lucarella <luca-frequenz@llucax.com>
1 parent e9da7af commit 07a464a

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

RELEASE_NOTES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,4 @@ But you might still need to adapt your code:
3535
### Cookiecutter template
3636

3737
- Added a migration step for api repositories to fix `mkdocs.yml` when the previous `mkdocstrings-python` v2 migration moved only `paths: ["src"]` under `handlers.python.options` but not `paths: ["py"]`.
38+
- Added a migration step to remove the copilot review request from the Protect version branch protection rules. This was also done by v0.15.0 i theory, but the migration step was wrong and didn't update it properly.

cookiecutter/migrate.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ def main() -> None:
4141
print("Fixing mkdocstrings-python v2 paths for api repos...")
4242
migrate_api_mkdocs_mkdocstrings_paths()
4343
print("=" * 72)
44+
print("Updating 'Protect version branches' GitHub ruleset...")
45+
migrate_protect_version_branches_ruleset()
46+
print("=" * 72)
4447
print()
4548

4649
if _manual_steps:
@@ -111,6 +114,68 @@ def migrate_api_mkdocs_mkdocstrings_paths() -> None:
111114
)
112115

113116

117+
def migrate_protect_version_branches_ruleset() -> None:
118+
"""Update the 'Protect version branches' GitHub ruleset.
119+
120+
Uses the GitHub API (via ``gh`` CLI) to check whether the
121+
'Protect version branches' ruleset on the current repository is aligned
122+
with the current template. Recent template changes include:
123+
124+
* Removing the ``copilot_code_review`` rule.
125+
126+
If the ruleset is already aligned, prints an informational message.
127+
If it needs updating, applies the changes via the API without removing
128+
any existing required status checks.
129+
If the ruleset is not found at all, issues a manual-step message that
130+
points the user to the docs.
131+
"""
132+
rule_name = "Protect version branches"
133+
docs_url = (
134+
"https://frequenz-floss.github.io/frequenz-repo-config-python/"
135+
"user-guide/start-a-new-project/configure-github/#rulesets"
136+
)
137+
138+
# Build a link to the repo's ruleset settings for manual-step messages.
139+
ruleset_url = get_ruleset_settings_url() or docs_url
140+
141+
# ── Fetch ruleset details ────────────────────────────────────────
142+
ruleset = get_ruleset(rule_name)
143+
if ruleset is None:
144+
manual_step(
145+
f"The '{rule_name}' GitHub ruleset was not found (or the gh CLI "
146+
"is not available / the API call failed). "
147+
"Please check whether it should exist for this repository. "
148+
f"If it should, import it following the instructions at: {docs_url}"
149+
)
150+
return
151+
152+
# ── Detect and apply changes in-memory ───────────────────────────────
153+
changes: list[str] = []
154+
updated_rules = []
155+
156+
for rule in ruleset.get("rules", []):
157+
if rule.get("type") == "copilot_code_review":
158+
changes.append("remove copilot_code_review")
159+
continue
160+
updated_rules.append(rule)
161+
162+
if not changes:
163+
print(f" Ruleset '{rule_name}' is already up to date")
164+
return
165+
166+
# ── Push the update ───────────────────────────────────────────────────
167+
ruleset["rules"] = updated_rules
168+
if not update_ruleset(ruleset["id"], ruleset):
169+
manual_step(
170+
f"Failed to update the '{rule_name}' ruleset via the GitHub API. "
171+
f"Please apply the following changes manually at {ruleset_url}: "
172+
+ "; ".join(changes)
173+
)
174+
return
175+
176+
print(f" Updated ruleset '{rule_name}': " + ", ".join(changes))
177+
178+
114179
def apply_patch(patch_content: str) -> None:
115180
"""Apply a patch using the patch utility."""
116181
subprocess.run(["patch", "-p1"], input=patch_content.encode(), check=True)

0 commit comments

Comments
 (0)