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