Skip to content

Commit 2d3548e

Browse files
authored
Enhance macOS support in GitHub Actions workflow and add autostart functionality (#5)
* Enhance macOS support in GitHub Actions workflow and add autostart functionality - Introduced code-signing and notarization steps for macOS binaries in the release workflow. - Added DMG installer creation and upload steps for macOS. - Implemented autostart functionality for macOS, allowing the application to start at login. - Added scripts for creating .icns files and DMG installers. - Included new assets such as logo and icons for better branding. * Remove .goreleaser.yaml configuration file as it is no longer needed for the project. * Enhance GitHub Actions workflow for versioning and macOS support - Added steps to generate version based on the latest tag and commit hash. - Updated build commands to use the generated version for binaries. - Introduced DMG installer creation and upload steps for macOS. - Added scripts for creating .icns files and DMG installers. * Refactor GitHub Actions workflow for improved macOS binary signing and packaging - Updated workflow to include detailed steps for building and signing macOS binaries. - Added support for development entitlements during code signing. - Enhanced DMG creation process with proper signing and verification. - Introduced a new entitlements file for development builds.
1 parent a8040e5 commit 2d3548e

18 files changed

Lines changed: 819 additions & 149 deletions

.github/workflows/pr-build.yml

Lines changed: 121 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,66 +8,154 @@ jobs:
88
build:
99
strategy:
1010
matrix:
11-
os: [ubuntu-latest, macos-latest, windows-latest]
12-
go-version: ["1.22", "1.23.10"]
11+
include:
12+
- os: ubuntu-latest
13+
goos: linux
14+
goarch: amd64
15+
cgo: "0"
16+
name: mcpproxy-linux-amd64
17+
archive_format: tar.gz
18+
- os: ubuntu-latest
19+
goos: windows
20+
goarch: amd64
21+
cgo: "0"
22+
name: mcpproxy-windows-amd64.exe
23+
archive_format: zip
24+
- os: macos-latest
25+
goos: darwin
26+
goarch: amd64
27+
cgo: "1"
28+
name: mcpproxy-darwin-amd64
29+
archive_format: tar.gz
30+
- os: macos-latest
31+
goos: darwin
32+
goarch: arm64
33+
cgo: "1"
34+
name: mcpproxy-darwin-arm64
35+
archive_format: tar.gz
1336

1437
runs-on: ${{ matrix.os }}
1538

16-
env:
17-
GO111MODULE: "on"
18-
1939
steps:
2040
- name: Checkout
2141
uses: actions/checkout@v4
42+
with:
43+
fetch-depth: 0
2244

2345
- name: Set up Go
2446
uses: actions/setup-go@v5
2547
with:
26-
go-version: ${{ matrix.go-version }}
48+
go-version: "1.23.10"
2749

2850
- name: Cache Go modules
2951
uses: actions/cache@v4
3052
with:
31-
path: |
32-
~/.cache/go-build
33-
~/go/pkg/mod
34-
~/AppData/Local/go-build
35-
key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }}
53+
path: ~/go/pkg/mod
54+
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
3655
restore-keys: |
37-
${{ runner.os }}-go-${{ matrix.go-version }}-
56+
${{ runner.os }}-go-
3857
3958
- name: Download dependencies
4059
run: go mod download
4160

4261
- name: Run tests (with nogui for CI)
4362
run: go test -tags nogui -v ./...
4463

