English | Tiếng Việt | 中文
A native macOS menu bar app for seamlessly switching between multiple developer profiles (GitHub + Cloudflare)
Features | Installation | Usage | How It Works | Troubleshooting
Juggling multiple developer identities is a headache. Whether you're switching between your Personal, Work, or Client accounts, manually updating your git config, managing different Personal Access Tokens (PATs), and swapping Cloudflare credentials takes time and leads to embarrassing accidental commits on the wrong account.
Great Deploy is your one-click context switcher. Living quietly in your macOS menu bar, it allows you to instantly switch your entire development environment.
With a single click, Great Deploy:
- Swaps your GitHub credentials securely in the macOS Keychain.
- Updates your global
git config user.nameanduser.email. - Injects the correct Cloudflare API tokens into your
~/.wrangler/config/default.tomland macOSlaunchctlenvironment.
No more terminal gymnastics. No more wrong account commits.
- Menu Bar Interface - Lives in your menu bar for instant access
- One-Click Switching - Switch developer profiles (GitHub + Cloudflare) with a single click
- Keychain Integration - Automatically updates credentials in macOS Keychain securely
- Git Config Management - Updates
git config --global user.nameanduser.email - Cloudflare Integration - Manages
CLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_IDin~/.wrangler/config/default.tomland launchctl environment. - Secure Storage - Personal Access Tokens & API Tokens stored securely in Keychain (never in plain text)
- Launch at Login - Optionally start automatically when you log in
- Native Notifications - Get notified when account switches complete
- No Dock Icon - Runs as a background utility (menu bar only)
- Dark Mode Support - Follows your system appearance
- Transparent Icons - App icons with 100% transparent backgrounds for a professional look
- macOS 13.0 (Ventura) or later
- Xcode 15.0 or later (for building from source)
- Git installed (typically at
/usr/bin/gitor via Homebrew) - Wrangler / Cloudflare CLI (optional, for Cloudflare deployments)
Use this path when you want a free build that can be copied to another Mac without an Apple Developer ID:
make package-ad-hocThe package is created in dist/ as GreatDeploy-<version>-macos-ad-hoc.zip. It is signed with an ad-hoc signature and is not notarized, so the first launch may require right-click -> Open or System Settings -> Privacy & Security -> Open Anyway.
If macOS says the app is damaged after copying it to /Applications, clear quarantine:
xattr -cr /Applications/GreatDeploy.app
open /Applications/GreatDeploy.appSee docs/INSTALL_ADHOC.md for the short install note included in the ZIP.
# Clone the repository
git clone https://github.com/MinhOmega/GreatDeploy.git
cd GreatDeploy/GreatDeploy
# Clean any previous builds (recommended for fresh builds)
xcodebuild -project GreatDeploy.xcodeproj \
-scheme GreatDeploy \
clean
# Clear derived data cache (ensures clean build)
rm -rf ~/Library/Developer/Xcode/DerivedData/GreatDeploy-*
# Build the app (Release configuration)
xcodebuild -project GreatDeploy.xcodeproj \
-scheme GreatDeploy \
-configuration Release \
build
# Find the built app
APP_PATH=$(find ~/Library/Developer/Xcode/DerivedData/GreatDeploy-*/Build/Products/Release -name "GreatDeploy.app" -type d | head -1)
# Remove old version if exists
rm -rf /Applications/GreatDeploy.app
# Copy to Applications folder
cp -R "$APP_PATH" /Applications/
# Launch the app
open /Applications/GreatDeploy.appQuick One-Liner (Clean Build & Install):
cd GreatDeploy/GreatDeploy && \
xcodebuild -project GreatDeploy.xcodeproj -scheme GreatDeploy clean && \
rm -rf ~/Library/Developer/Xcode/DerivedData/GreatDeploy-* && \
xcodebuild -project GreatDeploy.xcodeproj -scheme GreatDeploy -configuration Release build && \
rm -rf /Applications/GreatDeploy.app && \
cp -R ~/Library/Developer/Xcode/DerivedData/GreatDeploy-*/Build/Products/Release/GreatDeploy.app /Applications/ && \
open /Applications/GreatDeploy.app# Clone the repository
git clone https://github.com/MinhOmega/GreatDeploy.git
cd GreatDeploy/GreatDeploy
# Open in Xcode
open GreatDeploy.xcodeprojThen in Xcode:
- Select your Development Team in Project Settings > Signing & Capabilities
- Select Product > Archive for a release build, or press Cmd+R to build and run
- For Archive: Distribute App > Copy App to export the
.appfile
# Clone, build, and install in one command
git clone https://github.com/MinhOmega/GreatDeploy.git && \
cd GreatDeploy/GreatDeploy && \
xcodebuild -project GreatDeploy.xcodeproj \
-scheme GreatDeploy \
-configuration Release \
-derivedDataPath build \
build && \
cp -R build/Build/Products/Release/GreatDeploy.app /Applications/ && \
open /Applications/GreatDeploy.app# Check if the app is installed
ls -la /Applications/GreatDeploy.app
# Check if it's running
pgrep -l GreatDeploy# Remove the app
rm -rf /Applications/GreatDeploy.app
# Remove app data (optional)
rm -rf ~/Library/Application\ Support/GreatDeploy
rm -rf ~/Library/Preferences/com.greatdeploy.plist
# Remove from Login Items (if enabled)
# System Settings > General > Login Items > Remove GreatDeploy- Click the menu bar icon (shows current account or question mark if none)
- Click "Add Account" or the + button
- Fill in the details:
- Display Name: A friendly name (e.g., "Personal", "Work", "Client-X")
- GitHub Username: Your GitHub username
- Personal Access Token: Your GitHub PAT (create one here)
- Git User Name: The name for git commits (can differ from GitHub username)
- Git User Email: The email for git commits
- Cloudflare Account ID: (Optional) Your Cloudflare Account ID
- Cloudflare API Token: (Optional) Your Cloudflare API Token
- Click "Add"
From Menu Bar:
- Click the menu bar icon
- Click on the account you want to switch to
From Main Window:
- Click menu bar icon > "Open Window"
- Click "Switch" button on any account card
When you switch accounts, the app will:
- Update GitHub credentials in macOS Keychain
- Run
git config --global user.name "Your Name" - Run
git config --global user.email "your@email.com" - Set up Cloudflare tokens in
~/.wrangler/config/default.tomland vialaunchctl - Show a notification (if enabled)
- Edit: Click the ... menu on any account card > Edit
- Delete: Click the ... menu > Delete
- Reorder: Open Settings > Accounts tab (drag to reorder coming soon)
Access Settings via:
- Menu bar > gear icon, or
- Main window > gear icon in footer, or
- Cmd+, when the app is focused
General Settings:
- Show notification on account switch
- Launch at login
- Go to GitHub Settings > Developer settings > Personal access tokens
- Click "Generate new token (classic)" or "Fine-grained tokens"
For Classic Tokens: Select these scopes:
repo- Full control of private repositoriesread:user- Read user profile datauser:email- Access user email addresses
For Fine-grained Tokens:
- Repository access: All repositories (or select specific ones)
- Permissions: Contents (Read and write), Metadata (Read)
- Click "Generate token" and copy it immediately (you won't see it again!)
The app manages GitHub credentials using the macOS Keychain Services API:
Keychain Entry:
├── Kind: Internet password
├── Server: github.com
├── Protocol: HTTPS
├── Account: <your-github-username>
└── Password: <your-personal-access-token>
This is the same entry that Git's credential helper (osxkeychain) uses when you run git push with HTTPS.
App's Own Storage: Account metadata (display name, emails) is stored in the app's private Keychain entries, separate from the GitHub credential.
When switching accounts, the app executes:
git config --global user.name "Your Name"
git config --global user.email "your@email.com"This updates ~/.gitconfig:
[user]
name = Your Name
email = your@email.com┌─────────────────────────────────────────────────────────┐
│ Great Deploy │
├─────────────────────────────────────────────────────────┤
│ AccountStore (ObservableObject) │
│ - Coordinates all operations │
│ - Persists account metadata to UserDefaults │
│ - DOES NOT store tokens in UserDefaults │
├─────────────────────────────────────────────────────────┤
│ KeychainService (Singleton) │
│ - Stores/retrieves tokens from macOS Keychain │
│ - Uses Security.framework APIs │
│ - Tokens encrypted at rest by macOS │
├─────────────────────────────────────────────────────────┤
│ GitConfigService (Singleton) │
│ - Executes git commands via Process API │
│ - Manages global git configuration │
└─────────────────────────────────────────────────────────┘
GreatDeploy/
├── GreatDeploy.xcodeproj/ # Xcode project file
├── GreatDeploy/
│ ├── GreatDeployApp.swift # App entry point, MenuBarExtra, Windows
│ ├── Models/
│ │ └── GitAccount.swift # Account data model (Codable)
│ ├── Services/
│ │ ├── KeychainService.swift # macOS Keychain operations
│ │ ├── GitConfigService.swift # Git command execution
│ │ └── AccountStore.swift # State management (@MainActor)
│ ├── Views/
│ │ └── AddEditAccountView.swift # Account form UI
│ ├── Assets.xcassets/ # App icons and colors
│ ├── Info.plist # Bundle configuration
│ └── GreatDeploy.entitlements
├── docs/ # Documentation assets
├── build/ # Build output (gitignored)
└── README.md # This file
Cause: No existing GitHub credential in Keychain.
Solution: This is normal for first-time use. The app will create the credential when you switch to an account.
Cause: Git is not installed or not in expected location.
Solution:
# Check git installation
which git
# Expected: /usr/bin/git or /opt/homebrew/bin/git
# If not installed, install via Homebrew
brew install git
# Or install Xcode Command Line Tools
xcode-select --installCause: Git credential helper not configured.
Solution:
# Check current credential helper
git config --global credential.helper
# Expected: osxkeychain
# If not set, configure it
git config --global credential.helper osxkeychainCause: Keychain access denied or locked.
Solution:
- Open Keychain Access app
- Make sure your login keychain is unlocked
- Try removing any existing
github.comentries and let the app recreate them
Cause: App crashed or system UI issue.
Solution:
# Force quit and restart
pkill GreatDeploy
open /Applications/GreatDeploy.app
# Check Console.app for crash logs
open /Applications/Utilities/Console.app"Signing requires a development team"
- Open project in Xcode
- Select your team in Signing & Capabilities
- Or build with
CODE_SIGNING_ALLOWED=NOfor local testing:xcodebuild -project GreatDeploy.xcodeproj \ -scheme GreatDeploy \ -configuration Debug \ CODE_SIGNING_ALLOWED=NO \ build
"No provisioning profile"
- Sign in with Apple ID in Xcode > Settings > Accounts
- Select "Personal Team" for local development
The app requires these capabilities that are incompatible with App Store sandboxing:
- Full Keychain Access - Modify GitHub internet password entries
- Process Execution - Run
gitcommands via shell - File System Access - Read/write
~/.gitconfig
- Tokens are stored in macOS Keychain (encrypted at rest)
- Tokens are never logged or stored in plain text
- Tokens are never stored in UserDefaults or plist files
- Each account's token is stored in a separate Keychain entry
- Use fine-grained tokens with minimal required permissions
- Set token expiration dates (GitHub recommends 90 days or less)
- Rotate tokens regularly - Update tokens in the app when you regenerate them
- Review Keychain Access - Periodically check what apps have Keychain access
- macOS 13.0+
- Xcode 15.0+
- Swift 5.9+
# Debug build
xcodebuild -project GreatDeploy.xcodeproj \
-scheme GreatDeploy \
-configuration Debug \
build
# Run tests (when available)
xcodebuild -project GreatDeploy.xcodeproj \
-scheme GreatDeploy \
test- SwiftUI with MVVM architecture
@MainActorfor UI-related codeasync/awaitfor asynchronous operations// MARK: -comments for code organization- Triple-slash (
///) documentation for public APIs
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
MIT License - Feel free to modify and distribute.
- Special Thanks: GreatDeploy is a comprehensive upgrade and expansion of the original GitAccountSwitcher application. We sincerely thank the original authors (including MinhOmega) for providing the open-source foundation and excellent Keychain integration concepts that made this tool possible.
- Built with SwiftUI and the Security framework
- Uses native macOS Keychain Services API
- Icons from SF Symbols
Made with ❤️ for developers who deploy code across multiple accounts