Enhance build metadata handling and server info logging
Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit

Add a function to write build metadata to src/buildInfo.json during the build process in Jenkinsfile. Update local server to include version and build number in the /info endpoint response. Modify index.js to log detailed host information when the --info flag is used. Update .gitignore to include src/buildInfo.json and adjust config.json with new host credentials.
This commit is contained in:
Tom Butcher 2026-07-26 23:14:04 +01:00
parent 997b374e0e
commit a62df6a5c6
7 changed files with 97 additions and 19 deletions

4
.gitignore vendored
View File

@ -138,4 +138,6 @@ build
temp_files/*
dist/*
dist/*
src/buildInfo.json

22
Jenkinsfile vendored
View File

@ -1,3 +1,17 @@
def writeBuildMetadata() {
nodejs(nodeJSInstallationName: 'Node23') {
if (isUnix()) {
sh '''
node -e "const fs = require('fs'); fs.writeFileSync('src/buildInfo.json', JSON.stringify({ buildNumber: process.env.BUILD_NUMBER || 'dev' }, null, 2) + '\\n');"
'''
} else {
bat '''
node -e "const fs = require('fs'); fs.writeFileSync('src/buildInfo.json', JSON.stringify({ buildNumber: process.env.BUILD_NUMBER || 'dev' }, null, 2) + '\\n');"
'''
}
}
}
def buildLinux() {
node('ubuntu') {
try {
@ -18,6 +32,10 @@ def buildLinux() {
}
}
stage('Write Build Metadata (Ubuntu)') {
writeBuildMetadata()
}
stage('Build (Ubuntu)') {
nodejs(nodeJSInstallationName: 'Node23') {
sh "VITE_BUILD_NUMBER=${env.BUILD_NUMBER} NODE_ENV=production pnpm build:linux"
@ -62,6 +80,10 @@ def buildOnLabel(label, buildCommand) {
}
}
stage("Write Build Metadata (${label})") {
writeBuildMetadata()
}
stage("Build (${label})") {
nodejs(nodeJSInstallationName: 'Node23') {
if (isUnix()) {

View File

@ -4,8 +4,8 @@
"url": "https://dev-wss.tombutcher.work",
"apiUrl": "https://dev.tombutcher.work/api",
"host": {
"id": "691a1db49ce913faf0e51284",
"authCode": "BNj13heKj9zUZIJ0IodSU-V-OSZHNJGAA-nLa4nwFrDHa6N1wah7mpw_7pqbT9Il"
"id": "6a6654425330570c496f12ee",
"authCode": "VCXo44VxFhJb2pvZDQ0b3QPX7lYMg7SGZ6s4HBU72dJb-PBNk81UfwYhqqYKn1Ez"
}
},
"production": {

View File

@ -9,3 +9,4 @@ systemctl enable farmcontrol-server.service
# Start the service
systemctl start farmcontrol-server.service
farmcontrol-server --info

View File

@ -17,6 +17,24 @@ const logger = log4js.getLogger("App");
logger.level = config.logLevel;
const isHeadless = process.argv.includes("--headless");
const isInfo = process.argv.includes("--info");
const printerHostInfo = (host) => {
var ref = host?._reference || "Unknown";
if (ref != "Unknown") {
ref = "HST:" + ref;
}
logger.info("Reference:", ref);
logger.info("Name:", host?.name || "Unknown");
logger.info("Tags: -", host?.tags?.[0] || "n/a");
for (var i = 0; i < host?.tags?.length - 1; i++) {
const tag = host?.tags[i + 1];
logger.info(" -", tag);
}
logger.info("State:", host?.state?.type || "Unknown");
};
function getArgValue(flag) {
const withEquals = process.argv.find((arg) => arg.startsWith(`${flag}=`));
@ -68,10 +86,24 @@ export async function init() {
const runningServer = await checkRunning();
if (otpCode != undefined) {
if (otpCode != undefined || isInfo == true) {
logger.info("✔ Farm Control Server is running.");
}
if (isInfo) {
logger.info("-----FarmControl Server-----");
logger.info("Version:", "v" + runningServer.version || "n/a");
logger.info("Build:", runningServer.build || "n/a");
logger.info(
"Authenticated:",
runningServer.authenticated == true ? "Yes" : "No",
);
logger.info("------------Host------------");
printerHostInfo(runningServer.host);
logger.info("----------------------------");
return runningServer;
}
if (otpCode != undefined) {
logger.info("🔒 Authenticating with OTP...");
const authenticatedServer = await authenticateWithOtp(otpCode);
@ -82,15 +114,9 @@ export async function init() {
);
} else {
logger.info("✔ Authenticated with OTP.");
logger.info("----------Host----------");
logger.info("Name:", authenticatedServer.host?.name || "Unknown");
logger.info("Tags: -", authenticatedServer.host?.tags?.[0] || "n/a");
for (var i = 0; i < authenticatedServer.host?.tags?.length - 1; i++) {
const tag = authenticatedServer.host?.tags[i + 1];
logger.info(" -", tag);
}
logger.info("State:", "Online");
logger.info("------------------------");
logger.info("------------Host------------");
printerHostInfo(authenticatedServer.host);
logger.info("----------------------------");
return authenticatedServer;
}
return authenticatedServer;

View File

@ -1,8 +1,30 @@
import { readFileSync } from "node:fs";
import express from "express";
import log4js from "log4js";
import { notPrompting } from "../utils.js";
import { loadConfig } from "../config.js";
const readJsonFile = (fileUrl) => {
try {
return JSON.parse(readFileSync(fileUrl, "utf8"));
} catch {
return {};
}
};
const packageJsonUrl = new URL("../../package.json", import.meta.url);
const buildInfoUrl = new URL("../buildInfo.json", import.meta.url);
const getServerVersionInfo = () => {
const packageJson = readJsonFile(packageJsonUrl);
const buildInfo = readJsonFile(buildInfoUrl);
return {
version: packageJson.version ?? "dev",
buildNumber: buildInfo.buildNumber ?? "dev",
};
};
export const LOCAL_SERVER_PORT = 47291;
const config = loadConfig();
@ -22,7 +44,12 @@ export class LocalServer {
setupRoutes() {
this.app.get("/info", (_req, res) => {
logger.debug("Received request to check if server is running");
res.json({ running: true });
res.json({
running: true,
authenticated: this.socketClient.authenticated,
host: this.socketClient.host,
...getServerVersionInfo(),
});
});
this.app.post("/otpAuth", async (req, res) => {

View File

@ -203,12 +203,12 @@ export class SocketClient {
state: { type: "offline" },
});
}
this.host = verifyResult.host;
sendIPC("setHost", {
...this.host,
online: true,
this.host = {
...verifyResult.host,
state: { type: "online" },
});
online: true,
};
sendIPC("setHost", this.host);
this.id = this.host._id;
config.host = { id: this.id, authCode: this.host.authCode };