This commit is contained in:
Priec
2026-09-02 13:33:28 +02:00
parent 2b2edbd816
commit 6f37284f8c
8 changed files with 388 additions and 1 deletions

View File

@@ -0,0 +1,59 @@
# Combined Linux Flatpak
This packaging builds `server` with `full-embed` and `client-gui2` inside the
GNOME 50 Flatpak SDK, then exports a single x86_64 Flatpak bundle. It is an
additive alternative to the AppImage packaging; the existing AppImage build is
unchanged.
The build uses the official Flatpak Rust and Node SDK extensions. Cargo and
Yarn resolve the committed lockfiles inside the build sandbox with network
access. The PostgreSQL 17.10.0 archive, Typst 0.13.1 binary and protoc 21.12
binary are downloaded by `flatpak-builder` as checksum-pinned sources.
## Build
Install `flatpak` and `flatpak-builder` through the host package manager, then
run from the repository root:
```sh
packaging/flatpak/build.sh
```
The script configures the per-user Flathub remote when necessary, installs the
GNOME SDK and SDK extensions through `flatpak-builder`, retains its reusable
cache below `${XDG_CACHE_HOME:-$HOME/.cache}/komp-ac-flatpak-builder`, and
creates:
```text
flatpak-dist/KompAC-embedded-x86_64.flatpak
```
An alternative output directory and filename may be supplied:
```sh
packaging/flatpak/build.sh /path/to/releases KompAC-0.8.50-x86_64.flatpak
```
## Install and run
On the destination machine, install Flatpak through the system package manager
and configure Flathub if it is not already available. Then install and run:
```sh
flatpak install ./KompAC-embedded-x86_64.flatpak
flatpak run com.kompac.client
```
The bundle records Flathub as the source of its GNOME runtime. The first
installation therefore downloads the runtime when it is not already installed.
For an offline destination, transfer the runtime through a Flatpak repository
or offline-update workflow as well as the application bundle.
Application configuration and embedded database state live in Flatpak's
per-user persistent XDG directories. Typst is included for document rendering;
no host Typst installation or `.env` file is required.
The manifest deliberately grants build-time network access for the locked
Cargo and Yarn dependency graphs. This keeps private bundle builds automatic.
A Flathub submission should replace that build permission with generated Cargo
and Yarn source manifests from `flatpak-builder-tools`.

77
packaging/flatpak/build.sh Executable file
View File

