From e4a15869c06934c716b4b48f8b1c1ae72a92f7a8 Mon Sep 17 00:00:00 2001 From: Grant Whitmer Date: Wed, 23 Sep 2026 02:44:19 -0400 Subject: [PATCH] ci: onboard windy-connect + windy-search to private-repo CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit windy-connect promoted from pull mirror to writable (release.yml, which publishes to PyPI on tag push, disabled — the sync pushes tags). windy-search was already writable; its scheduled drift-check is disabled because it now runs as cron on Kit 0. Both added to BRIDGE_REPOS. Co-Authored-By: Claude Opus 5.5 --- api/tests/test_pr_status_bridge.py | 32 +++++++++++++++++++------- scripts/pr_status_bridge.py | 37 +++++++++++++++++++----------- scripts/sync_from_github.sh | 2 +- 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/api/tests/test_pr_status_bridge.py b/api/tests/test_pr_status_bridge.py index 4dd9d29..c641b51 100644 --- a/api/tests/test_pr_status_bridge.py +++ b/api/tests/test_pr_status_bridge.py @@ -14,7 +14,9 @@ from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[2] -_spec = importlib.util.spec_from_file_location("pr_status_bridge", ROOT / "scripts" / "pr_status_bridge.py") +_spec = importlib.util.spec_from_file_location( + "pr_status_bridge", ROOT / "scripts" / "pr_status_bridge.py" +) bridge = importlib.util.module_from_spec(_spec) _spec.loader.exec_module(bridge) @@ -22,7 +24,14 @@ SHA = "a" * 40 def _run(i, wf, job, status, sha=SHA, n=1): - return {"id": i, "workflow_id": wf, "name": job, "status": status, "head_sha": sha, "run_number": n} + return { + "id": i, + "workflow_id": wf, + "name": job, + "status": status, + "head_sha": sha, + "run_number": n, + } class Fake: @@ -34,7 +43,7 @@ class Fake: def gitea(self, method, path, body=None): if "/actions/tasks" in path: page = int(path.rsplit("page=", 1)[1]) - return 200, {"workflow_runs": self.runs[(page - 1) * 50: page * 50]} + return 200, {"workflow_runs": self.runs[(page - 1) * 50 : page * 50]} if method == "GET" and path.endswith("/pulls?state=open&limit=50"): return 200, self.wg_prs if method == "POST" and path.endswith("/pulls"): @@ -63,6 +72,7 @@ def fake(monkeypatch): monkeypatch.setattr(bridge, "gitea", f.gitea) monkeypatch.setattr(bridge, "github", f.github) return f + return make @@ -74,8 +84,10 @@ def test_posts_latest_verdict_per_job(fake): def test_unchanged_state_is_not_reposted(fake): - f = fake(runs=[_run(1, "ci.yml", "test", "success")], - statuses=[{"context": "windy-git/ci/test", "state": "success"}]) + f = fake( + runs=[_run(1, "ci.yml", "test", "success")], + statuses=[{"context": "windy-git/ci/test", "state": "success"}], + ) bridge.post_statuses("r", SHA) assert f.posted == [] @@ -100,9 +112,13 @@ def test_runs_past_the_first_page_are_seen(fake): def _gh_pr(n, repo="sneakyfree/r"): - return {"number": n, "title": "t", "html_url": "u", - "head": {"ref": f"b{n}", "sha": SHA, "repo": {"full_name": repo} if repo else None}, - "base": {"ref": "main"}} + return { + "number": n, + "title": "t", + "html_url": "u", + "head": {"ref": f"b{n}", "sha": SHA, "repo": {"full_name": repo} if repo else None}, + "base": {"ref": "main"}, + } def test_fork_prs_are_never_mirrored(fake, monkeypatch): diff --git a/scripts/pr_status_bridge.py b/scripts/pr_status_bridge.py index d429159..ed22442 100755 --- a/scripts/pr_status_bridge.py +++ b/scripts/pr_status_bridge.py @@ -43,7 +43,8 @@ WG_OWNER = os.environ.get("WINDYGIT_OWNER", "windyadmin") # Private repos only. Public repos run real GitHub Actions on veron1's GitHub # runner; bridging those too would put two competing verdicts on every commit. REPOS = os.environ.get( - "BRIDGE_REPOS", "windy-chat windy-mail windy-calendar Windy-Clone WindyCloud" + "BRIDGE_REPOS", + "windy-chat windy-mail windy-calendar Windy-Clone WindyCloud windy-search windy-connect", ).split() # Gitea run status -> GitHub status state. `skipped` is deliberately absent: a @@ -108,13 +109,17 @@ def sync_prs(repo: str) -> list[str]: heads.append(pr["head"]["sha"]) if tag in ours: continue - st, _ = gitea("POST", f"/repos/{WG_OWNER}/{repo}/pulls", { - "head": pr["head"]["ref"], - "base": pr["base"]["ref"], - "title": f"{tag} {pr['title']}"[:250], - "body": f"Mirror of {pr['html_url']} so CI runs here. Do not merge in Windy Git — " - "GitHub is the source of truth; merge there.", - }) + st, _ = gitea( + "POST", + f"/repos/{WG_OWNER}/{repo}/pulls", + { + "head": pr["head"]["ref"], + "base": pr["base"]["ref"], + "title": f"{tag} {pr['title']}"[:250], + "body": f"Mirror of {pr['html_url']} so CI runs here. Do not merge in Windy Git — " + "GitHub is the source of truth; merge there.", + }, + ) print(f" {repo}: opened mirror PR for GH#{pr['number']} -> {st}") for tag, p in ours.items(): @@ -154,12 +159,16 @@ def post_statuses(repo: str, sha: str) -> None: state = STATE.get(r["status"]) if state is None or current.get(ctx) == state: continue - st, _ = github("POST", f"/repos/{GH_OWNER}/{repo}/statuses/{sha}", { - "state": state, - "context": ctx, - "description": f"Windy Git CI on Veron 1: {r['status']}"[:140], - "target_url": f"{PUBLIC}/{WG_OWNER}/{repo}/actions/runs/{r['run_number']}", - }) + st, _ = github( + "POST", + f"/repos/{GH_OWNER}/{repo}/statuses/{sha}", + { + "state": state, + "context": ctx, + "description": f"Windy Git CI on Veron 1: {r['status']}"[:140], + "target_url": f"{PUBLIC}/{WG_OWNER}/{repo}/actions/runs/{r['run_number']}", + }, + ) print(f" {repo}@{sha[:7]} {ctx} = {state} -> {st}") diff --git a/scripts/sync_from_github.sh b/scripts/sync_from_github.sh index 8cb9110..fd7f7b3 100755 --- a/scripts/sync_from_github.sh +++ b/scripts/sync_from_github.sh @@ -38,7 +38,7 @@ FAILED=0 # Repos Windy Git tracks FROM GitHub. Remove a repo from this list at the moment # it flips to Windy-Git-first, or the sync will fight its authors and win. -REPOS="${SYNC_REPOS:-windy-calendar windy-search windy-registry Windy-Clone WindyCloud windy-cloud-sites windy-mind eternitas windy-agent windy-git windy-chat windy-mail}" +REPOS="${SYNC_REPOS:-windy-calendar windy-search windy-registry Windy-Clone WindyCloud windy-cloud-sites windy-mind eternitas windy-agent windy-git windy-chat windy-mail windy-connect}" mkdir -p "$WORK" log() { printf '[sync %s] %s\n' "$(date -u +%H:%M:%SZ)" "$*"; }