Skip to content

Commit 1679015

Browse files
authored
Introduce Goreleaser (#366)
<!-- Provide a brief summary of your changes --> ## Motivation and Context <!-- Why is this change needed? What problem does it solve? --> The following PR introduces Goreleaser for the releases of the registry server and the publisher CLI. **Details:** - Builds registry and publisher binaries for Linux, macOS, and Windows (amd64 + arm64) - Leverage GitHub's release process by creating releases directly from GitHub's interface - Added .goreleaser.yaml configuration - New .github/workflows/release.yml workflow triggered by GitHub releases - Updated Docker tagging in deploy workflow (:latest and :semver(the tag) for releases, :main-YYYYMMDD-sha for testing/development) - Consolidated version handling in main.go files - Added release documentation ## How Has This Been Tested? <!-- Have you tested this in a real application? Which scenarios were tested? --> Locally (but we have to test it by creating a release, i.e. v0.0.1 once this gets merged) ## Breaking Changes <!-- Will users need to update their code or configurations? --> Yes, the notion of `latest` for the container image is now different ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [ ] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [ ] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed ## Additional context <!-- Add any other context, implementation notes, or design decisions --> Related to #358 --------- Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
1 parent 2e7108d commit 1679015

File tree

10 files changed

+273
-65
lines changed

10 files changed

+273
-65
lines changed

.github/workflows/deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ jobs:
3636
with:
3737
images: ghcr.io/${{ github.repository }}
3838
tags: |
39-
type=raw,value=latest,enable={{is_default_branch}}
4039
type=sha,prefix=main-{{date 'YYYYMMDD'}}-,enable={{is_default_branch}}
40+
type=raw,value=main,enable={{is_default_branch}}
4141
4242
- name: Build and push Docker image
4343
uses: docker/build-push-action@v5

.github/workflows/release.yml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
permissions:
8+
contents: write
9+
packages: write
10+
id-token: write # needed for signing
11+
12+
jobs:
13+
goreleaser:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
20+
21+
- name: Set up Go
22+
uses: actions/setup-go@v5
23+
with:
24+
go-version: '1.24.x'
25+
26+
- name: Install cosign
27+
uses: sigstore/cosign-installer@v3
28+
29+
- name: Run GoReleaser
30+
uses: goreleaser/goreleaser-action@v6
31+
with:
32+
distribution: goreleaser
33+
version: latest
34+
args: release --clean
35+
env:
36+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37+
38+
docker:
39+
runs-on: ubuntu-latest
40+
needs: goreleaser
41+
steps:
42+
- name: Checkout
43+
uses: actions/checkout@v4
44+
45+
- name: Set up Docker Buildx
46+
uses: docker/setup-buildx-action@v3
47+
48+
- name: Log in to Container Registry
49+
uses: docker/login-action@v3
50+
with:
51+
registry: ghcr.io
52+
username: ${{ github.actor }}
53+
password: ${{ secrets.GITHUB_TOKEN }}
54+
55+
- name: Extract metadata
56+
id: meta
57+
uses: docker/metadata-action@v5
58+
with:
59+
images: ghcr.io/${{ github.repository }}
60+
tags: |
61+
type=semver,pattern={{version}}
62+
type=raw,value=latest
63+
64+
- name: Build and push Docker image
65+
uses: docker/build-push-action@v5
66+
with:
67+
context: .
68+
file: ./Dockerfile
69+
platforms: linux/amd64,linux/arm64
70+
push: true
71+
tags: ${{ steps.meta.outputs.tags }}
72+
labels: ${{ steps.meta.outputs.labels }}
73+
cache-from: type=gha
74+
cache-to: type=gha,mode=max

.goreleaser.yaml

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# GoReleaser configuration for MCP Registry
2+
version: 2
3+
4+
# Build configuration
5+
builds:
6+
# Registry server binary
7+
- id: registry
8+
binary: registry
9+
main: ./cmd/registry
10+
env:
11+
- CGO_ENABLED=0
12+
goos:
13+
- linux
14+
- darwin
15+
- windows
16+
goarch:
17+
- amd64
18+
- arm64
19+
ldflags:
20+
- -s -w
21+
- -X main.Version={{.Version}}
22+
- -X main.GitCommit={{.FullCommit}}
23+
- -X main.BuildTime={{.Date}}
24+
25+
# Publisher CLI tool binary
26+
- id: publisher
27+
binary: mcp-publisher
28+
main: ./cmd/publisher
29+
env:
30+
- CGO_ENABLED=0
31+
goos:
32+
- linux
33+
- darwin
34+
- windows
35+
goarch:
36+
- amd64
37+
- arm64
38+
ldflags:
39+
- -s -w
40+
- -X main.Version={{.Version}}
41+
- -X main.GitCommit={{.FullCommit}}
42+
- -X main.BuildTime={{.Date}}
43+
44+
# This section defines whether we want to release the source code too.
45+
source:
46+
enabled: true
47+
48+
# This section defines how to generate the changelog
49+
changelog:
50+
sort: asc
51+
use: github
52+
filters:
53+
exclude:
54+
- '^docs:'
55+
- '^test:'
56+
- '^ci:'
57+
- '^chore:'
58+
- '^style:'
59+
- 'merge conflict'
60+
- 'Merge pull request'
61+
- 'Merge remote-tracking branch'
62+
- 'Merge branch'
63+
groups:
64+
- title: 'New Features'
65+
regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$'
66+
order: 0
67+
- title: 'Bug Fixes'
68+
regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$'
69+
order: 1
70+
- title: 'Performance Improvements'
71+
regexp: '^.*?perf(\([[:word:]]+\))??!?:.+$'
72+
order: 2
73+
- title: 'Refactors'
74+
regexp: '^.*?refactor(\([[:word:]]+\))??!?:.+$'
75+
order: 3
76+
- title: 'Documentation'
77+
regexp: '^.*?docs?(\([[:word:]]+\))??!?:.+$'
78+
order: 4
79+
- title: 'Other Changes'
80+
order: 999
81+
82+
# This section defines for which artifact types to generate SBOMs.
83+
sboms:
84+
- artifacts: archive
85+
86+
# This section defines the release policy.
87+
release:
88+
github:
89+
owner: modelcontextprotocol
90+
name: registry
91+
92+
# This section defines how and which artifacts we want to sign for the release.
93+
signs:
94+
- id: archives
95+
cmd: cosign
96+
args:
97+
- "sign-blob"
98+
- "--output-signature=${signature}"
99+
- "--output-certificate=${certificate}"
100+
- "${artifact}"
101+
- "--yes" # needed on cosign 2.0.0+
102+
artifacts: archive
103+
output: true
104+
certificate: '{{ trimsuffix (trimsuffix .Env.artifact ".zip") ".tar.gz" }}.pem'
105+
106+
# Also sign checksums file for additional verification
107+
- id: checksums
108+
cmd: cosign
109+
args:
110+
- "sign-blob"
111+
- "--output-signature=${signature}"
112+
- "--output-certificate=${certificate}"
113+
- "${artifact}"
114+
- "--yes"
115+
artifacts: checksum
116+
output: true
117+
certificate: '{{ trimsuffix .Env.artifact ".txt" }}.pem'
118+
119+
# This section defines the release format.
120+
archives:
121+
- name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"

Makefile

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ help: ## Show this help message
66
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " %-20s %s\n", $$1, $$2}'
77

