Skip to content

Conversation

@mertssmnoglu
Copy link
Member

@mertssmnoglu mertssmnoglu commented Aug 19, 2025

Summary

Extend Capture metadata to include more build information when execute capture --version

  • Build commit has
  • Date of the build commit
  • Build date time
  • Git Tag

Fixes: #92

CLI

Execute capture with --version flag

capture --version

Output

Capture Build Information
-------------------------
Version          : 1.3.0-SNAPSHOT-f9dc4b8
Commit Hash      : f9dc4b8b8267d88cb55a1433ebb5474bda3785c0
Commit Date      : 2025-08-20T14:26:08Z
Compiled At      : 2025-08-20T14:26:21Z
Git Tag          : v1.3.0

API

curl -s -X GET "http://localhost:59232/api/v1/metrics" \
    -H "Authorization: Bearer abc" \
    -H "Accept: application/json" | jq '.capture'
{
  "version": "1.3.0-SNAPSHOT-f9dc4b8",
  "mode": "release"
}

Summary by CodeRabbit

  • New Features

    • Enhanced -version output now shows detailed build information: Version, Commit, CommitDate, CompiledAt, and GitTag.
  • Chores

    • Binaries now embed build metadata (commit, commit date, build time, git tag) via standardized build flags.
    • Consolidated build flag configuration for consistency across build targets.

- CLI: 'capture --version'
- API: GET /api/v1/metrics | jq '.capture'

Signed-off-by: Mert Şişmanoğlu <[email protected]>
@mertssmnoglu mertssmnoglu added this to the Next Minor Release milestone Aug 19, 2025
@mertssmnoglu mertssmnoglu self-assigned this Aug 19, 2025
@mertssmnoglu mertssmnoglu added the enhancement New feature or request label Aug 19, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 19, 2025

Walkthrough

Adds build-time metadata injection via Goreleaser ldflags and extends the Capture binary’s -version output to include commit, commit date, compiled timestamp, and git tag using new public variables.

Changes

Cohort / File(s) Summary
Build metadata via Goreleaser
/.goreleaser.yml
Introduces shared ldflags anchor and reuses it for kos; injects Version, Commit, CommitDate, CompiledAt, GitTag via -X flags; retains -s -w and static linking flags.
Runtime metadata exposure
/cmd/capture/main.go
Adds public vars: Version, Commit, CommitDate, CompiledAt, GitTag with defaults; updates -version flag to print a multi-line “Capture Build Information”; adds doc comment for appConfig.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Dev as Developer
  participant GR as Goreleaser
  participant Go as Go Compiler
  participant Bin as Capture Binary

  Dev->>GR: goreleaser release
  GR->>Go: Build with ldflags (-X main.* from templates)
  Go-->>Bin: Produce binary with embedded Version, Commit, CommitDate, CompiledAt, GitTag
Loading
sequenceDiagram
  autonumber
  participant User as User
  participant Bin as Capture (main)
  participant OS as OS

  User->>Bin: Run capture -version
  Bin->>Bin: Read Version, Commit, CommitDate, CompiledAt, GitTag
  Bin-->>User: Print multi-line build information
  Bin->>OS: Exit(0)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
