style(1b): auto-format + lint-clean the whole codebase (RL1)
Mechanical, semantics-preserving cleanup so the codebase passes the new lint stage:
- ruff format: all 32 Python files (wraps long signatures, normalizes quotes/blank lines).
- nixpkgs-fmt: modules/drone-runner.nix.
- shfmt (-i 2 -ci): scripts/*.sh.
Lint fixes (reviewed, behavior-preserving — no test weakened):
- ruff SIM105: try/except-pass -> contextlib.suppress (abra.py app_config rm; lifecycle.py janitor).
- ruff SIM115: open().read() -> with open() (run_recipe_ci.py redaction-values + gitea-token).
- statix: merge repeated sops `secrets.*` keys into one `secrets = { ... }` (comments kept);
empty fn pattern `{ ... }:` -> `_:` (packages.nix).
- deadnix: drop unused lambda args (flake `self`; configuration.nix `lib`; overlay `final` -> `_`).
Verified on cc-ci: `scripts/lint.sh` -> lint: PASS; nixosConfigurations.cc-ci evaluates;
all Python byte-compiles. The deployed bridge/dashboard/runner source changes hash (reformat),
so cc-ci will be rebuilt to the new closure in W2 before the cold D1-D10 re-verification.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@ -26,6 +26,7 @@ Config (env): BRIDGE_LISTEN, GITEA_API, DRONE_URL, CI_REPO, HMAC_FILE, DRONE_TOK
|
||||
GITEA_TOKEN_FILE, POLL_INTERVAL (default 30), POLL_REPOS (csv of enrolled repos), AUTH_ALLOWLIST
|
||||
(csv, optional).
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
@ -118,14 +119,22 @@ def trigger_build(recipe, ref, pr, src):
|
||||
|
||||
|
||||
def post_comment(owner, repo, number, body):
|
||||
status, c = _api(f"{GITEA_API}/repos/{owner}/{repo}/issues/{number}/comments", GITEA_TOKEN,
|
||||
method="POST", data={"body": body})
|
||||
status, c = _api(
|
||||
f"{GITEA_API}/repos/{owner}/{repo}/issues/{number}/comments",
|
||||
GITEA_TOKEN,
|
||||
method="POST",
|
||||
data={"body": body},
|
||||
)
|
||||
return c.get("id") if status in (200, 201) and c else None
|
||||
|
||||
|
||||
def edit_comment(owner, repo, comment_id, body):
|
||||
_api(f"{GITEA_API}/repos/{owner}/{repo}/issues/comments/{comment_id}", GITEA_TOKEN,
|
||||
method="PATCH", data={"body": body})
|
||||
_api(
|
||||
f"{GITEA_API}/repos/{owner}/{repo}/issues/comments/{comment_id}",
|
||||
GITEA_TOKEN,
|
||||
method="PATCH",
|
||||
data={"body": body},
|
||||
)
|
||||
|
||||
|
||||
def build_status(num):
|
||||
@ -140,6 +149,7 @@ def watch_and_reflect(owner, name, number, num, recipe, sha, comment_id, run_url
|
||||
"""Poll the Drone build to completion, then edit the PR comment to reflect the outcome (D7).
|
||||
Bounded by the build timeout (60m) + margin."""
|
||||
import time as _t
|
||||
|
||||
deadline = _t.time() + 75 * 60
|
||||
last = None
|
||||
while _t.time() < deadline:
|
||||
@ -150,8 +160,12 @@ def watch_and_reflect(owner, name, number, num, recipe, sha, comment_id, run_url
|
||||
icon = {"success": "✅"}.get(last, "❌")
|
||||
verdict = "passed" if last == "success" else (last or "did not complete")
|
||||
if comment_id:
|
||||
edit_comment(owner, name, comment_id,
|
||||
f"cc-ci: run for `{recipe}` @ `{sha[:8]}` {icon} **{verdict}** → {run_url}")
|
||||
edit_comment(
|
||||
owner,
|
||||
name,
|
||||
comment_id,
|
||||
f"cc-ci: run for `{recipe}` @ `{sha[:8]}` {icon} **{verdict}** → {run_url}",
|
||||
)
|
||||
log(f"reflected outcome build {num} ({recipe} PR #{number}): {last}")
|
||||
|
||||
|
||||
@ -192,14 +206,19 @@ def process_testme(full_name, owner, name, number, user, comment_id, source):
|
||||
post_comment(owner, name, number, "cc-ci: failed to start a CI run (see bridge logs).")
|
||||
return None, "trigger failed"
|
||||
run_url = f"{DRONE_URL}/{CI_REPO}/{num}"
|
||||
cid = post_comment(owner, name, number,
|
||||
f"cc-ci: started CI run for `{name}` @ `{head['sha'][:8]}` → {run_url}")
|
||||
log(f"[{source}] triggered build {num} for {name}@{head['sha'][:8]} "
|
||||
f"(PR #{number}, comment {comment_id}) by {user}")
|
||||
cid = post_comment(
|
||||
owner, name, number, f"cc-ci: started CI run for `{name}` @ `{head['sha'][:8]}` → {run_url}"
|
||||
)
|
||||
log(
|
||||
f"[{source}] triggered build {num} for {name}@{head['sha'][:8]} "
|
||||
f"(PR #{number}, comment {comment_id}) by {user}"
|
||||
)
|
||||
# Reflect the final pass/fail back onto that comment when the build finishes (D7).
|
||||
threading.Thread(target=watch_and_reflect,
|
||||
args=(owner, name, number, num, name, head["sha"], cid, run_url),
|
||||
daemon=True).start()
|
||||
threading.Thread(
|
||||
target=watch_and_reflect,
|
||||
args=(owner, name, number, num, name, head["sha"], cid, run_url),
|
||||
daemon=True,
|
||||
).start()
|
||||
return run_url, "ok"
|
||||
|
||||
|
||||
@ -242,9 +261,14 @@ class Handler(BaseHTTPRequestHandler):
|
||||
return self._send(204, "not a PR")
|
||||
|
||||
run_url, reason = process_testme(
|
||||
repo.get("full_name", ""), (repo.get("owner") or {}).get("login", ""),
|
||||
repo.get("name", ""), issue.get("number"),
|
||||
c.get("user", {}).get("login", ""), c.get("id"), "webhook")
|
||||
repo.get("full_name", ""),
|
||||
(repo.get("owner") or {}).get("login", ""),
|
||||
repo.get("name", ""),
|
||||
issue.get("number"),
|
||||
c.get("user", {}).get("login", ""),
|
||||
c.get("id"),
|
||||
"webhook",
|
||||
)
|
||||
if not run_url:
|
||||
if reason == "duplicate":
|
||||
return self._send(200, "already handled")
|
||||
|
||||
Reference in New Issue
Block a user