Skip to content

build(version): stamp deploy metadata - #11

Merged
garrettladley merged 1 commit into
mainfrom
gml/version-build-metadata
May 23, 2026
Merged

garrettladley merged 1 commit into
mainfrom
gml/version-build-metadata

Conversation

@garrettladley

Copy link
Copy Markdown
Owner
  • add internal/version helpers for public, release, commit, and cli version formatting
  • inject VERSION and COMMIT through Dockerfile, Justfile, and fly deploy build args
  • keep public health, mcp metadata, and pkgsite user-agent on stable public version strings
  • attach deploy revision metadata to logs, sentry metrics, and otel resources

@garrettladley
garrettladley enabled auto-merge (squash) May 23, 2026 17:05
@garrettladley
garrettladley merged commit 0cd7947 into main May 23, 2026
3 checks passed
@garrettladley
garrettladley deleted the gml/version-build-metadata branch May 23, 2026 17:06
@greptile-apps

greptile-apps Bot commented May 23, 2026

Copy link
Copy Markdown

Greptile Summary

This PR stamps deploy metadata (git SHA and full commit) into the binary via ldflags, injects it through the Dockerfile, Justfile, and GitHub Actions workflow, and routes the information to structured startup logs, OTel resource attributes, and Sentry metrics. A new internal/version package exposes purpose-specific formatters (Public, Release, CommandOutput) so external-facing strings stay stable while internal observability surfaces the precise revision.

  • internal/version/version.go replaces a single const with stamped vars and helpers that handle the dev/unknown fallback chain for each display context.
  • The health endpoint is simplified to {\"status\":\"ok\"} (no longer leaks the build version), backed by a new test asserting this invariant.
  • internal/pkgsite/client.go also contains a small unrelated fix: warmSearchResult now prefers packagePath over path when extracting the path from a single-item search result.

Confidence Score: 4/5

Safe to merge; the version stamping plumbing is correct end-to-end and the health endpoint change is guarded by a new test.

The core wiring is correct — SHA is passed from CI through build args, injected via ldflags, and routed to the right observability sinks with consistent unknown filtering. Two small inconsistencies exist in internal/version: release() does not filter the string unknown the way shortCommit() does, and a local variable in commandOutput shadows the package function. In server.go the short commit computed from ShortCommit() is discarded and the raw full-length variable is logged instead. None of these affect production behaviour under normal CI conditions, but they are worth tidying.

internal/version/version.go and internal/httpserver/server.go have the minor inconsistencies noted in the inline comments.

Important Files Changed

Filename Overview
internal/version/version.go New version helpers replacing a single constant; release() inconsistently omits the unknown guard that shortCommit() applies, and a local variable in commandOutput shadows the package-level function.
internal/httpserver/server.go Extracts health handler, adds commit to startup log, and wires ServiceRevision to observability; the ShortCommit guard discards the computed short hash and logs the raw full-length variable instead.
internal/observability/observability.go Adds ServiceRevision to Options and conditionally appends vcs.ref.head.revision to OTel resource attributes when a real commit is present.
internal/observability/sentry/sentry.go Conditionally attaches vcs.ref.head.revision to Sentry metrics using the same non-empty/non-unknown guard as the OTel path.
internal/pkgsite/client.go User-agent updated to use Public(); warmSearchResult now prefers packagePath over path when extracting the path from a search result item — a correct, unrelated fix bundled in the PR.
Dockerfile Introduces VERSION and COMMIT build args with safe defaults, injected via -ldflags into the binary.
.github/workflows/fly-deploy.yml Passes VERSION=sha-SHORT and full COMMIT=FULL_SHA as build args to flyctl deploy.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Build time"] -->|version.Version| B["version.Release()"]
    A -->|version.Commit| C["version.ShortCommit()"]
    B --> D["Startup log"]
    B --> E["OTel service.version"]
    B --> F["Sentry Release"]
    C --> G["OTel vcs.ref.head.revision"]
    C --> H["Sentry vcs.ref.head.revision"]
    A -->|PublicVersion| I["version.Public()"]
    I --> J["MCP Version"]
    I --> K["pkgsite User-Agent"]
Loading

Reviews (1): Last reviewed commit: "build(version): stamp deploy metadata" | Re-trigger Greptile

Comment on lines +30 to +34
func release(version, commit string) string {
version = strings.TrimSpace(version)
if version != "" && version != "dev" {
return version
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 release() guards against empty and "dev" but not "unknown", while shortCommit() explicitly rejects "unknown". If Version is stamped with "unknown" (e.g. the build arg is unset or the shell fallback fires), release() returns "unknown" verbatim, which would propagate to OTel service.version and Sentry Release without filtering.

Suggested change
func release(version, commit string) string {
version = strings.TrimSpace(version)
if version != "" && version != "dev" {
return version
}
func release(version, commit string) string {
version = strings.TrimSpace(version)
if version != "" && version != "dev" && version != "unknown" {
return version
}

Comment on lines +62 to +64
func commandOutput(version, commit string) string {
release := release(version, commit)
commit = strings.TrimSpace(commit)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The local variable release shadows the package-level function release() in the same scope. Go resolves the function call on the right-hand side before the variable is declared, so this compiles and runs correctly today, but it makes the code fragile — any future call to release(...) after this line inside commandOutput would silently invoke the string value rather than the function. Renaming the local avoids the hazard.

Suggested change
func commandOutput(version, commit string) string {
release := release(version, commit)
commit = strings.TrimSpace(commit)
func commandOutput(version, commit string) string {
releaseStr := release(version, commit)
commit = strings.TrimSpace(commit)

Comment on lines 109 to +115
errCh := make(chan error, 1)
go func() {
logger.InfoContext(ctx, "starting pkgsite-mcp http server", slog.String("addr", cfg.Addr), slog.String("version", version.Version))
attrs := []any{slog.String("addr", cfg.Addr), slog.String("version", version.Release())}
if commit := version.ShortCommit(); commit != "" {
attrs = append(attrs, slog.String("commit", version.Commit))
}
logger.InfoContext(ctx, "starting pkgsite-mcp http server", attrs...)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The guard assigns the short commit to commit but then discards it, logging the raw package-level version.Commit instead. Using ShortCommit() purely as a boolean guard while ignoring the returned value is misleading — either log the short form already in hand, or guard directly on the raw variable.

Suggested change
errCh := make(chan error, 1)
go func() {
logger.InfoContext(ctx, "starting pkgsite-mcp http server", slog.String("addr", cfg.Addr), slog.String("version", version.Version))
attrs := []any{slog.String("addr", cfg.Addr), slog.String("version", version.Release())}
if commit := version.ShortCommit(); commit != "" {
attrs = append(attrs, slog.String("commit", version.Commit))
}
logger.InfoContext(ctx, "starting pkgsite-mcp http server", attrs...)
errCh := make(chan error, 1)
go func() {
attrs := []any{slog.String("addr", cfg.Addr), slog.String("version", version.Release())}
if commit := version.ShortCommit(); commit != "" {
attrs = append(attrs, slog.String("commit", commit))
}
logger.InfoContext(ctx, "starting pkgsite-mcp http server", attrs...)

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.

1 participant