45-
- name: Build binary for Linux
46-
if: runner.os == 'Linux'
64+
- name: Generate PR version
65+
id: version
4766
shell: bash
4867
run: |
49-
VERSION=pr-${{ github.event.number }}-${{ github.sha }}
50-
CGO_ENABLED=0 go build -ldflags "-X main.version=${VERSION}" -o mcpproxy ./cmd/mcpproxy
68+
# Get the latest tag
69+
LATEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
70+
# Get short commit hash
71+
COMMIT_HASH=$(git rev-parse --short HEAD)
72+
# Create version: last-tag-dev-hash
73+
VERSION="${LATEST_TAG}-dev-${COMMIT_HASH}"
74+
echo "version=${VERSION}" >> $GITHUB_OUTPUT
75+
echo "Generated PR version: ${VERSION}"
5176
52-
- name: Build binary for macOS
53-
if: runner.os == 'macOS'
54-
shell: bash
77+
- name: Build binary and create archives
78+
env:
79+
CGO_ENABLED: ${{ matrix.cgo }}
80+
GOOS: ${{ matrix.goos }}
81+
GOARCH: ${{ matrix.goarch }}
5582
run: |
56-
VERSION=pr-${{ github.event.number }}-${{ github.sha }}
57-
go build -ldflags "-X main.version=${VERSION}" -o mcpproxy ./cmd/mcpproxy
83+
VERSION=${{ steps.version.outputs.version }}
84+
LDFLAGS="-s -w -X mcpproxy-go/cmd/mcpproxy.version=${VERSION} -X main.version=${VERSION}"
5885
59-
- name: Build binary for Windows
60-
if: runner.os == 'Windows'
61-
shell: bash
62-
run: |
63-
VERSION=pr-${{ github.event.number }}-${{ github.sha }}
64-
CGO_ENABLED=0 go build -ldflags "-X main.version=${VERSION}" -o mcpproxy.exe ./cmd/mcpproxy
86+
# Determine clean binary name
87+
if [ "${{ matrix.goos }}" = "windows" ]; then
88+
CLEAN_BINARY="mcpproxy.exe"
89+
else
90+
CLEAN_BINARY="mcpproxy"
91+
fi
6592
66-
- name: Test version output
67-
shell: bash
68-
run: |
69-
if [[ "${{ runner.os }}" == "Windows" ]]; then
70-
./mcpproxy.exe --version
93+
# Create clean binary for archive
94+
go build -ldflags "${LDFLAGS}" -o ${CLEAN_BINARY} ./cmd/mcpproxy
95+
96+
# Ad-hoc sign macOS binaries (development only)
97+
if [ "${{ matrix.goos }}" = "darwin" ]; then
98+
echo "Ad-hoc signing macOS binary for development..."
99+
codesign --force --deep --sign - --identifier "com.smartmcpproxy.mcpproxy.dev" ${CLEAN_BINARY}
100+
101+
# Verify signing
102+
codesign --verify --verbose ${CLEAN_BINARY}
103+
echo "Binary signed successfully (development)"
104+
fi
105+
106+
# Create archive with version info
107+
ARCHIVE_BASE="mcpproxy-${VERSION#v}-${{ matrix.goos }}-${{ matrix.goarch }}"
108+
109+
if [ "${{ matrix.archive_format }}" = "zip" ]; then
110+
# Create archive
111+
zip "${ARCHIVE_BASE}.zip" ${CLEAN_BINARY}
71112
else
72-
./mcpproxy --version
113+
# Create archive
114+
tar -czf "${ARCHIVE_BASE}.tar.gz" ${CLEAN_BINARY}
73115
fi
116+
117+
- name: Create .icns icon (macOS)
118+
if: matrix.goos == 'darwin'
119+
run: |
120+
chmod +x scripts/create-icns.sh
121+
./scripts/create-icns.sh
122+
123+
- name: Create DMG installer (macOS)
124+
if: matrix.goos == 'darwin'
125+
run: |
126+
VERSION=${{ steps.version.outputs.version }}
127+
chmod +x scripts/create-dmg.sh
128+
129+
# Determine binary name
130+
CLEAN_BINARY="mcpproxy"
131+
132+
# Create DMG
133+
./scripts/create-dmg.sh ${CLEAN_BINARY} ${VERSION} ${{ matrix.goarch }}
134+
135+
# Ad-hoc sign DMG (development only)
136+
DMG_NAME="mcpproxy-${VERSION#v}-darwin-${{ matrix.goarch }}.dmg"
137+
echo "Ad-hoc signing DMG for development: ${DMG_NAME}"
138+
codesign --force --deep --sign - "${DMG_NAME}"
139+
140+
echo "DMG created and signed (development): ${DMG_NAME}"
141+
142+
- name: Skip notarization (PR Build)
143+
if: matrix.goos == 'darwin'
144+
run: |
145+
echo "Skipping notarization for PR build - this is a development build"
146+
echo "Production builds go through full notarization in release workflow"
147+
148+
- name: Upload archive artifact
149+
uses: actions/upload-artifact@v4
150+
with:
151+
name: archive-${{ matrix.goos }}-${{ matrix.goarch }}
152+
path: mcpproxy-*-${{ matrix.goos }}-${{ matrix.goarch }}.${{ matrix.archive_format }}
153+
retention-days: 7
154+
155+
- name: Upload DMG installer (macOS)
156+
if: matrix.goos == 'darwin'
157+
uses: actions/upload-artifact@v4
158+
with:
159+
name: dmg-${{ matrix.goos }}-${{ matrix.goarch }}
160+
path: mcpproxy-*-darwin-${{ matrix.goarch }}.dmg
161+
retention-days: 7

