Add production .deb packaging, apt setup, desktop integration, and icons
Template tests / tests (pull_request) Failing after 31s
Template tests / tests (pull_request) Failing after 31s
Phase 3 of the improvement plan (PR 8 of the sequence): the apt/X11 packaging half of Linux support, in separate Linux-specific files. Replaces the old scripts/package-linux.sh, which the audit flagged as "not production packaging" (it copied the whole dev node_modules — including vulnerable build deps — plus docs/prompts/examples/audit files, hardcoded amd64, declared only xinput, lacked desktop/icon/MIME integration, and could build without node_modules). Production builder (packaging/linux/debian/package.sh): - Stages ONLY runtime files: app code, a fixed Electron runtime, and the production npm deps (enumerated via npm ls --omit=dev). Never copies the development node_modules; guards against electron-builder/app-builder-lib leaking in. Fails if node_modules is absent instead of shipping an unusable artifact. - Detects architecture (dpkg --print-architecture, x64/arm64) rather than hardcoding amd64. Generates DEBIAN/control from control.in with proper runtime Depends, real maintainer, and homepage. - Installs a desktop entry, hicolor icons (16–512), .sfgz/.sfglt MIME registration, the launcher, and the license. postinst makes chrome-sandbox setuid and refreshes desktop/MIME/icon caches; postrm cleans them. - Emits a .deb, a portable tarball that now INCLUDES /usr/bin/stepforge (the old tarball omitted it), and a sha256 sums file. Launcher (packaging/linux/common/launcher.sh): - Runs sandboxed; prefers the user-namespace sandbox, accepts a root-owned setuid helper, and otherwise refuses to launch with an actionable message. --no-sandbox requires an explicit STEPFORGE_ALLOW_NO_SANDBOX opt-in. Never installs anything at runtime. Setup (separate build vs runtime, apt only): - scripts/linux/apt/install-runtime-deps.sh (Chromium/Electron libs, X11 tools, portal/PipeWire) and install-build-deps.sh (dpkg-dev, fakeroot, xvfb). Runtime script installs no build tools. Assets: original StepForge icon — packaging/assets/stepforge.svg plus a generator (scripts/make-icons.js) that renders the PNG set with the repo's own rasterizer/PNG writer (no third-party art). npm run icons regenerates them. Wiring: package.json gains package:linux:deb / package:linux:rpm / icons; build-release.sh uses the production builder and requires node_modules; README points at the apt/dnf guides. Tests: tests/unit/packaging-linux.test.js (structural: files present in their separate locations, old script gone, valid desktop entry, templated arch + runtime Depends, launcher gates --no-sandbox, builder requires node_modules and guards dev-dep leaks, apt build/runtime dep separation, original icon set generates a valid PNG) runs in the normal suite; tests/integration/linux/package-deb.test.sh builds a real .deb and asserts the right files present and the dev tree / build tooling / app docs absent (honest skip only when dpkg-deb/node_modules are genuinely missing). Verified locally: 276 unit tests pass; the integration test builds and validates stepforge_0.3.2_amd64.deb; build-release E2E passes with the new production package. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Executable
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env sh
|
||||
# StepForge launcher installed at /usr/bin/stepforge.
|
||||
#
|
||||
# Runs the packaged Electron runtime against the installed app at
|
||||
# /opt/stepforge. It NEVER installs or repairs anything at runtime and it does
|
||||
# NOT silently disable the Chromium sandbox: an unsandboxed launch requires the
|
||||
# explicit STEPFORGE_ALLOW_NO_SANDBOX=1 opt-in (development/CI only).
|
||||
|
||||
set -eu
|
||||
|
||||
APP_DIR=/opt/stepforge
|
||||
ELECTRON="$APP_DIR/node_modules/electron/dist/electron"
|
||||
SANDBOX_HELPER="$APP_DIR/node_modules/electron/dist/chrome-sandbox"
|
||||
|
||||
if [ ! -x "$ELECTRON" ]; then
|
||||
echo "stepforge: Electron runtime missing at $ELECTRON (reinstall the package)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$APP_DIR" || exit 1
|
||||
|
||||
# Linux screen capture: enable the PipeWire path for Wayland portals; harmless
|
||||
# on X11 where Ozone auto-selects.
|
||||
COMMON_ARGS="--enable-features=WebRTCPipeWireCapturer --ozone-platform-hint=auto"
|
||||
|
||||
sandbox_ok() {
|
||||
[ -e "$SANDBOX_HELPER" ] || return 1
|
||||
helper_uid="$(stat -c '%u' "$SANDBOX_HELPER" 2>/dev/null || echo '')"
|
||||
helper_mode="$(stat -c '%a' "$SANDBOX_HELPER" 2>/dev/null || echo '')"
|
||||
[ "$helper_uid" = "0" ] || return 1
|
||||
[ -n "$helper_mode" ] || return 1
|
||||
# setuid bit set?
|
||||
[ $(( $((8#$helper_mode)) & 04000 )) -ne 0 ] || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
userns_ok() {
|
||||
# Namespaced sandbox works without the setuid helper on kernels that allow
|
||||
# unprivileged user namespaces.
|
||||
if [ -r /proc/sys/kernel/unprivileged_userns_clone ]; then
|
||||
[ "$(cat /proc/sys/kernel/unprivileged_userns_clone)" = "1" ] && return 0 || return 1
|
||||
fi
|
||||
if [ -r /proc/sys/kernel/apparmor_restrict_unprivileged_userns ]; then
|
||||
[ "$(cat /proc/sys/kernel/apparmor_restrict_unprivileged_userns)" = "0" ] && return 0 || return 1
|
||||
fi
|
||||
[ -e /proc/self/ns/user ] && return 0 || return 1
|
||||
}
|
||||
|
||||
if sandbox_ok || userns_ok; then
|
||||
exec "$ELECTRON" $COMMON_ARGS "$APP_DIR" "$@"
|
||||
fi
|
||||
|
||||
if [ "${STEPFORGE_ALLOW_NO_SANDBOX:-}" = "1" ] || [ "${ELECTRON_DISABLE_SANDBOX:-}" = "1" ]; then
|
||||
echo "stepforge: launching WITHOUT the Chromium sandbox (explicit opt-in)." >&2
|
||||
exec "$ELECTRON" --no-sandbox $COMMON_ARGS "$APP_DIR" "$@"
|
||||
fi
|
||||
|
||||
cat >&2 <<'MSG'
|
||||
stepforge: the Chromium sandbox is not available and StepForge will not launch
|
||||
unsandboxed by default.
|
||||
|
||||
Fix one of the following:
|
||||
* Make the setuid sandbox helper usable:
|
||||
sudo chown root:root /opt/stepforge/node_modules/electron/dist/chrome-sandbox
|
||||
sudo chmod 4755 /opt/stepforge/node_modules/electron/dist/chrome-sandbox
|
||||
* Enable unprivileged user namespaces (kernel/sysctl dependent):
|
||||
sudo sysctl -w kernel.unprivileged_userns_clone=1
|
||||
|
||||
For development/CI only you may set STEPFORGE_ALLOW_NO_SANDBOX=1 to override.
|
||||
MSG
|
||||
exit 1
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
<mime-type type="application/x-stepforge-guide">
|
||||
<comment>StepForge guide archive</comment>
|
||||
<glob pattern="*.sfgz"/>
|
||||
<icon name="stepforge"/>
|
||||
</mime-type>
|
||||
<mime-type type="application/x-stepforge-template">
|
||||
<comment>StepForge export template</comment>
|
||||
<glob pattern="*.sfglt"/>
|
||||
<icon name="stepforge"/>
|
||||
</mime-type>
|
||||
</mime-info>
|
||||
@@ -0,0 +1,13 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=StepForge
|
||||
GenericName=Step-by-step guide capture
|
||||
Comment=Capture, annotate, and export step-by-step guides
|
||||
Exec=stepforge %U
|
||||
Icon=stepforge
|
||||
Terminal=false
|
||||
Categories=Office;Graphics;Utility;
|
||||
Keywords=documentation;screenshot;guide;capture;steps;
|
||||
StartupNotify=true
|
||||
StartupWMClass=StepForge
|
||||
MimeType=application/x-stepforge-guide;
|
||||
Reference in New Issue
Block a user