86 lines
2.6 KiB
Bash
Executable File
86 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# check-gitea-release-download-links.sh - verify Gitea's public release page
|
|
# points users at the canonical HTTPS download URLs, not an internal ROOT_URL.
|
|
#
|
|
# Usage:
|
|
# scripts/check-gitea-release-download-links.sh VERSION ASSET_NAME...
|
|
|
|
set -euo pipefail
|
|
|
|
VERSION="${1:-}"
|
|
if [ -z "$VERSION" ] || [ "$#" -lt 2 ]; then
|
|
echo "usage: $0 VERSION ASSET_NAME..." >&2
|
|
exit 2
|
|
fi
|
|
shift
|
|
|
|
PUBLIC_BASE="${ARCHY_RELEASE_PUBLIC_BASE:-https://source.archipelago-foundation.org/lfg2025/archy}"
|
|
page_url="$PUBLIC_BASE/releases/tag/v$VERSION"
|
|
|
|
command -v curl >/dev/null 2>&1 || { echo "ERROR: curl required" >&2; exit 2; }
|
|
command -v python3 >/dev/null 2>&1 || { echo "ERROR: python3 required" >&2; exit 2; }
|
|
|
|
tmp="$(mktemp)"
|
|
trap 'rm -f "$tmp"' EXIT
|
|
curl -fsSL "$page_url" -o "$tmp"
|
|
|
|
python3 - "$tmp" "$PUBLIC_BASE" "$VERSION" "$page_url" "$@" <<'PY'
|
|
from html.parser import HTMLParser
|
|
from urllib.parse import quote
|
|
import sys
|
|
|
|
html_path, public_base, version, page_url, *assets = sys.argv[1:]
|
|
with open(html_path, encoding="utf-8") as f:
|
|
html = f.read()
|
|
|
|
class LinkParser(HTMLParser):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.hrefs = []
|
|
|
|
def handle_starttag(self, tag, attrs):
|
|
if tag.lower() != "a":
|
|
return
|
|
attrs = dict(attrs)
|
|
href = attrs.get("href")
|
|
if href:
|
|
self.hrefs.append(href)
|
|
|
|
parser = LinkParser()
|
|
parser.feed(html)
|
|
hrefs = set(parser.hrefs)
|
|
|
|
bad_internal = sorted(
|
|
h for h in hrefs
|
|
if "/releases/download/" in h and h.startswith(("http://", "https://"))
|
|
and not h.startswith(public_base + "/releases/download/")
|
|
)
|
|
|
|
failures = []
|
|
for asset in assets:
|
|
expected = f"{public_base}/releases/download/v{quote(version)}/{quote(asset)}"
|
|
if expected not in hrefs:
|
|
matches = sorted(h for h in hrefs if h.endswith("/" + quote(asset)))
|
|
if matches:
|
|
failures.append(f"{asset}: expected {expected}, found {matches[0]}")
|
|
else:
|
|
failures.append(f"{asset}: expected {expected}, but no matching release-page link was found")
|
|
|
|
if bad_internal:
|
|
failures.append("release page contains non-canonical download href(s):")
|
|
failures.extend(f" {h}" for h in bad_internal[:10])
|
|
|
|
if failures:
|
|
print(f"FAIL: public release page has broken download links: {page_url}", file=sys.stderr)
|
|
for failure in failures:
|
|
print(f" {failure}", file=sys.stderr)
|
|
print(
|
|
"Fix the Gitea public URL/proxy configuration so release links are generated "
|
|
"from the canonical HTTPS origin, then re-run the publish check.",
|
|
file=sys.stderr,
|
|
)
|
|
sys.exit(1)
|
|
|
|
print(f"OK: public release page download links use {public_base}")
|
|
PY
|