Extend metadata to include Commit, Commit Date, Compiled at, Git Tag via build ldflags and expose in app (#92) Build vars and ldflags added; endpoint changes not shown. Unclear if metadata endpoint now returns these fields.

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Added doc comment for appConfig (cmd/capture/main.go) Documentation-only; not tied to metadata feature requirements from #92.

Poem

I twitched my ears at version’s gleam,
Now tags and commits join the stream—
A timestamp hops, compiled with cheer,
The date and hash both burrow near.
With flags aflutter, builds take flight—
A metadata moon in the capture night! 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-build-metadata

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (7)
.goreleaser.yml (2)

11-14: Avoid empty GitTag values on snapshot builds (fallback to 'unknown').

When building snapshots (no tag), {{.Tag}} can be empty. With -X "main.GitTag={{.Tag}}" this will override the in-binary default and set GitTag to the empty string, which then yields an empty/incorrect Git Tag and a broken Git Tag URL at runtime.

Use a conditional to set a sensible fallback for snapshots:

Apply this diff in both ldflags blocks:

-      - -X "main.GitTag={{.Tag}}"
+      - -X "main.GitTag={{ if not .IsSnapshot }}{{ .Tag }}{{ else }}unknown{{ end }}"

Also applies to: 50-53


7-14: DRY the duplicate ldflags with a YAML anchor.

The ldflags list is duplicated for builds and kos. Consider a YAML anchor to keep them in sync and reduce maintenance errors.

You can refactor like this (illustrative snippet):

builds:
  - id: capture
    main: ./cmd/capture
    ldflags: &common_ldflags
      - -s -w
      - -extldflags "-static"
      - -X "main.Version={{.Version}}"
      - -X "main.Commit={{.Commit}}"
      - -X "main.CommitDate={{.CommitDate}}"
      - -X "main.CompiledAt={{.Date}}"
      - -X "main.GitTag={{ if not .IsSnapshot }}{{ .Tag }}{{ else }}unknown{{ end }}"

kos:
  - id: capture
    main: ./cmd/capture
    ldflags: *common_ldflags

Also applies to: 47-53

internal/server/handler/types.go (1)

12-18: Consider omitting empty metadata fields from the API response.

Right now, unknown values will serialize as empty strings. If you prefer a leaner response, add omitempty so snapshot/local builds don’t show placeholders clients can’t use (particularly git_tag_url).

Example diff:

- Version    string `json:"version"`
- Mode       string `json:"mode"`
- Commit     string `json:"commit"`
- CommitDate string `json:"commit_date"`
- CompiledAt string `json:"compiled_at"`
- GitTag     string `json:"git_tag"`
- GitTagURL  string `json:"git_tag_url"`
+ Version    string `json:"version"`
+ Mode       string `json:"mode,omitempty"`
+ Commit     string `json:"commit,omitempty"`
+ CommitDate string `json:"commit_date,omitempty"`
+ CompiledAt string `json:"compiled_at,omitempty"`
+ GitTag     string `json:"git_tag,omitempty"`
+ GitTagURL  string `json:"git_tag_url,omitempty"`

If keeping fields always present is intentional for clients, feel free to ignore.

cmd/capture/main.go (4)

15-20: Fix comment: APISecret is required (fatal if missing), not “default is blank”.

Per prior implementation in internal/config/config.go, API_SECRET is required and the app exits if it’s missing. Update the comment to avoid misleading readers.

Apply this diff:

-// Application configuration variable that holds the settings.
-//
-//
-//   - Port: Server port, default is 59232
-//
-//
-//   - APISecret: Secret key for API access, default is a blank string.
+// appConfig holds application settings.
+// - Port: Server port (defaults to 59232 if empty).
+// - APISecret: Secret key for API access (required; process exits if missing).

22-38: Derive GitTagURL at runtime to avoid “unknown”/empty URLs.

When building snapshots, GitTag may be unknown or empty. Pre-initializing GitTagURL to a constant string concatenation will produce a broken URL. Compute it at runtime and omit when not meaningful.

Apply this diff:

-	// GitTagURL holds the URL of the Git tag, if any.
-	GitTagURL = "https://github.com/bluewave-labs/capture/releases/tag/" + GitTag
+	// GitTagURL holds the URL of the Git tag, if any. Set at runtime from GitTag.
+	GitTagURL = ""

Then add this helper (outside the shown ranges):

// buildGitTagURL returns the GitHub release URL for the given tag, or "" if tag is empty/unknown.
func buildGitTagURL(tag string) string {
	if tag == "" || tag == "unknown" {
		return ""
	}
	return "https://github.com/bluewave-labs/capture/releases/tag/" + tag
}

44-54: Only print Git Tag URL when available and build it from the tag.

This keeps the output clean on snapshot/local builds and avoids showing a broken URL.

Apply this diff:

-	// Check if the version flag is provided and show build information
+	// Check if the version flag is provided and show build information
 	if *showVersion {
 		fmt.Println("Capture Build Information")
 		fmt.Println("-------------------------")
 		fmt.Printf("Version          : %s\n", Version)
 		fmt.Printf("Commit Hash      : %s\n", Commit)
 		fmt.Printf("Commit Date      : %s\n", CommitDate)
 		fmt.Printf("Compiled At      : %s\n", CompiledAt)
 		fmt.Printf("Git Tag          : %s\n", GitTag)
-		fmt.Printf("Git Tag URL      : %s\n", GitTagURL)
+		if url := buildGitTagURL(GitTag); url != "" {
+			fmt.Printf("Git Tag URL      : %s\n", url)
+		}
 		os.Exit(0)
 	}

62-69: Populate GitTagURL from the tag at startup (omit when not available).

This ensures API responses don’t expose a broken URL on snapshot/local builds.

Apply this diff:

 	srv := server.NewServer(appConfig, nil, &handler.CaptureMeta{
 		Version:    Version,
 		Commit:     Commit,
 		CommitDate: CommitDate,
 		CompiledAt: CompiledAt,
 		GitTag:     GitTag,
-		GitTagURL:  GitTagURL,
+		GitTagURL:  buildGitTagURL(GitTag),
 	})
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 86059f7 and ee88ec2.

📒 Files selected for processing (3)
  • .goreleaser.yml (2 hunks)
  • cmd/capture/main.go (2 hunks)
  • internal/server/handler/types.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-02-01T14:10:43.142Z
Learnt from: mertssmnoglu
PR: bluewave-labs/capture#45
File: cmd/capture/main.go:34-38
Timestamp: 2025-02-01T14:10:43.142Z
Learning: In the Capture project, environment variable validation for PORT and API_SECRET is handled in internal/config/config.go's NewConfig function. PORT gets a default value if not set, and API_SECRET is required with a fatal error if missing.

Applied to files:

  • cmd/capture/main.go
🧬 Code Graph Analysis (2)
internal/server/handler/types.go (1)
cmd/capture/main.go (6)
  • Version (27-27)
  • Commit (29-29)
  • CommitDate (31-31)
  • CompiledAt (33-33)
  • GitTag (35-35)
  • GitTagURL (37-37)
cmd/capture/main.go (1)
internal/config/config.go (1)
  • Config (5-8)
🔇 Additional comments (2)
cmd/capture/main.go (2)

41-45: No action required: --version is supported by the stdlib flag

Go’s standard flag package accepts both -version and --version interchangeably, so capture --version will work without any preprocessing or external libraries.


62-69: No action needed: CaptureMeta.Mode is already set

The call to server.NewServer(appConfig, nil, &handler.CaptureMeta{…}) passes your metadata into InitializeHandler, which immediately does:

metadata.Mode = gin.Mode()

so .mode will always reflect the active Gin mode. You can safely ignore the suggestion to set Mode in the struct literal.

Likely an incorrect or invalid review comment.

@mertssmnoglu mertssmnoglu moved this to In review in Capture Aug 19, 2025
@mertssmnoglu
Copy link
Member Author

Hi @gorkem-bwl @ajhollid

These commit hash and build time values are useful for troubleshooting but I'm not sure about sending so much metadata on each request. What is your opinion? I can make it only appear on CLI and stop exposing them through the API.

@gorkem-bwl
Copy link
Contributor

Hi @gorkem-bwl @ajhollid

These commit hash and build time values are useful for troubleshooting but I'm not sure about sending so much metadata on each request. What is your opinion? I can make it only appear on CLI and stop exposing them through the API.

I feel like this is too much for production. Your suggestion is better.

@ajhollid
Copy link
Collaborator

Hi @gorkem-bwl @ajhollid

These commit hash and build time values are useful for troubleshooting but I'm not sure about sending so much metadata on each request. What is your opinion? I can make it only appear on CLI and stop exposing them through the API.

I feel like this is too much for production. Your suggestion is better.

Yeah cli is probably good, or add a dev flag and only add that info if the flag is set.

@mertssmnoglu
Copy link
Member Author

Thank you for the responses.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
cmd/capture/main.go (2)

15-19: Fix inaccurate config comment: APISecret is required; avoid hardcoding defaults

Per the project’s config behavior (see internal/config.NewConfig), PORT has a default if unset, and API_SECRET is required and fatal if missing. The current comment says APISecret defaults to blank and hardcodes a port value, which can drift.

Apply this diff to make the comment accurate and resilient to future changes:

-// Application configuration variable that holds the settings.
-//
-//
-//   - Port: Server port, default is 59232
-//
-//
-//   - APISecret: Secret key for API access, default is a blank string.
+// Application configuration parsed by internal/config.NewConfig:
+//   - Port: Server port. Default is provided by NewConfig when PORT is unset.
+//   - APISecret: Secret key for API access. Required; NewConfig exits fatally if missing.

If you want to keep the exact default port documented, please verify it from internal/config and then update the comment accordingly. I can run a repo search to confirm the current default if you want.


42-51: No action needed for “--version”; consider optional JSON output

  • The Go standard flag package accepts both -version and --version (they’re treated identically), so capture --version already works as intended.
  • Only migrate to a GNU‐style parser (e.g. spf13/pflag or cobra) if you require strict long/short distinctions, flag chaining, or specialized help formatting.
  • Optional: in cmd/capture/main.go:42-51, add a JSON output mode (e.g. --version-json) or detect a TTY to emit machine-readable version info for scripting purposes.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d42c602 and f9dc4b8.

📒 Files selected for processing (1)
  • cmd/capture/main.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-02-01T14:10:43.142Z
Learnt from: mertssmnoglu
PR: bluewave-labs/capture#45
File: cmd/capture/main.go:34-38
Timestamp: 2025-02-01T14:10:43.142Z
Learning: In the Capture project, environment variable validation for PORT and API_SECRET is handled in internal/config/config.go's NewConfig function. PORT gets a default value if not set, and API_SECRET is required with a fatal error if missing.

Applied to files:

  • cmd/capture/main.go
🧬 Code Graph Analysis (1)
cmd/capture/main.go (1)
internal/config/config.go (1)
  • Config (5-8)

@mertssmnoglu mertssmnoglu changed the title feat: Add more build metadata to Capture and API response #92 feat: Add more build metadata like commit hash, commit date, build date and git tag Aug 20, 2025
@mertssmnoglu mertssmnoglu merged commit ac0f516 into develop Aug 20, 2025
14 checks passed
@github-project-automation github-project-automation bot moved this from In review to Done in Capture Aug 20, 2025
@mertssmnoglu mertssmnoglu deleted the feat/add-build-metadata branch August 20, 2025 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Add more metadata about Capture

4 participants