Skip to content

feat: report the build version and aggregate the platform's; add release automation - #3

Merged
flaccid merged 2 commits into
mainfrom
ci/release-automation-and-version
Aug 25, 2026
Merged

feat: report the build version and aggregate the platform's; add release automation#3
flaccid merged 2 commits into
mainfrom
ci/release-automation-and-version

Conversation

@flaccid

@flaccid flaccid commented Aug 25, 2026

Copy link
Copy Markdown
Member

Closes #2. Part of kube-workspaces/deploy#2.

Version at runtime

Nothing recorded which version was running. The Dockerfile built with no
-ldflags, there was no version variable, and no endpoint reported one — so the
only signal was the image tag, which is latest in the default manifests and
therefore says nothing.

Surface Output
--version v0.3.0 (commit abc1234, built …, linux/amd64, go1.26.7)
startup log same, structured
GET /platform/version JSON

Defaults are dev/unknown, so a plain go build still works.

/platform/version aggregates the whole platform

The API is the natural place to answer "what is this cluster running?", so the
endpoint reports its own compiled-in build plus the image each of the four
components is actually running
:

{
  "api": {
    "version": "v0.3.0", "commit": "abc1234", "buildDate": "",
    "go": "go1.26.7", "platform": "linux/amd64"
  },
  "images": {
    "controller": "ghcr.io/kube-workspaces/controller:v0.3.0",
    "api":        "ghcr.io/kube-workspaces/api:v0.3.0",
    "proxy":      "ghcr.io/kube-workspaces/proxy:v0.3.0",
    "frontend":   "ghcr.io/kube-workspaces/frontend:v0.3.0"
  }
}

It reads pod specs rather than calling each component's own /version, which
avoids assuming the other components are healthy — precisely the situation in
which you most want this endpoint.

Auth

Exempt from the auth middleware and from maintenance mode. Identifying a
deployment is diagnostic, not privileged, and needing a session to read it
defeats the purpose during an incident; it exposes nothing beyond component image
tags.

The maintenance exemption was broadened from /platform/config to /platform/
to cover both, since both are used to diagnose maintenance mode.

debug.ReadBuildInfo() is not a substitute: it reports (devel) for a build
not driven by go install module@version, which is the case for the container
build.

The workflow passes VERSION from docker/metadata-action rather than
reconstructing it, so the image tag and the reported version cannot drift.

Release automation

Adds the release workflow and .github/release.yml categories, identical across
the five repositories. The note preamble comes from a shared generator in the
deploy repo which states explicitly when a release has no functional changes —
relevant here, since this component is often tagged only to hold the platform
version line. Defaults to a dry run.

Verification

  • go build, go vet, go test ./cmd/... ./internal/... all pass
  • --version verified locally

Note

cmd/kube_workspaces/http.go and internal/auth/config.go have pre-existing
gofmt deviations. I left them untouched rather than mixing unrelated formatting
churn into this diff, but they are worth a separate cleanup.

Part of kube-workspaces/deploy#2.

Adds a release workflow and the .github/release.yml categories used to generate
notes, both identical across the five repositories so a reader moving between
them sees the same structure.

The note preamble comes from a shared generator in the deploy repo, which
classifies the commits since the last tag. That matters here because this
component often has nothing but CI and docs changes in a cycle and still gets
tagged to hold the platform version line — in that case the notes say so
explicitly rather than leaving someone to infer it from a list of CI commits.

The workflow defaults to a dry run so the notes can be reviewed before anything
is tagged.
Closes #2.

Nothing recorded which version was running. The Dockerfile built with no
-ldflags, there was no version variable, and no endpoint reported one — so the
only signal was the image tag, which is `latest` in the default manifests and
therefore says nothing.

Version, commit and build date are now compiled in, defaulting to dev/unknown so
a plain `go build` still works, and surfaced three ways:

  --version                 prints and exits
  startup log               so a pod is identifiable from its logs alone
  GET /platform/version     JSON

The API is the natural place to answer "what is this cluster running?", so
/platform/version aggregates: its own compiled-in build, plus the image each of
the four components is actually running, read from their pod specs. Reading pod
specs rather than calling each component's own /version avoids assuming the other
components are healthy — which is precisely when you most want this endpoint.

It is exempt from the auth middleware and from maintenance mode. Identifying a
deployment is diagnostic, not privileged, and needing a session to read it defeats
the purpose during an incident; it exposes nothing beyond component image tags.
The maintenance exemption was broadened from /platform/config to /platform/ to
cover both, since both are used to diagnose maintenance mode.

debug.ReadBuildInfo() is not a substitute: it reports "(devel)" for a build not
driven by `go install module@version`, which is the case for the container build.

The workflow passes VERSION from docker/metadata-action rather than
reconstructing it, so the image tag and the reported version cannot drift.

Note: http.go and internal/auth/config.go have pre-existing gofmt deviations,
left untouched rather than mixing unrelated formatting into this change.
@flaccid flaccid added enhancement New feature or request ci CI, build and release tooling labels Aug 25, 2026
@flaccid
flaccid merged commit f38325a into main Aug 25, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci CI, build and release tooling enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bake the version into the binary and expose it at runtime

1 participant