@@ -0,0 +1,77 @@
#!/bin/bash
set -euo pipefail
if [[ $# -gt 2 ]]; then
echo "Usage: $0 [OUTPUT_DIRECTORY] [OUTPUT_FILENAME]" >&2
exit 2
fi
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd -- "$script_dir/../.." && pwd)"
output_directory="${1:-$repo_root/flatpak-dist}"
output_name="${2:-KompAC-embedded-x86_64.flatpak}"
if [[ "$output_name" == */* || "$output_name" != *.flatpak ]]; then
echo "OUTPUT_FILENAME must be a portable filename ending in .flatpak" >&2
exit 2
fi
if [[ "$(uname -m)" != x86_64 ]]; then
echo "The Flatpak production build currently supports x86_64 only" >&2
exit 1
fi
for command in flatpak flatpak-builder; do
if ! command -v "$command" >/dev/null 2>&1; then
echo "$command is required to build the Flatpak" >&2
exit 1
fi
done
mkdir -p "$output_directory"
output_directory="$(cd -- "$output_directory" && pwd)"
cache_home="${XDG_CACHE_HOME:-${HOME:?HOME is not set}/.cache}"
state_dir="$cache_home/komp-ac-flatpak-builder"
mkdir -p "$state_dir"
work_dir="$(mktemp -d /tmp/komp-ac-flatpak-build.XXXXXX)"
cleanup() {
case "$work_dir" in
/tmp/komp-ac-flatpak-build.*)
rm -rf -- "$work_dir"
;;
*)
echo "Refusing to remove unexpected Flatpak workspace: $work_dir" >&2
;;
esac
}
trap cleanup EXIT INT TERM HUP
flathub_repository=https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak remote-add --user --if-not-exists flathub "$flathub_repository"
echo "Building Komp AC against the GNOME 50 Flatpak runtime"
echo " output: $output_directory/$output_name"
echo " cache: $state_dir"
echo
cd "$script_dir"
flatpak-builder \
--user \
--install-deps-from=flathub \
--force-clean \
--state-dir="$state_dir" \
--repo="$work_dir/repository" \
"$work_dir/build" \
com.kompac.client.yml
flatpak build-bundle \
--runtime-repo="$flathub_repository" \
"$work_dir/repository" \
"$work_dir/$output_name" \
com.kompac.client \
stable
cp -- "$work_dir/$output_name" "$output_directory/$output_name"
echo "Created $output_directory/$output_name"

View File

@@ -0,0 +1,8 @@
[Desktop Entry]
Type=Application
Name=Komp AC
Comment=Accounting application
Exec=komp-ac
Icon=com.kompac.client
Terminal=false
Categories=Office;Finance;

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>com.kompac.client</id>
<name>Komp AC</name>
<summary>Accounting application</summary>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0-or-later AND AGPL-3.0-or-later</project_license>
<developer id="com.kompac">
<name>Filip Priečinský</name>
</developer>
<url type="homepage">https://gitlab.com/filipriec/komp_ac</url>
<description>
<p>Komp AC is an accounting application with an embedded PostgreSQL database.</p>
</description>
<launchable type="desktop-id">com.kompac.client.desktop</launchable>
<content_rating type="oars-1.1"/>
<releases>
<release version="0.8.50" date="2026-09-02"/>
</releases>
</component>

View File

@@ -0,0 +1,117 @@
id: com.kompac.client
branch: stable
runtime: org.gnome.Platform
runtime-version: "50"
sdk: org.gnome.Sdk
command: komp-ac
sdk-extensions:
- org.freedesktop.Sdk.Extension.node22
- org.freedesktop.Sdk.Extension.rust-stable
finish-args:
- --share=ipc
- --share=network
- --socket=wayland
- --socket=fallback-x11
- --device=dri
- --env=GTK_USE_PORTAL=1
- --talk-name=org.a11y.Bus
build-options:
append-path: /usr/lib/sdk/node22/bin:/usr/lib/sdk/rust-stable/bin
modules:
- name: komp-ac
buildsystem: simple
build-options:
strip: true
no-debuginfo: true
build-args:
- --share=network
env:
HOME: /run/build/komp-ac
CARGO_HOME: /run/build/komp-ac/cargo-home
CARGO_TARGET_DIR: /run/build/komp-ac/target/server
COREPACK_HOME: /run/build/komp-ac/corepack
POSTGRESQL_VERSION: "=17.10.0"
PROTOC: /app/bin/protoc
PROTOC_INCLUDE: /app/include
RUSTFLAGS: ""
SQLX_OFFLINE: "true"
YARN_CACHE_FOLDER: /run/build/komp-ac/yarn-cache
sources:
- type: dir
path: ../..
skip:
- .git
- .agents
- .codex
- .codex-scheduled
- .direnv
- .env
- .env.*
- .env_*
- .envrc
- .idea
- .vscode
- "*.log"
- target
- "*/target"
- node_modules
- "*/node_modules"
- client-gui2/dist
- client-gui2/dist-ssr
- client-gui2/coverage
- client-gui2/.vite
- debian-dist
- flatpak-dist
- result
- result-*
- tantivy_indexes
- "*/tantivy_indexes"
- dumps
- "*/dumps"
- .postgres-data
- "*/.postgres-data"
- benchmark-results
- "*/benchmark-results"
- testing
- run_bins
- corporate_erp
- type: archive
url: https://github.com/protocolbuffers/protobuf/releases/download/v21.12/protoc-21.12-linux-x86_64.zip
sha256: 3a4c1e5f2516c639d3079b1586e703fc7bcfa2136d58bda24d1d54f949c315e8
dest: protoc-source
- type: file
url: https://github.com/theseus-rs/postgresql-binaries/releases/download/17.10.0/postgresql-17.10.0-x86_64-unknown-linux-gnu.tar.gz
sha256: 333937dac26a33d367810b0db20892bbca6cf244f670e26f54f3e0b57dcb50b6
dest: postgresql-cache
dest-filename: postgresql-17.10.0-x86_64-unknown-linux-gnu.tar.gz
- type: archive
url: https://github.com/typst/typst/releases/download/v0.13.1/typst-x86_64-unknown-linux-musl.tar.xz
sha256: 7d214bfeffc2e585dc422d1a09d2b144969421281e8c7f5d784b65fc69b5673f
dest: typst-source
build-commands:
- install -Dm755 protoc-source/bin/protoc /app/bin/protoc
- install -d /app/include
- cp -a protoc-source/include/. /app/include/
- mkdir -p "$HOME/.theseus/postgresql"
- cp postgresql-cache/postgresql-17.10.0-x86_64-unknown-linux-gnu.tar.gz "$HOME/.theseus/postgresql/"
- cargo build --locked --release --package server --features full-embed
- cd client-gui2 && corepack yarn install --frozen-lockfile --non-interactive
- cd client-gui2 && CARGO_TARGET_DIR=/run/build/komp-ac/target/gui corepack yarn tauri build --no-bundle
- install -Dm755 /run/build/komp-ac/target/server/release/server /app/bin/komp-ac-server
- install -Dm755 /run/build/komp-ac/target/gui/release/client-gui2 /app/bin/client-gui2
- install -Dm755 packaging/flatpak/launcher.sh /app/bin/komp-ac
- install -Dm755 typst-source/typst-x86_64-unknown-linux-musl/typst /app/bin/typst
- install -d /app/lib/komp_ac/themes
- cp -a client/runtime/themes/. /app/lib/komp_ac/themes/
- install -Dm644 packaging/flatpak/com.kompac.client.desktop /app/share/applications/com.kompac.client.desktop
- install -Dm644 packaging/flatpak/com.kompac.client.metainfo.xml /app/share/metainfo/com.kompac.client.metainfo.xml
- install -Dm644 client-gui2/src-tauri/icons/32x32.png /app/share/icons/hicolor/32x32/apps/com.kompac.client.png
- install -Dm644 client-gui2/src-tauri/icons/128x128.png /app/share/icons/hicolor/128x128/apps/com.kompac.client.png
- install -Dm644 client-gui2/src-tauri/icons/128x128@2x.png /app/share/icons/hicolor/256x256/apps/com.kompac.client.png
cleanup:
- /bin/protoc
- /include

105
packaging/flatpak/launcher.sh Executable file
View File

@@ -0,0 +1,105 @@
#!/bin/bash
set -u
umask 077
data_home="${XDG_DATA_HOME:-${HOME:?HOME is not set}/.local/share}"
data_root="${KOMP_AC_DATA_DIR:-$data_home/komp_ac}"
postgres_root="$data_root/postgresql"
dump_root="$data_root/dumps"
tantivy_root="$data_root/tantivy_indexes"
secret_file="$data_root/jwt.secret"
log_file="$data_root/server.log"
lock_dir="$data_root/flatpak.lock"
server=/app/bin/komp-ac-server
gui=/app/bin/client-gui2
mkdir -p "$data_root" "$postgres_root" "$dump_root" "$tantivy_root"
if [[ ! -s "$secret_file" ]]; then
secret_tmp="$secret_file.$$"
if ! od -An -N 48 -tx1 /dev/urandom | tr -d ' \n' > "$secret_tmp"; then
rm -f -- "$secret_tmp"
echo "Komp AC: could not generate the local server secret" >&2
exit 1
fi
chmod 600 "$secret_tmp"
if [[ -e "$secret_file" ]]; then
rm -f -- "$secret_tmp"
else
mv -- "$secret_tmp" "$secret_file"
fi
fi
if ! mkdir "$lock_dir" 2>/dev/null; then
lock_pid=""
if [[ -r "$lock_dir/pid" ]]; then
read -r lock_pid < "$lock_dir/pid" || true
fi
if [[ "$lock_pid" =~ ^[0-9]+$ ]] && kill -0 "$lock_pid" 2>/dev/null; then
echo "Komp AC is already running (launcher PID $lock_pid)." >&2
exit 1
fi
rm -f -- "$lock_dir/pid"
if ! rmdir "$lock_dir" 2>/dev/null || ! mkdir "$lock_dir" 2>/dev/null; then
echo "Komp AC: could not acquire the application lock at $lock_dir" >&2
exit 1
fi
fi
printf '%s\n' "$$" > "$lock_dir/pid"
server_pid=""
cleanup() {
status=$?
trap - EXIT INT TERM HUP
if [[ -n "$server_pid" ]] && kill -0 "$server_pid" 2>/dev/null; then
kill -TERM "$server_pid" 2>/dev/null || true
wait "$server_pid" 2>/dev/null || true
fi
rm -f -- "$lock_dir/pid"
rmdir "$lock_dir" 2>/dev/null || true
exit "$status"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
trap 'exit 129' HUP
export GRPC_ENDPOINT=http://127.0.0.1:50051
export KOMP_AC_TYPST=/app/bin/typst
if (exec 3<>/dev/tcp/127.0.0.1/50051) 2>/dev/null; then
echo "Komp AC: local port 50051 is already in use" >&2
exit 1
fi
RUST_DB_MODE=embedded \
KOMP_AC_POSTGRES_DIR="$postgres_root" \
PG_DUMP_DIR="$dump_root" \
TANTIVY_INDEX_DIR="$tantivy_root" \
JWT_SECRET="$(<"$secret_file")" \
GRPC_LISTEN_ADDRESS=127.0.0.1:50051 \
"$server" server >> "$log_file" 2>&1 &
server_pid=$!
ready=false
for ((attempt = 0; attempt < 600; attempt++)); do
if ! kill -0 "$server_pid" 2>/dev/null; then
wait "$server_pid" || true
echo "Komp AC: the bundled server failed to start; see $log_file" >&2
exit 1
fi
if (exec 3<>/dev/tcp/127.0.0.1/50051) 2>/dev/null; then
ready=true
break
fi
sleep 0.1
done
if [[ "$ready" != true ]]; then
echo "Komp AC: the bundled server did not become ready; see $log_file" >&2
exit 1
fi
"$gui"