diff --git a/.forgejo/workflows/release.yml b/.forgejo/workflows/release.yml index d5902ea0..0366f156 100644 --- a/.forgejo/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -50,9 +50,11 @@ jobs: if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then VERSION="${GITHUB_REF#refs/tags/}" echo "args=-t ${IMAGE}:${VERSION} -t ${IMAGE}:latest" >> "$GITHUB_OUTPUT" + echo "version=${VERSION}" >> "$GITHUB_OUTPUT" echo "::notice::Release build: ${VERSION} + latest" else echo "args=-t ${IMAGE}:main" >> "$GITHUB_OUTPUT" + echo "version=main" >> "$GITHUB_OUTPUT" echo "::notice::Main-branch build: :main" fi @@ -93,4 +95,7 @@ jobs: - name: Build and push if: steps.guard.outputs.ready == 'true' - run: docker buildx build --push ${{ steps.tags.outputs.args }} . + run: | + docker buildx build \ + --build-arg MINSTREL_VERSION="${{ steps.tags.outputs.version }}" \ + --push ${{ steps.tags.outputs.args }} . diff --git a/Dockerfile b/Dockerfile index 34cc41ad..436df34c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,13 @@ COPY . . # Overwrite the committed placeholder with the freshly-built SPA assets. COPY --from=web /web/build ./web/build ENV CGO_ENABLED=0 -RUN go build -trimpath -ldflags="-s -w" -o /out/minstrel ./cmd/minstrel +# Version stamping: release.yml passes the git tag via MINSTREL_VERSION +# build-arg; local `docker build` falls back to "dev". Surfaced at +# /healthz for operator-side image-version verification. +ARG MINSTREL_VERSION=dev +RUN go build -trimpath \ + -ldflags="-s -w -X 'git.fabledsword.com/bvandeusen/minstrel/internal/server.ServerVersion=${MINSTREL_VERSION}'" \ + -o /out/minstrel ./cmd/minstrel FROM debian:bookworm-slim RUN apt-get update \ diff --git a/internal/server/server.go b/internal/server/server.go index db363e6e..699418ac 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -148,6 +148,7 @@ func (s *Server) handleHealthz(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _ = json.NewEncoder(w).Encode(map[string]string{ "status": "ok", + "version": ServerVersion, "min_client_version": MinClientVersion, }) } diff --git a/internal/server/version.go b/internal/server/version.go index b97672d0..d9ffb254 100644 --- a/internal/server/version.go +++ b/internal/server/version.go @@ -4,3 +4,13 @@ package server // accepts. Bump it when a server change requires a paired client update; // older clients see version_too_old at /healthz and refuse to operate. const MinClientVersion = "0.1.0" + +// ServerVersion is the deployed server image's version tag. Defaults to +// "dev" for local builds; overridden at link time via: +// +// -ldflags="-X 'git.fabledsword.com/bvandeusen/minstrel/internal/server.ServerVersion=v2026.05.10.2'" +// +// release.yml passes the git tag through MINSTREL_VERSION build-arg → +// Dockerfile ldflag. Surfaced at /healthz so operators can verify which +// image their container is running without exec'ing into it. +var ServerVersion = "dev" diff --git a/web/src/lib/components/ServerVersion.svelte b/web/src/lib/components/ServerVersion.svelte new file mode 100644 index 00000000..2fc80eea --- /dev/null +++ b/web/src/lib/components/ServerVersion.svelte @@ -0,0 +1,37 @@ + + +{#if version} +
Server {version}
+{/if} diff --git a/web/src/routes/settings/+page.svelte b/web/src/routes/settings/+page.svelte index 2e71cee0..4dbabce3 100644 --- a/web/src/routes/settings/+page.svelte +++ b/web/src/routes/settings/+page.svelte @@ -18,6 +18,7 @@ import { errCode } from '$lib/api/errors'; import { pushToast } from '$lib/stores/toast.svelte'; import MobileAppDownload from '$lib/components/MobileAppDownload.svelte'; + import ServerVersion from '$lib/components/ServerVersion.svelte'; const queryClient = useQueryClient(); @@ -326,4 +327,8 @@