From 318551558c8afe4e372ffb69ea66d18683547db1 Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Tue, 24 Jun 2025 12:05:36 -0700 Subject: [PATCH 1/4] Add version tagging resolves #4038 closes #4034 closes #4028 --- collector/package.json | 2 +- docker/Dockerfile | 1 + .../src/components/SettingsSidebar/index.jsx | 18 +++++++++++ frontend/src/models/system.js | 31 +++++++++++++++++++ package.json | 2 +- server/endpoints/utils.js | 15 +++++++++ server/package.json | 2 +- 7 files changed, 68 insertions(+), 3 deletions(-) diff --git a/collector/package.json b/collector/package.json index 628501e7f5a..19c29848b77 100644 --- a/collector/package.json +++ b/collector/package.json @@ -1,6 +1,6 @@ { "name": "anything-llm-document-collector", - "version": "0.2.0", + "version": "1.8.2", "description": "Document collector server endpoints", "main": "index.js", "author": "Timothy Carambat (Mintplex Labs)", diff --git a/docker/Dockerfile b/docker/Dockerfile index 221d2e400d7..67089ee46cc 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -169,6 +169,7 @@ USER anythingllm # Setup the environment ENV NODE_ENV=production ENV ANYTHING_LLM_RUNTIME=docker +ENV DEPLOYMENT_VERSION=$(node -p "require('./server/package.json').version") # Setup the healthcheck HEALTHCHECK --interval=1m --timeout=10s --start-period=1m \ diff --git a/frontend/src/components/SettingsSidebar/index.jsx b/frontend/src/components/SettingsSidebar/index.jsx index 03d39d46372..ad70241107c 100644 --- a/frontend/src/components/SettingsSidebar/index.jsx +++ b/frontend/src/components/SettingsSidebar/index.jsx @@ -22,6 +22,7 @@ import showToast from "@/utils/toast"; import System from "@/models/system"; import Option from "./MenuOption"; import { CanViewChatHistoryProvider } from "../CanViewChatHistory"; +import useAppVersion from "@/hooks/useAppVersion"; export default function SettingsSidebar() { const { t } = useTranslation(); @@ -119,6 +120,7 @@ export default function SettingsSidebar() { > {t("settings.privacy")} + @@ -169,6 +171,7 @@ export default function SettingsSidebar() { > {t("settings.privacy")} + @@ -451,3 +454,18 @@ function HoldToReveal({ children, holdForMs = 3_000 }) { if (!showing) return null; return children; } + +function AppVersion() { + const { version, isLoading } = useAppVersion(); + if (isLoading) return null; + return ( + + v{version} + + ); +} diff --git a/frontend/src/models/system.js b/frontend/src/models/system.js index ddb9d82092a..6dd30a6b518 100644 --- a/frontend/src/models/system.js +++ b/frontend/src/models/system.js @@ -11,6 +11,7 @@ const System = { supportEmail: "anythingllm_support_email", customAppName: "anythingllm_custom_app_name", canViewChatHistory: "anythingllm_can_view_chat_history", + deploymentVersion: "anythingllm_deployment_version", }, ping: async function () { return await fetch(`${API_BASE}/ping`) @@ -742,6 +743,36 @@ const System = { }); }, + /** + * Fetches the app version from the server. + * @returns {Promise} The app version. + */ + fetchAppVersion: async function () { + const cache = window.localStorage.getItem(this.cacheKeys.deploymentVersion); + const { version, lastFetched } = cache + ? safeJsonParse(cache, { version: null, lastFetched: 0 }) + : { version: null, lastFetched: 0 }; + + if (!!version && Date.now() - lastFetched < 3_600_000) return version; + const newVersion = await fetch(`${API_BASE}/utils/metrics`, { + method: "GET", + cache: "no-cache", + }) + .then((res) => { + if (!res.ok) throw new Error("Could not fetch app version."); + return res.json(); + }) + .then((res) => res?.version) + .catch(() => null); + + if (!newVersion) return null; + window.localStorage.setItem( + this.cacheKeys.deploymentVersion, + JSON.stringify({ version: newVersion, lastFetched: Date.now() }) + ); + return newVersion; + }, + experimentalFeatures: { liveSync: LiveDocumentSync, agentPlugins: AgentPlugins, diff --git a/package.json b/package.json index e9f50319fb3..b4ce57f3b4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "anything-llm", - "version": "0.2.0", + "version": "1.8.2", "description": "The best solution for turning private documents into a chat bot using off-the-shelf tools and commercially viable AI technologies.", "main": "index.js", "type": "module", diff --git a/server/endpoints/utils.js b/server/endpoints/utils.js index 399d8cf5f69..cf4183251b8 100644 --- a/server/endpoints/utils.js +++ b/server/endpoints/utils.js @@ -13,6 +13,7 @@ function utilEndpoints(app) { : "single-user", vectorDB: process.env.VECTOR_DB || "lancedb", storage: await getDiskStorage(), + version: getDeploymentVersion(), }; response.status(200).json(metrics); } catch (e) { @@ -148,6 +149,20 @@ function getModelTag() { return model; } +/** + * Returns the deployment version. + * - Dev: reads from package.json + * - Prod: reads from ENV + * expected format: major.minor.patch + * @returns {string|null} The deployment version. + */ +function getDeploymentVersion() { + if (process.env.NODE_ENV === "development") + return require("../../package.json").version; + if (process.env.DEPLOYMENT_VERSION) return process.env.DEPLOYMENT_VERSION; + return null; +} + module.exports = { utilEndpoints, getGitVersion, diff --git a/server/package.json b/server/package.json index f226239d898..7fb19a9bbff 100644 --- a/server/package.json +++ b/server/package.json @@ -1,6 +1,6 @@ { "name": "anything-llm-server", - "version": "0.2.0", + "version": "1.8.2", "description": "Server endpoints to process or create content for chatting", "main": "index.js", "author": "Timothy Carambat (Mintplex Labs)", From f15dbcc802b61d863cc89ea527c3fe64dbfbca43 Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Tue, 24 Jun 2025 12:05:44 -0700 Subject: [PATCH 2/4] add hook --- frontend/src/hooks/useAppVersion.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 frontend/src/hooks/useAppVersion.js diff --git a/frontend/src/hooks/useAppVersion.js b/frontend/src/hooks/useAppVersion.js new file mode 100644 index 00000000000..e0cbb28b8c0 --- /dev/null +++ b/frontend/src/hooks/useAppVersion.js @@ -0,0 +1,20 @@ +import { useEffect, useState } from "react"; +import System from "../models/system"; + +/** + * Hook to fetch the app version. + * @returns {Object} The app version. + * @returns {string | null} version - The app version. + * @returns {boolean} isLoading - Whether the app version is loading. + */ +export default function useAppVersion() { + const [version, setVersion] = useState(null); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + System.fetchAppVersion() + .then(setVersion) + .finally(() => setIsLoading(false)); + }, []); + return { version, isLoading }; +} From 204bc44158970f6b991df664c996eb876f39a046 Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Tue, 24 Jun 2025 12:06:07 -0700 Subject: [PATCH 3/4] add build --- .github/workflows/dev-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dev-build.yaml b/.github/workflows/dev-build.yaml index 18873afe497..e699a630f68 100644 --- a/.github/workflows/dev-build.yaml +++ b/.github/workflows/dev-build.yaml @@ -6,7 +6,7 @@ concurrency: on: push: - branches: ['3982-disable-login-simple-sso'] # put your current branch to create a build. Core team only. + branches: ['4034-version-control'] # put your current branch to create a build. Core team only. paths-ignore: - '**.md' - 'cloud-deployments/*' From 4c65de8652362aec3115577562a67d6dc6028396 Mon Sep 17 00:00:00 2001 From: timothycarambat Date: Tue, 24 Jun 2025 12:08:12 -0700 Subject: [PATCH 4/4] patch --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 67089ee46cc..f9ffbd55eb1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -169,7 +169,7 @@ USER anythingllm # Setup the environment ENV NODE_ENV=production ENV ANYTHING_LLM_RUNTIME=docker -ENV DEPLOYMENT_VERSION=$(node -p "require('./server/package.json').version") +ENV DEPLOYMENT_VERSION=1.8.2 # Setup the healthcheck HEALTHCHECK --interval=1m --timeout=10s --start-period=1m \