diff --git a/.github/workflows/deploy-containers.yaml b/.github/workflows/deploy-containers.yaml index 5f954a212..19dfdcb42 100644 --- a/.github/workflows/deploy-containers.yaml +++ b/.github/workflows/deploy-containers.yaml @@ -57,11 +57,17 @@ jobs: digest: ${{ steps.build.outputs.digest }} steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Compute image prefix id: meta run: echo "prefix=${REGISTRY}/${GITHUB_REPOSITORY,,}" >> "$GITHUB_OUTPUT" + - name: Compute dashboard version + id: dashboard_version + run: echo "dashboard_version=$(git describe --tags --always)" >> "$GITHUB_OUTPUT" + - name: Log in to GHCR uses: docker/login-action@v3 with: @@ -79,6 +85,8 @@ jobs: context: . file: ./dashboard/Dockerfile push: true + build-args: | + DASHBOARD_VERSION=${{ steps.dashboard_version.outputs.dashboard_version }} tags: | ${{ steps.meta.outputs.prefix }}/dashboard-frontend:latest ${{ steps.meta.outputs.prefix }}/dashboard-frontend:${{ github.sha }} diff --git a/.github/workflows/deploy-staging.yaml b/.github/workflows/deploy-staging.yaml index e51b67a35..2ea12464e 100644 --- a/.github/workflows/deploy-staging.yaml +++ b/.github/workflows/deploy-staging.yaml @@ -49,15 +49,14 @@ jobs: needs: check-migrations runs-on: ubuntu-latest steps: - - &ssh-host-auth - name: Configure staging host authenticity + - name: Configure staging host authenticity run: | mkdir -p ~/.ssh/ && chmod 700 ~/.ssh/ touch ~/.ssh/known_hosts && chmod 600 ~/.ssh/known_hosts echo "$SSH_HOSTKEY" > ~/.ssh/known_hosts env: SSH_HOSTKEY: ${{ secrets.STAGING_HOSTKEY }} - + - name: Deploy to staging run: | eval $(ssh-agent -s) @@ -68,36 +67,17 @@ jobs: cp ~/.env-staging dashboard-staging/.env && cd dashboard-staging && git checkout ${GITHUB_SHA} && - docker compose pull --ignore-buildable --policy=always && + git fetch --tags --depth 1 || true && + export DASHBOARD_VERSION=\$(git describe --tags --always) && + docker compose down && docker compose build --no-cache && - docker compose up -d --remove-orphans + docker compose up -d " env: SSH_USER: ${{ secrets.STAGING_USER }} SSH_HOST: ${{ secrets.STAGING_HOST }} SSH_KEY: ${{ secrets.STAGING_KEY }} - cleanup: - needs: deploy-staging - runs-on: ubuntu-latest - steps: - - *ssh-host-auth - - name: Prune docker artifacts on remote - env: - SSH_USER: ${{ secrets.STAGING_USER }} - SSH_HOST: ${{ secrets.STAGING_HOST }} - SSH_KEY: ${{ secrets.STAGING_KEY }} - run: | - eval $(ssh-agent -s) - echo "$SSH_KEY" | ssh-add - >/dev/null - ssh "${SSH_USER}@${SSH_HOST}" <<'EOF' - set -eu - docker image prune -fa --filter "until=48h" - docker builder prune -f --filter "until=48h" - docker volume ls --filter dangling=true --format "::warning::volume {{.Name}} is dangling" - docker container ls --filter status=exited --format "::warning::container {{.ID}} {{.Status}} ({{.Names}})" - EOF - e2e-tests: runs-on: ubuntu-latest timeout-minutes: 10 diff --git a/dashboard/Dockerfile b/dashboard/Dockerfile index c09726261..53fd5237b 100644 --- a/dashboard/Dockerfile +++ b/dashboard/Dockerfile @@ -8,6 +8,9 @@ RUN npm install -g pnpm@10.33.3 && pnpm install --frozen-lockfile COPY dashboard/. ./ +ARG DASHBOARD_VERSION +ENV VITE_DASHBOARD_VERSION=$DASHBOARD_VERSION + RUN pnpm build # Stage 2: Copy the static files from the builder stage diff --git a/dashboard/src/components/SideMenu/SideMenuContent.tsx b/dashboard/src/components/SideMenu/SideMenuContent.tsx index 31fde4cf7..c9b4d0225 100644 --- a/dashboard/src/components/SideMenu/SideMenuContent.tsx +++ b/dashboard/src/components/SideMenu/SideMenuContent.tsx @@ -16,6 +16,8 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/Tooltip'; import { ExternalLinkIcon } from '@/components/Icons/ExternalLink'; +import { REPO_URL } from '@/utils/constants/general'; + import SendFeedback from './SendFeedback'; import NavLink from './NavLink'; import { @@ -25,6 +27,19 @@ import { type RouteMenuItems, } from './menuItems'; +const versionRepoUrl = (version: string): string => { + if (!version || version === 'unknown' || version.endsWith('-dirty')) { + return REPO_URL; + } + + const commitAfterTag = version.match(/-g([0-9a-f]+)$/)?.[1]; + if (commitAfterTag) { + return `${REPO_URL}/tree/${commitAfterTag}`; + } + + return `${REPO_URL}/tree/${version}`; +}; + type SideMenuItemProps = { item: RouteMenuItems; }; @@ -124,6 +139,15 @@ const SideMenuContent = ({
{dashboardElements}
+ + + {import.meta.env.VITE_DASHBOARD_VERSION} + ); diff --git a/dashboard/vite.config.ts b/dashboard/vite.config.ts index a0ca62a28..380fe7d26 100644 --- a/dashboard/vite.config.ts +++ b/dashboard/vite.config.ts @@ -1,4 +1,6 @@ import path from 'path'; +import { execSync } from 'node:child_process'; + import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import tsconfigPaths from 'vite-tsconfig-paths'; @@ -6,9 +8,22 @@ import tailwindcss from '@tailwindcss/vite'; import { TanStackRouterVite } from '@tanstack/router-plugin/vite'; +const dashboardVersion = + process.env.VITE_DASHBOARD_VERSION || + ((): string => { + try { + return execSync('git describe --tags --always --dirty').toString().trim(); + } catch { + return 'unknown'; + } + })(); + // https://vitejs.dev/config/ export default defineConfig({ plugins: [tailwindcss(), tsconfigPaths(), react(), TanStackRouterVite()], + define: { + 'import.meta.env.VITE_DASHBOARD_VERSION': JSON.stringify(dashboardVersion), + }, resolve: { alias: { '@': path.resolve(__dirname, './src'), diff --git a/docker-compose.yml b/docker-compose.yml index eb4fc4a21..109478add 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -114,6 +114,8 @@ services: build: context: . dockerfile: ./dashboard/Dockerfile + args: + DASHBOARD_VERSION: ${DASHBOARD_VERSION:-} image: ${IMAGE_REGISTRY:-ghcr.io}/${IMAGE_REPOSITORY:-local}/dashboard-frontend:${IMAGE_TAG:-latest} volumes: - static-data:/data/static