From d7e948df3329ae947dcb0f2c06a4b2829e686de5 Mon Sep 17 00:00:00 2001 From: h Date: Thu, 10 Sep 2026 16:06:27 +0000 Subject: [PATCH] feat(gitea): commit the preset stub instead of asking for it --- README.md | 13 ++++--------- templates.py | 52 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 3fef43d..3de5f7c 100644 --- a/README.md +++ b/README.md @@ -27,15 +27,10 @@ today these were created by hand for every repo. giteaproject ms-agents/my-thing ``` -Then drop a `renovate.jsonc` into the repo root with nothing but the shared -preset: - -```json -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": ["local>templates/renovate"] -} -``` +It creates the labels and, if the repo has no `renovate.jsonc` yet, commits one +that is nothing but an `extends` on the shared preset in `templates/renovate`. +Projects rendered by `newproject` already carry that file from the `infra` +template, so for them the command only does the labels. **Extending the preset does not subscribe the repo to anything.** The bot walks an explicit list, so the repo also has to be added to `repositories` in diff --git a/templates.py b/templates.py index 4bd1552..baa91ff 100644 --- a/templates.py +++ b/templates.py @@ -113,6 +113,12 @@ def update(args: argparse.Namespace) -> None: GITEA = os.environ.get("GITEA_URL", "https://git.kotikot.com").rstrip("/") +RENOVATE_FILE = "renovate.jsonc" +RENOVATE_STUB = """{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["local>templates/renovate"] +} +""" RENOVATE_LABELS = [ ("renovate", "1f6feb", "Pull request from the Renovate bot"), ("wait-3d", "d29922", "Waits three days: the registry has no release timestamp, the age gate merges it"), @@ -131,22 +137,29 @@ def gitea_token() -> str: def gitea(args: argparse.Namespace) -> None: - """Prepare a Gitea repo for Renovate: the labels it fails without.""" + """Prepare a Gitea repo for Renovate: labels and the preset stub.""" + import base64 import json import urllib.error import urllib.request token = gitea_token() - for name, color, description in RENOVATE_LABELS: - body = json.dumps({"name": name, "color": color, "description": description}).encode() + + def call(method: str, path: str, body: dict | None = None): request = urllib.request.Request( - f"{GITEA}/api/v1/repos/{args.repo}/labels", - data=body, - method="POST", + f"{GITEA}/api/v1{path}", + data=json.dumps(body).encode() if body is not None else None, + method=method, headers={"Authorization": f"token {token}", "Content-Type": "application/json"}, ) + with urllib.request.urlopen(request, timeout=30) as response: + raw = response.read() + return json.loads(raw) if raw else None + + for name, color, description in RENOVATE_LABELS: try: - urllib.request.urlopen(request, timeout=30) + call("POST", f"/repos/{args.repo}/labels", + {"name": name, "color": color, "description": description}) print(f"label {name}: created") except urllib.error.HTTPError as error: if error.code in (409, 422): @@ -154,13 +167,24 @@ def gitea(args: argparse.Namespace) -> None: else: sys.exit(f"label {name}: {error.code} {error.read()[:200]!r}") + try: + call("GET", f"/repos/{args.repo}/contents/{RENOVATE_FILE}") + print(f"{RENOVATE_FILE}: already there") + except urllib.error.HTTPError as error: + if error.code != 404: + sys.exit(f"{RENOVATE_FILE}: {error.code} {error.read()[:200]!r}") + call("POST", f"/repos/{args.repo}/contents/{RENOVATE_FILE}", { + "content": base64.b64encode(RENOVATE_STUB.encode()).decode(), + "message": "chore(renovate): extend the shared preset", + }) + print(f"{RENOVATE_FILE}: created") + print( - "\nLabels done. Two things are still manual, and neither happens by itself:\n" - f" 1. renovate.jsonc in {args.repo} with" - ' {"extends": ["local>templates/renovate"]}\n' - " 2. the repo added to `repositories` in renovate-config.js of infra/komodo,\n" - " plus the bot given write access to it. Extending the preset subscribes\n" - " nothing: the bot only visits repos named in that list." + "\nOne thing is still manual, and it does not happen by itself: the repo has\n" + "to be added to `repositories` in projects/personal/renovate/renovate-config.js\n" + "of infra/komodo, and the `renovate` team of its organization needs write\n" + "access to it. Extending the preset subscribes nothing - the bot only visits\n" + "repos named in that list." ) @@ -182,7 +206,7 @@ def main() -> None: u.add_argument("--ask", action="store_true", help="ask every question again") u.add_argument("--defaults", action="store_true") u.set_defaults(func=update) - g = sub.add_parser("gitea", help="Create the Renovate labels a repo needs") + g = sub.add_parser("gitea", help="Set a repo up for Renovate: labels and preset stub") g.add_argument("repo", help="org/name on Gitea") g.set_defaults(func=gitea) args = parser.parse_args()