chore(pkg): add Arch Linux PKGBUILDs for game client and sync server

- pkg/solitaire-quest/PKGBUILD: builds solitaire_app binary, depends on
  alsa-lib, libxkbcommon, systemd-libs (Bevy Linux requirements); check()
  runs only non-Bevy crates (solitaire_core, solitaire_sync) since Bevy
  integration tests require a GPU/display unavailable in chroot
- pkg/solitaire-quest-server/PKGBUILD: builds solitaire_server binary,
  installs systemd service unit and hardened environment file template
- pkg/solitaire-quest-server/solitaire-quest-server.service: systemd unit
  with ProtectSystem=strict, NoNewPrivileges, dedicated service user
- pkg/solitaire-quest-server/server.env: documented env template installed
  to /etc/solitaire-quest-server/server.env (mode 0640, listed in backup=)
- LICENSE: add MIT license
- Cargo.toml: add license = "MIT" to [workspace.package]
- All member crates: add license.workspace = true

Both PKGBUILDs follow the Arch Rust package guidelines:
  prepare() uses --locked + cargo fetch
  build() uses --frozen --release -p <crate>
  RUSTUP_TOOLCHAIN=stable and CARGO_TARGET_DIR=target set in each stage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-04-28 22:44:44 +00:00
parent 735d8766a2
commit 800dfb50ce
14 changed files with 177 additions and 0 deletions
+1
View File
@@ -14,6 +14,7 @@ resolver = "2"
[workspace.package]
edition = "2021"
version = "0.1.0"
license = "MIT"
[workspace.dependencies]
serde = { version = "1", features = ["derive"] }
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 funman300
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+63
View File
@@ -0,0 +1,63 @@
# Maintainer: funman300 <funman300@gmail.com>
pkgname=solitaire-quest-server
pkgver=0.1.0
pkgrel=1
pkgdesc='Self-hosted sync server for Solitaire Quest (stats, achievements, leaderboards)'
url='https://github.com/funman300/solitaire-quest'
license=('MIT')
arch=('x86_64')
makedepends=('cargo' 'rust')
depends=(
'gcc-libs'
'glibc'
)
backup=('etc/solitaire-quest-server/server.env')
source=(
"$pkgname-$pkgver.tar.gz::https://github.com/funman300/solitaire-quest/archive/v$pkgver.tar.gz"
'solitaire-quest-server.service'
'server.env'
)
b2sums=('SKIP'
'SKIP'
'SKIP')
prepare() {
cd "solitaire-quest-$pkgver"
export RUSTUP_TOOLCHAIN=stable
cargo fetch --locked --target "$(rustc -Vv | grep host | cut -d' ' -f2)"
}
build() {
cd "solitaire-quest-$pkgver"
export RUSTUP_TOOLCHAIN=stable
export CARGO_TARGET_DIR=target
cargo build --frozen --release -p solitaire_server
}
check() {
cd "solitaire-quest-$pkgver"
export RUSTUP_TOOLCHAIN=stable
cargo test --frozen -p solitaire_server -p solitaire_sync
}
package() {
cd "solitaire-quest-$pkgver"
# Binary
install -Dm0755 -t "$pkgdir/usr/bin/" "target/release/solitaire_server"
# systemd service
install -Dm0644 "$srcdir/solitaire-quest-server.service" \
"$pkgdir/usr/lib/systemd/system/solitaire-quest-server.service"
# Environment file (contains JWT_SECRET, DATABASE_URL, SERVER_PORT)
install -Dm0640 "$srcdir/server.env" \
"$pkgdir/etc/solitaire-quest-server/server.env"
# License
install -Dm0644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
# Self-hosting guide
install -Dm0644 README_SERVER.md \
"$pkgdir/usr/share/doc/$pkgname/README_SERVER.md"
}
+15
View File
@@ -0,0 +1,15 @@
# Solitaire Quest Server — environment configuration
# This file is installed to /etc/solitaire-quest-server/server.env (mode 0640).
# Edit these values before starting the service.
# Path to the SQLite database file.
# The directory must be writable by the solitaire-quest service user.
DATABASE_URL=sqlite:///var/lib/solitaire-quest-server/solitaire.db
# HS256 signing secret for JWT tokens.
# Generate a strong secret with: openssl rand -hex 32
# REQUIRED — server will refuse to start if unset.
JWT_SECRET=changeme_generate_with_openssl_rand_hex_32
# TCP port the server listens on.
SERVER_PORT=8080
@@ -0,0 +1,23 @@
[Unit]
Description=Solitaire Quest Sync Server
Documentation=https://github.com/funman300/solitaire-quest/blob/main/README_SERVER.md
After=network.target
[Service]
Type=simple
User=solitaire-quest
Group=solitaire-quest
EnvironmentFile=/etc/solitaire-quest-server/server.env
ExecStart=/usr/bin/solitaire_server
Restart=on-failure
RestartSec=5s
# Harden the service
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/solitaire-quest-server
[Install]
WantedBy=multi-user.target
+46
View File
@@ -0,0 +1,46 @@
# Maintainer: funman300 <funman300@gmail.com>
pkgname=solitaire-quest
pkgver=0.1.0
pkgrel=1
pkgdesc='Cross-platform Klondike Solitaire with progression, achievements, and optional sync'
url='https://github.com/funman300/solitaire-quest'
license=('MIT')
arch=('x86_64')
makedepends=('cargo' 'rust')
depends=(
'gcc-libs'
'glibc'
'alsa-lib'
'libxkbcommon'
'systemd-libs' # libudev.so — required by Bevy input
)
source=("$pkgname-$pkgver.tar.gz::https://github.com/funman300/solitaire-quest/archive/v$pkgver.tar.gz")
b2sums=('SKIP')
prepare() {
cd "solitaire-quest-$pkgver"
export RUSTUP_TOOLCHAIN=stable
cargo fetch --locked --target "$(rustc -Vv | grep host | cut -d' ' -f2)"
}
build() {
cd "solitaire-quest-$pkgver"
export RUSTUP_TOOLCHAIN=stable
export CARGO_TARGET_DIR=target
cargo build --frozen --release -p solitaire_app
}
check() {
cd "solitaire-quest-$pkgver"
export RUSTUP_TOOLCHAIN=stable
# Only test the non-Bevy crates — Bevy integration tests require a GPU/display
# which is not available in a clean build environment.
cargo test --frozen -p solitaire_core -p solitaire_sync
}
package() {
cd "solitaire-quest-$pkgver"
install -Dm0755 -t "$pkgdir/usr/bin/" "target/release/solitaire_app"
install -Dm0644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
}
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "solitaire_app"
version.workspace = true
license.workspace = true
edition.workspace = true
[[bin]]
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "solitaire_assetgen"
version.workspace = true
license.workspace = true
edition.workspace = true
publish = false
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "solitaire_core"
version.workspace = true
license.workspace = true
edition.workspace = true
[dependencies]
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "solitaire_data"
version.workspace = true
license.workspace = true
edition.workspace = true
[dependencies]
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "solitaire_engine"
version.workspace = true
license.workspace = true
edition.workspace = true
[dependencies]
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "solitaire_gpgs"
version.workspace = true
license.workspace = true
edition.workspace = true
[dependencies]
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "solitaire_server"
version.workspace = true
license.workspace = true
edition.workspace = true
[lib]
+1
View File
@@ -1,6 +1,7 @@
[package]
name = "solitaire_sync"
version.workspace = true
license.workspace = true
edition.workspace = true
[dependencies]