From aeba845e9ef04f9b8bea0867857f36dda538cdce Mon Sep 17 00:00:00 2001 From: Athul Date: Thu, 11 Jun 2026 13:46:56 +0530 Subject: [PATCH 1/3] UN-2265 Display platform version in the frontend profile page Bake the build VERSION into the frontend image as UNSTRACT_APPS_VERSION (same pattern as backend.Dockerfile), surface it through the runtime config injected at container start, and show it as a 'Platform Version' field on the profile page. Production CI already passes *.args.VERSION to all images via docker bake, so published images carry the real version on every deployment target; the field is hidden when no version is available (e.g. local npm start). Co-Authored-By: Claude Fable 5 --- docker/dockerfiles/frontend.Dockerfile | 4 ++++ frontend/generate-runtime-config.sh | 3 ++- frontend/src/components/profile/Profile.jsx | 13 +++++++++++++ frontend/src/config.js | 1 + 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docker/dockerfiles/frontend.Dockerfile b/docker/dockerfiles/frontend.Dockerfile index 0c3fdcc92a..8f9de32996 100644 --- a/docker/dockerfiles/frontend.Dockerfile +++ b/docker/dockerfiles/frontend.Dockerfile @@ -72,6 +72,10 @@ RUN sed -i 's|| \n < COPY frontend/generate-runtime-config.sh /docker-entrypoint.d/40-env.sh RUN chmod +x /docker-entrypoint.d/40-env.sh +# Capture build version at the very end so it doesn't affect layer caching +ARG VERSION=dev +ENV UNSTRACT_APPS_VERSION=${VERSION} + EXPOSE 80 USER nginx diff --git a/frontend/generate-runtime-config.sh b/frontend/generate-runtime-config.sh index d79fa3c002..dae9d05869 100755 --- a/frontend/generate-runtime-config.sh +++ b/frontend/generate-runtime-config.sh @@ -9,7 +9,8 @@ cat > /usr/share/nginx/html/config/runtime-config.js << EOF // This file is auto-generated at runtime. Do not modify manually. window.RUNTIME_CONFIG = { faviconPath: "${VITE_FAVICON_PATH:-${REACT_APP_FAVICON_PATH}}", - logoUrl: "${VITE_CUSTOM_LOGO_URL:-${REACT_APP_CUSTOM_LOGO_URL}}" + logoUrl: "${VITE_CUSTOM_LOGO_URL:-${REACT_APP_CUSTOM_LOGO_URL}}", + version: "${UNSTRACT_APPS_VERSION:-}" }; EOF diff --git a/frontend/src/components/profile/Profile.jsx b/frontend/src/components/profile/Profile.jsx index 899110c777..aedf755e44 100644 --- a/frontend/src/components/profile/Profile.jsx +++ b/frontend/src/components/profile/Profile.jsx @@ -11,6 +11,7 @@ import { useNavigate } from "react-router-dom"; import "./Profile.css"; import { OrganizationIcon } from "../../assets"; +import config from "../../config"; import { useAxiosPrivate } from "../../hooks/useAxiosPrivate"; import { useAlertStore } from "../../store/alert-store.js"; import { useSessionStore } from "../../store/session-store.js"; @@ -234,6 +235,18 @@ function Profile() { )} + {config.version && ( +
+ + Platform Version + +
+ + {config.version} + +
+
+ )} diff --git a/frontend/src/config.js b/frontend/src/config.js index c3c79d4171..1f1abc3bf8 100644 --- a/frontend/src/config.js +++ b/frontend/src/config.js @@ -17,6 +17,7 @@ const config = { import.meta.env.VITE_FAVICON_PATH || "/favicon.ico", logoUrl: runtimeConfig.logoUrl || import.meta.env.VITE_CUSTOM_LOGO_URL, + version: runtimeConfig.version || import.meta.env.VITE_VERSION, // Add more values as OR case, if needed for fallback. }; From ad1f1b21ef252d0f2400631b045cd002aa70443b Mon Sep 17 00:00:00 2001 From: Athul Date: Thu, 11 Jun 2026 16:15:26 +0530 Subject: [PATCH 2/3] UN-2265 Address review: empty VERSION default, escape value in runtime config - ARG VERSION defaults to empty so images built without a version hide the field instead of showing 'dev' - Escape backslashes/quotes before embedding the version in the generated JS --- docker/dockerfiles/frontend.Dockerfile | 5 +++-- frontend/generate-runtime-config.sh | 10 +++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docker/dockerfiles/frontend.Dockerfile b/docker/dockerfiles/frontend.Dockerfile index 8f9de32996..cf3a14ee5a 100644 --- a/docker/dockerfiles/frontend.Dockerfile +++ b/docker/dockerfiles/frontend.Dockerfile @@ -72,8 +72,9 @@ RUN sed -i 's|| \n < COPY frontend/generate-runtime-config.sh /docker-entrypoint.d/40-env.sh RUN chmod +x /docker-entrypoint.d/40-env.sh -# Capture build version at the very end so it doesn't affect layer caching -ARG VERSION=dev +# Capture build version at the very end so it doesn't affect layer caching. +# Empty default: the UI hides the version field when none was provided. +ARG VERSION="" ENV UNSTRACT_APPS_VERSION=${VERSION} EXPOSE 80 diff --git a/frontend/generate-runtime-config.sh b/frontend/generate-runtime-config.sh index dae9d05869..f3990091cb 100755 --- a/frontend/generate-runtime-config.sh +++ b/frontend/generate-runtime-config.sh @@ -5,12 +5,20 @@ # Generate the runtime-config.js file with the current environment variables # Note: Using VITE_ prefix for Vite compatibility, fallback to REACT_APP_ for backward compatibility + +# Escape backslashes and double quotes so values stay valid inside JS strings +js_escape() { + printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g' +} + +APP_VERSION=$(js_escape "${UNSTRACT_APPS_VERSION:-}") + cat > /usr/share/nginx/html/config/runtime-config.js << EOF // This file is auto-generated at runtime. Do not modify manually. window.RUNTIME_CONFIG = { faviconPath: "${VITE_FAVICON_PATH:-${REACT_APP_FAVICON_PATH}}", logoUrl: "${VITE_CUSTOM_LOGO_URL:-${REACT_APP_CUSTOM_LOGO_URL}}", - version: "${UNSTRACT_APPS_VERSION:-}" + version: "${APP_VERSION}" }; EOF From 572d38092fa78332a040cf4a8dc26f4871836bc1 Mon Sep 17 00:00:00 2001 From: Athul Date: Mon, 29 Jun 2026 21:47:00 +0530 Subject: [PATCH 3/3] UN-2265 [FIX] Source platform version from runtime env, not baked image RC->stable promotion re-tags images (it does not rebuild), so a version baked into the frontend image at build time would stay frozen at the rc tag after promotion. Drop the frontend.Dockerfile ARG/ENV baking and instead supply UNSTRACT_APPS_VERSION from docker-compose using ${VERSION} -- the same value that already tags the image, so the displayed version always matches what runs. Addresses review from @ritwik-g / @ejhari (version must come dynamically from compose in OSS and the Helm chart in Enterprise). Co-Authored-By: Claude Opus 4.8 (1M context) --- docker/docker-compose.yaml | 4 ++++ docker/dockerfiles/frontend.Dockerfile | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index b7b49a7618..8442db0144 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -132,6 +132,10 @@ services: - reverse-proxy environment: - ENVIRONMENT=development + # Running platform version, surfaced on the profile page. Reuses the same + # ${VERSION} that tags the image, so it always matches what's deployed + # (and updates on RC->stable promotion, which only retags — doesn't rebuild). + - UNSTRACT_APPS_VERSION=${VERSION} labels: - traefik.enable=true - traefik.http.routers.frontend.rule=Host(`frontend.unstract.localhost`) && !PathPrefix(`/api/v1`) && !PathPrefix(`/deployment`) && !PathPrefix(`/public`) diff --git a/docker/dockerfiles/frontend.Dockerfile b/docker/dockerfiles/frontend.Dockerfile index cf3a14ee5a..0c3fdcc92a 100644 --- a/docker/dockerfiles/frontend.Dockerfile +++ b/docker/dockerfiles/frontend.Dockerfile @@ -72,11 +72,6 @@ RUN sed -i 's|| \n < COPY frontend/generate-runtime-config.sh /docker-entrypoint.d/40-env.sh RUN chmod +x /docker-entrypoint.d/40-env.sh -# Capture build version at the very end so it doesn't affect layer caching. -# Empty default: the UI hides the version field when none was provided. -ARG VERSION="" -ENV UNSTRACT_APPS_VERSION=${VERSION} - EXPOSE 80 USER nginx