88
# Build targets
9-
build: ## Build the registry application
10-
go build -o bin/registry ./cmd/registry
9+
build: ## Build the registry application with version info
10+
@mkdir -p bin
11+
go build -ldflags="-X main.Version=dev-$(shell git rev-parse --short HEAD) -X main.GitCommit=$(shell git rev-parse HEAD) -X main.BuildTime=$(shell date -u +%Y-%m-%dT%H:%M:%SZ)" -o bin/registry ./cmd/registry
1112

12-
publisher: ## Build the publisher tool
13-
cd cmd/publisher && ./build.sh
13+
publisher: ## Build the publisher tool with version info
14+
@mkdir -p bin
15+
go build -ldflags="-X main.Version=dev-$(shell git rev-parse --short HEAD) -X main.GitCommit=$(shell git rev-parse HEAD) -X main.BuildTime=$(shell date -u +%Y-%m-%dT%H:%M:%SZ)" -o bin/mcp-publisher ./cmd/publisher
1416

1517
# Test targets
1618
test-unit: ## Run unit tests with coverage
@@ -64,7 +66,6 @@ dev-local: ## Run registry locally
6466
clean: ## Clean build artifacts and coverage files
6567
rm -rf bin
6668
rm -f coverage.out coverage.html
67-
cd cmd/publisher && rm -f publisher
6869

