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:
+49
-25
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user