diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c6af598 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,10 @@ +# Paths excluded from release tarballs. `git archive` (used by +# scripts/release/make_release.sh) honours `export-ignore`, so these dev-only +# trees never ship in libreportal-.tar.gz. +scripts/unused export-ignore +scripts/release export-ignore +site export-ignore +.claude export-ignore +.gitignore export-ignore +.gitattributes export-ignore +CONTRIBUTING.md export-ignore diff --git a/.gitignore b/.gitignore index 0bacc21..ac0fc82 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ # Node dependencies — installed via `npm ci` at image build, never vendored. node_modules/ npm-debug.log* + +# Release build output (scripts/release/make_release.sh). +/dist/ diff --git a/scripts/release/make_release.sh b/scripts/release/make_release.sh new file mode 100644 index 0000000..8c367b2 --- /dev/null +++ b/scripts/release/make_release.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# +# Build a versioned, checksum-verified LibrePortal release artifact. +# +# The stable install fetches a release tarball over plain HTTPS (no git, no auth), +# so it's reproducible and version-pinned. This builds that artifact from the +# COMMITTED tree via `git archive`, which honours the `export-ignore` rules in +# .gitattributes — so dev-only trees (scripts/unused, site, .claude, …) never ship. +# +# No infrastructure needed: output lands in dist// laid out exactly like +# the hosting will serve it, so you can point an install at it with: +# ( cd dist && python3 -m http.server 8000 ) +# LP_RELEASE_BASE_URL=http://localhost:8000 ./install.sh ... +# +# Usage: scripts/release/make_release.sh [channel] [git-ref] +# channel stable (default) | edge +# git-ref HEAD (default) | a tag/commit to build from +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +cd "$REPO_ROOT" + +CHANNEL="${1:-stable}" +REF="${2:-HEAD}" + +VERSION="$(tr -d ' \t\n\r' < VERSION 2>/dev/null || true)" +[[ -n "$VERSION" ]] || { echo "make_release: VERSION file is empty or missing" >&2; exit 1; } + +TARBALL="libreportal-${VERSION}.tar.gz" +PREFIX="libreportal-${VERSION}/" # top-level dir inside the tarball +OUT="$REPO_ROOT/dist/$CHANNEL" +mkdir -p "$OUT" + +echo "Building $TARBALL (channel=$CHANNEL, ref=$REF) ..." +git archive --format=tar.gz --prefix="$PREFIX" -o "$OUT/$TARBALL" "$REF" + +( cd "$OUT" && sha256sum "$TARBALL" > "$TARBALL.sha256" ) +SHA="$(cut -d' ' -f1 < "$OUT/$TARBALL.sha256")" + +cat > "$OUT/latest.json" <