vahiiiid/go-rest-api-boilerplate
Add Version Information and Build Metadata to Application
Open
#70 opened on Oct 18, 2025
enhancementgood first issue
Repository metrics
- Stars
- (60 stars)
- PR merge metrics
- (PR metrics pending)
Description
Problem
The application has no version information or build metadata, making it difficult to:
- Track which version is running in production
- Debug deployment issues
- Correlate logs/errors with releases
- Verify successful deployments
- Support customers effectively
Current State
No version information visible anywhere:
- Not in logs
- Not in health check
- Not exposed via API
- Cannot determine what's running
Proposed Solution
Add build-time version injection and expose it via API.
1. Add Version Variables in main.go
package main
var (
version = "dev" // Set via -ldflags at build time
commit = "none" // Git commit hash
buildDate = "unknown" // Build timestamp
goVersion = runtime.Version()
)
func main() {
log.Printf("Starting %s", getVersionInfo())
// ... rest of startup
}
func getVersionInfo() string {
return fmt.Sprintf("v%s (commit: %s, built: %s, go: %s)",
version, commit[:7], buildDate, goVersion)
}
2. Update Dockerfile for Build-Time Injection
# Get build args
ARG VERSION=dev
ARG COMMIT=unknown
ARG BUILD_DATE=unknown
# Build with ldflags
RUN go build -ldflags="\
-X main.version=${VERSION} \
-X main.commit=${COMMIT} \
-X main.buildDate=${BUILD_DATE}" \
-o main ./cmd/server
3. Add Version Endpoint
// internal/server/router.go
router.GET("/version", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"version": version,
"commit": commit,
"buildDate": buildDate,
"goVersion": goVersion,
})
})
4. Enhance Health Check
router.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"version": version,
"timestamp": time.Now(),
})
})
5. Update Makefile for Local Builds
VERSION ?= $(shell git describe --tags --always --dirty)
COMMIT ?= $(shell git rev-parse HEAD)
BUILD_DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
.PHONY: build
build:
\t@go build -ldflags="\
\t\t-X main.version=${VERSION} \
\t\t-X main.commit=${COMMIT} \
\t\t-X main.buildDate=${BUILD_DATE}" \
\t\t-o bin/server ./cmd/server
Benefits
- ✅ Track running versions in production
- ✅ Better deployment verification
- ✅ Easier debugging and support
- ✅ Version endpoint for monitoring tools
- ✅ Improved observability
- ✅ Professional production readiness
Implementation Checklist
- Add version variables to
cmd/server/main.go - Log version info at startup
- Create
/versionendpoint - Update
/healthto include version - Update Dockerfile with build args
- Update Makefile with ldflags
- Update CI/CD to inject version info
- Update docker-compose.yml with build args
- Add version to Swagger docs
- Update documentation
Example Output
Startup Logs
Starting GRAB API v1.2.3 (commit: abc1234, built: 2025-10-18T10:30:00Z, go: go1.24.0)
Server starting on :8080
GET /version
{
"version": "1.2.3",
"commit": "abc1234567890abcdef1234567890abcdef1234",
"buildDate": "2025-10-18T10:30:00Z",
"goVersion": "go1.24.0"
}
References
- Semantic Versioning
- Go Build ldflags
- Standard practice in Kubernetes, Docker Hub, etc.
Priority
IMPORTANT - Improves production operations
Related Issues
- #15 (Graceful Shutdown) - Part of production readiness
- #11 (Prometheus Metrics) - Can expose version as metric