From 619a269071f52ef903dad2f166c5617b87176058 Mon Sep 17 00:00:00 2001 From: Dave Earley Date: Sun, 15 Mar 2026 20:33:01 +0000 Subject: [PATCH] Add version management and system info endpoint - Version script to set version across VERSION, composer.json, and package.json - Superadmin-only GET /admin/system-info endpoint - Expose app version at build time in frontend - Easter egg: tap logo 5 times on login page to see version - Set version to 1.7.0-beta --- Dockerfile.all-in-one | 2 ++ VERSION | 1 + .../Actions/Admin/GetSystemInfoAction.php | 29 +++++++++++++++++++ backend/composer.json | 2 +- backend/routes/api.php | 4 +++ docker/development/docker-compose.dev.yml | 3 ++ frontend/package.json | 2 +- .../components/layouts/AuthLayout/index.tsx | 18 ++++++++++-- frontend/src/globals.d.ts | 1 + frontend/vite.config.ts | 17 +++++++++++ scripts/set-version.sh | 24 +++++++++++++++ 11 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 VERSION create mode 100644 backend/app/Http/Actions/Admin/GetSystemInfoAction.php create mode 100644 frontend/src/globals.d.ts create mode 100755 scripts/set-version.sh diff --git a/Dockerfile.all-in-one b/Dockerfile.all-in-one index 8e5ff472a..45b18a531 100644 --- a/Dockerfile.all-in-one +++ b/Dockerfile.all-in-one @@ -10,6 +10,7 @@ RUN yarn config set network-timeout 600000 COPY ./frontend/package.json ./frontend/yarn.lock ./ COPY ./frontend . +COPY ./VERSION /app/VERSION RUN yarn install --network-timeout 600000 --frozen-lockfile && yarn build @@ -28,6 +29,7 @@ RUN apk add --no-cache nodejs yarn nginx supervisor dos2unix COPY --from=node-frontend /app/frontend /app/frontend COPY ./backend /app/backend +COPY ./VERSION /app/backend/VERSION RUN mkdir -p /app/backend/bootstrap/cache \ && mkdir -p /app/backend/storage \ && chown -R www-data:www-data /app/backend \ diff --git a/VERSION b/VERSION new file mode 100644 index 000000000..2e1cd7d5a --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.7.0-beta diff --git a/backend/app/Http/Actions/Admin/GetSystemInfoAction.php b/backend/app/Http/Actions/Admin/GetSystemInfoAction.php new file mode 100644 index 000000000..d26856049 --- /dev/null +++ b/backend/app/Http/Actions/Admin/GetSystemInfoAction.php @@ -0,0 +1,29 @@ +minimumAllowedRole(Role::SUPERADMIN); + + $version = trim(@file_get_contents(base_path('VERSION')) ?: 'unknown'); + + return $this->jsonResponse([ + 'version' => $version, + 'php_version' => PHP_VERSION, + 'laravel_version' => app()->version(), + 'environment' => app()->environment(), + 'debug_mode' => config('app.debug'), + 'timezone' => config('app.timezone'), + 'os' => PHP_OS, + ]); + } +} diff --git a/backend/composer.json b/backend/composer.json index 8dbd2ad25..90341cb29 100644 --- a/backend/composer.json +++ b/backend/composer.json @@ -4,7 +4,7 @@ "description": "hi.events - Ticket selling and event management.", "keywords": ["ticketing", "events"], "license": "AGPL-3.0", - "version": "0.0.1", + "version": "1.7.0-beta", "require": { "php": "^8.2", "ext-intl": "*", diff --git a/backend/routes/api.php b/backend/routes/api.php index 09ca424e4..85af28760 100644 --- a/backend/routes/api.php +++ b/backend/routes/api.php @@ -191,6 +191,7 @@ use HiEvents\Http\Actions\Admin\Accounts\UpdateAccountMessagingTierAction; use HiEvents\Http\Actions\Admin\Orders\GetAllOrdersAction; use HiEvents\Http\Actions\Admin\Attribution\GetUtmAttributionStatsAction; +use HiEvents\Http\Actions\Admin\GetSystemInfoAction; use HiEvents\Http\Actions\Admin\Stats\GetAdminDashboardDataAction; use HiEvents\Http\Actions\Admin\Stats\GetAdminStatsAction; use HiEvents\Http\Actions\Admin\Users\GetAllUsersAction; @@ -472,6 +473,9 @@ function (Router $router): void { // Messaging Tiers $router->get('/messaging-tiers', GetMessagingTiersAction::class); $router->put('/accounts/{account_id}/messaging-tier', UpdateAccountMessagingTierAction::class); + + // System Info + $router->get('/system-info', GetSystemInfoAction::class); } ); diff --git a/docker/development/docker-compose.dev.yml b/docker/development/docker-compose.dev.yml index 2516a6c62..1c605156c 100644 --- a/docker/development/docker-compose.dev.yml +++ b/docker/development/docker-compose.dev.yml @@ -10,6 +10,7 @@ services: - ./../../backend:/var/www/html - ./../../backend/storage:/var/www/html/storage - ./../../backend/bootstrap/cache:/var/www/html/bootstrap/cache + - ./../../VERSION:/var/www/html/VERSION:ro environment: APP_ENV: '${APP_ENV:-local}' APP_KEY: '${APP_KEY}' @@ -32,6 +33,7 @@ services: volumes: - ./../../frontend:/app - /app/node_modules + - ./../../VERSION:/app/VERSION:ro command: yarn dev:csr environment: @@ -49,6 +51,7 @@ services: volumes: - ./../../frontend:/app - /app/node_modules + - ./../../VERSION:/app/VERSION:ro command: yarn dev:ssr environment: diff --git a/frontend/package.json b/frontend/package.json index 996450036..6a4d8653a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "hievents-frontend", "private": true, - "version": "0.0.0", + "version": "1.7.0-beta", "type": "module", "scripts": { "dev:csr": "vite --port 5678 --host 0.0.0.0", diff --git a/frontend/src/components/layouts/AuthLayout/index.tsx b/frontend/src/components/layouts/AuthLayout/index.tsx index a27a83f49..88ca89099 100644 --- a/frontend/src/components/layouts/AuthLayout/index.tsx +++ b/frontend/src/components/layouts/AuthLayout/index.tsx @@ -15,9 +15,10 @@ import { IconTicket, IconUsers, } from '@tabler/icons-react'; -import {useMemo} from "react"; +import {useCallback, useMemo, useRef} from "react"; import {getConfig} from "../../../utilites/config.ts"; import {isHiEvents} from "../../../utilites/helpers.ts"; +import {showInfo} from "../../../utilites/notifications.tsx"; const allFeatures = [ { @@ -107,6 +108,19 @@ const FeaturePanel = () => { const AuthLayout = () => { const me = useGetMe(); + const clickCountRef = useRef(0); + const clickTimerRef = useRef>(); + + const handleLogoClick = useCallback(() => { + clickCountRef.current += 1; + clearTimeout(clickTimerRef.current); + clickTimerRef.current = setTimeout(() => { clickCountRef.current = 0; }, 2000); + + if (clickCountRef.current >= 5) { + clickCountRef.current = 0; + showInfo(`HiEvents v${__APP_VERSION__}`); + } + }, []); if (me.isSuccess) { return @@ -117,7 +131,7 @@ const AuthLayout = () => {
-
+
{t`${getConfig("VITE_APP_NAME"," + echo "Example: $0 1.7.0-beta" + exit 1 +fi + +VERSION="$1" +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ROOT_DIR="$(dirname "$SCRIPT_DIR")" + +echo "$VERSION" > "$ROOT_DIR/VERSION" +echo "Updated VERSION file to $VERSION" + +awk -v ver="$VERSION" '!done && /"version":/ { sub(/"version": ".*"/, "\"version\": \"" ver "\""); done=1 } 1' "$ROOT_DIR/backend/composer.json" > "$ROOT_DIR/backend/composer.json.tmp" && mv "$ROOT_DIR/backend/composer.json.tmp" "$ROOT_DIR/backend/composer.json" +echo "Updated backend/composer.json to $VERSION" + +awk -v ver="$VERSION" '!done && /"version":/ { sub(/"version": ".*"/, "\"version\": \"" ver "\""); done=1 } 1' "$ROOT_DIR/frontend/package.json" > "$ROOT_DIR/frontend/package.json.tmp" && mv "$ROOT_DIR/frontend/package.json.tmp" "$ROOT_DIR/frontend/package.json" +echo "Updated frontend/package.json to $VERSION" + +echo "All files updated to version $VERSION"