add build version tracking with commit SHA, version number, and build timestamp to frontend
Some checks failed
Build and Push Docker Images / build-backend (push) Has been cancelled
Build and Push Docker Images / build-frontend (push) Has been cancelled

This commit is contained in:
Egor Pozharov
2026-05-04 16:08:37 +06:00
parent a3929bec8d
commit f9c54b5172
5 changed files with 39 additions and 3 deletions

View File

@@ -43,6 +43,8 @@ jobs:
with: with:
context: ./frontend context: ./frontend
push: true push: true
build-args: |
GITEA_SHA=${{ gitea.sha }}
tags: | tags: |
gitea.gitea.chedius.ru/${{ gitea.repository_owner }}/delivery-tracker/frontend:latest gitea.gitea.chedius.ru/${{ gitea.repository_owner }}/delivery-tracker/frontend:latest
gitea.gitea.chedius.ru/${{ gitea.repository_owner }}/delivery-tracker/frontend:${{ gitea.sha }} gitea.gitea.chedius.ru/${{ gitea.repository_owner }}/delivery-tracker/frontend:${{ gitea.sha }}

View File

@@ -5,6 +5,9 @@ FROM node:20-alpine AS builder
WORKDIR /app WORKDIR /app
ARG GITEA_SHA
ARG COMMIT_SHA
# Copy package files # Copy package files
COPY package.json yarn.lock ./ COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile RUN yarn install --frozen-lockfile

View File

@@ -4,21 +4,31 @@ import { useRegisterSW } from 'virtual:pwa-register/react';
// Check for SW updates every hour and on tab focus/visibility change // Check for SW updates every hour and on tab focus/visibility change
const UPDATE_INTERVAL_MS = 60 * 60 * 1000; const UPDATE_INTERVAL_MS = 60 * 60 * 1000;
const buildLabel = `${__APP_VERSION__}-${__APP_COMMIT__}`;
export function UpdatePrompt() { export function UpdatePrompt() {
const { const {
needRefresh: [needRefresh], needRefresh: [needRefresh],
updateServiceWorker, updateServiceWorker,
} = useRegisterSW({ } = useRegisterSW({
onRegisteredSW(_swUrl, registration) { onRegisteredSW(_swUrl, registration) {
console.info('[App] version', {
version: __APP_VERSION__,
commit: __APP_COMMIT__,
builtAt: __APP_BUILT_AT__,
serviceWorker: registration ? 'registered' : 'unavailable',
});
if (!registration) return; if (!registration) return;
const checkForUpdate = async () => { const checkForUpdate = async () => {
if (registration.installing || !navigator) return; if (registration.installing || !navigator) return;
if ('connection' in navigator && !navigator.onLine) return; if ('connection' in navigator && !navigator.onLine) return;
try { try {
console.debug('[PWA] checking for update', { version: buildLabel });
await registration.update(); await registration.update();
} catch { } catch {
// network error — ignore, will retry console.debug('[PWA] update check failed, will retry later', { version: buildLabel });
} }
}; };
@@ -34,7 +44,9 @@ export function UpdatePrompt() {
useEffect(() => { useEffect(() => {
if (needRefresh) { if (needRefresh) {
console.log('[PWA] New version detected, auto-updating...'); console.info('[PWA] new version detected, applying automatically', {
currentVersion: buildLabel,
});
updateServiceWorker(true); updateServiceWorker(true);
} }
}, [needRefresh, updateServiceWorker]); }, [needRefresh, updateServiceWorker]);

5
frontend/src/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1,5 @@
/// <reference types="vite/client" />
declare const __APP_VERSION__: string;
declare const __APP_COMMIT__: string;
declare const __APP_BUILT_AT__: string;

View File

@@ -3,8 +3,22 @@ import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite' import tailwindcss from '@tailwindcss/vite'
import { VitePWA } from 'vite-plugin-pwa' import { VitePWA } from 'vite-plugin-pwa'
const appVersion = process.env.npm_package_version ?? '0.0.0'
const appCommit = (
process.env.GITEA_SHA ??
process.env.GITHUB_SHA ??
process.env.COMMIT_SHA ??
'dev'
).slice(0, 12)
const appBuiltAt = new Date().toISOString()
// https://vite.dev/config/ // https://vite.dev/config/
export default defineConfig({ export default defineConfig({
define: {
__APP_VERSION__: JSON.stringify(appVersion),
__APP_COMMIT__: JSON.stringify(appCommit),
__APP_BUILT_AT__: JSON.stringify(appBuiltAt),
},
plugins: [ plugins: [
react(), react(),
tailwindcss(), tailwindcss(),
@@ -35,4 +49,4 @@ export default defineConfig({
}, },
}, },
}, },
}) })