diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index def0d48..a485575 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -76,6 +76,10 @@ jobs: type=sha,prefix=sha- type=raw,value=latest + - name: Prepare build metadata + id: build-meta + run: echo "short_sha=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT" + - name: Build and push image uses: docker/build-push-action@v6 with: @@ -84,3 +88,5 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-args: | + GIT_HASH=${{ steps.build-meta.outputs.short_sha }} diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 81aa2f5..80ec244 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -1,3 +1,4 @@ +ARG GIT_HASH=unknown FROM oven/bun:1.3 AS deps WORKDIR /app @@ -8,8 +9,10 @@ RUN bun install --frozen-lockfile RUN bun install --cwd /app/apps/web --frozen-lockfile FROM deps AS builder +ARG GIT_HASH WORKDIR /app/apps/web ENV NEXT_TELEMETRY_DISABLED=1 +ENV NEXT_PUBLIC_GIT_HASH=$GIT_HASH RUN bun run build FROM oven/bun:1.3 AS runner diff --git a/apps/web/app/api/commit-hash/route.ts b/apps/web/app/api/commit-hash/route.ts index 8b4dce4..de8b63e 100644 --- a/apps/web/app/api/commit-hash/route.ts +++ b/apps/web/app/api/commit-hash/route.ts @@ -1,7 +1,17 @@ -import { NextResponse } from "next/server"; import { execSync } from "child_process"; +import { NextResponse } from "next/server"; + +export const dynamic = "force-dynamic"; export function GET() { - const hash = execSync("git rev-parse --short HEAD").toString().trim(); - return NextResponse.json({ hash }); -} \ No newline at end of file + if (process.env.NODE_ENV !== "development") { + return NextResponse.json({ hash: process.env.NEXT_PUBLIC_GIT_HASH || "unknown" }); + } + + try { + const hash = execSync("git rev-parse --short HEAD", { cwd: process.cwd() }).toString().trim(); + return NextResponse.json({ hash }); + } catch { + return NextResponse.json({ hash: "unknown" }); + } +} diff --git a/apps/web/components/footer.tsx b/apps/web/components/footer.tsx index d8c96fa..ce7b159 100644 --- a/apps/web/components/footer.tsx +++ b/apps/web/components/footer.tsx @@ -2,13 +2,22 @@ import { useEffect, useState } from "react"; +const BUILD_HASH = process.env.NEXT_PUBLIC_GIT_HASH || "unknown"; +const SHOULD_LOAD_DEV_HASH = process.env.NODE_ENV === "development" && BUILD_HASH === "unknown"; + +function formatHash(hash: string) { + return hash === "unknown" ? hash : hash.slice(0, 7); +} + export function Footer() { - const [hash, setHash] = useState("..."); + const [hash, setHash] = useState(formatHash(BUILD_HASH)); useEffect(() => { + if (!SHOULD_LOAD_DEV_HASH) return; + fetch("/api/commit-hash") .then((res) => res.json()) - .then((data) => setHash(data.hash)) + .then((data: { hash?: string }) => setHash(formatHash(data.hash || "unknown"))) .catch(() => setHash("unknown")); }, []); @@ -17,4 +26,4 @@ export function Footer() { {hash} ); -} \ No newline at end of file +}