packages/sync-omarchy-repo.sh diffs the upstream omarchy.db against the registry's own db by filename, streams missing packages through (409 = already present), and deletes entries upstream no longer lists. Only a 404 counts as first sync; any other mirror-db failure aborts rather than faking an empty mirror. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019hLK3wsDuKVAC37GgDqg6H
102 lines
3.3 KiB
Bash
102 lines
3.3 KiB
Bash
#!/bin/bash
|
|
# Mirrors the upstream [omarchy] stable repo into the OmarchyCN Gitea Arch registry.
|
|
# Maintainer/CI script (pkg-repo-sync.yml); needs a package-write token, network.
|
|
|
|
set -euo pipefail
|
|
export LC_ALL=C
|
|
|
|
GITEA=${GITEA:-https://git.zacharyzhang.com}
|
|
OWNER=${OWNER:-ZacharyZhang-NY}
|
|
REPO=${REPO:-omarchy}
|
|
UPSTREAM=${UPSTREAM:-https://pkgs.omarchy.org/stable/x86_64}
|
|
: "${PKG_SYNC_TOKEN:?PKG_SYNC_TOKEN (Gitea package-write token) is required}"
|
|
|
|
registry="$GITEA/api/packages/$OWNER/arch"
|
|
mirror="$registry/$REPO/x86_64"
|
|
|
|
workdir=$(mktemp -d)
|
|
trap 'rm -rf "$workdir"' EXIT
|
|
|
|
# One "filename name version arch" line per package in a repo db (zstd or gzip tar)
|
|
db_entries() {
|
|
local db="$1" dir="$2" desc
|
|
mkdir -p "$dir"
|
|
tar --zstd -xf "$db" -C "$dir" 2>/dev/null || tar -xzf "$db" -C "$dir"
|
|
for desc in "$dir"/*/desc; do
|
|
[[ -f $desc ]] || continue
|
|
awk '
|
|
/^%FILENAME%$/ { getline; f = $0 }
|
|
/^%NAME%$/ { getline; n = $0 }
|
|
/^%VERSION%$/ { getline; v = $0 }
|
|
/^%ARCH%$/ { getline; a = $0 }
|
|
END {
|
|
if (f == "" || n == "" || v == "" || a == "") {
|
|
print "malformed desc: " FILENAME > "/dev/stderr"
|
|
exit 1
|
|
}
|
|
print f, n, v, a
|
|
}
|
|
' "$desc"
|
|
done
|
|
}
|
|
|
|
curl -sSf --retry 3 -o "$workdir/upstream.db" "$UPSTREAM/omarchy.db"
|
|
db_entries "$workdir/upstream.db" "$workdir/upstream" | sort > "$workdir/upstream.list"
|
|
|
|
# Only 404 means first sync; any other failure must not fake an empty mirror,
|
|
# which would skip deletions and report a bogus success
|
|
code=$(curl -sS --retry 3 -o "$workdir/mirror.db" -w '%{http_code}' "$mirror/$REPO.db" || true)
|
|
[[ -z $code ]] && code=000
|
|
case "$code" in
|
|
200)
|
|
db_entries "$workdir/mirror.db" "$workdir/mirror" | sort > "$workdir/mirror.list"
|
|
;;
|
|
404)
|
|
: > "$workdir/mirror.list"
|
|
;;
|
|
*)
|
|
echo "mirror db fetch failed (HTTP $code): $mirror/$REPO.db" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
comm -23 "$workdir/upstream.list" "$workdir/mirror.list" > "$workdir/to-add.list"
|
|
comm -13 "$workdir/upstream.list" "$workdir/mirror.list" > "$workdir/to-remove.list"
|
|
echo "upstream: $(wc -l < "$workdir/upstream.list") packages," \
|
|
"mirror: $(wc -l < "$workdir/mirror.list")," \
|
|
"to add: $(wc -l < "$workdir/to-add.list")," \
|
|
"to remove: $(wc -l < "$workdir/to-remove.list")"
|
|
|
|
added=0
|
|
while read -r filename name version arch; do
|
|
echo "add: $filename"
|
|
curl -sSf --retry 3 -o "$workdir/pkg" "$UPSTREAM/$filename"
|
|
code=$(curl -sS --retry 2 -o "$workdir/put.out" -w '%{http_code}' -X PUT \
|
|
-H "Authorization: token $PKG_SYNC_TOKEN" \
|
|
--upload-file "$workdir/pkg" "$registry/$REPO")
|
|
case "$code" in
|
|
201) added=$((added + 1)) ;;
|
|
409) echo " already present (409)" ;;
|
|
*)
|
|
echo "upload of $filename failed (HTTP $code): $(head -c 300 "$workdir/put.out")" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
rm -f "$workdir/pkg"
|
|
done < "$workdir/to-add.list"
|
|
|
|
removed=0
|
|
while read -r filename name version arch; do
|
|
echo "remove: $filename"
|
|
code=$(curl -sS --retry 2 -o "$workdir/del.out" -w '%{http_code}' -X DELETE \
|
|
-H "Authorization: token $PKG_SYNC_TOKEN" \
|
|
"$registry/$REPO/$name/$version/$arch")
|
|
if [[ $code != 2?? && $code != 404 ]]; then
|
|
echo "removal of $filename failed (HTTP $code): $(head -c 300 "$workdir/del.out")" >&2
|
|
exit 1
|
|
fi
|
|
removed=$((removed + 1))
|
|
done < "$workdir/to-remove.list"
|
|
|
|
echo "Sync complete: $added added, $removed removed"
|