Skip to content

Commit 8512cc3

Browse files
committed
build: Build-metadata usage via go:embed
Refactor build metadata injection logic: - Introduced `build_info` package to manage version, commit, and date details. - Removed ldflags-based metadata injection. - Updated workflows and Dockerfile to prepare `build_info` files. - Added unit tests for `build_info` initialization and formatting. Because: Since build-metadata no longer needs compiling to binary, this information can already be defined at the source code level. Related github#630
1 parent d15026b commit 8512cc3

File tree

10 files changed

+124
-11
lines changed

10 files changed

+124
-11
lines changed

.github/workflows/go.yml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Build and Test Go Project
2-
on: [push, pull_request]
2+
on: [ push, pull_request ]
33

44
permissions:
55
contents: read
@@ -9,7 +9,7 @@ jobs:
99
strategy:
1010
fail-fast: false
1111
matrix:
12-
os: [ubuntu-latest, windows-latest, macos-latest]
12+
os: [ ubuntu-latest, windows-latest, macos-latest ]
1313

1414
runs-on: ${{ matrix.os }}
1515

@@ -28,5 +28,17 @@ jobs:
2828
- name: Run unit tests
2929
run: script/test
3030

31+
- name: Prepare build_info files
32+
shell: bash
33+
run: |
34+
BUILD_DATE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
35+
mkdir -p cmd/github-mcp-server/build_info
36+
echo "${{ github.sha }}" > cmd/github-mcp-server/build_info/commit.txt
37+
echo "$BUILD_DATE" > cmd/github-mcp-server/build_info/date.txt
38+
if [ "${{ github.event_name }}" = "push" ]; then
39+
echo "${{ github.ref_name }}" > cmd/github-mcp-server/build_info/version.txt
40+
else
41+
echo "pr-${{ github.event.pull_request.number }}" > cmd/github-mcp-server/build_info/version.txt
42+
fi
3143
- name: Build
3244
run: go build -v ./cmd/github-mcp-server

.goreleaser.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ before:
44
hooks:
55
- go mod tidy
66
- go generate ./...
7+
- mkdir -p cmd/github-mcp-server/build_info
8+
- echo "{{.Commit}}" > cmd/github-mcp-server/build_info/commit.txt
9+
- echo "{{.Date}}" > cmd/github-mcp-server/build_info/date.txt
10+
- echo "{{.Version}}" > cmd/github-mcp-server/build_info/version.txt
711

812
builds:
913
- env:
1014
- CGO_ENABLED=0
1115
ldflags:
12-
- -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}
16+
- -s -w
1317
goos:
1418
- linux
1519
- windows

Dockerfile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@ WORKDIR /build
88
RUN --mount=type=cache,target=/var/cache/apk \
99
apk add git
1010

11+
# Prepare build_info files
12+
RUN --mount=type=bind,target=. \
13+
mkdir -p cmd/github-mcp-server/build_info && \
14+
git rev-parse HEAD > cmd/github-mcp-server/build_info/commit.txt && \
15+
date -u +%Y-%m-%dT%H:%M:%SZ > cmd/github-mcp-server/build_info/date.txt && \
16+
echo "${VERSION}" > cmd/github-mcp-server/build_info/version.txt
17+
1118
# Build the server
1219
# go build automatically download required module dependencies to /go/pkg/mod
1320
RUN --mount=type=cache,target=/go/pkg/mod \
1421
--mount=type=cache,target=/root/.cache/go-build \
1522
--mount=type=bind,target=. \
16-
CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=${VERSION} -X main.commit=$(git rev-parse HEAD) -X main.date=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
23+
CGO_ENABLED=0 go build -ldflags="-s -w" \
1724
-o /bin/github-mcp-server cmd/github-mcp-server/main.go
1825

1926
# Make a stage to run the app

cmd/github-mcp-server/build_info.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package main
2+
3+
import (
4+
"embed"
5+
"fmt"
6+
"strings"
7+
)
8+
9+
//go:embed build_info/commit.txt build_info/date.txt build_info/version.txt
10+
var versionFS embed.FS
11+
12+
type buildInfoStruct struct {
13+
commit string
14+
date string
15+
version string
16+
}
17+
18+
func (b buildInfoStruct) String() string {
19+
return fmt.Sprintf("Commit: %s\nBuild Date: %s\nVersion: %s", b.commit, b.date, b.version)
20+
}
21+
22+
var buildInfo = func() buildInfoStruct {
23+
readFile := func(path, fallback string) string {
24+
if content, err := versionFS.ReadFile(path); err == nil {
25+
return strings.TrimSpace(string(content))
26+
}
27+
return fallback
28+
}
29+
30+
return buildInfoStruct{
31+
commit: readFile("build_info/commit.txt", "unknown commit"),
32+
date: readFile("build_info/date.txt", "unknown date"),
33+
version: readFile("build_info/version.txt", "unknown version"),
34+
}
35+
}()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
commit
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
date
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
version
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestBuildInfoStruct_String(t *testing.T) {
10+
tests := []struct {
11+
name string
12+
info buildInfoStruct
13+
expected string
14+
}{
15+
{
16+
name: "all fields populated",
17+
info: buildInfoStruct{
18+
commit: "abc123",
19+
date: "2024-01-01",
20+
version: "1.0.0",
21+
},
22+
expected: "Commit: abc123\nBuild Date: 2024-01-01\nVersion: 1.0.0",
23+
},
24+
{
25+
name: "initialized struct",
26+
info: buildInfoStruct{},
27+
expected: "Commit: \nBuild Date: \nVersion: ",
28+
},
29+
}
30+
31+
for _, tt := range tests {
32+
t.Run(tt.name, func(t *testing.T) {
33+
result := tt.info.String()
34+
assert.Equal(t, tt.expected, result)
35+
})
36+
}
37+
}
38+
39+
func TestBuildInfo_Initialization(t *testing.T) {
40+
assert.Equal(t, "commit", buildInfo.commit)
41+
assert.Equal(t, "date", buildInfo.date)
42+
assert.Equal(t, "version", buildInfo.version)
43+
}

cmd/github-mcp-server/main.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,12 @@ import (
1313
"github.com/spf13/viper"
1414
)
1515

16-
// These variables are set by the build process using ldflags.
17-
var version = "version"
18-
var commit = "commit"
19-
var date = "date"
20-
2116
var (
2217
rootCmd = &cobra.Command{
2318
Use: "server",
2419
Short: "GitHub MCP Server",
2520
Long: `A GitHub MCP server that handles various tools and resources.`,
26-
Version: fmt.Sprintf("Version: %s\nCommit: %s\nBuild Date: %s", version, commit, date),
21+
Version: buildInfo.String(),
2722
}
2823

2924
stdioCmd = &cobra.Command{
@@ -46,7 +41,7 @@ var (
4641
}
4742

4843
stdioServerConfig := ghmcp.StdioServerConfig{
49-
Version: version,
44+
Version: buildInfo.version,
5045
Host: viper.GetString("host"),
5146
Token: token,
5247
EnabledToolsets: enabledToolsets,

cmd/github-mcp-server/main_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func Test_RootCmdVersion(t *testing.T) {
10+
expectedVersion := buildInfo.String()
11+
actualVersion := rootCmd.Version
12+
13+
assert.Equal(t, expectedVersion, actualVersion)
14+
}

0 commit comments

Comments
 (0)