diff --git a/.gitea/scripts/ci-required-drift.py b/.gitea/scripts/ci-required-drift.py index 8de6de46c..4e50a7272 100755 --- a/.gitea/scripts/ci-required-drift.py +++ b/.gitea/scripts/ci-required-drift.py @@ -274,7 +274,8 @@ def required_checks_env(audit_doc: dict) -> set[str]: found.append(v) if not found: sys.stderr.write( - f"::error::REQUIRED_CHECKS env not found in any step of {AUDIT_WORKFLOW_PATH}\n" + f"::error::REQUIRED_CHECKS env not found in any step of " + f"{AUDIT_WORKFLOW_PATH}\n" ) sys.exit(3) if len(found) > 1: @@ -387,7 +388,8 @@ def detect_drift(branch: str) -> tuple[list[str], dict]: missing_from_needs = sorted(jobs - needs) if missing_from_needs: findings.append( - "F1 — jobs in ci.yml NOT under sentinel `needs:` (sentinel doesn't gate them):\n" + "F1 — jobs in ci.yml NOT under sentinel `needs:` " + "(sentinel doesn't gate them):\n" + "\n".join(f" - {n}" for n in missing_from_needs) ) @@ -397,7 +399,8 @@ def detect_drift(branch: str) -> tuple[list[str], dict]: stale_needs = sorted(needs - jobs_all) if stale_needs: findings.append( - "F1b — sentinel `needs:` lists jobs NOT present in ci.yml (typo or removed job):\n" + "F1b — sentinel `needs:` lists jobs NOT present in ci.yml " + "(typo or removed job):\n" + "\n".join(f" - {n}" for n in stale_needs) ) @@ -405,7 +408,9 @@ def detect_drift(branch: str) -> tuple[list[str], dict]: # Compute the contexts the CI YAML actually produces. The sentinel # is in (B) intentionally (`ci / all-required (pull_request)`); we # whitelist it explicitly. - emitted_contexts = {expected_context(j) for j in jobs} | {expected_context(SENTINEL_JOB)} + emitted_contexts = { + expected_context(j) for j in jobs + } | {expected_context(SENTINEL_JOB)} # Contexts NOT produced by ci.yml may still come from other # workflows in the repo (Secret scan etc). We can't enumerate # every workflow's emissions cheaply; instead, flag only contexts @@ -418,7 +423,8 @@ def detect_drift(branch: str) -> tuple[list[str], dict]: ) if stale_protection: findings.append( - "F2 — protection `status_check_contexts` entries with `ci / ` prefix that NO " + "F2 — protection `status_check_contexts` entries with " + "`ci / ` prefix that NO " "job in ci.yml emits (stale name → silent advisory gate):\n" + "\n".join(f" - {c}" for c in stale_protection) ) @@ -494,7 +500,9 @@ def render_body(branch: str, findings: list[str], debug: dict) -> str: f"# Drift detected on `{REPO}/{branch}`", "", "Auto-filed by `.gitea/workflows/ci-required-drift.yml` " - "(RFC [internal#219](https://git.moleculesai.app/molecule-ai/internal/issues/219) §4 + §6).", + "(RFC [internal#219]" + "(https://git.moleculesai.app/molecule-ai/internal/issues/219) " + "§4 + §6).", "", "## Findings", "", @@ -547,12 +555,12 @@ def file_or_update( if dry_run: print(f"::notice::[dry-run] would file/update drift issue for {branch}") - print(f"::group::[dry-run] title") + print("::group::[dry-run] title") print(title) - print(f"::endgroup::") - print(f"::group::[dry-run] body") + print("::endgroup::") + print("::group::[dry-run] body") print(body) - print(f"::endgroup::") + print("::endgroup::") return existing = find_open_issue(title) diff --git a/.gitea/scripts/detect-changes.py b/.gitea/scripts/detect-changes.py index f436b03c3..5fc5750ad 100644 --- a/.gitea/scripts/detect-changes.py +++ b/.gitea/scripts/detect-changes.py @@ -15,7 +15,6 @@ import subprocess import sys from pathlib import Path - PROFILES: dict[str, dict[str, str]] = { "ci": { "platform": r"^workspace-server/", @@ -153,7 +152,10 @@ def parse_args(argv: list[str]) -> argparse.Namespace: parser.add_argument("--event-name", default=os.environ.get("GITHUB_EVENT_NAME", "")) parser.add_argument("--pr-base-sha", default="") parser.add_argument("--base-ref", default="") - parser.add_argument("--push-before", default=os.environ.get("GITHUB_EVENT_BEFORE", "")) + parser.add_argument( + "--push-before", + default=os.environ.get("GITHUB_EVENT_BEFORE", ""), + ) return parser.parse_args(argv) diff --git a/.gitea/scripts/lint-workflow-yaml.py b/.gitea/scripts/lint-workflow-yaml.py index bd254c90c..3c021ea9b 100755 --- a/.gitea/scripts/lint-workflow-yaml.py +++ b/.gitea/scripts/lint-workflow-yaml.py @@ -71,7 +71,10 @@ from typing import Any, Iterable try: import yaml except ImportError: - print("::error::PyYAML is required. Install with: pip install PyYAML", file=sys.stderr) + print( + "::error::PyYAML is required. Install with: pip install PyYAML", + file=sys.stderr, + ) sys.exit(2) @@ -198,7 +201,7 @@ USES_CROSS_REPO_RE = re.compile( (?P[A-Za-z0-9_.\-]+) / (?P[A-Za-z0-9_.\-]+) - / # mandatory subpath separator => cross-repo composite/reusable + / # mandatory subpath separator => cross-repo composite/reusable (?P[^@\s]+) @ (?P\S+) diff --git a/.gitea/scripts/main-red-watchdog.py b/.gitea/scripts/main-red-watchdog.py index 235317391..8822ca005 100755 --- a/.gitea/scripts/main-red-watchdog.py +++ b/.gitea/scripts/main-red-watchdog.py @@ -607,7 +607,10 @@ def close_open_red_issues_for_other_shas( "`feedback_no_such_thing_as_flakes`." ) if dry_run: - print(f"::notice::[dry-run] would close issue #{num} ({issue.get('title')})") + title = issue.get("title", "") + print( + f"::notice::[dry-run] would close issue #{num} ({title})" + ) closed += 1 continue # Comment first, then close. Order matters: a closed issue can diff --git a/.gitea/scripts/prod-auto-deploy.py b/.gitea/scripts/prod-auto-deploy.py index 67fd46d43..4baf84f7e 100644 --- a/.gitea/scripts/prod-auto-deploy.py +++ b/.gitea/scripts/prod-auto-deploy.py @@ -17,7 +17,6 @@ import urllib.error import urllib.request from urllib.parse import quote - TRUE_VALUES = {"1", "true", "yes", "on", "disabled", "disable"} PROD_CP_URL = "https://api.moleculesai.app" DEFAULT_REQUIRED_CONTEXTS = [ @@ -60,7 +59,10 @@ def build_plan(env: dict[str, str]) -> dict: } short_sha = sha[:7] - target_tag = env.get("PROD_AUTO_DEPLOY_TARGET_TAG", "").strip() or f"staging-{short_sha}" + target_tag = ( + env.get("PROD_AUTO_DEPLOY_TARGET_TAG", "").strip() + or f"staging-{short_sha}" + ) canary_slug = env.get("PROD_AUTO_DEPLOY_CANARY_SLUG", "hongming").strip() body = { "target_tag": target_tag, @@ -78,7 +80,9 @@ def build_plan(env: dict[str, str]) -> dict: body["canary_slug"] = canary_slug cp_url = env.get("CP_URL", "").strip() or PROD_CP_URL - if cp_url != PROD_CP_URL and not truthy_flag(env.get("PROD_ALLOW_NON_PROD_CP_URL", "")): + if cp_url != PROD_CP_URL and not truthy_flag( + env.get("PROD_ALLOW_NON_PROD_CP_URL", "") + ): raise ValueError( f"Refusing production deploy to CP_URL={cp_url!r}; " f"set PROD_ALLOW_NON_PROD_CP_URL=true for an explicit non-prod drill" @@ -127,7 +131,11 @@ def required_contexts(env: dict[str, str]) -> list[str]: raw = env.get("PROD_AUTO_DEPLOY_REQUIRED_CONTEXTS", "") if not raw.strip(): return DEFAULT_REQUIRED_CONTEXTS - return [line.strip() for line in raw.replace(",", "\n").splitlines() if line.strip()] + return [ + line.strip() + for line in raw.replace(",", "\n").splitlines() + if line.strip() + ] def _api_json(url: str, token: str) -> dict: @@ -176,10 +184,14 @@ def live_disable_flag(env: dict[str, str]) -> str: def assert_not_disabled(env: dict[str, str]) -> None: plan = build_plan(env) if not plan.get("enabled"): - raise RuntimeError(plan.get("disabled_reason", "production auto-deploy disabled")) + raise RuntimeError( + plan.get("disabled_reason", "production auto-deploy disabled") + ) live_value = live_disable_flag(env) if truthy_flag(live_value): - raise RuntimeError(f"PROD_AUTO_DEPLOY_DISABLED={live_value} (live Gitea variable)") + raise RuntimeError( + f"PROD_AUTO_DEPLOY_DISABLED={live_value} (live Gitea variable)" + ) def wait_for_ci_context(env: dict[str, str]) -> str: @@ -221,15 +233,24 @@ def wait_for_ci_context(env: dict[str, str]) -> str: if all(context_is_satisfied(state) for state in states.values()): return "success" time.sleep(interval) - last = ", ".join(f"{context}={state}" for context, state in last_states.items()) or "none" - raise TimeoutError(f"Timed out waiting {timeout}s for required CI contexts; last_states={last}") + last = ", ".join( + f"{context}={state}" + for context, state in last_states.items() + ) or "none" + raise TimeoutError( + f"Timed out waiting {timeout}s for required CI contexts; " + f"last_states={last}" + ) def main() -> int: parser = argparse.ArgumentParser(description=__doc__) sub = parser.add_subparsers(dest="command", required=True) sub.add_parser("plan", help="print production deploy plan as JSON") - sub.add_parser("assert-enabled", help="fail if production deploy is currently disabled") + sub.add_parser( + "assert-enabled", + help="fail if production deploy is currently disabled", + ) sub.add_parser("wait-ci", help="block until required CI context is green") args = parser.parse_args() diff --git a/.gitea/scripts/status-reaper.py b/.gitea/scripts/status-reaper.py index 5bf4c7d5f..c797aef46 100644 --- a/.gitea/scripts/status-reaper.py +++ b/.gitea/scripts/status-reaper.py @@ -125,7 +125,9 @@ OWNER, NAME = (REPO.split("/", 1) + [""])[:2] if REPO else ("", "") API = f"https://{GITEA_HOST}/api/v1" if GITEA_HOST else "" API_TIMEOUT_SEC = int(_env("STATUS_REAPER_API_TIMEOUT_SEC", default="30") or "30") API_RETRIES = int(_env("STATUS_REAPER_API_RETRIES", default="3") or "3") -API_RETRY_SLEEP_SEC = float(_env("STATUS_REAPER_API_RETRY_SLEEP_SEC", default="2") or "2") +API_RETRY_SLEEP_SEC = float( + _env("STATUS_REAPER_API_RETRY_SLEEP_SEC", default="2") or "2" +) # Compensating-status description prefix. Used as the marker so a human # auditing commit statuses can tell at a glance that the green was @@ -506,7 +508,9 @@ def reap( successful_contexts = { (s.get("context") or "") for s in statuses - if isinstance(s, dict) and (s.get("status") or s.get("state") or "") == "success" + if isinstance(s, dict) and ( + s.get("status") or s.get("state") or "" + ) == "success" } for s in statuses: if not isinstance(s, dict):