From dd9b102b7d577b5e6c89a813a74851f27dc3002a Mon Sep 17 00:00:00 2001 From: agw Date: Sat, 3 Oct 2026 23:44:39 +0200 Subject: [PATCH] Record state.json through the Gitea API instead of git push Git over HTTP is disabled on this Gitea ('Interacting with repositories by HTTP protocol is not allowed'), and the URL the old script derived from the SSH remote pointed HTTPS at the SSH port, so the first real publish failed right after committing state.json. Create or update the file through the contents API instead, with the runner's GITHUB_SERVER_URL/GITHUB_REPOSITORY. Tested create, unchanged and update against a throwaway private repo, and that the runner reaches the API through the edge. Claude-Session: https://claude.ai/code/session_01GGe7kUhooMFuzY6GaDb2w9 --- scripts/record-state.sh | 76 +++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/scripts/record-state.sh b/scripts/record-state.sh index c21c2de..c7e8b16 100755 --- a/scripts/record-state.sh +++ b/scripts/record-state.sh @@ -2,14 +2,23 @@ # Commit state.json back to this repo so the next scheduled run knows what was # already built. Without this the daily check would rebuild every night. # -# STATE_PUSH_TOKEN token with write access to this repo (required) +# The commit is made through Gitea's file-contents API rather than git push: +# git over HTTP is disabled on this Gitea ("Interacting with repositories by +# HTTP protocol is not allowed"), and the job has no SSH key for the repo. +# +# STATE_PUSH_TOKEN token with write access to this repo (required) +# GITHUB_SERVER_URL set by the runner, e.g. https://gitea.example.org +# GITHUB_REPOSITORY set by the runner, owner/repo +# GITHUB_REF_NAME branch to commit to (default master) set -euo pipefail : "${STATE_PUSH_TOKEN:?STATE_PUSH_TOKEN is required}" +: "${GITHUB_SERVER_URL:?GITHUB_SERVER_URL is required}" +: "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY is required}" python3 - <<'PY' -import json +import base64, json, os, urllib.error, urllib.request meta = json.load(open("release-meta.json")) state = { @@ -22,28 +31,43 @@ state = { "sha256": meta["sha256"], "download_url": meta["download_url"], } -with open("state.json", "w") as fh: - json.dump(state, fh, indent=2) - fh.write("\n") -print(json.dumps(state, indent=2)) +body = json.dumps(state, indent=2) + "\n" +print(body, end="") + +api = f'{os.environ["GITHUB_SERVER_URL"].rstrip("/")}/api/v1/repos/{os.environ["GITHUB_REPOSITORY"]}/contents/state.json' +branch = os.environ.get("GITHUB_REF_NAME") or "master" +headers = { + "Authorization": f'token {os.environ["STATE_PUSH_TOKEN"]}', + "Content-Type": "application/json", +} + +def call(method, url, payload=None): + req = urllib.request.Request(url, method=method, headers=headers, + data=json.dumps(payload).encode() if payload else None) + with urllib.request.urlopen(req, timeout=60) as r: + return json.load(r) + +# Updating an existing file needs its blob sha; a missing file is a create. +existing_sha = None +try: + current = call("GET", f"{api}?ref={branch}") + if base64.b64decode(current["content"]).decode() == body: + print(":: state.json unchanged") + raise SystemExit(0) + existing_sha = current["sha"] +except urllib.error.HTTPError as e: + if e.code != 404: + raise + +payload = { + "branch": branch, + "content": base64.b64encode(body.encode()).decode(), + "message": f'Record build of {meta["jasp_version"]}-{meta["pkgrel"]}', + "author": {"name": "jasp-bin autobuilder", "email": "noreply@weircon.dk"}, + "committer": {"name": "jasp-bin autobuilder", "email": "noreply@weircon.dk"}, +} +if existing_sha: + payload["sha"] = existing_sha +result = call("PUT" if existing_sha else "POST", api, payload) +print(f':: state recorded in {result["commit"]["sha"][:7]}') PY - -# Stage first: `git diff` ignores untracked files, so on the very first run -# (no state.json in the repo yet) it reported "unchanged" and nothing was ever -# recorded, which would have rebuilt and republished every night. -git add state.json -if git diff --cached --quiet -- state.json; then - echo ":: state.json unchanged" - exit 0 -fi - -git config user.name "jasp-bin autobuilder" -git config user.email "noreply@weircon.dk" -git commit -m "Record build of ${GITHUB_REF_NAME:-build}: $(python3 -c 'import json;print(json.load(open("state.json"))["jasp_version"])')" - -origin="$(git remote get-url origin)" -host_path="${origin#*://}" -host_path="${host_path#*@}" -git push "https://x-access-token:${STATE_PUSH_TOKEN}@${host_path}" HEAD:"${GITHUB_REF_NAME:-master}" - -echo ":: state recorded"