mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 16:56:33 +00:00
fix(release): surface build versions
This commit is contained in:
parent
3ffaf780e3
commit
3d5e27bdfb
8 changed files with 59 additions and 8 deletions
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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))| {
|
||||
serde_json::json!({ "index": index, "name": name, "width_px": w, "height_px": h })
|
||||
}).collect();
|
||||
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();
|
||||
// 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,
|
||||
|
|
|
|||
|
|
@ -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("/", () => {
|
||||
|
|
|
|||
9
server/src/shared/version.ts
Normal file
9
server/src/shared/version.ts
Normal 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"
|
||||
);
|
||||
}
|
||||
|
|
@ -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" },
|
||||
|
|
|
|||
Loading…
Reference in a new issue