diff --git a/.changeset/proud-maps-reply.md b/.changeset/proud-maps-reply.md
new file mode 100644
index 00000000..2a584c90
--- /dev/null
+++ b/.changeset/proud-maps-reply.md
@@ -0,0 +1,5 @@
+---
+"draupnir": patch
+---
+
+Add Distrubution information to version information in status / version command.
diff --git a/.gitignore b/.gitignore
index b5b22357..3b39a672 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,8 @@ version.txt.tmp
version.txt
# branch file generated from npm build
branch.txt
+# distribution file generated from npm build
+distribution.txt
# Logs
logs
diff --git a/Dockerfile b/Dockerfile
index 4142b1c6..695141d3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -5,6 +5,10 @@
# syntax=docker/dockerfile:1.7
+# Build-time distribution identifier (default for docker builds). Declared
+# before any FROM so it can be overridden with `--build-arg`.
+ARG DRAUPNIR_DISTRIBUTION=Docker
+
FROM node:24-slim AS build-stage
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
apt-get update \
@@ -27,6 +31,10 @@ RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
# build and install
+# make the build see the distribution value
+ARG DRAUPNIR_DISTRIBUTION
+ENV DRAUPNIR_DISTRIBUTION=${DRAUPNIR_DISTRIBUTION}
+
RUN npm run build \
&& npm prune --production
diff --git a/apps/draupnir/package.json b/apps/draupnir/package.json
index 2c6b1e37..739bcf9d 100644
--- a/apps/draupnir/package.json
+++ b/apps/draupnir/package.json
@@ -9,9 +9,10 @@
"private": true,
"scripts": {
"build": "tsc --project test/tsconfig.json && npm run build:assets",
- "build:assets": "npm run describe-version && npm run describe-branch",
+ "build:assets": "npm run describe-version && npm run describe-branch && npm run describe-distribution",
"describe-version": "(git describe > version.txt.tmp && mv version.txt.tmp version.txt) || true && rm -f version.txt.tmp",
"describe-branch": "(git rev-parse --abbrev-ref HEAD > branch.txt.tmp && mv branch.txt.tmp branch.txt) || true && rm -f branch.txt.tmp",
+ "describe-distribution": "echo \"${DRAUPNIR_DISTRIBUTION:-source}\" > distribution.txt.tmp && mv distribution.txt.tmp distribution.txt",
"harness-registration": "node dist/appservice/cli.js -r -u \"http://host.docker.internal:9000\" --enable-source-maps",
"test:unit": "mocha --require './test/tsnode.cjs' --forbid-only 'test/unit/**/*.{ts,tsx}'",
"test:unit:single": "mocha --require test/tsnode.cjs",
diff --git a/apps/draupnir/src/appservice/bot/VersionCommand.tsx b/apps/draupnir/src/appservice/bot/VersionCommand.tsx
index 1a03c241..7a53cf00 100644
--- a/apps/draupnir/src/appservice/bot/VersionCommand.tsx
+++ b/apps/draupnir/src/appservice/bot/VersionCommand.tsx
@@ -9,11 +9,12 @@ import {
describeCommand,
} from "@the-draupnir-project/interface-manager";
import { AppserviceBotInterfaceAdaptor } from "./AppserviceBotInterfaceAdaptor";
-import { CURRENT_BRANCH, SOFTWARE_VERSION } from "../../config";
+import { CURRENT_BRANCH, SOFTWARE_VERSION, DISTRIBUTION} from "../../config";
type AppserviceVersionInfo = {
version: string;
branch: string;
+ distribution: string;
};
export const AppserviceVersionCommand = describeCommand({
@@ -26,6 +27,7 @@ export const AppserviceVersionCommand = describeCommand({
return Ok({
version: SOFTWARE_VERSION,
branch: CURRENT_BRANCH,
+ distribution: DISTRIBUTION,
});
},
});
@@ -42,6 +44,9 @@ AppserviceBotInterfaceAdaptor.describeRenderer(AppserviceVersionCommand, {
Branch:
{result.ok.branch}
+
+ Distribution:
+ {result.ok.distribution}
);
},
diff --git a/apps/draupnir/src/commands/StatusCommand.tsx b/apps/draupnir/src/commands/StatusCommand.tsx
index e6aca311..26eee7ee 100644
--- a/apps/draupnir/src/commands/StatusCommand.tsx
+++ b/apps/draupnir/src/commands/StatusCommand.tsx
@@ -13,6 +13,7 @@ import {
DOCUMENTATION_URL,
PACKAGE_JSON,
SOFTWARE_VERSION,
+ DISTRIBUTION,
} from "../config";
import {
ActionResult,
@@ -59,6 +60,7 @@ export type StatusInfo = {
branch: string;
repository: string;
documentationURL: string;
+ distribution: string;
} & DraupnirNotificationRoomsInfo &
WatchedPolicyRoomsInfo;
@@ -142,6 +144,7 @@ export function draupnirStatusInfo(draupnir: Draupnir): StatusInfo {
documentationURL: DOCUMENTATION_URL,
version: SOFTWARE_VERSION,
branch: CURRENT_BRANCH,
+ distribution: DISTRIBUTION,
repository: (PACKAGE_JSON["repository"] as string | undefined) ?? "Unknown",
...extractProtectionNotificationRooms(draupnir),
};
@@ -235,6 +238,9 @@ export function renderStatusInfo(info: StatusInfo): DocumentNode {
Branch:
{info.branch}
+ Distribution:
+ {info.distribution}
+
Repository:
{info.repository}
diff --git a/apps/draupnir/src/config.ts b/apps/draupnir/src/config.ts
index 03823e66..e9fd7ebf 100644
--- a/apps/draupnir/src/config.ts
+++ b/apps/draupnir/src/config.ts
@@ -503,6 +503,24 @@ export const CURRENT_BRANCH = (() => {
return /^(.*)$/m.exec(branchFile)?.at(0) ?? defaultText;
})();
+export const DISTRIBUTION = (() => {
+ let distributionFile;
+ const defaultText =
+ "A distribution name was either not provided when building Draupnir or could not be read.";
+ try {
+ distributionFile = fs.readFileSync(
+ path.join(__dirname, "../distribution.txt"),
+ "utf-8"
+ );
+ } catch (e) {
+ LogService.error("config", "Could not read Draupnir distribution", e);
+ distributionFile = defaultText;
+ }
+ // it's important to ignore the newline if the distribution is going to be put
+ // into
or where it will create an unnecessary newline.
+ return /^(.*)$/m.exec(distributionFile)?.at(0) ?? defaultText;
+})();
+
export const DOCUMENTATION_URL =
"https://the-draupnir-project.github.io/draupnir-documentation/";
diff --git a/apps/draupnir/test/appservice/integration/versionAndBranchDraupnirTest.ts b/apps/draupnir/test/appservice/integration/versionAndBranchDraupnirTest.ts
index 05d0ccbe..719ac116 100644
--- a/apps/draupnir/test/appservice/integration/versionAndBranchDraupnirTest.ts
+++ b/apps/draupnir/test/appservice/integration/versionAndBranchDraupnirTest.ts
@@ -39,5 +39,6 @@ describe("Test appservice version command", function () {
}
expect(result.ok).toHaveProperty("version");
expect(result.ok).toHaveProperty("branch");
+ expect(result.ok).toHaveProperty("distribution");
});
});