Skip to content

Commit e675b67

Browse files
committed
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 f1a8268 commit e675b67

3 files changed

Lines changed: 121 additions & 54 deletions

File tree

.github/workflows/pr-build.yml

Lines changed: 90 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,60 @@ 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
2242
with:
23-
fetch-depth: 0 # Need full history for git describe
43+
fetch-depth: 0
2444

2545
- name: Set up Go
2646
uses: actions/setup-go@v5
2747
with:
28-
go-version: ${{ matrix.go-version }}
48+
go-version: "1.23.10"
2949

3050
- name: Cache Go modules
3151
uses: actions/cache@v4
3252
with:
33-
path: |
34-
~/.cache/go-build
35-
~/go/pkg/mod
36-
~/AppData/Local/go-build
37-
key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }}
53+
path: ~/go/pkg/mod
54+
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
3855
restore-keys: |
39-
${{ runner.os }}-go-${{ matrix.go-version }}-
56+
${{ runner.os }}-go-
4057
4158
- name: Download dependencies
4259
run: go mod download
4360

4461
- name: Run tests (with nogui for CI)
4562
run: go test -tags nogui -v ./...
4663

47-
- name: Generate version
64+
- name: Generate PR version
4865
id: version
4966
shell: bash
5067
run: |
@@ -55,71 +72,90 @@ jobs:
5572
# Create version: last-tag-dev-hash
5673
VERSION="${LATEST_TAG}-dev-${COMMIT_HASH}"
5774
echo "version=${VERSION}" >> $GITHUB_OUTPUT
58-
echo "Generated version: ${VERSION}"
75+
echo "Generated PR version: ${VERSION}"
5976
60-
- name: Build binary for Linux
61-
if: runner.os == 'Linux'
62-
shell: bash
77+
- name: Build binary and create archives
78+
env:
79+
CGO_ENABLED: ${{ matrix.cgo }}
80+
GOOS: ${{ matrix.goos }}
81+
GOARCH: ${{ matrix.goarch }}
6382
run: |
64-
CGO_ENABLED=0 go build -ldflags "-X main.version=${{ steps.version.outputs.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}"
6585
66-
- name: Build binary for macOS
67-
if: runner.os == 'macOS'
68-
shell: bash
69-
run: |
70-
go build -ldflags "-X main.version=${{ steps.version.outputs.version }}" -o mcpproxy ./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
7192
72-
- name: Build binary for Windows
73-
if: runner.os == 'Windows'
74-
shell: bash
75-
run: |
76-
CGO_ENABLED=0 go build -ldflags "-X main.version=${{ steps.version.outputs.version }}" -o mcpproxy.exe ./cmd/mcpproxy
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
77105
78-
- name: Test version output
79-
shell: bash
80-
run: |
81-
if [[ "${{ runner.os }}" == "Windows" ]]; then
82-
./mcpproxy.exe --version
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}
83112
else
84-
./mcpproxy --version
113+
# Create archive
114+
tar -czf "${ARCHIVE_BASE}.tar.gz" ${CLEAN_BINARY}
85115
fi
86116
87117
- name: Create .icns icon (macOS)
88-
if: runner.os == 'macOS'
118+
if: matrix.goos == 'darwin'
89119
run: |
90120
chmod +x scripts/create-icns.sh
91121
./scripts/create-icns.sh
92122
93123
- name: Create DMG installer (macOS)
94-
if: runner.os == 'macOS'
124+
if: matrix.goos == 'darwin'
95125
run: |
126+
VERSION=${{ steps.version.outputs.version }}
96127
chmod +x scripts/create-dmg.sh
97128
98-
# Determine binary name and architecture
129+
# Determine binary name
99130
CLEAN_BINARY="mcpproxy"
100-
ARCH=$(uname -m)
101-
if [ "$ARCH" = "x86_64" ]; then
102-
ARCH="amd64"
103-
elif [ "$ARCH" = "arm64" ]; then
104-
ARCH="arm64"
105-
fi
106131
107132
# Create DMG
108-
./scripts/create-dmg.sh ${CLEAN_BINARY} ${{ steps.version.outputs.version }} ${ARCH}
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"
109147
110-
- name: Upload DMG artifact (macOS)
111-
if: runner.os == 'macOS'
148+
- name: Upload archive artifact
112149
uses: actions/upload-artifact@v4
113150
with:
114-
name: mcpproxy-dmg-${{ matrix.go-version }}-${{ runner.arch }}
115-
path: mcpproxy-*-darwin-*.dmg
151+
name: archive-${{ matrix.goos }}-${{ matrix.goarch }}
152+
path: mcpproxy-*-${{ matrix.goos }}-${{ matrix.goarch }}.${{ matrix.archive_format }}
116153
retention-days: 7
117154

118-
- name: Upload binary artifact
155+
- name: Upload DMG installer (macOS)
156+
if: matrix.goos == 'darwin'
119157
uses: actions/upload-artifact@v4
120158
with:
121-
name: mcpproxy-${{ runner.os }}-${{ matrix.go-version }}
122-
path: |
123-
mcpproxy*
124-
!mcpproxy-*-darwin-*.dmg
159+
name: dmg-${{ matrix.goos }}-${{ matrix.goarch }}
160+
path: mcpproxy-*-darwin-${{ matrix.goarch }}.dmg
125161
retention-days: 7

scripts/create-dmg.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,25 @@ cat >> "$TEMP_DIR/$APP_BUNDLE/Contents/Info.plist" << EOF
8787
</plist>
8888
EOF
8989

90+
# Create empty PkgInfo file (required for proper app bundle)
91+
echo "APPLMCPP" > "$TEMP_DIR/$APP_BUNDLE/Contents/PkgInfo"
92+
93+
# Sign the app bundle properly
94+
echo "Signing app bundle..."
95+
96+
# Use development entitlements if available, otherwise sign without entitlements
97+
if [ -f "scripts/entitlements-dev.plist" ]; then
98+
echo "Using development entitlements..."
99+
codesign --force --deep --sign - --identifier "$BUNDLE_ID" --entitlements "scripts/entitlements-dev.plist" "$TEMP_DIR/$APP_BUNDLE"
100+
else
101+
echo "Signing without entitlements..."
102+
codesign --force --deep --sign - --identifier "$BUNDLE_ID" "$TEMP_DIR/$APP_BUNDLE"
103+
fi
104+
105+
# Verify signing
106+
codesign --verify --verbose "$TEMP_DIR/$APP_BUNDLE"
107+
echo "App bundle signed successfully"
108+
90109
# Create Applications symlink
91110
ln -s /Applications "$TEMP_DIR/Applications"
92111

scripts/entitlements-dev.plist

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.network.client</key>
6+
<true/>
7+
<key>com.apple.security.network.server</key>
8+
<true/>
9+
<key>com.apple.security.files.user-selected.read-write</key>
10+
<true/>
11+
</dict>
12+
</plist>

0 commit comments

Comments
 (0)