fix(release): surface build versions

This commit is contained in:
Mitchell R 2026-05-21 08:51:41 +02:00
parent 3ffaf780e3
commit 3d5e27bdfb
No known key found for this signature in database
8 changed files with 59 additions and 8 deletions

View file

@ -81,6 +81,7 @@ jobs:
working-directory: kiosk
env:
BF_BUILD_ARCH: ${{ matrix.target }}
BF_BUILD_VERSION: ${{ inputs.version }}
run: cargo build --release --target ${{ matrix.target }}
- name: Strip + rename

View file

@ -1,7 +1,7 @@
# BetterFrame server image — Node 23 + native deps for argon2/sqlite.
# BetterFrame server image — Node 24 + native deps for argon2/sqlite.
# Trixie base (Debian 13, latest stable) — matches the host distro we
# recommend in deploy/README.md.
FROM node:23-trixie-slim AS builder
FROM node:24-trixie-slim AS builder
WORKDIR /app
@ -22,7 +22,9 @@ WORKDIR /app/server
RUN npm run build
# ---- Runtime image ----
FROM node:23-trixie-slim
FROM node:24-trixie-slim
ARG BF_SERVER_VERSION=
# ffmpeg for camera snapshot capture (optional but needed for /admin/entities/:id/snapshot)
RUN apt-get update && apt-get install -y --no-install-recommends \
@ -51,5 +53,6 @@ USER betterframe
WORKDIR /app/server
ENV NODE_OPTIONS=--import=tsx
ENV BF_SERVER_VERSION=${BF_SERVER_VERSION}
CMD ["node", "--import", "tsx", "/app/node_modules/@bsb/base/lib/scripts/bsb-plugin-cli.js", "start"]

View file

@ -17,6 +17,8 @@ services:
build:
context: .
dockerfile: deploy/docker/Dockerfile.server
args:
BF_SERVER_VERSION: ${BF_SERVER_VERSION:-}
container_name: betterframe-server
restart: unless-stopped
environment:
@ -25,6 +27,9 @@ services:
- BF_SQLITE_PATH=/var/lib/betterframe/betterframe.db
- BF_NODERED_URL=http://nodered:1880
- BF_SELF_URL=http://server:18080
- BF_SERVER_VERSION=${BF_SERVER_VERSION:-}
- COOLIFY_GIT_COMMIT=${COOLIFY_GIT_COMMIT:-}
- SOURCE_COMMIT=${SOURCE_COMMIT:-}
volumes:
- betterframe-data:/var/lib/betterframe
expose:

View file

@ -27,6 +27,8 @@ services:
build:
context: .
dockerfile: deploy/docker/Dockerfile.server
args:
BF_SERVER_VERSION: ${BF_SERVER_VERSION:-}
container_name: betterframe-server
restart: unless-stopped
# Env overrides win over sec-config.yaml — Coolify / k8s inject these.
@ -36,6 +38,9 @@ services:
- BF_SQLITE_PATH=/var/lib/betterframe/betterframe.db
- BF_NODERED_URL=http://nodered:1880
- BF_SELF_URL=http://server:18080
- BF_SERVER_VERSION=${BF_SERVER_VERSION:-}
- COOLIFY_GIT_COMMIT=${COOLIFY_GIT_COMMIT:-}
- SOURCE_COMMIT=${SOURCE_COMMIT:-}
# Optional: paste Ed25519 PEM private key here for firmware signing.
# - BF_FIRMWARE_SIGNING_KEY=
# Optional: single-purpose Bearer token for GitHub Actions firmware import.

View file

