Skip to content

Show app version from git tag instead of dev commit-diff link#3196

Merged
kimadactyl merged 2 commits into
mainfrom
fix-2055-app-version
May 29, 2026
Merged

Show app version from git tag instead of dev commit-diff link#3196
kimadactyl merged 2 commits into
mainfrom
fix-2055-app-version

Conversation

@kimadactyl
Copy link
Copy Markdown
Member

What & why

Closes #2055.

The admin sidebar and both site footers previously showed a 7-char commit SHA linking to the merge diff that produced the deploy. That diff is only intelligible to developers and is noisy (it's the squashed mainprod merge). This replaces it with a friendly app version derived from the latest git tag (e.g. v0.27.3), linking to the matching GitHub release page.

Changes

  • app/lib/app_version.rb — new AppVersion value object encapsulating the display logic, so the three call sites don't duplicate it:
    • AppVersion.label(fallback:)ENV['APP_VERSION'] → short ENV['GIT_REV'] (first 7) → fallback ('dev' for admin, 'main' for footers).
    • AppVersion.urlreleases/tag/<tag> when APP_VERSION is set (the -N-gSHA git-describe suffix is stripped so the link stays valid when a build is ahead of the latest tag) → commit diff when only GIT_REV is set → repo home otherwise.
    • Blank env values are treated as unset (.presence), so a tarball deploy with no git context degrades gracefully.
  • app/views/layouts/admin/application.rb (leftbar_build_info), app/components/footer.rb, app/components/directory/footer.rb — now use AppVersion. The existing admin.leftbar.build i18n key is kept.
  • Dockerfile — added ARG APP_VERSION / ENV APP_VERSION to the runtime stage. .git is excluded from the build context (.dockerignore), so the value cannot be derived inside the build and is passed in.
  • config/deploy.yml — Kamal computes git describe --tags --always on the host and passes it both as a builder.args build arg (baked into the image) and via env.clear (present in the running container), mirroring the existing RUBY_VERSION pattern.

Tests

  • spec/lib/app_version_spec.rb — label + URL fallback chain, suffix stripping, blank-env handling.
  • spec/components/footer_component_spec.rb, spec/components/directory/footer_component_spec.rb — render the version + release link when APP_VERSION is set, fall back to main + repo link when unset.
  • spec/components/admin/leftbar_build_info_spec.rb — covers the admin sidebar fragment (APP_VERSION set vs unset), asserts the Build label is retained.

All 15 examples pass; Rubocop clean.

⚠️ Needs maintainer verification

The Dockerfile / config/deploy.yml git describe injection cannot be RSpec-verified and needs a maintainer to confirm on a real build/deploy that APP_VERSION reaches the running container (and shows e.g. v0.27.3 rather than a SHA) — particularly that the deploy host's checkout has tags available (git fetch --tags).

Note: config/appsignal.yml still uses GIT_REV for revision tracking; that's intentionally left unchanged.

🤖 Generated with Claude Code

Replace the developer-only commit-diff link in the admin sidebar and both
site footers with a friendly app version derived from the latest git tag
(e.g. v0.27.3), linking to the GitHub release page for that tag.

- Add AppVersion (app/lib) encapsulating the label + URL fallback chain:
  ENV['APP_VERSION'] (git describe) -> short ENV['GIT_REV'] -> 'dev'/'main'.
  When APP_VERSION is set the link points at releases/tag/<tag> (the
  git-describe '-N-gSHA' suffix is stripped so the link stays valid when a
  build is ahead of the latest tag); otherwise it falls back to the commit
  diff (GIT_REV) or the repo home.
- Inject APP_VERSION at Docker build via an ARG/ENV in the runtime stage and
  pass it through Kamal (config/deploy.yml builder.args + env.clear),
  computed on the host from 'git describe --tags --always' since .git is
  excluded from the build context (.dockerignore).
- Update admin layout leftbar_build_info and both footers to use AppVersion;
  keep the existing admin.leftbar.build i18n key.
- Specs: AppVersion unit spec, component specs for both footers, and a
  component spec covering leftbar_build_info (APP_VERSION set vs unset).
@kimadactyl
Copy link
Copy Markdown
Member Author

We are no longer using the main -> prod merge, we are using main to deploy to staging and releases to deploy to prod. Does that change this? It seems very complicated!

@kimadactyl
Copy link
Copy Markdown
Member Author

Good question — the new model actually makes this cleaner, not broken:

  • Prod (deploys from a release): the checkout is at a git tag, so git describe --tags resolves to a clean v0.9.1. Exactly what we want shown in prod.
  • Staging (deploys from main): git describe --tags gives v0.9.1-5-gabc1234 (5 commits past the last release) — which is genuinely useful info for "what's on staging".

So no change is needed for it to work under main→staging / releases→prod.

The "complicated" bit is the Kamal wiring, and there's one real simplification available: git describe is currently passed twice — as a builder.args (baked into the image via the Dockerfile ARGENV) and as a runtime env:. If Kamal builds per-deploy (the default), the build arg alone is enough and the runtime env: is redundant — we could drop it. The only case where you'd want to keep both is if you ever promote one prebuilt image across environments.

I didn't edit deploy.yml/Dockerfile here because it can't be RSpec-verified (the PR already flags this) and a wrong guess breaks deploys. Tell me which you'd prefer and I'll make just that change:

  1. Leave as-is (works for both envs).
  2. Drop the redundant runtime env: APP_VERSION (rely on the baked build arg).
  3. On release deploys, use the CI tag (GITHUB_REF_NAME) directly instead of git describe.

Per review: drop the redundant runtime env.clear.APP_VERSION from deploy.yml. The Dockerfile already bakes the builder.args APP_VERSION into the image as ENV (ARG->ENV in the runtime stage), so the value reaches runtime without a duplicate env var — one git-describe instead of two. Also tidy the spec stubs to the real current version (v0.27.3).
@kimadactyl
Copy link
Copy Markdown
Member Author

Done — went with the simplest option. Pushed: dropped the redundant runtime env.clear.APP_VERSION from deploy.yml, since the Dockerfile already bakes the builder.args value into the image as ENV APP_VERSION (ARG→ENV in the runtime stage). So it's now one git describe at build time, no duplication — deploy.yml is net −2 lines.

And re: your version note — nothing hardcodes a version; git describe --tags --always resolves the real latest tag, so this shows v0.27.3 today and tracks future releases automatically. (The earlier "v0.9.1" was just a stale example of mine from a lexical git tag sort — v0.9.x sorts after v0.27.x.) I also updated the spec stubs from v0.9.1 to v0.27.3 so the tests read truthfully. app_version.rb itself was already clean, so it's untouched. The Dockerfile/deploy plumbing still needs a real-deploy eyeball as before.

@kimadactyl kimadactyl merged commit 7d4d5f5 into main May 29, 2026
14 checks passed
@kimadactyl kimadactyl deleted the fix-2055-app-version branch May 29, 2026 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make github release link in admin interface friendlier

1 participant