Add Void Linux packaging; fix production builds embedding the frontend
Voiced now ships as a native Void Linux package: - packaging/void/template: xbps-src template - packaging/void/build-xbps.sh: builds and indexes a local .xbps repository - packaging/void/voiced.desktop: application entry Also fixes a real bug: the `custom-protocol` feature was never enabled, so releases ran in development mode and tried to reach a dev server on localhost:1420 instead of serving the embedded frontend. It is now declared in Cargo.toml and passed explicitly by every build script. The Void package output moved out of Vite's `dist/` (which is wiped on each build) to `build/void/`. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
@@ -4,6 +4,7 @@ node_modules/
|
|||||||
# Build output
|
# Build output
|
||||||
dist/
|
dist/
|
||||||
dist-ssr/
|
dist-ssr/
|
||||||
|
build/
|
||||||
|
|
||||||
# Rust / Tauri
|
# Rust / Tauri
|
||||||
src-tauri/target/
|
src-tauri/target/
|
||||||
|
|||||||
@@ -90,6 +90,35 @@ distributions that don't package NSIS (e.g. Void Linux):
|
|||||||
With those in place, `npm run app:build:windows` produces the NSIS `-setup.exe` and the
|
With those in place, `npm run app:build:windows` produces the NSIS `-setup.exe` and the
|
||||||
portable `voiced.exe`.
|
portable `voiced.exe`.
|
||||||
|
|
||||||
|
## Installing on Void Linux
|
||||||
|
|
||||||
|
Two ways to get a native `.xbps` package.
|
||||||
|
|
||||||
|
### Prebuilt binary package (no xbps-src needed)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./packaging/void/build-xbps.sh # -> build/void/repo/voiced-<version>_1.<arch>.xbps
|
||||||
|
echo "repository=$(pwd)/build/void/repo" | sudo tee /etc/xbps.d/99-voiced-local.conf
|
||||||
|
sudo xbps-install -Sy voiced
|
||||||
|
```
|
||||||
|
|
||||||
|
Launch **Voiced** from the application menu, or run `voiced`. Remove it with
|
||||||
|
`sudo xbps-remove voiced`.
|
||||||
|
|
||||||
|
The package installs `/usr/bin/voiced`, a desktop entry and hicolor icons, and depends on
|
||||||
|
`libwebkit2gtk41`.
|
||||||
|
|
||||||
|
### Building through xbps-src
|
||||||
|
|
||||||
|
Copy `packaging/void/template` into a `void-packages` checkout and build it the standard way:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp -r packaging/void/template void-packages/srcpkgs/voiced/template
|
||||||
|
cd void-packages && ./xbps-src pkg voiced
|
||||||
|
```
|
||||||
|
|
||||||
|
See the comments at the top of the template about the private source archive and checksums.
|
||||||
|
|
||||||
## Where data lives
|
## Where data lives
|
||||||
|
|
||||||
| What | Location |
|
| What | Location |
|
||||||
@@ -108,6 +137,7 @@ src/ React + Carbon frontend
|
|||||||
src-tauri/ Rust backend (Tauri commands, SQLite schema, asset store)
|
src-tauri/ Rust backend (Tauri commands, SQLite schema, asset store)
|
||||||
public/brand/ Bongbetic + vendor brand assets
|
public/brand/ Bongbetic + vendor brand assets
|
||||||
public/fonts/ IBM Plex (woff/woff2)
|
public/fonts/ IBM Plex (woff/woff2)
|
||||||
|
packaging/void/ Void Linux packaging (xbps-src template + build script + desktop entry)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Ownership
|
## Ownership
|
||||||
|
|||||||
+2
-2
@@ -11,8 +11,8 @@
|
|||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"tauri": "tauri",
|
"tauri": "tauri",
|
||||||
"app:dev": "tauri dev",
|
"app:dev": "tauri dev",
|
||||||
"app:build": "tauri build",
|
"app:build": "tauri build --features custom-protocol",
|
||||||
"app:build:windows": "tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc"
|
"app:build:windows": "tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc --features custom-protocol"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@carbon/icons-react": "^11.89.0",
|
"@carbon/icons-react": "^11.89.0",
|
||||||
|
|||||||
Executable
+87
@@ -0,0 +1,87 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Build a Void Linux binary package (.xbps) for Voiced from this source tree,
|
||||||
|
# without needing the full xbps-src / void-packages setup.
|
||||||
|
#
|
||||||
|
# ./packaging/void/build-xbps.sh
|
||||||
|
#
|
||||||
|
# Output:
|
||||||
|
# dist/void/repo/voiced-<version>_1.<arch>.xbps (and a local repository index)
|
||||||
|
#
|
||||||
|
# Install it with:
|
||||||
|
# sudo xbps-install -S --repository="$(pwd)/dist/void/repo" voiced
|
||||||
|
#
|
||||||
|
# Remove it with:
|
||||||
|
# sudo xbps-remove voiced
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
|
cd "$ROOT"
|
||||||
|
|
||||||
|
need() {
|
||||||
|
command -v "$1" >/dev/null 2>&1 || { echo "error: '$1' is required but not on PATH" >&2; exit 1; }
|
||||||
|
}
|
||||||
|
for tool in xbps-create xbps-rindex node npm cargo; do need "$tool"; done
|
||||||
|
|
||||||
|
VERSION="$(node -p "require('./package.json').version")"
|
||||||
|
REVISION="${REVISION:-1}"
|
||||||
|
ARCH="$(xbps-uhelper arch 2>/dev/null || uname -m)"
|
||||||
|
PKGVER="voiced-${VERSION}_${REVISION}"
|
||||||
|
|
||||||
|
echo "==> Building the Linux binary (frontend embedded via the Tauri CLI)"
|
||||||
|
npx tauri build --no-bundle --features custom-protocol
|
||||||
|
|
||||||
|
BIN="src-tauri/target/release/voiced"
|
||||||
|
[ -x "$BIN" ] || { echo "error: expected binary not found at $BIN" >&2; exit 1; }
|
||||||
|
|
||||||
|
echo "==> Staging install tree"
|
||||||
|
STAGE="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$STAGE"' EXIT
|
||||||
|
|
||||||
|
install -Dm755 "$BIN" "$STAGE/usr/bin/voiced"
|
||||||
|
install -Dm644 packaging/void/voiced.desktop "$STAGE/usr/share/applications/voiced.desktop"
|
||||||
|
|
||||||
|
install_icon() {
|
||||||
|
[ -f "$1" ] || return 0
|
||||||
|
install -Dm644 "$1" "$STAGE/usr/share/icons/hicolor/$2/apps/voiced.png"
|
||||||
|
}
|
||||||
|
install_icon src-tauri/icons/32x32.png 32x32
|
||||||
|
install_icon src-tauri/icons/64x64.png 64x64
|
||||||
|
install_icon src-tauri/icons/128x128.png 128x128
|
||||||
|
install_icon src-tauri/icons/128x128@2x.png 256x256
|
||||||
|
install_icon src-tauri/icons/icon.png 512x512
|
||||||
|
|
||||||
|
install -Dm644 README.md "$STAGE/usr/share/doc/voiced/README.md"
|
||||||
|
|
||||||
|
echo "==> Creating $PKGVER.$ARCH.xbps"
|
||||||
|
# Kept outside Vite's `dist/` output directory, which is wiped on every build.
|
||||||
|
OUT="$ROOT/build/void"
|
||||||
|
REPO="$OUT/repo"
|
||||||
|
mkdir -p "$REPO"
|
||||||
|
|
||||||
|
# xbps-create writes the package into the current directory.
|
||||||
|
(
|
||||||
|
cd "$OUT"
|
||||||
|
xbps-create \
|
||||||
|
-A "$ARCH" \
|
||||||
|
-n "$PKGVER" \
|
||||||
|
-s "Offline invoicing app by Bongbetic" \
|
||||||
|
-S "Voiced is an offline-first invoice generator with automatic numbering, GST support, optional signatures and print-ready PDF export." \
|
||||||
|
-l "proprietary" \
|
||||||
|
-H "https://git.bongbetic.com/xavierk/Voiced" \
|
||||||
|
-m "Xavier Karma <xavier@bongbetic.com>" \
|
||||||
|
-D "libwebkit2gtk41>=2.40_1" \
|
||||||
|
-t "office finance" \
|
||||||
|
--compression zstd \
|
||||||
|
"$STAGE"
|
||||||
|
)
|
||||||
|
|
||||||
|
mv -f "$OUT"/${PKGVER}.*.xbps "$REPO/"
|
||||||
|
|
||||||
|
echo "==> Indexing local repository"
|
||||||
|
xbps-rindex -a "$REPO"/*.xbps
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Package: $REPO/${PKGVER}.${ARCH}.xbps"
|
||||||
|
echo "Install: sudo xbps-install -S --repository=\"$REPO\" voiced"
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
# Template file for 'voiced'
|
||||||
|
#
|
||||||
|
# Canonical Void Linux package definition, to be built with xbps-src from a
|
||||||
|
# void-packages checkout:
|
||||||
|
#
|
||||||
|
# cp -r packaging/void/template void-packages/srcpkgs/voiced/template
|
||||||
|
# cd void-packages && ./xbps-src pkg voiced
|
||||||
|
#
|
||||||
|
# Notes:
|
||||||
|
# * `distfiles` points at a tagged archive of the (private) source repository.
|
||||||
|
# Private repositories require credentials, so either publish a release
|
||||||
|
# tarball, mirror it, or drop the sources into the xbps-src masterdir.
|
||||||
|
# * `checksum=SKIP` avoids pinning a hash that cannot be computed here; replace
|
||||||
|
# it with the real sha256 once the tarball is published.
|
||||||
|
# * If the build machine is offline, pre-populate the npm cache and Cargo
|
||||||
|
# registry in the masterdir before building.
|
||||||
|
#
|
||||||
|
pkgname=voiced
|
||||||
|
version=0.1.0
|
||||||
|
revision=1
|
||||||
|
archs="x86_64*"
|
||||||
|
hostmakedepends="rust nodejs pkg-config"
|
||||||
|
makedepends="libwebkit2gtk41-devel libsoup3-devel gtk+3-devel librsvg-devel openssl-devel"
|
||||||
|
depends="libwebkit2gtk41"
|
||||||
|
short_desc="Offline invoicing app by Bongbetic"
|
||||||
|
maintainer="Xavier Karma <xavier@bongbetic.com>"
|
||||||
|
license="custom:proprietary"
|
||||||
|
homepage="https://git.bongbetic.com/xavierk/Voiced"
|
||||||
|
distfiles="https://git.bongbetic.com/xavierk/Voiced/archive/v${version}.tar.gz"
|
||||||
|
checksum=SKIP
|
||||||
|
compression="zstd"
|
||||||
|
|
||||||
|
do_build() {
|
||||||
|
npm install --include=dev --no-audit --no-fund
|
||||||
|
npm run build
|
||||||
|
cd src-tauri
|
||||||
|
# `custom-protocol` embeds the frontend for production; without it the app
|
||||||
|
# expects a dev server on localhost:1420.
|
||||||
|
cargo build --release --features custom-protocol
|
||||||
|
}
|
||||||
|
|
||||||
|
do_install() {
|
||||||
|
vbin "${wrksrc}/src-tauri/target/release/voiced"
|
||||||
|
vinstall "${wrksrc}/packaging/void/voiced.desktop" 644 usr/share/applications
|
||||||
|
for size in 32 64 128; do
|
||||||
|
vinstall "${wrksrc}/src-tauri/icons/${size}x${size}.png" 644 \
|
||||||
|
"usr/share/icons/hicolor/${size}x${size}/apps" voiced.png
|
||||||
|
done
|
||||||
|
vinstall "${wrksrc}/src-tauri/icons/128x128@2x.png" 644 \
|
||||||
|
usr/share/icons/hicolor/256x256/apps voiced.png
|
||||||
|
vinstall "${wrksrc}/src-tauri/icons/icon.png" 644 \
|
||||||
|
usr/share/icons/hicolor/512x512/apps voiced.png
|
||||||
|
vdoc "${wrksrc}/README.md"
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Version=1.0
|
||||||
|
Name=Voiced
|
||||||
|
GenericName=Invoice Generator
|
||||||
|
Comment=Offline invoicing by Bongbetic
|
||||||
|
Exec=voiced
|
||||||
|
Icon=voiced
|
||||||
|
Terminal=false
|
||||||
|
Categories=Office;Finance;
|
||||||
|
Keywords=invoice;billing;gst;pdf;bongbetic;
|
||||||
|
StartupNotify=true
|
||||||
|
StartupWMClass=Voiced
|
||||||
@@ -26,6 +26,12 @@ uuid = { version = "1", features = ["v4"] }
|
|||||||
thiserror = "2"
|
thiserror = "2"
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
# Production builds embed the frontend and serve it over the custom asset
|
||||||
|
# protocol. Without this, the app expects a dev server on localhost:1420.
|
||||||
|
# DO NOT REMOVE.
|
||||||
|
custom-protocol = ["tauri/custom-protocol"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
lto = true
|
lto = true
|
||||||
|
|||||||
Reference in New Issue
Block a user