@ -7,6 +7,10 @@ use tracing::info;
use crate::bundle::KioskBundle;
fn kiosk_app_version() -> &'static str {
option_env!("BF_BUILD_VERSION").unwrap_or(env!("CARGO_PKG_VERSION"))
}
fn state_dir() -> PathBuf {
let home = dirs::home_dir().expect("no home directory");
let dir = home.join(".betterframe-kiosk");
@ -258,9 +262,13 @@ pub fn heartbeat(
hw: &crate::hwmon::HwInfo,
) -> bool {
let client = reqwest::blocking::Client::new();
let display_info: Vec<_> = displays.iter().enumerate().map(|(index, (name, w, h))| {
let display_info: Vec<_> = displays
.iter()
.enumerate()
.map(|(index, (name, w, h))| {
serde_json::json!({ "index": index, "name": name, "width_px": w, "height_px": h })
}).collect();
})
.collect();
// Surface the LAN-side local key + port to admin so the UI can show a
// copy-paste URL for bookmark-style layout switches.
let local_key = load_or_create_local_key();
@ -272,7 +280,7 @@ pub fn heartbeat(
.post(format!("{server}/api/kiosk/heartbeat"))
.header("Authorization", format!("Bearer {key}"))
.json(&serde_json::json!({
"kiosk_app_version": env!("CARGO_PKG_VERSION"),
"kiosk_app_version": kiosk_app_version(),
"displays": display_info,
"cpu_temp_c": hw.cpu_temp_c,
"cpu_load_percent": hw.cpu_load_percent,

View file

@ -22,6 +22,7 @@ import { initNoderedBridge, type NoderedBridge } from "../../shared/nodered-brid
import { initFirmware, type FirmwareApi } from "../../shared/firmware.js";
import { initOsUpdates, type OsUpdateApi } from "../../shared/os-updates.js";
import { envStr } from "../../shared/env-overrides.js";
import { serverVersion } from "../../shared/version.js";
import type { Repository } from "../service-store/repository.js";
import { registerMiddleware } from "./middleware.js";
@ -207,7 +208,7 @@ export class Plugin extends BSBService<InstanceType<typeof Config>, typeof Event
});
app.get("/version", () => ({
name: "betterframe",
version: "0.1.0",
version: serverVersion(),
now: new Date().toISOString(),
}));
app.get("/", () => {

View file

@ -0,0 +1,9 @@
export function serverVersion(): string {
return (
process.env.BF_SERVER_VERSION
|| process.env.BF_BUILD_VERSION
|| process.env.COOLIFY_GIT_COMMIT
|| process.env.SOURCE_COMMIT
|| "dev"
);
}

View file

@ -3,6 +3,7 @@
* Server-side rendered via jsx-htmx returns string.
*/
import { css, js } from "jsx-htmx";
import { serverVersion } from "../shared/version.js";
// ---- Shared types -----------------------------------------------------------
@ -64,6 +65,7 @@ function Sidebar(props: { activeNav?: string }) {
// ---- Layout -----------------------------------------------------------------
export function Layout(props: PageProps) {
const version = serverVersion();
return (
<html lang="en">
<head>
@ -92,6 +94,12 @@ export function Layout(props: PageProps) {
<div class={`flash flash-${props.flash.type}`}>{props.flash.message}</div>
)}
<main class="content">{props.children}</main>
{!props.minimal && (
<footer class="app-footer">
<span>Copyright BetterCorp (PTY) Ltd 2016 - 2026 - All Rights Reserved</span>
<span>Server: <code>{version}</code></span>
</footer>
)}
</div>
<script src="/static/htmx.min.js"></script>
</body>
@ -176,6 +184,17 @@ const baseStyles = {
".topbar-user": { color: "#666", fontSize: "0.85rem" },
".main-wrap": { display: "flex", flexDirection: "column", minHeight: "100vh" },
".content": { flex: "1", padding: "1.5rem" },
".app-footer": {
display: "flex",
justifyContent: "space-between",
gap: "1rem",
padding: "0.75rem 1.5rem",
color: "#666",
fontSize: "0.8rem",
borderTop: "1px solid #e0e0e0",
backgroundColor: "#fff",
},
".app-footer code": { color: "#374151", fontSize: "0.8rem" },
".minimal .content": { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "100vh" },
".center-card": { width: "100%", maxWidth: "420px" },
".auth-logo": { display: "block", width: "220px", maxWidth: "100%", height: "auto", margin: "0 0 1.25rem" },