Add production .rpm packaging and dnf setup; share runtime staging
Template tests / tests (pull_request) Failing after 33s
Template tests / tests (pull_request) Failing after 33s
Phase 3 of the improvement plan (PR 9 of the sequence): the dnf/Fedora packaging half, in separate Linux-specific files, mirroring the apt/.deb work. - packaging/linux/common/stage-runtime.sh: shared runtime-only payload staging extracted from the .deb builder so the two package formats never drift. It copies app code + a fixed Electron runtime + production npm deps (npm ls --omit=dev), guards against dev-dep leaks, and fails without node_modules. The .deb builder now delegates to it. - packaging/linux/fedora/stepforge.spec: runtime Requires (nss, nspr, gtk3, …), Recommends (xinput, portal, pipewire), %license, and a %post that makes chrome-sandbox setuid and refreshes desktop/MIME/icon caches. No compilation — it packages the prebuilt BuildRoot. - packaging/linux/fedora/package.sh: stages the shared payload, substitutes version/maintainer into the spec, and runs rpmbuild against the prebuilt BuildRoot with detected arch. Requires rpmbuild + node_modules; emits an .rpm + sha256. - scripts/linux/dnf/install-runtime-deps.sh and install-build-deps.sh: separate runtime vs build dependency sets for dnf (runtime installs no build tools). - docs/linux/dnf.md: Fedora/RHEL install + build guide, distinct from apt.md. Tests: packaging-linux.test.js gains Fedora/dnf structural checks (spec Requires + MPL-2.0 + %license + sandbox setup, builder shares staging + requires rpmbuild, dnf build/runtime dep separation, shared staging never copies the whole dev tree). tests/integration/linux/package-rpm.test.sh builds a real .rpm and asserts runtime-only contents (honest skip when rpmbuild is absent, as on this apt host). Verified: 13 packaging unit tests pass; the refactored .deb builder still produces a valid runtime-only package (integration test green); the .rpm integration test skips cleanly where rpmbuild is unavailable. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Executable
+65
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
# Shared staging for the Linux packages. Populates $STAGE_ROOT with the FHS
|
||||
# layout common to the .deb and .rpm: a pruned runtime-only /opt/stepforge, the
|
||||
# launcher, desktop entry, icons, MIME registration, and the license.
|
||||
#
|
||||
# Distro-specific metadata (Depends vs Requires) and the packaging step
|
||||
# (dpkg-deb vs rpmbuild) stay in the per-distro builders. This file only
|
||||
# assembles the payload so the two never drift.
|
||||
#
|
||||
# Usage: ROOT_DIR=<repo> STAGE_ROOT=<dir> bash stage-runtime.sh
|
||||
set -euo pipefail
|
||||
|
||||
: "${ROOT_DIR:?ROOT_DIR must be set}"
|
||||
: "${STAGE_ROOT:?STAGE_ROOT must be set}"
|
||||
|
||||
# A packaged app must contain a fixed runtime; never install at build time and
|
||||
# never ship without node_modules.
|
||||
if [ ! -d "$ROOT_DIR/node_modules/electron/dist" ]; then
|
||||
echo "error: node_modules/electron is missing. Run 'npm ci' before packaging." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
APP_DIR="$STAGE_ROOT/opt/stepforge"
|
||||
mkdir -p "$APP_DIR/node_modules" \
|
||||
"$STAGE_ROOT/usr/bin" \
|
||||
"$STAGE_ROOT/usr/share/applications" \
|
||||
"$STAGE_ROOT/usr/share/mime/packages"
|
||||
|
||||
# --- application code (runtime only) ----------------------------------------
|
||||
for item in app core exporters package.json package-lock.json; do
|
||||
cp -a "$ROOT_DIR/$item" "$APP_DIR/$item"
|
||||
done
|
||||
|
||||
# --- runtime node_modules ----------------------------------------------------
|
||||
# The fixed Electron runtime (needed at runtime even though it is a dev dep):
|
||||
cp -a "$ROOT_DIR/node_modules/electron" "$APP_DIR/node_modules/electron"
|
||||
# Production npm dependencies (tesseract.js + language data + transitive):
|
||||
while IFS= read -r dep; do
|
||||
[ -n "$dep" ] || continue
|
||||
rel="${dep#"$ROOT_DIR"/}"
|
||||
[ "$rel" != "$dep" ] || continue
|
||||
[ -d "$dep" ] || continue
|
||||
mkdir -p "$APP_DIR/$(dirname "$rel")"
|
||||
cp -a "$dep" "$APP_DIR/$rel"
|
||||
done < <(cd "$ROOT_DIR" && npm ls --omit=dev --all --parseable 2>/dev/null | tail -n +2)
|
||||
|
||||
# Guard: the development-only packaging toolchain must not have leaked in.
|
||||
if [ -d "$APP_DIR/node_modules/electron-builder" ] || [ -d "$APP_DIR/node_modules/app-builder-lib" ]; then
|
||||
echo "error: build-only dependency leaked into the package payload." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- launcher ----------------------------------------------------------------
|
||||
install -m 0755 "$ROOT_DIR/packaging/linux/common/launcher.sh" "$STAGE_ROOT/usr/bin/stepforge"
|
||||
|
||||
# --- desktop entry, icons, MIME ---------------------------------------------
|
||||
install -m 0644 "$ROOT_DIR/packaging/linux/common/stepforge.desktop" "$STAGE_ROOT/usr/share/applications/stepforge.desktop"
|
||||
install -m 0644 "$ROOT_DIR/packaging/linux/common/stepforge-mime.xml" "$STAGE_ROOT/usr/share/mime/packages/stepforge.xml"
|
||||
for size in 16 32 48 64 128 256 512; do
|
||||
icon="$ROOT_DIR/packaging/assets/icons/stepforge-${size}.png"
|
||||
[ -f "$icon" ] || continue
|
||||
dest="$STAGE_ROOT/usr/share/icons/hicolor/${size}x${size}/apps"
|
||||
mkdir -p "$dest"
|
||||
install -m 0644 "$icon" "$dest/stepforge.png"
|
||||
done
|
||||
Reference in New Issue
Block a user