6970

7071
.DEFAULT_GOAL := help

README.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,23 @@ The service runs on [`localhost:8080`](http://localhost:8080) by default. This c
6767
Pre-built Docker images are automatically published to GitHub Container Registry:
6868

6969
```bash
70-
# Run latest from main branch
70+
# Run latest stable release
7171
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:latest
7272

73-
# Run specific commit build
74-
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main-20250806-a1b2c3d
73+
# Run latest from main branch (continuous deployment)
74+
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main
75+
76+
# Run specific release version
77+
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:v1.0.0
78+
79+
# Run development build from main branch
80+
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main-20250906-abc123d
7581
```
7682

77-
**Available tags:** `latest`, `main-<date>-<sha>`
83+
**Available tags:**
84+
- **Releases**: `latest`, `v1.0.0`, `v1.1.0`, etc.
85+
- **Continuous**: `main` (latest main branch build)
86+
- **Development**: `main-<date>-<sha>` (specific commit builds)
7887

7988
</details>
8089

@@ -87,7 +96,7 @@ To publish a server, we've built a simple CLI. You can use it with:
8796
make publisher
8897

8998
# Use it!
90-
./cmd/publisher/bin/mcp-publisher --help
99+
./bin/mcp-publisher --help
91100
```
92101

93102
See [the publisher guide](./docs/guides/publishing/publish-server.md) for more details.

cmd/publisher/build.sh

Lines changed: 0 additions & 41 deletions
This file was deleted.

cmd/publisher/main.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,25 @@ package main
22

33
import (
44
"fmt"
5+
"log"
56
"os"
67

78
"github.com/modelcontextprotocol/registry/cmd/publisher/commands"
89
)
910

11+
// Version info for the MCP Publisher tool
12+
// These variables are injected at build time via ldflags by goreleaser
13+
var (
14+
// Version is the current version of the MCP Publisher tool
15+
Version = "dev"
16+
17+
// BuildTime is the time at which the binary was built
18+
BuildTime = "unknown"
19+
20+
// GitCommit is the git commit that was compiled
21+
GitCommit = "unknown"
22+
)
23+
1024
func main() {
1125
if len(os.Args) < 2 {
1226
printUsage()
@@ -23,6 +37,9 @@ func main() {
2337
err = commands.LogoutCommand()
2438
case "publish":
2539
err = commands.PublishCommand(os.Args[2:])
40+
case "--version", "-v", "version":
41+
log.Printf("mcp-publisher %s (commit: %s, built: %s)", Version, GitCommit, BuildTime)
42+
return
2643
case "--help", "-h", "help":
2744
printUsage()
2845
default:

cmd/registry/main.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ import (
1919
"github.com/modelcontextprotocol/registry/internal/telemetry"
2020
)
2121

22+
// Version info for the MCP Registry application
23+
// These variables are injected at build time via ldflags
24+
var (
25+
// Version is the current version of the MCP Registry application
26+
Version = "dev"
27+
28+
// BuildTime is the time at which the binary was built
29+
BuildTime = "unknown"
30+
31+
// GitCommit is the git commit that was compiled
32+
GitCommit = "unknown"
33+
)
34+
2235
func main() {
2336
// Parse command line flags
2437
showVersion := flag.Bool("version", false, "Display version information")

cmd/registry/version.go

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)