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
This commit is contained in:
agw
2026-10-03 23:44:39 +02:00
parent d658c96bc3
commit dd9b102b7d
+49 -25
View File
@@ -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.
#
# 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"