feat(ops): /api/version endpoint with git SHA + build time
Adds a public, no-auth endpoint at /api/version that returns:
{ commit, commitShort, buildTime, nodeEnv, cutover, nextVersion }
Build-time injection via GIT_COMMIT + BUILD_TIME ARG/ENV propagated
from compose build.args through Dockerfile builder + runner stages.
Excluded from middleware auth gating.
Deploy command (run on satra after git pull):
GIT_COMMIT=$(git rev-parse HEAD) \
BUILD_TIME=$(date -u +%FT%TZ) \
docker compose build architools
Without these env vars, falls back to "unknown" so the build never
fails; only the endpoint shows reduced info.
Useful for: confirming what's actually deployed after CI, cross-app
deploy correlation (api.gis.ac, eterra.live, orchestrator), uptime
monitors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+11
@@ -26,11 +26,16 @@ ARG NEXT_PUBLIC_APP_NAME=ArchiTools
|
|||||||
ARG NEXT_PUBLIC_APP_URL=https://tools.beletage.ro
|
ARG NEXT_PUBLIC_APP_URL=https://tools.beletage.ro
|
||||||
ARG NEXT_PUBLIC_MARTIN_URL=https://tools.beletage.ro/tiles
|
ARG NEXT_PUBLIC_MARTIN_URL=https://tools.beletage.ro/tiles
|
||||||
ARG NEXT_PUBLIC_PMTILES_URL=
|
ARG NEXT_PUBLIC_PMTILES_URL=
|
||||||
|
# Version metadata baked at build time → /api/version
|
||||||
|
ARG GIT_COMMIT=unknown
|
||||||
|
ARG BUILD_TIME=unknown
|
||||||
ENV NEXT_PUBLIC_STORAGE_ADAPTER=${NEXT_PUBLIC_STORAGE_ADAPTER}
|
ENV NEXT_PUBLIC_STORAGE_ADAPTER=${NEXT_PUBLIC_STORAGE_ADAPTER}
|
||||||
ENV NEXT_PUBLIC_APP_NAME=${NEXT_PUBLIC_APP_NAME}
|
ENV NEXT_PUBLIC_APP_NAME=${NEXT_PUBLIC_APP_NAME}
|
||||||
ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}
|
ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}
|
||||||
ENV NEXT_PUBLIC_MARTIN_URL=${NEXT_PUBLIC_MARTIN_URL}
|
ENV NEXT_PUBLIC_MARTIN_URL=${NEXT_PUBLIC_MARTIN_URL}
|
||||||
ENV NEXT_PUBLIC_PMTILES_URL=${NEXT_PUBLIC_PMTILES_URL}
|
ENV NEXT_PUBLIC_PMTILES_URL=${NEXT_PUBLIC_PMTILES_URL}
|
||||||
|
ENV GIT_COMMIT=${GIT_COMMIT}
|
||||||
|
ENV BUILD_TIME=${BUILD_TIME}
|
||||||
|
|
||||||
# Increase memory for Next.js build if VM has limited RAM
|
# Increase memory for Next.js build if VM has limited RAM
|
||||||
ENV NODE_OPTIONS="--max-old-space-size=2048"
|
ENV NODE_OPTIONS="--max-old-space-size=2048"
|
||||||
@@ -40,6 +45,12 @@ RUN npm run build
|
|||||||
FROM node:22-alpine AS runner
|
FROM node:22-alpine AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Re-declare build-time version args so they propagate into runner ENV
|
||||||
|
ARG GIT_COMMIT=unknown
|
||||||
|
ARG BUILD_TIME=unknown
|
||||||
|
ENV GIT_COMMIT=${GIT_COMMIT}
|
||||||
|
ENV BUILD_TIME=${BUILD_TIME}
|
||||||
|
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
ENV TZ=Europe/Bucharest
|
ENV TZ=Europe/Bucharest
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ services:
|
|||||||
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-https://tools.beletage.ro}
|
- NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-https://tools.beletage.ro}
|
||||||
- NEXT_PUBLIC_MARTIN_URL=${NEXT_PUBLIC_MARTIN_URL}
|
- NEXT_PUBLIC_MARTIN_URL=${NEXT_PUBLIC_MARTIN_URL}
|
||||||
- NEXT_PUBLIC_PMTILES_URL=${NEXT_PUBLIC_PMTILES_URL}
|
- NEXT_PUBLIC_PMTILES_URL=${NEXT_PUBLIC_PMTILES_URL}
|
||||||
|
# Inject git SHA + build timestamp; deploy via:
|
||||||
|
# GIT_COMMIT=$(git rev-parse HEAD) BUILD_TIME=$(date -u +%FT%TZ) docker compose build
|
||||||
|
- GIT_COMMIT=${GIT_COMMIT:-unknown}
|
||||||
|
- BUILD_TIME=${BUILD_TIME:-unknown}
|
||||||
container_name: architools
|
container_name: architools
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export const runtime = "nodejs";
|
||||||
|
export const dynamic = "force-dynamic";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public version endpoint. Returns the git commit + build time baked at
|
||||||
|
* `docker compose build` (via GIT_COMMIT / BUILD_TIME build args) plus
|
||||||
|
* a few runtime flags useful for ops + remote verification.
|
||||||
|
*
|
||||||
|
* No auth. Excluded from middleware matcher.
|
||||||
|
*
|
||||||
|
* Deploy command on satra (after `git pull`):
|
||||||
|
* GIT_COMMIT=$(git rev-parse HEAD) \
|
||||||
|
* BUILD_TIME=$(date -u +%FT%TZ) \
|
||||||
|
* docker compose build architools
|
||||||
|
*/
|
||||||
|
export async function GET() {
|
||||||
|
const commit = process.env.GIT_COMMIT || "unknown";
|
||||||
|
return NextResponse.json({
|
||||||
|
commit,
|
||||||
|
commitShort: commit.slice(0, 7),
|
||||||
|
buildTime: process.env.BUILD_TIME || "unknown",
|
||||||
|
nodeEnv: process.env.NODE_ENV || "unknown",
|
||||||
|
cutover: {
|
||||||
|
useGisAcDefault: process.env.USE_GIS_AC === "1",
|
||||||
|
pilotUsers: (process.env.GIS_AC_PILOT_USERS || "").split(",").filter(Boolean).length,
|
||||||
|
},
|
||||||
|
nextVersion: "16.1.6",
|
||||||
|
});
|
||||||
|
}
|
||||||
+1
-1
@@ -58,6 +58,6 @@ export const config = {
|
|||||||
* - /favicon.ico, /robots.txt, /sitemap.xml
|
* - /favicon.ico, /robots.txt, /sitemap.xml
|
||||||
* - Files with extensions (images, fonts, etc.)
|
* - Files with extensions (images, fonts, etc.)
|
||||||
*/
|
*/
|
||||||
"/((?!api/auth|api/notifications/digest|api/eterra/auto-refresh|api/compress-pdf|api/address-book|api/projects|auth/signin|_next|favicon\\.ico|robots\\.txt|sitemap\\.xml|.*\\..*).*)",
|
"/((?!api/auth|api/version|api/notifications/digest|api/eterra/auto-refresh|api/compress-pdf|api/address-book|api/projects|auth/signin|_next|favicon\\.ico|robots\\.txt|sitemap\\.xml|.*\\..*).*)",
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user