#!/usr/bin/env python3 """Configure GRM repository: branch protection + labels via Gitea REST API. Usage: REPO_TOKEN= python3 scripts/configure_repo.py """ import http import os from typing import cast import click from dotenv import load_dotenv # pyright: ignore[reportMissingImports,reportUnknownVariableType] from gitea_runner_manager.api_clients import GiteaClient from gitea_runner_manager.config import ( BRANCH_PROTECTION_CONFIG, GITEA_API_URL, LABEL_CONFIG, REPO_NAME, REPO_OWNER, REPO_SETTINGS_CONFIG, ) from gitea_runner_manager.exceptions import APIError from gitea_runner_manager.i18n import _ load_dotenv(override=True) def _handle_http_error(e: APIError) -> None: """Raise a user-friendly Click exception for HTTP errors.""" if e.status == http.HTTPStatus.FORBIDDEN: raise click.ClickException( _( "HTTP {status} Forbidden — your token lacks admin rights.\n" "Make sure the token belongs to a repo owner or organisation admin.\n" "Alternatively, configure branch protection manually in Settings → Branches.", status=e.status, ) ) raise click.ClickException( _("HTTP error: {status} — {message}", status=e.status, message=e.message) ) def main() -> None: token = os.environ.get("REPO_TOKEN", "") if not token: raise click.ClickException(_("ERROR: REPO_TOKEN is not set.")) client = GiteaClient(GITEA_API_URL, token, REPO_OWNER, REPO_NAME) try: click.echo(_("Configuring branch protection for {branch}...", branch="master")) client.ensure_branch_protection("master", BRANCH_PROTECTION_CONFIG) click.echo(_(" - Direct pushes: BLOCKED (require PR)")) click.echo( _( " - Required approvals: {count}", count=BRANCH_PROTECTION_CONFIG["required_approvals"], ) ) click.echo(_(" - Dismiss stale approvals: yes")) click.echo(_(" - Block outdated branches: yes")) click.echo(_(" - Block rejected reviews: yes")) checks = ", ".join(cast(list[str], BRANCH_PROTECTION_CONFIG["status_check_contexts"])) click.echo(_(" - Required status checks: {checks}", checks=checks)) click.echo("") label_name = cast(str, LABEL_CONFIG["name"]) click.echo(_("Creating {label} label...", label=label_name)) result = client.ensure_label( name=cast(str, LABEL_CONFIG["name"]), color=cast(str, LABEL_CONFIG["color"]), description=cast(str, LABEL_CONFIG["description"]), ) if result is None: click.echo(_(" Label '{label}' already exists.", label=label_name)) else: click.echo(_(" Label '{label}' created.", label=label_name)) click.echo("") click.echo(_("Configuring repository settings...")) client.update_repo_settings(cast(dict[str, object], REPO_SETTINGS_CONFIG)) click.echo(_(" - Auto-delete branch after merge: yes")) click.echo("") click.echo(_("Repository configuration complete.")) except APIError as e: _handle_http_error(e) if __name__ == "__main__": # pragma: no cover main() # pragma: no cover