Skip to content

Commit 8e3c8e6

Browse files
authored
Merge pull request #18 from StrongMonkey/add-release-process
Chore: Add CI to release tagged image and binary
2 parents 95fc784 + a732e4a commit 8e3c8e6

File tree

7 files changed

+368
-9
lines changed

7 files changed

+368
-9
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Build and Push Docker Image
22

33
on:
44
push:
5-
branches: [master, main]
5+
branches: [main]
66

77
env:
88
REGISTRY: ghcr.io

.github/workflows/release.yml

Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
env:
9+
GO_VERSION: "1.25"
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
services:
15+
postgres:
16+
image: postgres:15
17+
env:
18+
POSTGRES_DB: oauth_test
19+
POSTGRES_USER: test
20+
POSTGRES_PASSWORD: test
21+
options: >-
22+
--health-cmd pg_isready
23+
--health-interval 10s
24+
--health-timeout 5s
25+
--health-retries 5
26+
ports:
27+
- 5432:5432
28+
29+
steps:
30+
- name: Checkout repository
31+
uses: actions/checkout@v4
32+
33+
- name: Set up Go
34+
uses: actions/setup-go@v5
35+
with:
36+
go-version: ${{ env.GO_VERSION }}
37+
38+
- name: Install dependencies
39+
run: go mod download
40+
41+
- name: Set Go toolchain
42+
run: go env -w GOTOOLCHAIN=go1.25.0+auto
43+
44+
- name: Run linter
45+
uses: golangci/golangci-lint-action@v8
46+
with:
47+
version: v2.4.0
48+
args: --timeout=5m --tests=false
49+
50+
- name: Run tests
51+
env:
52+
TEST_DATABASE_DSN: "postgres://test:test@localhost:5432/oauth_test?sslmode=disable"
53+
run: |
54+
go test -v -short ./...
55+
go test -v -race ./...
56+
57+
build-linux:
58+
needs: test
59+
runs-on: ubuntu-latest
60+
strategy:
61+
matrix:
62+
include:
63+
# Linux builds
64+
- goos: linux
65+
goarch: amd64
66+
name: linux-amd64
67+
- goos: linux
68+
goarch: arm64
69+
name: linux-arm64
70+
71+
steps:
72+
- name: Checkout repository
73+
uses: actions/checkout@v4
74+
75+
- name: Set up Go
76+
uses: actions/setup-go@v5
77+
with:
78+
go-version: ${{ env.GO_VERSION }}
79+
80+
- name: Install dependencies
81+
run: go mod download
82+
83+
- name: Get version
84+
id: version
85+
run: |
86+
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
87+
88+
- name: Build binary
89+
env:
90+
GOOS: ${{ matrix.goos }}
91+
GOARCH: ${{ matrix.goarch }}
92+
CGO_ENABLED: 1
93+
run: |
94+
# Install cross-compilation tools for CGO (needed for SQLite)
95+
if [ "${{ matrix.goos }}" = "linux" ]; then
96+
if [ "${{ matrix.goarch }}" = "arm64" ]; then
97+
sudo apt-get update
98+
sudo apt-get install -y gcc-aarch64-linux-gnu
99+
export CC=aarch64-linux-gnu-gcc
100+
fi
101+
elif [ "${{ matrix.goos }}" = "darwin" ]; then
102+
# For macOS, we'll use a different approach with osxcross or build on macOS runners
103+
echo "Building for macOS..."
104+
fi
105+
106+
mkdir -p dist
107+
binary_name="mcp-oauth-proxy-${{ steps.version.outputs.VERSION }}-${{ matrix.name }}"
108+
if [ "${{ matrix.goos }}" = "windows" ]; then
109+
binary_name="${binary_name}.exe"
110+
fi
111+
112+
go build -o "dist/${binary_name}" \
113+
-ldflags="-X main.version=${{ steps.version.outputs.VERSION }} -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ) -s -w" \
114+
.
115+
116+
- name: Upload binary artifact
117+
uses: actions/upload-artifact@v4
118+
with:
119+
name: binary-${{ matrix.name }}
120+
path: dist/
121+
retention-days: 1
122+
123+
build-macos:
124+
needs: test
125+
runs-on: macos-latest
126+
strategy:
127+
matrix:
128+
include:
129+
- goarch: amd64
130+
name: darwin-amd64
131+
- goarch: arm64
132+
name: darwin-arm64
133+
134+
steps:
135+
- name: Checkout repository
136+
uses: actions/checkout@v4
137+
138+
- name: Set up Go
139+
uses: actions/setup-go@v5
140+
with:
141+
go-version: ${{ env.GO_VERSION }}
142+
143+
- name: Install dependencies
144+
run: go mod download
145+
146+
- name: Get version
147+
id: version
148+
run: |
149+
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
150+
151+
- name: Build binary
152+
env:
153+
GOOS: darwin
154+
GOARCH: ${{ matrix.goarch }}
155+
CGO_ENABLED: 1
156+
run: |
157+
mkdir -p dist
158+
binary_name="mcp-oauth-proxy-${{ steps.version.outputs.VERSION }}-${{ matrix.name }}"
159+
160+
go build -o "dist/${binary_name}" \
161+
-ldflags="-X main.version=${{ steps.version.outputs.VERSION }} -X main.buildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ) -s -w" \
162+
.
163+
164+
- name: Upload binary artifact
165+
uses: actions/upload-artifact@v4
166+
with:
167+
name: binary-${{ matrix.name }}
168+
path: dist/
169+
retention-days: 1
170+
171+
create-universal-macos:
172+
needs: build-macos
173+
runs-on: macos-latest
174+
steps:
175+
- name: Get version
176+
id: version
177+
run: |
178+
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
179+
180+
- name: Download macOS binaries
181+
uses: actions/download-artifact@v4
182+
with:
183+
pattern: binary-darwin-*
184+
path: ./binaries/
185+
186+
- name: Create universal binary
187+
run: |
188+
mkdir -p dist
189+
190+
# Find the actual binary files
191+
amd64_binary=$(find ./binaries -name "*darwin-amd64*" -type f | head -1)
192+
arm64_binary=$(find ./binaries -name "*darwin-arm64*" -type f | head -1)
193+
194+
echo "AMD64 binary: $amd64_binary"
195+
echo "ARM64 binary: $arm64_binary"
196+
197+
# Create universal binary
198+
lipo -create \
199+
"$amd64_binary" \
200+
"$arm64_binary" \
201+
-output "dist/mcp-oauth-proxy-${{ steps.version.outputs.VERSION }}-darwin-universal"
202+
203+
- name: Upload universal binary artifact
204+
uses: actions/upload-artifact@v4
205+
with:
206+
name: binary-darwin-universal
207+
path: dist/
208+
retention-days: 1
209+
210+
docker:
211+
needs: test
212+
runs-on: ubuntu-latest
213+
permissions:
214+
contents: read
215+
packages: write
216+
217+
steps:
218+
- name: Checkout repository
219+
uses: actions/checkout@v4
220+
221+
- name: Get version
222+
id: version
223+
run: |
224+
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
225+
226+
- name: Set up Docker Buildx
227+
uses: docker/setup-buildx-action@v3
228+
229+
- name: Log in to GitHub Container Registry
230+
uses: docker/login-action@v3
231+
with:
232+
registry: ghcr.io
233+
username: ${{ github.actor }}
234+
password: ${{ secrets.GITHUB_TOKEN }}
235+
236+
- name: Extract metadata
237+
id: meta
238+
uses: docker/metadata-action@v5
239+
with:
240+
images: ghcr.io/${{ github.repository_owner }}/mcp-oauth-proxy
241+
tags: |
242+
type=ref,event=tag
243+
type=semver,pattern={{version}}
244+
type=semver,pattern={{major}}.{{minor}}
245+
type=semver,pattern={{major}}
246+
type=raw,value=latest,enable={{is_default_branch}}
247+
248+
- name: Build and push Docker image
249+
uses: docker/build-push-action@v5
250+
with:
251+
context: .
252+
push: true
253+
tags: ${{ steps.meta.outputs.tags }}
254+
labels: ${{ steps.meta.outputs.labels }}
255+
platforms: linux/amd64,linux/arm64
256+
build-args: |
257+
VERSION=${{ steps.version.outputs.VERSION }}
258+
BUILD_TIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
259+
260+
release:
261+
needs: [build, build-macos, create-universal-macos, docker]
262+
runs-on: ubuntu-latest
263+
permissions:
264+
contents: write
265+
266+
steps:
267+
- name: Checkout repository
268+
uses: actions/checkout@v4
269+
270+
- name: Get version
271+
id: version
272+
run: |
273+
echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
274+
275+
- name: Download all artifacts
276+
uses: actions/download-artifact@v4
277+
with:
278+
pattern: binary-*
279+
path: ./artifacts/
280+
281+
- name: Prepare release assets
282+
run: |
283+
mkdir -p release
284+
find ./artifacts -type f -name "mcp-oauth-proxy-*" -exec cp {} release/ \;
285+
286+
# Create checksums
287+
cd release
288+
sha256sum * > checksums.txt
289+
290+
# List files for verification
291+
echo "Release files:"
292+
ls -la
293+
294+
- name: Generate changelog
295+
id: changelog
296+
run: |
297+
cat << 'EOF' > CHANGELOG.md
298+
## What's Changed in ${{ steps.version.outputs.VERSION }}
299+
300+
### 🚀 Features
301+
- Cross-platform release with native binaries for Linux and macOS
302+
- Multi-architecture Docker images for Linux (AMD64 and ARM64)
303+
304+
### 📦 Binary Downloads
305+
- **Linux AMD64**: `mcp-oauth-proxy-${{ steps.version.outputs.VERSION }}-linux-amd64`
306+
- **Linux ARM64**: `mcp-oauth-proxy-${{ steps.version.outputs.VERSION }}-linux-arm64`
307+
- **macOS Universal**: `mcp-oauth-proxy-${{ steps.version.outputs.VERSION }}-darwin-universal` (Intel + Apple Silicon)
308+
- **macOS AMD64**: `mcp-oauth-proxy-${{ steps.version.outputs.VERSION }}-darwin-amd64` (Intel)
309+
- **macOS ARM64**: `mcp-oauth-proxy-${{ steps.version.outputs.VERSION }}-darwin-arm64` (Apple Silicon)
310+
311+
### 🐳 Docker Images
312+
- **Tagged Release**: `ghcr.io/${{ github.repository_owner }}/mcp-oauth-proxy:${{ steps.version.outputs.VERSION }}`
313+
- **Latest**: `ghcr.io/${{ github.repository_owner }}/mcp-oauth-proxy:latest`
314+
- **Platforms**: linux/amd64, linux/arm64
315+
316+
### 🔍 Verification
317+
All binaries can be verified using the included `checksums.txt` file.
318+
319+
### 🛠️ Installation
320+
321+
**Binary Installation:**
322+
1. Download the appropriate binary for your platform
323+
2. Make it executable: `chmod +x mcp-oauth-proxy-*`
324+
3. Move to your PATH: `mv mcp-oauth-proxy-* /usr/local/bin/mcp-oauth-proxy`
325+
326+
**Docker Installation:**
327+
```bash
328+
docker pull ghcr.io/${{ github.repository_owner }}/mcp-oauth-proxy:${{ steps.version.outputs.VERSION }}
329+
# or
330+
docker pull ghcr.io/${{ github.repository_owner }}/mcp-oauth-proxy:latest
331+
```
332+
333+
**Full Changelog**: https://github.com/${{ github.repository }}/commits/${{ steps.version.outputs.VERSION }}
334+
EOF
335+
336+
- name: Create Release
337+
uses: ncipollo/release-action@v1
338+
with:
339+
tag: ${{ steps.version.outputs.VERSION }}
340+
name: Release ${{ steps.version.outputs.VERSION }}
341+
bodyFile: CHANGELOG.md
342+
artifacts: "release/*"
343+
draft: false
344+
prerelease: ${{ contains(steps.version.outputs.VERSION, '-') }}
345+
token: ${{ secrets.GITHUB_TOKEN }}
346+
generateReleaseNotes: true
347+
allowUpdates: true

.github/workflows/test.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ jobs:
3636
- name: Install dependencies
3737
run: go mod download
3838

39+
- name: Set Go toolchain
40+
run: go env -w GOTOOLCHAIN=go1.25.0+auto
41+
3942
- name: Run linter
40-
uses: golangci/golangci-lint-action@v4
43+
uses: golangci/golangci-lint-action@v8
4144
with:
42-
version: latest
43-
args: --timeout=5m
45+
version: v2.4.0
46+
args: --timeout=5m --tests=false
4447

4548
- name: Run unit tests (PostgreSQL)
4649
run: go test -v -short ./...
@@ -93,6 +96,9 @@ jobs:
9396
- name: Install dependencies
9497
run: go mod download
9598

99+
- name: Set Go toolchain
100+
run: go env -w GOTOOLCHAIN=go1.25.0+auto
101+
96102
- name: Run unit tests (SQLite)
97103
run: go test -v -short ./...
98104

0 commit comments

Comments
 (0)