.github/workflows/release.yml

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ jobs:
6161
- name: Download dependencies
6262
run: go mod download
6363

64+
- name: Import Code-Signing Certificates (macOS)
65+
if: matrix.goos == 'darwin'
66+
uses: Apple-Actions/import-codesign-certs@v3
67+
with:
68+
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_ID_CERT }}
69+
p12-password: ${{ secrets.APPLE_DEVELOPER_ID_CERT_PASSWORD }}
70+
6471
- name: Build binary and create archives
6572
env:
6673
CGO_ENABLED: ${{ matrix.cgo }}
@@ -80,6 +87,16 @@ jobs:
8087
# Create clean binary for archive
8188
go build -ldflags "${LDFLAGS}" -o ${CLEAN_BINARY} ./cmd/mcpproxy
8289
90+
# Code sign macOS binaries
91+
if [ "${{ matrix.goos }}" = "darwin" ]; then
92+
echo "Code signing macOS binary..."
93+
codesign --force --options runtime --entitlements scripts/entitlements.plist --sign "${{ secrets.APPLE_TEAM_ID }}" ${CLEAN_BINARY}
94+
95+
# Verify signing
96+
codesign --verify --verbose ${CLEAN_BINARY}
97+
echo "Binary signed successfully"
98+
fi
99+
83100
# Create archive with version info
84101
ARCHIVE_BASE="mcpproxy-${VERSION#v}-${{ matrix.goos }}-${{ matrix.goarch }}"
85102
LATEST_ARCHIVE_BASE="mcpproxy-latest-${{ matrix.goos }}-${{ matrix.goarch }}"
@@ -96,6 +113,48 @@ jobs:
96113
tar -czf "${LATEST_ARCHIVE_BASE}.tar.gz" ${CLEAN_BINARY}
97114
fi
98115
116+
- name: Create .icns icon (macOS)
117+
if: matrix.goos == 'darwin'
118+
run: |
119+
chmod +x scripts/create-icns.sh
120+
./scripts/create-icns.sh
121+
122+
- name: Create DMG installer (macOS)
123+
if: matrix.goos == 'darwin'
124+
run: |
125+
VERSION=${GITHUB_REF#refs/tags/}
126+
chmod +x scripts/create-dmg.sh
127+
128+
# Determine binary name
129+
CLEAN_BINARY="mcpproxy"
130+
131+
# Create DMG
132+
./scripts/create-dmg.sh ${CLEAN_BINARY} ${VERSION} ${{ matrix.goarch }}
133+
134+
# Sign DMG
135+
DMG_NAME="mcpproxy-${VERSION#v}-darwin-${{ matrix.goarch }}.dmg"
136+
echo "Signing DMG: ${DMG_NAME}"
137+
codesign --force --sign "${{ secrets.APPLE_TEAM_ID }}" "${DMG_NAME}"
138+
139+
echo "DMG created and signed: ${DMG_NAME}"
140+
141+
- name: Notarize macOS artifacts
142+
if: matrix.goos == 'darwin'
143+
run: |
144+
VERSION=${GITHUB_REF#refs/tags/}
145+
DMG_NAME="mcpproxy-${VERSION#v}-darwin-${{ matrix.goarch }}.dmg"
146+
147+
echo "Submitting DMG for notarization..."
148+
xcrun notarytool submit "${DMG_NAME}" --apple-id "${{ secrets.APPLE_ID_USERNAME }}" --password "${{ secrets.APPLE_ID_APP_PASSWORD }}" --team-id "${{ secrets.APPLE_TEAM_ID }}" --wait
149+
150+
echo "Stapling notarization to DMG..."
151+
xcrun stapler staple "${DMG_NAME}"
152+
153+
echo "Verifying notarization..."
154+
xcrun stapler validate "${DMG_NAME}"
155+
156+
echo "DMG notarized successfully"
157+
99158
- name: Upload versioned archive artifact
100159
uses: actions/upload-artifact@v4
101160
with:
@@ -108,6 +167,13 @@ jobs:
108167
name: latest-${{ matrix.goos }}-${{ matrix.goarch }}
109168
path: mcpproxy-latest-${{ matrix.goos }}-${{ matrix.goarch }}.${{ matrix.archive_format }}
110169

170+
- name: Upload DMG installer (macOS)
171+
if: matrix.goos == 'darwin'
172+
uses: actions/upload-artifact@v4
173+
with:
174+
name: dmg-${{ matrix.goos }}-${{ matrix.goarch }}
175+
path: mcpproxy-*-darwin-${{ matrix.goarch }}.dmg
176+
111177
release:
112178
needs: build
113179
runs-on: ubuntu-latest
@@ -127,7 +193,7 @@ jobs:
127193
run: |
128194
# Create a flat structure to avoid duplicates
129195
mkdir -p release-files
130-
find dist -name "*.tar.gz" -o -name "*.zip" | while read file; do
196+
find dist -name "*.tar.gz" -o -name "*.zip" -o -name "*.dmg" | while read file; do
131197
filename=$(basename "$file")
132198
cp "$file" "release-files/$filename"
133199
done
@@ -154,6 +220,10 @@ jobs:
154220
- [macOS AMD64](https://github.com/${{ github.repository }}/releases/latest/download/mcpproxy-latest-darwin-amd64.tar.gz)
155221
- [macOS ARM64](https://github.com/${{ github.repository }}/releases/latest/download/mcpproxy-latest-darwin-arm64.tar.gz)
156222
223+
**macOS Installers (Recommended):**
224+
- [macOS Universal DMG](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/mcpproxy-${{ github.ref_name }}-darwin-arm64.dmg) (Apple Silicon)
225+
- [macOS Intel DMG](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/mcpproxy-${{ github.ref_name }}-darwin-amd64.dmg) (Intel)
226+
157227
**This Version (${{ github.ref_name }}):**
158228
- [Linux AMD64](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/mcpproxy-${{ github.ref_name }}-linux-amd64.tar.gz)
159229
- [Windows AMD64](https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/mcpproxy-${{ github.ref_name }}-windows-amd64.zip)
@@ -162,6 +232,14 @@ jobs:
162232
163233
### Installation
164234
235+
**macOS (Recommended - DMG Installer):**
236+
1. Download the appropriate DMG file for your Mac (Apple Silicon or Intel)
237+
2. Double-click the DMG to mount it
238+
3. Drag mcpproxy.app to Applications folder
239+
4. Launch from Applications or Launchpad
240+
5. The app will appear in your system tray with autostart capability
241+
242+
**Manual Installation (All Platforms):**
165243
1. Download the appropriate archive for your platform using the links above
166244
2. Extract the archive: `tar -xzf mcpproxy-*.tar.gz` (Linux/macOS) or unzip (Windows)
167245
3. Make it executable: `chmod +x mcpproxy` (Linux/macOS)

0 commit comments

Comments
 (0)