Zero Ops on Mac Mini M4: Native CI/CD for C# APIs
Transforming your Mac Mini into a self-healing, auto-deploying production server.
"The goal is simple: Git Push and forget. No manual terminals, no complex Docker layers—just pure macOS native resilience."
1 The Core: Deployment Script
We create a dedicated deploy.sh script. This "heart" of the system handles compiling the ARM64 binary and restarting the service.
#!/bin/bash
# 1. Explicitly define PATH so Launchd can find git and dotnet
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/share/dotnet"
PROJECT_DIR="/Users/ismael/code/csharp/repo-name"
PUBLISH_DIR="$PROJECT_DIR/src/publish"
PLIST_PATH="$HOME/Library/LaunchAgents/com.appname.api.plist"
# 2. Use the absolute path for dotnet (adjusted based on 'which dotnet' output)
DOTNET_BIN="/usr/local/share/dotnet/dotnet"
echo "馃殌 Starting automatic deployment..."
cd "$PROJECT_DIR/src"
# Execute publish using the absolute path
$DOTNET_BIN publish -c Release -r osx-arm64 --self-contained false -o "$PUBLISH_DIR"
if [ $? -eq 0 ]; then
# 3. Restart the service
launchctl unload "$PLIST_PATH" 2>/dev/null
launchctl load "$PLIST_PATH"
echo "✅ AppName updated and running."
else
echo "❌ Build failed. Check for missing SDK or code errors."
exit 1
fi
Don't forget to run: chmod +x deploy.sh
2 Resilience: The .plist Agent
Instead of using .zshrc, we use a Launch Agent. This ensures the API runs 24/7, restarts on crashes, and boots automatically with the Mac.
Set ASPNETCORE_URLS to http://0.0.0.0:5000 to allow external access within your network, and set KeepAlive to true for 100% uptime.
Initialize with: launchctl load [path_to_plist]
3 The Brain: Auto-Git Watcher
To achieve true Zero Ops, we set up a second agent that monitors your repository every 60 seconds. If it detects a change on GitHub, it pulls and triggers the deploy script.
git fetch origin && [ $(git rev-parse HEAD) != $(git rev-parse @{u}) ] && git pull && ./deploy.sh
This command compares your local HEAD with the remote. It only triggers a build when new code is actually present.
4 Why This is Superior
- Zero Terminal Dependency: No need to keep a terminal window open or use tools like
fswatch. - Git-Driven: Your only action is
git pushfrom your development laptop. - Native Resilience: If the Mac Mini restarts after a power outage, the agents boot up automatically.
Comentarios
Publicar un comentario