Files
PastilhasandClaude Opus 5 81c8e17a8e Start av-club: what it is, and a verified installer
Media processing pulled out of the website that first needed it. ffmpeg,
ImageMagick, libvips and exiftool are a real installation rather than an npm
install, and encoder settings get revisited as browser support moves — neither of
which belongs on the same clock as page templates and database schemas.

No processing code yet. What is here is the tooling requirement, an installer, and
docs/PIPELINE.md writing down what has NOT been decided — how a consumer talks to
this, whether processing blocks an upload, where output goes — so those get chosen
deliberately instead of by whatever gets written first.

verify.sh checks by running: it encodes a video and probes the result against what
ffmpeg was told to make, loads sharp under Bun specifically, and asserts a
re-encode still strips GPS. That last one guards a real leak — if a future sharp
changes its default, this fails a check rather than quietly publishing the
coordinates of a client's living room. Confirmed non-vacuous by hiding ffmpeg and
watching it exit 1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 02:18:14 +01:00

65 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Bring a machine to the state av-club needs, then prove it by running verify.sh.
#
# Idempotent: apt-get install on an already-installed package is a no-op, so re-running this is safe
# and is the intended way to check a machine is still correct.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# Everything the pipeline shells out to. Kept as one list so the README, the docs and this script
# cannot disagree about what an install consists of.
PACKAGES=(
ffmpeg # ffmpeg + ffprobe: transcode, poster frames, probe duration/codec/size
libimage-exiftool-perl # exiftool: read and strip metadata — client photos carry GPS
imagemagick # convert + identify: odd formats, and inspecting a file by hand
libvips-tools # vipsthumbnail: the CLI side of the library sharp uses
webp # cwebp + dwebp
libavif-bin # avifenc + avifdec
)
say() { printf '\n\033[1m%s\033[0m\n' "$1"; }
warn() { printf '\033[33m%s\033[0m\n' "$1"; }
die() { printf '\033[31m%s\033[0m\n' "$1" >&2; exit 1; }
say "Checking the machine"
[ -f /etc/os-release ] || die "No /etc/os-release — cannot tell what this machine is."
# shellcheck disable=SC1091
. /etc/os-release
echo " ${PRETTY_NAME:-unknown}"
# Say so rather than guessing. The package names below are Debian/Ubuntu ones and would simply not
# exist elsewhere; failing here with a sentence beats failing later with "E: Unable to locate package".
if [ "${ID:-}" != "ubuntu" ] && [ "${ID_LIKE:-}" != *debian* ]; then
die "This installer only knows apt-based systems. Install these by hand: ${PACKAGES[*]}"
fi
if [ "${VERSION_ID:-}" != "24.04" ]; then
warn " Verified on Ubuntu 24.04; this is ${VERSION_ID:-unknown}. Continuing — check the output."
fi
command -v bun >/dev/null 2>&1 || die "bun is not on PATH. See https://bun.sh"
echo " bun $(bun --version)"
SUDO=""
if [ "$(id -u)" -ne 0 ]; then
command -v sudo >/dev/null 2>&1 || die "Not root and no sudo available."
SUDO="sudo"
fi
say "Installing system packages"
echo " ${PACKAGES[*]}"
echo
# noninteractive so a package with a debconf prompt cannot hang an unattended run.
$SUDO env DEBIAN_FRONTEND=noninteractive apt-get update -qq
$SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y "${PACKAGES[@]}"
say "Installing bun dependencies"
(cd "$REPO_ROOT" && bun install)
say "Verifying"
"$REPO_ROOT/scripts/verify.sh"