v1.1.3
Citizen Launcher CI / arch-package (push) Failing after 22s
Citizen Launcher CI / rpm-package (push) Failing after 29s
Citizen Launcher CI / verify (push) Successful in 2m50s

This commit is contained in:
2026-09-01 20:17:04 +02:00
parent 5aadfd3427
commit 7bc0c63743
23 changed files with 332 additions and 126 deletions
+96 -29
View File
@@ -8,8 +8,41 @@ set -euo pipefail
api_base="${GITEA_API_URL%/}/repos/${GITEA_REPOSITORY}"
auth=( -H "Authorization: token ${GITEA_TOKEN}" )
select_json_backend() {
case "${CITIZEN_JSON_BACKEND:-auto}" in
python|python3)
command -v python3 >/dev/null 2>&1 || { echo "python3 is required by CITIZEN_JSON_BACKEND" >&2; exit 2; }
printf '%s\n' python
;;
jq)
command -v jq >/dev/null 2>&1 || { echo "jq is required by CITIZEN_JSON_BACKEND" >&2; exit 2; }
printf '%s\n' jq
;;
auto|"")
if command -v python3 >/dev/null 2>&1; then
printf '%s\n' python
elif command -v jq >/dev/null 2>&1; then
printf '%s\n' jq
else
echo "Gitea release helper needs python3 or jq" >&2
exit 2
fi
;;
*)
echo "Unknown CITIZEN_JSON_BACKEND=${CITIZEN_JSON_BACKEND}" >&2
exit 2
;;
esac
}
JSON_BACKEND="$(select_json_backend)"
urlencode() {
python3 -c 'import sys,urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$1"
if [[ "$JSON_BACKEND" == python ]]; then
python3 -c 'import sys,urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$1"
else
jq -rn --arg value "$1" '$value | @uri'
fi
}
release_json() {
@@ -19,8 +52,10 @@ release_json() {
}
release_payload() {
local tag="$1" title="$2" body_file="$3" target="${4:-}"
python3 - "$tag" "$title" "$body_file" "$target" <<'PY'
local tag="$1" title="$2" body_file="$3" target="${4:-}" body=""
[[ -f "$body_file" ]] && body="$(cat "$body_file")"
if [[ "$JSON_BACKEND" == python ]]; then
python3 - "$tag" "$title" "$body_file" "$target" <<'PY'
import json, pathlib, sys
body_path = pathlib.Path(sys.argv[3])
body = body_path.read_text(encoding='utf-8') if body_path.exists() else ''
@@ -33,6 +68,55 @@ print(json.dumps({
'target_commitish': sys.argv[4],
}))
PY
else
jq -cn \
--arg tag "$tag" \
--arg title "$title" \
--arg body "$body" \
--arg target "$target" \
'{tag_name:$tag,name:$title,body:$body,draft:false,prerelease:false,target_commitish:$target}'
fi
}
json_release_id() {
if [[ "$JSON_BACKEND" == python ]]; then
python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])'
else
jq -er '.id'
fi
}
json_matching_asset_ids() {
local name="$1"
if [[ "$JSON_BACKEND" == python ]]; then
python3 -c 'import json,sys; name=sys.argv[1]; [print(a["id"]) for a in json.load(sys.stdin).get("assets",[]) if a.get("name")==name]' "$name"
else
jq -er --arg name "$name" '.assets[]? | select(.name == $name) | .id' 2>/dev/null || true
fi
}
json_downloadable_assets_tsv() {
if [[ "$JSON_BACKEND" == python ]]; then
python3 -c '
import json, sys
release = json.load(sys.stdin)
for asset in release.get("assets", []):
name = asset.get("name", "")
url = asset.get("browser_download_url", "")
if not name or not url or name == "SHA256SUMS.txt":
continue
if name.endswith(".deb") or name.endswith(".rpm") or name.endswith(".pkg.tar.zst") or name.endswith("-linux-amd64.tar.gz"):
print(f"{name}\t{url}")
'
else
jq -r '
.assets[]?
| select(.name != null and .browser_download_url != null and .name != "SHA256SUMS.txt")
| select(.name | endswith(".deb") or endswith(".rpm") or endswith(".pkg.tar.zst") or endswith("-linux-amd64.tar.gz"))
| [.name, .browser_download_url]
| @tsv
'
fi
}
ensure_release() {
@@ -40,7 +124,7 @@ ensure_release() {
local payload current id
payload="$(release_payload "$tag" "$title" "$body_file" "$target")"
if current="$(release_json "$tag" 2>/dev/null)"; then
id="$(printf '%s' "$current" | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')"
id="$(printf '%s' "$current" | json_release_id)"
curl -fsS "${auth[@]}" -H 'Content-Type: application/json' \
-X PATCH -d "$payload" "${api_base}/releases/${id}" >/dev/null
echo "Updated Gitea release ${tag}"
@@ -56,10 +140,10 @@ upload_asset() {
[[ -s "$file" ]] || { echo "Asset missing/empty: $file" >&2; exit 1; }
local rel id name enc existing_ids
rel="$(release_json "$tag")"
id="$(printf '%s' "$rel" | python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')"
id="$(printf '%s' "$rel" | json_release_id)"
name="$(basename "$file")"
enc="$(urlencode "$name")"
existing_ids="$(printf '%s' "$rel" | python3 -c 'import json,sys; name=sys.argv[1]; [print(a["id"]) for a in json.load(sys.stdin).get("assets",[]) if a.get("name")==name]' "$name")"
existing_ids="$(printf '%s' "$rel" | json_matching_asset_ids "$name")"
if [[ -n "$existing_ids" ]]; then
while IFS= read -r aid; do
[[ -n "$aid" ]] || continue
@@ -75,30 +159,13 @@ upload_asset() {
download_assets() {
local tag="$1" dir="$2"
mkdir -p "$dir"
local rel
local rel name url
rel="$(release_json "$tag")"
printf '%s' "$rel" | python3 -c '
import json, os, pathlib, sys, urllib.request
out = pathlib.Path(sys.argv[1])
release = json.load(sys.stdin)
for asset in release.get("assets", []):
name = asset.get("name", "")
if not name or name == "SHA256SUMS.txt":
continue
if not (name.endswith(".deb") or name.endswith(".rpm") or name.endswith(".pkg.tar.zst") or name.endswith("-linux-amd64.tar.gz")):
continue
req = urllib.request.Request(asset["browser_download_url"])
token = os.environ.get("GITEA_TOKEN", "")
if token:
req.add_header("Authorization", f"token {token}")
with urllib.request.urlopen(req, timeout=120) as r, open(out / name, "wb") as f:
while True:
block = r.read(1024 * 1024)
if not block:
break
f.write(block)
print(name)
' "$dir"
while IFS=$'\t' read -r name url; do
[[ -n "$name" && -n "$url" ]] || continue
curl -fsSL "${auth[@]}" "$url" -o "$dir/$name"
echo "$name"
done < <(printf '%s' "$rel" | json_downloadable_assets_tsv)
}
case "${1:-}" in