Skip to content

Commit 1055c9a

Browse files
committed
feat: add automated release workflow, release Dockerfile and docs
- Add .github/workflows/release.yml to build multi-platform binaries, create GitHub Releases (with checksums and attestations), and build/push multi-arch Docker images reusing pre-built binaries. - Add Dockerfile.release to produce release images from workflow artifacts (non-root, alpine). - Add docs/RELEASE.md and docs/RELEASE_WORKFLOW_SUMMARY.md with release process, verification and troubleshooting. - Remove legacy .github/workflows/docker.yml (Docker builds are now handled on tagged releases). - Add Makefile target `release-build` for local multi-platform builds. - Support build-time version injection in cmd/server/main.go (falls back to config when not set). - Update README: add "Download Pre-Built Binaries" section and link to release docs.
1 parent e9cbef2 commit 1055c9a

File tree

8 files changed

+616
-73
lines changed

8 files changed

+616
-73
lines changed

.github/workflows/docker.yml

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

.github/workflows/release.yml

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
packages: write
11+
id-token: write
12+
attestations: write
13+
14+
env:
15+
REGISTRY: ghcr.io
16+
IMAGE_NAME: ${{ github.repository }}
17+
18+
jobs:
19+
build-binaries:
20+
name: Build Binaries
21+
runs-on: ubuntu-latest
22+
strategy:
23+
matrix:
24+
include:
25+
- goos: linux
26+
goarch: amd64
27+
platform: linux-amd64
28+
- goos: linux
29+
goarch: arm64
30+
platform: linux-arm64
31+
- goos: darwin
32+
goarch: amd64
33+
platform: darwin-amd64
34+
- goos: darwin
35+
goarch: arm64
36+
platform: darwin-arm64
37+
- goos: windows
38+
goarch: amd64
39+
platform: windows-amd64
40+
ext: .exe
41+
42+
steps:
43+
- name: Checkout code
44+
uses: actions/checkout@v4
45+
46+
- name: Set up Go
47+
uses: actions/setup-go@v5
48+
with:
49+
go-version: '1.25'
50+
cache: true
51+
52+
- name: Build binary
53+
env:
54+
GOOS: ${{ matrix.goos }}
55+
GOARCH: ${{ matrix.goarch }}
56+
CGO_ENABLED: 0
57+
run: |
58+
mkdir -p dist
59+
go build -trimpath -ldflags="-w -s -X main.version=${{ github.ref_name }}" \
60+
-o dist/mcp-vosdroits-${{ matrix.platform }}${{ matrix.ext }} \
61+
./cmd/server
62+
63+
- name: Generate artifact attestation
64+
uses: actions/attest-build-provenance@v3
65+
with:
66+
subject-path: 'dist/mcp-vosdroits-${{ matrix.platform }}${{ matrix.ext }}'
67+
68+
- name: Upload build artifacts
69+
uses: actions/upload-artifact@v4
70+
with:
71+
name: mcp-vosdroits-${{ matrix.platform }}
72+
path: dist/mcp-vosdroits-${{ matrix.platform }}${{ matrix.ext }}
73+
if-no-files-found: error
74+
75+
create-release:
76+
name: Create GitHub Release
77+
needs: build-binaries
78+
runs-on: ubuntu-latest
79+
80+
steps:
81+
- name: Checkout code
82+
uses: actions/checkout@v4
83+
84+
- name: Download all artifacts
85+
uses: actions/download-artifact@v5
86+
with:
87+
path: dist
88+
merge-multiple: true
89+
90+
- name: Create checksums
91+
run: |
92+
cd dist
93+
sha256sum * > checksums.txt
94+
cat checksums.txt
95+
96+
- name: Create GitHub Release
97+
uses: softprops/action-gh-release@v2
98+
with:
99+
generate_release_notes: true
100+
files: |
101+
dist/*
102+
fail_on_unmatched_files: true
103+
104+
build-docker:
105+
name: Build and Push Docker Image
106+
needs: build-binaries
107+
runs-on: ubuntu-latest
108+
109+
steps:
110+
- name: Checkout code
111+
uses: actions/checkout@v4
112+
113+
- name: Download Linux AMD64 binary
114+
uses: actions/download-artifact@v5
115+
with:
116+
name: mcp-vosdroits-linux-amd64
117+
path: dist-amd64
118+
119+
- name: Download Linux ARM64 binary
120+
uses: actions/download-artifact@v5
121+
with:
122+
name: mcp-vosdroits-linux-arm64
123+
path: dist-arm64
124+
125+
- name: Set up QEMU
126+
uses: docker/setup-qemu-action@v3
127+
128+
- name: Set up Docker Buildx
129+
uses: docker/setup-buildx-action@v3
130+
131+
- name: Log in to Container Registry
132+
uses: docker/login-action@v3
133+
with:
134+
registry: ${{ env.REGISTRY }}
135+
username: ${{ github.actor }}
136+
password: ${{ secrets.GITHUB_TOKEN }}
137+
138+
- name: Extract metadata
139+
id: meta
140+
uses: docker/metadata-action@v5
141+
with:
142+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
143+
tags: |
144+
type=semver,pattern={{version}}
145+
type=semver,pattern={{major}}.{{minor}}
146+
type=semver,pattern={{major}}
147+
148+
- name: Build and push Docker image
149+
uses: docker/build-push-action@v6
150+
with:
151+
context: .
152+
file: ./Dockerfile.release
153+
platforms: linux/amd64,linux/arm64
154+
push: true
155+
tags: ${{ steps.meta.outputs.tags }}
156+
labels: ${{ steps.meta.outputs.labels }}
157+
cache-from: type=gha
158+
cache-to: type=gha,mode=max
159+
build-args: |
160+
VERSION=${{ github.ref_name }}
161+
provenance: false
162+
sbom: false

Dockerfile.release

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Release Dockerfile that uses pre-built binaries
2+
# This is used by the release workflow to avoid rebuilding binaries
3+
FROM alpine:latest
4+
5+
ARG TARGETARCH
6+
ARG VERSION=v1.0.0
7+
8+
# Install CA certificates for HTTPS requests
9+
RUN apk --no-cache add ca-certificates tzdata && \
10+
adduser -D -u 1000 appuser
11+
12+
WORKDIR /app
13+
14+
# Copy the pre-built binary for the target architecture
15+
COPY dist-${TARGETARCH}/mcp-vosdroits-linux-${TARGETARCH} /app/mcp-vosdroits
16+
RUN chmod +x /app/mcp-vosdroits
17+
18+
# Run as non-root user
19+
USER appuser
20+
21+
# Set environment variables
22+
ENV SERVER_NAME=vosdroits \
23+
SERVER_VERSION=${VERSION} \
24+
LOG_LEVEL=info
25+
26+
ENTRYPOINT ["/app/mcp-vosdroits"]

Makefile

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1-
.PHONY: build test clean run docker-build docker-run fmt vet tidy
1+
.PHONY: build test clean run docker-build docker-run fmt vet tidy release-build
22

33
# Build the binary
44
build:
55
go build -o bin/mcp-vosdroits ./cmd/server
66

7+
# Build release binaries for all platforms
8+
release-build:
9+
@echo "Building release binaries..."
10+
@mkdir -p bin/release
11+
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-w -s" -o bin/release/mcp-vosdroits-linux-amd64 ./cmd/server
12+
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags="-w -s" -o bin/release/mcp-vosdroits-linux-arm64 ./cmd/server
13+
GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-w -s" -o bin/release/mcp-vosdroits-darwin-amd64 ./cmd/server
14+
GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -trimpath -ldflags="-w -s" -o bin/release/mcp-vosdroits-darwin-arm64 ./cmd/server
15+
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -trimpath -ldflags="-w -s" -o bin/release/mcp-vosdroits-windows-amd64.exe ./cmd/server
16+
@echo "Release binaries built in bin/release/"
17+
718
# Run tests
819
test:
920
go test -v ./...

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,24 @@ This MCP server enables AI assistants to search and retrieve official French adm
2222

2323
## Installation
2424

25+
### Download Pre-Built Binaries
26+
27+
Download the latest release for your platform from the [Releases page](https://github.com/guigui42/mcp-vosdroits/releases).
28+
29+
Available platforms:
30+
- **Linux**: amd64, arm64
31+
- **macOS**: amd64 (Intel), arm64 (Apple Silicon)
32+
- **Windows**: amd64
33+
34+
```bash
35+
# Example: Download and run Linux binary
36+
curl -LO https://github.com/guigui42/mcp-vosdroits/releases/latest/download/mcp-vosdroits-linux-amd64
37+
chmod +x mcp-vosdroits-linux-amd64
38+
./mcp-vosdroits-linux-amd64
39+
```
40+
41+
All binaries include SHA256 checksums for verification.
42+
2543
### Using Docker (Recommended)
2644

2745
Pull and run the official image from GitHub Container Registry:
@@ -363,6 +381,7 @@ List available categories of tax information on impots.gouv.fr.
363381

364382
For developers and contributors:
365383
- [Development Guide](docs/DEVELOPMENT.md) - Local development, testing, and contribution guidelines
384+
- [Release Process](docs/RELEASE.md) - How releases are created and automated
366385
- [Web Scraping Implementation](docs/SCRAPING.md) - Technical details on service-public.gouv.fr scraping
367386
- [Colly Integration Guide](docs/COLLY_INTEGRATION.md) - Web scraping framework documentation
368387

cmd/server/main.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
"github.com/modelcontextprotocol/go-sdk/mcp"
1616
)
1717

18+
var version = "dev"
19+
1820
func main() {
1921
if err := run(); err != nil {
2022
log.Fatal(err)
@@ -25,6 +27,11 @@ func run() error {
2527
// Load configuration
2628
cfg := config.Load()
2729

30+
// Override version if set at build time
31+
if version != "dev" {
32+
cfg.ServerVersion = version
33+
}
34+
2835
// Set up logging
2936
setupLogging(cfg.LogLevel)
3037

0 commit comments

Comments
 (0)