feat(cinny-web): serve avatar decorations from chat.lotusguild.org/decorations (#22)
Lint / Shell (shellcheck) (push) Successful in 14s
Lint / JS (eslint) (push) Successful in 11s
Lint / No secrets in webhook configs (push) Successful in 5s
Lint / Landing page is rendered (matrix (push) Successful in 4s
Lint / Python (ruff) (push) Successful in 6s
Lint / Python deps (pip-audit) (push) Successful in 32s
Lint / Secret scan (gitleaks) (push) Successful in 4s
Lint / Shell (shellcheck) (pull_request) Successful in 7s
Lint / JS (eslint) (pull_request) Successful in 5s
Lint / No secrets in webhook configs (pull_request) Successful in 4s
Lint / Landing page is rendered (matrix (pull_request) Successful in 3s
Lint / Python (ruff) (pull_request) Successful in 4s
Lint / Python deps (pip-audit) (pull_request) Successful in 30s
Lint / Secret scan (gitleaks) (pull_request) Successful in 4s

Decorations came through Nextcloud's public DAV: a new PHP session (four
cookies) per image and no cache headers, on every decorated avatar. The
set (629 decorations + thumbnails, 573 MB) is now a versioned Gitea
generic package (avatar-decorations 1.0.0, 4 tar parts), pinned by
sha256 in cinny/decorations.sha256. LXC 106's deploy installs it to
/var/www/decorations-<version> (verified against the pin and the
in-package manifest; previous version kept; failures leave the live set
alone), and nginx serves /decorations/ with a one-week public cache.
deploy/publish-decorations.sh publishes a new version and writes the pin.

Fixes #22

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
This commit is contained in:
Lotus CI
2026-10-19 12:32:34 -04:00
co-authored by Claude Opus 5.5
parent 96d1778bb4
commit b6380b6c8a
5 changed files with 131 additions and 1 deletions
+50 -1
View File
@@ -16,7 +16,7 @@ echo "=== $(date) === LXC106 deploy triggered ==="
if [ ! -d "$REPO_DIR/.git" ]; then
git clone "$CLONE_URL" "$REPO_DIR"
CHANGED="cinny/config.json cinny/nginx.conf cinny/upstream-check.sh cinny/lotus-build.sh cinny/lotus_deploy.sh deploy/hooks-lxc106.json systemd/cinny-upstream-check.cron"
CHANGED="cinny/config.json cinny/decorations.sha256 cinny/nginx.conf cinny/upstream-check.sh cinny/lotus-build.sh cinny/lotus_deploy.sh deploy/hooks-lxc106.json systemd/cinny-upstream-check.cron"
else
cd "$REPO_DIR"
git fetch --all
@@ -63,6 +63,55 @@ PY
fi
fi
# [matrix #22] Avatar decorations: a versioned Gitea generic package, pinned
# (version + sha256 of each part) in cinny/decorations.sha256, installed to
# /var/www/decorations-<version> and served by nginx at /decorations/. Runs on a
# pin change or when nothing is installed yet. A failed download or checksum
# leaves the live set untouched; the previous version is kept for rollback.
install_decorations() {
local pin="$REPO_DIR/cinny/decorations.sha256"
local ver base tmp dest
ver=$(grep -oE 'avatar-decorations-[0-9][^ ]*\.part1\.tar' "$pin" | sed -E 's/^avatar-decorations-(.*)\.part1\.tar$/\1/')
[ -n "$ver" ] || { echo "✗ decorations: no version in $pin"; return 1; }
dest="/var/www/decorations-$ver"
if [ -d "$dest/decorations" ] && [ "$(readlink -f /var/www/decorations)" = "$dest/decorations" ]; then
echo "decorations $ver already live"; return 0
fi
base="https://code.lotusguild.org/api/packages/LotusGuild/generic/avatar-decorations/$ver"
tmp=$(mktemp -d /var/www/.decorations-XXXXXX)
# Every step checks its own exit status: `set -e` does not apply inside a
# subshell on the left of `||`, so a failed checksum would be ignored.
if ! (
cd "$tmp" || exit 1
cp "$pin" SHA256SUMS || exit 1
while read -r _ f; do
curl -fsSL --retry 3 -o "$f" "$base/$f" || exit 1
done < SHA256SUMS
sha256sum -c --quiet SHA256SUMS || exit 1
while read -r _ f; do
tar -xf "$f" || exit 1
rm -f "$f"
done < SHA256SUMS
cd decorations || exit 1
sha256sum -c --quiet MANIFEST.sha256 || exit 1
); then
echo "✗ decorations $ver: download/verify failed — live set unchanged"
rm -rf "$tmp"
return 1
fi
rm -rf "$dest"; mkdir -p "$dest"; mv "$tmp/decorations" "$dest/decorations"; rm -rf "$tmp"
chmod -R a+rX "$dest"
ln -sfn "$dest/decorations" /var/www/decorations.new && mv -T /var/www/decorations.new /var/www/decorations
# Keep the live version and the one before it; drop older ones.
find /var/www -maxdepth 1 -name 'decorations-*' -type d -printf '%T@ %p\n' | sort -rn \
| tail -n +3 | cut -d' ' -f2- | xargs -r rm -rf
echo "✓ decorations $ver live at /var/www/decorations ($(find "$dest/decorations" -maxdepth 1 -name '*.png' | wc -l) images)"
}
if echo "$CHANGED" | grep -q '^cinny/decorations.sha256' || [ ! -e /var/www/decorations ]; then
echo "Deploying avatar decorations..."
install_decorations || true
fi
if echo "$CHANGED" | grep -q '^cinny/nginx.conf'; then
echo "Deploying cinny nginx site config..."
# Back up the live config, swap in the repo copy, and validate before