From b6da80d58d2540ce8193d08c14b86dd3e1d1f29a Mon Sep 17 00:00:00 2001 From: "benjamin.747" Date: Tue, 11 Aug 2026 09:36:26 +0800 Subject: [PATCH 1/2] feat(web): show build version in sidebar, drop feedback/changelog Replace the bottom-left Share Feedback and Changelog controls with a baked short SHA + build date so onprem can match Harbor image tags. --- .github/workflows/web-deploy.yml | 4 + moon/apps/web/Dockerfile | 7 ++ .../NavigationSidebar/ChangelogDropdown.tsx | 104 ------------------ .../components/Sidebar/SidebarAppVersion.tsx | 31 ++++++ .../web/components/Sidebar/SidebarProfile.tsx | 19 +--- moon/apps/web/hooks/useGetLatestRelease.ts | 14 --- moon/apps/web/pages/api/latest-release.ts | 73 ------------ moon/apps/web/utils/types.ts | 6 - 8 files changed, 44 insertions(+), 214 deletions(-) delete mode 100644 moon/apps/web/components/NavigationSidebar/ChangelogDropdown.tsx create mode 100644 moon/apps/web/components/Sidebar/SidebarAppVersion.tsx delete mode 100644 moon/apps/web/hooks/useGetLatestRelease.ts delete mode 100644 moon/apps/web/pages/api/latest-release.ts diff --git a/.github/workflows/web-deploy.yml b/.github/workflows/web-deploy.yml index 2eaaa32e7..e81d14d0f 100644 --- a/.github/workflows/web-deploy.yml +++ b/.github/workflows/web-deploy.yml @@ -102,9 +102,13 @@ jobs: echo "TEMP: skipping AWS ECR push (Harbor only)" fi + BUILD_TIME="$(date -u +%Y-%m-%dT%H:%M:%SZ)" + docker buildx build \ --platform "$PLATFORM" \ --build-arg TIPTAP_PRIVATE_REGISTRY_KEY="$TIPTAP_PRIVATE_REGISTRY_KEY" \ + --build-arg GIT_SHA="${GITHUB_SHA}" \ + --build-arg BUILD_TIME="${BUILD_TIME}" \ --cache-from type=gha,scope=mega-ui \ --cache-to type=gha,mode=max,scope=mega-ui \ --provenance=false \ diff --git a/moon/apps/web/Dockerfile b/moon/apps/web/Dockerfile index 853150e3c..335a81d51 100644 --- a/moon/apps/web/Dockerfile +++ b/moon/apps/web/Dockerfile @@ -20,6 +20,9 @@ WORKDIR /app FROM base AS installer ARG TARGETARCH ARG TIPTAP_PRIVATE_REGISTRY_KEY +# Baked into the client bundle at next build (not runtime-injected). +ARG GIT_SHA=dev +ARG BUILD_TIME= # Debian slim defaults to http://deb.debian.org. Through corporate proxies (NFCLOUD): # - plain HTTP hangs # - HTTPS works but MITM breaks apt's CA verify @@ -51,6 +54,10 @@ COPY --from=builder /app/out/full/ . RUN rm -f /app/apps/web/.env.local \ && cp /app/apps/web/.env.runtime /app/apps/web/.env.production +# Image identity: short/full git SHA + UTC build time for sidebar version display. +ENV NEXT_PUBLIC_APP_VERSION=${GIT_SHA} +ENV NEXT_PUBLIC_APP_BUILD_TIME=${BUILD_TIME} + RUN --mount=type=cache,id=mega-ui-next-${TARGETARCH},target=/app/apps/web/.next/cache,sharing=locked \ --mount=type=cache,id=mega-ui-turbo-${TARGETARCH},target=/app/.turbo,sharing=locked \ npx turbo run build --filter=@gitmono/web diff --git a/moon/apps/web/components/NavigationSidebar/ChangelogDropdown.tsx b/moon/apps/web/components/NavigationSidebar/ChangelogDropdown.tsx deleted file mode 100644 index b6dce09f8..000000000 --- a/moon/apps/web/components/NavigationSidebar/ChangelogDropdown.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import React, { useEffect, useState } from 'react' - -import { SITE_URL } from '@gitmono/config' -import { ArrowUpRightIcon, Button, ShipIcon, ShipUnreadIcon } from '@gitmono/ui' -import { DropdownMenu } from '@gitmono/ui/DropdownMenu' -import { buildMenuItems } from '@gitmono/ui/Menu' - -import { useGetCurrentUser } from '@/hooks/useGetCurrentUser' -import { useGetChangelog } from '@/hooks/useGetLatestRelease' -import { useStoredState } from '@/hooks/useStoredState' -import { Changelog } from '@/utils/types' - -export function ChangelogDropdown({ - side = 'top', - align = 'start' -}: { - side?: 'top' | 'bottom' - align?: 'start' | 'end' | 'center' -}) { - const { data: currentUser } = useGetCurrentUser() - const { data: changelog } = useGetChangelog({ enabled: true }) - const [ls, setLs] = useStoredState('seen-changelogs', []) - const isUnread = (release: Changelog) => !ls.includes(release.slug) - - const [v2Ls] = useStoredState('latest-release-upsell-sidebar', '') - const [hasUnread, setHasUnread] = useState(false) - - // mark as unread - useEffect(() => { - if (!changelog || changelog.length === 0) return - - // don't trigger unread dot for users who onboarded after the latest changelog was published - const userOnboardedAfterLatestChangelog = - currentUser?.onboarded_at && currentUser.onboarded_at > changelog[0].published_at - - if (userOnboardedAfterLatestChangelog) return - - const v2LsHasLatestRelease = v2Ls && v2Ls === changelog[0].slug - - if (v2LsHasLatestRelease) return - - // otherwise, mark it unread if the user hasn't seen the latest changelogs - setHasUnread(changelog.some((c) => !ls.includes(c.slug))) - }, [ls, changelog, currentUser, v2Ls]) - - const trigger = ( -