Skip to content

Commit 2e4afa4

Browse files
erudenkoclaude
andcommitted
feat(claude-desktop-profiles): CI/CD release pipeline with code signing and notarization
- Add GitHub Actions workflow triggered by tools/claude-desktop-profiles/v* tags - Pipeline: build → sign (Developer ID) → DMG → notarize → staple → GitHub Release - Add Apple signing secrets: APPLE_CERTIFICATE_BASE64, APPLE_CERTIFICATE_PASSWORD, APPLE_ID, APPLE_APP_PASSWORD, APPLE_TEAM_ID - Update .env.example with Apple signing variables - Update Taskfile: release uses Developer ID cert, add notarize task Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 136e899 commit 2e4afa4

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

.env.example

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@ OPENROUTER_API_KEY=sk-or-v1-your-key-here
3838
# Used by: Database MCP server tools
3939
# POSTGRES_CONNECTION_STRING=postgresql://localhost/mydb
4040

41+
# =============================================================================
42+
# OPTIONAL - Apple Code Signing & Notarization
43+
# =============================================================================
44+
45+
# Apple ID for notarization
46+
# Used by: Claude Desktop Profiles DMG notarization
47+
# APPLE_ID=your-apple-id@example.com
48+
49+
# App-specific password for notarization
50+
# Generate at: https://appleid.apple.com/account/manage → Sign-In and Security → App-Specific Passwords
51+
# Used by: xcrun notarytool submit
52+
# APPLE_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx
53+
54+
# Apple Developer Team ID
55+
# Found in: developer.apple.com/account → Membership Details
56+
# APPLE_TEAM_ID=XXXXXXXXXX
57+
4158
# =============================================================================
4259
# OPTIONAL - Tool Configuration
4360
# =============================================================================
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
name: Claude Profiles Release
2+
3+
on:
4+
push:
5+
tags:
6+
- 'tools/claude-desktop-profiles/v*'
7+
8+
jobs:
9+
build-and-release:
10+
runs-on: macos-15
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Import signing certificate
15+
env:
16+
CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
17+
CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
18+
run: |
19+
CERT_PATH=$RUNNER_TEMP/certificate.p12
20+
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
21+
KEYCHAIN_PASSWORD=$(uuidgen)
22+
23+
echo "$CERTIFICATE_BASE64" | base64 --decode -o $CERT_PATH
24+
25+
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
26+
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
27+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
28+
security import $CERT_PATH -P "$CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
29+
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
30+
security list-keychain -d user -s $KEYCHAIN_PATH
31+
32+
- name: Extract version from tag
33+
id: version
34+
run: echo "version=${GITHUB_REF_NAME#tools/claude-desktop-profiles/v}" >> $GITHUB_OUTPUT
35+
36+
- name: Build release
37+
working-directory: tools/claude-desktop-profiles
38+
run: |
39+
swift build -c release
40+
mkdir -p .build/ClaudeProfiles.app/Contents/{MacOS,Resources}
41+
cp .build/release/ClaudeProfiles .build/ClaudeProfiles.app/Contents/MacOS/ClaudeProfiles
42+
cp Info-task.plist .build/ClaudeProfiles.app/Contents/Info.plist
43+
cp AppIcon.icns .build/ClaudeProfiles.app/Contents/Resources/AppIcon.icns
44+
cp Sources/ClaudeProfiles/Resources/MadAppGangLogo.png .build/ClaudeProfiles.app/Contents/Resources/MadAppGangLogo.png
45+
printf 'APPL????' > .build/ClaudeProfiles.app/Contents/PkgInfo
46+
47+
- name: Sign app
48+
working-directory: tools/claude-desktop-profiles
49+
run: |
50+
codesign --force --options runtime \
51+
--sign "Developer ID Application: MADAPPGANG PTY. LTD. (E85N35G3YB)" \
52+
.build/ClaudeProfiles.app
53+
54+
- name: Create DMG
55+
working-directory: tools/claude-desktop-profiles
56+
run: |
57+
mkdir -p .build/dmg
58+
cp -R .build/ClaudeProfiles.app ".build/dmg/Claude Profiles.app"
59+
ln -s /Applications .build/dmg/Applications
60+
hdiutil create -volname "Claude Profiles" -srcfolder .build/dmg -ov -format UDZO \
61+
".build/ClaudeProfiles-${{ steps.version.outputs.version }}.dmg"
62+
rm -rf .build/dmg
63+
codesign --force \
64+
--sign "Developer ID Application: MADAPPGANG PTY. LTD. (E85N35G3YB)" \
65+
".build/ClaudeProfiles-${{ steps.version.outputs.version }}.dmg"
66+
67+
- name: Notarize DMG
68+
working-directory: tools/claude-desktop-profiles
69+
env:
70+
APPLE_ID: ${{ secrets.APPLE_ID }}
71+
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
72+
run: |
73+
xcrun notarytool submit \
74+
".build/ClaudeProfiles-${{ steps.version.outputs.version }}.dmg" \
75+
--apple-id "$APPLE_ID" \
76+
--team-id "E85N35G3YB" \
77+
--password "$APPLE_APP_PASSWORD" \
78+
--wait
79+
xcrun stapler staple \
80+
".build/ClaudeProfiles-${{ steps.version.outputs.version }}.dmg"
81+
82+
- name: Create GitHub Release
83+
env:
84+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
85+
run: |
86+
gh release create "${{ github.ref_name }}" \
87+
"tools/claude-desktop-profiles/.build/ClaudeProfiles-${{ steps.version.outputs.version }}.dmg" \
88+
--title "Claude Profiles v${{ steps.version.outputs.version }}" \
89+
--notes "Native macOS app for managing multiple isolated Claude Desktop profiles.
90+
91+
## Install
92+
1. Download the DMG
93+
2. Drag **Claude Profiles** to Applications
94+
3. Launch from Applications
95+
96+
Signed and notarized by MadAppGang."

0 commit comments

Comments
 (0)