From c2055e85ebc61570f2a14283566384446affc541 Mon Sep 17 00:00:00 2001 From: teahubxyz Date: Wed, 14 Oct 2026 14:02:51 -0700 Subject: [PATCH] time: every write but comments and statuses goes out as the time bot Gitea 1.24 also refuses the Actions identity label edits (removing a label is a 500), which crashed promote_next and stalled the queue. gh() now uses TIME_TOKEN for every write except comments (Time's beats are gitea-actions' comments) and commit statuses; the time user never counts as trusted and mention replies ignore it; astra.yml gets TIME_TOKEN. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017fTCFiw6ohysUDcWoPsTys --- .github/time/test_time.py | 17 +++++++++++++++++ .github/time/time.py | 17 +++++++++++------ .github/time/venture.py | 2 +- .github/workflows/astra.yml | 1 + .github/workflows/mention.yml | 3 ++- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/.github/time/test_time.py b/.github/time/test_time.py index 6a7b0ec..6419f78 100644 --- a/.github/time/test_time.py +++ b/.github/time/test_time.py @@ -421,6 +421,23 @@ assert real_git_commit("time/card-9", {"src/a.py": None}, "rm") and "src/a.py" n tm.SERVER, tm.REPO, tm.default_branch = _saved print("ALL OK 53") +# writes go out as Time's own user, except comments and statuses (Gitea refuses the Actions identity the rest) +_seen, _real_http, _gt = [], tm.http, os.environ.get("GITHUB_TOKEN") +tm.http = lambda method, url, token, body=None, timeout=0: _seen.append(token) or {} +os.environ["TIME_TOKEN"], os.environ["GITHUB_TOKEN"] = "tt", "gt" +for _m, _p in [("DELETE", "/repos/o/r/issues/1/labels/3"), ("POST", "/repos/o/r/issues/1/labels"), ("POST", "/repos/o/r/issues"), + ("PATCH", "/repos/o/r/issues/1"), ("POST", "/repos/o/r/pulls"), ("POST", "/repos/o/r/issues/1/comments"), + ("PATCH", "/repos/o/r/issues/comments/9"), ("POST", "/repos/o/r/statuses/abc"), ("GET", "/repos/o/r/labels?limit=100")]: + tm.gh(_m, _p, {}) +assert _seen == ["tt"] * 5 + ["gt"] * 4, _seen +os.environ.pop("TIME_TOKEN"); _seen.clear(); tm.gh("DELETE", "/repos/o/r/issues/1/labels/3") +assert _seen == ["gt"], "no TIME_TOKEN: the Actions token, as on GitHub" +assert not tm.trusted("time") and not tm.trusted(tm.TIME_BOT), "Time never vouches for itself" +tm.http = _real_http +if _gt is None: os.environ.pop("GITHUB_TOKEN", None) +else: os.environ["GITHUB_TOKEN"] = _gt +print("ALL OK 54") + # the worker itself (worker.js), against a fake D1, Workers AI and Pages import shutil as _sh, subprocess as _sp # noqa: E402 if _sh.which("node"): diff --git a/.github/time/time.py b/.github/time/time.py index c796b64..d6f05af 100644 --- a/.github/time/time.py +++ b/.github/time/time.py @@ -36,6 +36,7 @@ REPO = os.environ.get("GITHUB_REPOSITORY", "") SERVER = (os.environ.get("GITHUB_SERVER_URL") or "https://teahub.xyz").rstrip("/") GH = (os.environ.get("GITHUB_API_URL") or f"{SERVER}/api/v1").rstrip("/") TIME_BOT = os.environ.get("TIME_BOT") or "gitea-actions" # the Actions token's user; Time's own comments +TIME_USER = os.environ.get("TIME_USER") or "time" # Time's own Gitea user (TIME_TOKEN): every write but comments and statuses VENICE = "https://api.venice.ai/api/v1" ANTHROPIC = "https://api.anthropic.com/v1" MARK = "