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>
This commit is contained in:
parent
2e7108d366
commit
16790150e9
10 changed files with 273 additions and 65 deletions
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
|
|
@ -36,8 +36,8 @@ jobs:
|
|||
with:
|
||||
images: ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
type=sha,prefix=main-{{date 'YYYYMMDD'}}-,enable={{is_default_branch}}
|
||||
type=raw,value=main,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
|
|
|
|||
74
.github/workflows/release.yml
vendored
Normal file
74
.github/workflows/release.yml
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
name: Release
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
id-token: write # needed for signing
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.24.x'
|
||||
|
||||
- name: Install cosign
|
||||
uses: sigstore/cosign-installer@v3
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
needs: goreleaser
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=raw,value=latest
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
121
.goreleaser.yaml
Normal file
121
.goreleaser.yaml
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# GoReleaser configuration for MCP Registry
|
||||
version: 2
|
||||
|
||||
# Build configuration
|
||||
builds:
|
||||
# Registry server binary
|
||||
- id: registry
|
||||
binary: registry
|
||||
main: ./cmd/registry
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
ldflags:
|
||||
- -s -w
|
||||
- -X main.Version={{.Version}}
|
||||
- -X main.GitCommit={{.FullCommit}}
|
||||
- -X main.BuildTime={{.Date}}
|
||||
|
||||
# Publisher CLI tool binary
|
||||
- id: publisher
|
||||
binary: mcp-publisher
|
||||
main: ./cmd/publisher
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
- darwin
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
ldflags:
|
||||
- -s -w
|
||||
- -X main.Version={{.Version}}
|
||||
- -X main.GitCommit={{.FullCommit}}
|
||||
- -X main.BuildTime={{.Date}}
|
||||
|
||||
# This section defines whether we want to release the source code too.
|
||||
source:
|
||||
enabled: true
|
||||
|
||||
# This section defines how to generate the changelog
|
||||
changelog:
|
||||
sort: asc
|
||||
use: github
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
- '^ci:'
|
||||
- '^chore:'
|
||||
- '^style:'
|
||||
- 'merge conflict'
|
||||
- 'Merge pull request'
|
||||
- 'Merge remote-tracking branch'
|
||||
- 'Merge branch'
|
||||
groups:
|
||||
- title: 'New Features'
|
||||
regexp: '^.*?feat(\([[:word:]]+\))??!?:.+$'
|
||||
order: 0
|
||||
- title: 'Bug Fixes'
|
||||
regexp: '^.*?fix(\([[:word:]]+\))??!?:.+$'
|
||||
order: 1
|
||||
- title: 'Performance Improvements'
|
||||
regexp: '^.*?perf(\([[:word:]]+\))??!?:.+$'
|
||||
order: 2
|
||||
- title: 'Refactors'
|
||||
regexp: '^.*?refactor(\([[:word:]]+\))??!?:.+$'
|
||||
order: 3
|
||||
- title: 'Documentation'
|
||||
regexp: '^.*?docs?(\([[:word:]]+\))??!?:.+$'
|
||||
order: 4
|
||||
- title: 'Other Changes'
|
||||
order: 999
|
||||
|
||||
# This section defines for which artifact types to generate SBOMs.
|
||||
sboms:
|
||||
- artifacts: archive
|
||||
|
||||
# This section defines the release policy.
|
||||
release:
|
||||
github:
|
||||
owner: modelcontextprotocol
|
||||
name: registry
|
||||
|
||||
# This section defines how and which artifacts we want to sign for the release.
|
||||
signs:
|
||||
- id: archives
|
||||
cmd: cosign
|
||||
args:
|
||||
- "sign-blob"
|
||||
- "--output-signature=${signature}"
|
||||
- "--output-certificate=${certificate}"
|
||||
- "${artifact}"
|
||||
- "--yes" # needed on cosign 2.0.0+
|
||||
artifacts: archive
|
||||
output: true
|
||||
certificate: '{{ trimsuffix (trimsuffix .Env.artifact ".zip") ".tar.gz" }}.pem'
|
||||
|
||||
# Also sign checksums file for additional verification
|
||||
- id: checksums
|
||||
cmd: cosign
|
||||
args:
|
||||
- "sign-blob"
|
||||
- "--output-signature=${signature}"
|
||||
- "--output-certificate=${certificate}"
|
||||
- "${artifact}"
|
||||
- "--yes"
|
||||
artifacts: checksum
|
||||
output: true
|
||||
certificate: '{{ trimsuffix .Env.artifact ".txt" }}.pem'
|
||||
|
||||
# This section defines the release format.
|
||||
archives:
|
||||
- name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||
11
Makefile
11
Makefile
|
|
@ -6,11 +6,13 @@ help: ## Show this help message
|
|||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " %-20s %s\n", $$1, $$2}'
|
||||
|
||||
# Build targets
|
||||
build: ## Build the registry application
|
||||
go build -o bin/registry ./cmd/registry
|
||||
build: ## Build the registry application with version info
|
||||
@mkdir -p bin
|
||||
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
|
||||
|
||||
publisher: ## Build the publisher tool
|
||||
cd cmd/publisher && ./build.sh
|
||||
publisher: ## Build the publisher tool with version info
|
||||
@mkdir -p bin
|
||||
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
|
||||
|
||||
# Test targets
|
||||
test-unit: ## Run unit tests with coverage
|
||||
|
|
@ -64,7 +66,6 @@ dev-local: ## Run registry locally
|
|||
clean: ## Clean build artifacts and coverage files
|
||||
rm -rf bin
|
||||
rm -f coverage.out coverage.html
|
||||
cd cmd/publisher && rm -f publisher
|
||||
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
|
|
|
|||
19
README.md
19
README.md
|
|
@ -67,14 +67,23 @@ The service runs on [`localhost:8080`](http://localhost:8080) by default. This c
|
|||
Pre-built Docker images are automatically published to GitHub Container Registry:
|
||||
|
||||
```bash
|
||||
# Run latest from main branch
|
||||
# Run latest stable release
|
||||
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:latest
|
||||
|
||||
# Run specific commit build
|
||||
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main-20250806-a1b2c3d
|
||||
# Run latest from main branch (continuous deployment)
|
||||
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main
|
||||
|
||||
# Run specific release version
|
||||
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:v1.0.0
|
||||
|
||||
# Run development build from main branch
|
||||
docker run -p 8080:8080 ghcr.io/modelcontextprotocol/registry:main-20250906-abc123d
|
||||
```
|
||||
|
||||
**Available tags:** `latest`, `main-<date>-<sha>`
|
||||
**Available tags:**
|
||||
- **Releases**: `latest`, `v1.0.0`, `v1.1.0`, etc.
|
||||
- **Continuous**: `main` (latest main branch build)
|
||||
- **Development**: `main-<date>-<sha>` (specific commit builds)
|
||||
|
||||
</details>
|
||||
|
||||
|
|
@ -87,7 +96,7 @@ To publish a server, we've built a simple CLI. You can use it with:
|
|||
make publisher
|
||||
|
||||
# Use it!
|
||||
./cmd/publisher/bin/mcp-publisher --help
|
||||
./bin/mcp-publisher --help
|
||||
```
|
||||
|
||||
See [the publisher guide](./docs/guides/publishing/publish-server.md) for more details.
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Build script for MCP Registry Publisher Tool
|
||||
|
||||
# Set variables
|
||||
OUTPUT_DIR="./bin"
|
||||
BINARY_NAME="mcp-publisher"
|
||||
|
||||
# Create output directory if it doesn't exist
|
||||
mkdir -p $OUTPUT_DIR
|
||||
|
||||
# Print build information
|
||||
echo "Building MCP Registry Publisher Tool..."
|
||||
|
||||
# Build for current platform
|
||||
echo "Building for $(go env GOOS)/$(go env GOARCH)..."
|
||||
go build -o "$OUTPUT_DIR/$BINARY_NAME" .
|
||||
|
||||
# Make the binary executable
|
||||
chmod +x "$OUTPUT_DIR/$BINARY_NAME"
|
||||
|
||||
echo "Build complete: $(realpath $OUTPUT_DIR/$BINARY_NAME)"
|
||||
|
||||
# Optional: Build for multiple platforms
|
||||
if [ "$1" == "--all" ]; then
|
||||
echo "Building for all supported platforms..."
|
||||
|
||||
# Linux AMD64
|
||||
GOOS=linux GOARCH=amd64 go build -o "$OUTPUT_DIR/${BINARY_NAME}-linux-amd64" .
|
||||
|
||||
# MacOS AMD64
|
||||
GOOS=darwin GOARCH=amd64 go build -o "$OUTPUT_DIR/${BINARY_NAME}-darwin-amd64" .
|
||||
|
||||
# MacOS ARM64 (Apple Silicon)
|
||||
GOOS=darwin GOARCH=arm64 go build -o "$OUTPUT_DIR/${BINARY_NAME}-darwin-arm64" .
|
||||
|
||||
# Windows AMD64
|
||||
GOOS=windows GOARCH=amd64 go build -o "$OUTPUT_DIR/${BINARY_NAME}-windows-amd64.exe" .
|
||||
|
||||
echo "Multi-platform build complete in $(realpath $OUTPUT_DIR)"
|
||||
fi
|
||||
|
|
@ -2,11 +2,25 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/modelcontextprotocol/registry/cmd/publisher/commands"
|
||||
)
|
||||
|
||||
// Version info for the MCP Publisher tool
|
||||
// These variables are injected at build time via ldflags by goreleaser
|
||||
var (
|
||||
// Version is the current version of the MCP Publisher tool
|
||||
Version = "dev"
|
||||
|
||||
// BuildTime is the time at which the binary was built
|
||||
BuildTime = "unknown"
|
||||
|
||||
// GitCommit is the git commit that was compiled
|
||||
GitCommit = "unknown"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
printUsage()
|
||||
|
|
@ -23,6 +37,9 @@ func main() {
|
|||
err = commands.LogoutCommand()
|
||||
case "publish":
|
||||
err = commands.PublishCommand(os.Args[2:])
|
||||
case "--version", "-v", "version":
|
||||
log.Printf("mcp-publisher %s (commit: %s, built: %s)", Version, GitCommit, BuildTime)
|
||||
return
|
||||
case "--help", "-h", "help":
|
||||
printUsage()
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -19,6 +19,19 @@ import (
|
|||
"github.com/modelcontextprotocol/registry/internal/telemetry"
|
||||
)
|
||||
|
||||
// Version info for the MCP Registry application
|
||||
// These variables are injected at build time via ldflags
|
||||
var (
|
||||
// Version is the current version of the MCP Registry application
|
||||
Version = "dev"
|
||||
|
||||
// BuildTime is the time at which the binary was built
|
||||
BuildTime = "unknown"
|
||||
|
||||
// GitCommit is the git commit that was compiled
|
||||
GitCommit = "unknown"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Parse command line flags
|
||||
showVersion := flag.Bool("version", false, "Display version information")
|
||||
|
|
|
|||
|
|
@ -1,13 +0,0 @@
|
|||
package main
|
||||
|
||||
// Version info for the MCP Registry application
|
||||
var (
|
||||
// Version is the current version of the MCP Registry application
|
||||
Version = "0.1.0"
|
||||
|
||||
// BuildTime is the time at which the binary was built
|
||||
BuildTime = "undefined"
|
||||
|
||||
// GitCommit is the git commit that was compiled
|
||||
GitCommit = "undefined"
|
||||
)
|
||||
27
docs/releasing.md
Normal file
27
docs/releasing.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Release Guide
|
||||
|
||||
## Creating a Release
|
||||
|
||||
1. **Go to GitHub**: Navigate to https://github.com/modelcontextprotocol/registry/releases
|
||||
2. **Click "Draft a new release"**
|
||||
3. **Choose a tag**: Click "Choose a tag" and type a new semantic version that follows the last one available (e.g., `v1.0.0`)
|
||||
5. **Generate notes**: Click "Generate release notes" to auto-populate the name and description
|
||||
6. **Publish**: Click "Publish release"
|
||||
|
||||
The release workflow will automatically:
|
||||
- Build binaries for 6 platforms (Linux, macOS, Windows × amd64, arm64)
|
||||
- Create and push Docker images with `:latest` and `:vX.Y.Z` tags
|
||||
- Attach all artifacts to the GitHub release
|
||||
- Generate checksums and signatures
|
||||
|
||||
## After Release
|
||||
|
||||
- Docker images will be available at `ghcr.io/modelcontextprotocol/registry:latest`
|
||||
- Binaries can be downloaded from the GitHub release page
|
||||
|
||||
## Versioning
|
||||
|
||||
We use semantic versioning (SemVer):
|
||||
- `v1.0.0` - Major release with breaking changes
|
||||
- `v1.1.0` - Minor release with new features
|
||||
- `v1.0.1` - Patch release with bug fixes
|
||||
Loading…
Reference in a new issue