Last active
August 22, 2024 02:46
-
-
Save hartmantis/a0e417068f6148bac4ee343e8b411977 to your computer and use it in GitHub Desktop.
macOS bootstrap script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Provisioning script for a new macOS Big Sur machine. | |
# To bootstrap a brand new box: | |
# * Build a bootable USB installer drive: | |
# - Partition a USB flash drive as appropriate | |
# - On an existing macOS box, search the App Store for "Big Sur" | |
# - Download macOS and wait for the installer screen to pop up | |
# - Build the install media: | |
# sudo /Applications/Install\ macOS\ Big\ Sur.app/Contents/Resources/createinstallmedia --volume /Volumes/MyVolume | |
# * Boot the new machine and hold the Option key until it gives you the option to boot from the USB drive | |
# * Partition the boot drive as desired (I use APFS, case-sensitive) | |
# * Install macOS | |
# * Run through the iCloud, user creation, Apple Wallet, etc. setup of the initial boot | |
# * Run this script: | |
# bash -c "$(curl -fsSL https://gist.githubusercontent.com/RoboticCheese/a0e417068f6148bac4ee343e8b411977/raw/9ab9412a89ab0bfecf5a227d95b972d044a5d1ad/macos_bootstrap.sh)" | |
# | |
# | |
# TODO: | |
# - [ ] It doesn't pause the Homebrew install, but adobe-digital-editions throws up a dialog to allow access to the Documents folder then opens the app when granted | |
# - [ ] Ditto Zoom and the Downloads folder | |
# - [ ] Set my external monitor to scaled resolution and max desktop space | |
# - [ ] Set displays to bridged instead of mirrored | |
# - [ ] Install my favorite VSCode extensions | |
# - [ ] Reassign Cmd+Space to Alfred instead of Spotlight | |
# - [ ] Set up apps to start at login that don't do it on their own (Docker? Magnet? PIA?) | |
# - [ ] Box's extension needs to be granted access | |
# - [ ] Ditto VirtualBox's system extension | |
# - [ ] Reboot so Box's extension can take effect | |
# - [ ] Install DeDRM in Calibre | |
# - [ ] "Cask 'yubico-yubikey-manager' is unavailable: No Cask with this name exists." | |
# - [ ] Grant full disk access to Terminal, iTerm2, and Hyper(?) | |
# - [ ] Enable the 1Blocker and 1Password extensions in Safari | |
# - [ ] Run the PIA installer | |
set -e | |
# The initial sudo command will authorize this user and temporarily remove the 5min sudo timeout | |
sudo sh -c 'echo "Defaults timestamp_timeout=-1" > /private/etc/sudoers.d/disable_timeout' | |
# Grant user write access to man8??? Is this really needed? | |
# sudo chown -R $(whoami) /usr/local/share/man/man8 | |
echo | |
echo "##########################################" | |
echo "# Installing macOS command line tools... #" | |
echo "##########################################" | |
echo | |
# Borrowed from the Chef build-essential cookbook and updated for Big Sur | |
touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress | |
PROD=$(softwareupdate -l | grep "\* Label: Command Line Tools for Xcode" | tail -n 1 | sed 's/^\* Label: //') | |
softwareupdate -i "$PROD" --verbose | |
rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress | |
echo | |
echo "###########################" | |
echo "# Installing oh-my-zsh... #" | |
echo "###########################" | |
echo | |
/bin/sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" | |
echo | |
echo "############################################" | |
echo "# Setting up dot directories for Dropbox...#" | |
echo "############################################" | |
echo | |
for D in .aws .chef .gitconfig .gnupg .ssh .stove .zprofile; do | |
rm -rf "${HOME}/${D}" | |
ln -s "${HOME}/Dropbox/Home/${D}" "${HOME}/${D}" | |
done | |
echo | |
echo "#################################" | |
echo "# Configuring the macOS Dock... #" | |
echo "#################################" | |
echo | |
defaults write com.apple.dock autohide -bool true # Auto-hide the Dock | |
defaults write com.apple.dock magnification -bool true # Magnify icons on mouseover | |
defaults write com.apple.dock wvous-bl-corner -int 5 # Mouse to bottom left to start screensaver | |
defaults write com.apple.dock wvous-bl-modifier -int 0 | |
killall Dock # Make the new settings take effect | |
echo | |
echo "##########################" | |
echo "# Installing Homebrew... #" | |
echo "##########################" | |
echo | |
# Homebrew cannot be run as root, requires sudo access, and needs an environment variable to not prompt the user to press enter | |
CI=true /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" | |
# If this is new Homebrew, it needs some path help. | |
# Our .zprofile is in Dropbox but .bash_profile isn't. | |
if [ -d /opt/homebrew ]; then | |
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> "${HOME}/.bash_profile" | |
eval "$(/opt/homebrew/bin/brew shellenv)" | |
fi | |
# Turn off Homebrew analytics | |
brew analytics off | |
echo | |
echo "###############################" | |
echo "# Installing Homebrew apps... #" | |
echo "###############################" | |
echo | |
mkdir "${HOME}/.homebrew" | |
cat > "${HOME}/.homebrew/Brewfile" <<- EOM | |
# TBD: | |
# brew 'ballerina' # The Ballerina language depends on an ancient OpenJDK 8 | |
# brew 'garden-cli' # The Garden.io Kubernetes app lifecycle looks cool but I never used it | |
# cask 'avira-antivirus' # Doesn't support Big Sur yet | |
# cask 'chef-workstation' # Replace with either nothing or Cinc | |
# cask 'dropbox' # Maestral is better and has Arm support | |
# cask 'spectrum' # Was I using this chat app for anything? | |
# cask 'vagrant' # Doesn't support Arm | |
# cask 'virtualbox' # Probably won't ever support Arm | |
# mas 'Divvy', id: 413857545 # Magnet seems a better window manager | |
# mas 'Edison Mail', id: 1489591003 # Been just using Outlook lately | |
# mas 'Spark', id: 1176895641 # Been just using Outlook lately | |
# Taps that we use: | |
tap 'habitat-sh/habitat' # Chef Habitat | |
tap 'hashicorp/tap' # Hashicorp's various products | |
tap 'homebrew/cask' # Cask support | |
# Regular Homebrew apps: | |
brew 'aws-cdk' # The AWS Cloud Development Kit | |
brew 'awscli' # The AWS CLI | |
brew 'cfssl' # CloudFlare's PKI toolkit | |
brew 'doctl' # The DigitalOcean CLI | |
brew 'gh' # The GitHub CLI | |
brew 'git' # Get a newer version of Git than what's in macOS | |
brew 'go' # The Go programming language | |
brew 'hab' # Habitat by Chef (To be replaced when Cinc Packager is released) | |
brew 'helm' # The Helm Kubernetes package manager | |
brew 'httpie' # The httpie more user-friendly alternative to curl | |
brew 'hub' # The Hub command line extensions for Git | |
brew 'hugo' # The Hugo static site generator | |
brew 'jq' # Helpful JSON parsing CLI tool | |
brew 'kubernetes-cli' # The Kubernetes CLI | |
brew 'linkerd' # The CLI for the Linkerd service mesh | |
brew 'mas' # CLI for installing App Store apps | |
brew 'minikube' # The Minikube local Kubernetes cluster utility | |
brew 'node' # Node.js | |
brew 'nomad' # Hashicorp Nomad | |
brew 'obs' # OBS | |
brew 'openapi-generator' # Generator tool for OpenAPI specs | |
brew 'packer' # Hashicorp Packer | |
brew 'pre-commit' # Git pre-commit hooks | |
brew 'python' # A newer Python than what's in macOS | |
brew 'ruby' # A newer Ruby than what's in macOS | |
brew 'rust' # The Rust programming language | |
brew 'shellcheck' # The ShellCheck linter for Bash scripts | |
brew 'step' # SmallStep crypto and x509 swiss-army-knife | |
brew 'telnet' # macOS doesn't include a Telnet client | |
brew 'terraform' # Hashicorp Terraform | |
brew 'tig' # The Tig utiility for Git | |
brew 'tmux' # The terminal multiplexer | |
brew 'wget' # macOS doesn't include wget | |
brew 'zola' # The Zola (formerly Gutenberg) static site generator | |
# Homebrew casks: | |
# cask 'adobe-digital-editions' # For ePub library books; not Arm native yet | |
cask 'alfred' # Alfred still > Spotlight | |
cask 'authy' # MFA utility | |
cask 'balenaetcher' # Tool for making bootable flash drive OS images | |
# cask 'box-drive' # Box.com macOS Finder integration; not Arm native yet | |
cask 'calibre' # Calibre ebook utility | |
cask 'canva' # Graphical video tool | |
cask 'dash' # Dash documentation tool | |
cask 'discord' # Discord chat app | |
cask 'docker' # Docker! | |
# cask 'elgato-camera-hub' # Configures the Elgato FaceCam; not Arm native yet | |
cask 'firefox' # Firefox browser | |
cask 'github' # GitHub desktop client | |
cask 'google-chrome' # Chrome browser | |
cask 'google-cloud-sdk' # Google Cloud SDK | |
cask 'gpg-suite' # GPG key management tools | |
cask 'hyper' # An alternative, Electron-based terminal | |
# cask 'inspec' # Chef's Inspec testing utility; not Arm native yet | |
cask 'iterm2' # The iTerm2 alt terminal | |
cask 'lastfm' # For scrobbling songs from iTunes | |
cask 'maestral' # Third-party Dropbox app with Arm support | |
# cask 'mattermost' # Open source fork of a Slack knockoff; do I need this anymore? | |
cask 'microsoft-office' # Office 365 | |
# cask 'microsoft-teams' # Microsoft Teams; not Arm native | |
# cask 'multipass' # Canonical's lightweight VM manager; do I need this? | |
cask 'parallels' # Parallels VM manager | |
cask 'paw' # Paw API utility | |
cask 'philips-hue-sync' # Philips Hue light controller tool | |
cask 'powershell' # Microsoft PowerShell | |
cask 'private-internet-access' # PIA VPN client | |
cask 'retroarch-metal' # RetroArch game emulator platform | |
cask 'session-manager-plugin' # The session manager plugin for the AWS CLI | |
cask 'spotify' # Spotify! | |
cask 'steam' # Steam! | |
cask 'telegram' # Telegram messenger | |
# cask 'utm' # macOS frontend for QEMU; do I need this? | |
cask 'viscosity' # General purpose VPN client | |
cask 'visual-studio-code' # VS Code | |
cask 'vlc' # VLC video player | |
cask 'yacreader' # Comic book reader app | |
cask 'yubico-yubikey-manager' # Management app for Yubikeys | |
cask 'zoom' # Zoom video conference app | |
# App Store apps: | |
mas '1Blocker', id: 1365531024 # Ad blocker for Safari | |
mas '1Password 7', id: 1333542190 # 1Password password manager | |
mas 'DaVinci Resolve', id: 571213070 # BlackMagic's free video editor | |
mas 'Fantastical', id: 975937182 # Calendar tool | |
mas 'GarageBand', id: 682658836 # Apple GarageBand | |
mas 'GIPHY CAPTURE', id: 668208984 # GIF screen capture tool | |
mas 'iMovie', id: 408981434 # Apple iMovie | |
mas 'Keynote', id: 409183694 # Apple Keynote | |
mas 'Kindle', id: 405399194 # Amazon Kindle app | |
mas 'Magnet', id: 441258766 # Fancy window manager | |
mas 'Markdown Pro', id: 465965038 # Visual Markdown editor | |
mas 'Numbers', id: 409203825 # Apple Numbers | |
mas 'Pages', id: 409201541 # Apple Pages | |
mas 'Slack', id: 803453959 # Slack | |
mas 'Tweetbot', id: 1384080005 # The best Twitter client | |
mas 'WiFi Explorer', id: 494803304 # Wi-Fi network exploration | |
mas 'Xcode', id: 497799835 # Apple Xcode | |
EOM | |
pushd "${HOME}/.homebrew" || exit 1 | |
brew bundle | |
popd || exit 1 | |
# Kill apps that Homebrew starts but don't need to be running | |
killall Adobe\ Digital\ Editions | |
killall zoom.us | |
echo | |
echo "#####################################################" | |
echo "# Starting up apps that should always be running... #" | |
echo "#####################################################" | |
echo | |
# open /Applications/Alfred.app | |
# open /Applications/Box.app | |
# open /Applications/Docker.app | |
# open /Applications/Dropbox.app | |
# open Private Internet Access | |
echo | |
echo "#####################################" | |
echo "# Configuring Visual Studio Code... #" | |
echo "#####################################" | |
echo | |
# Disable sending telemetry data to Microsoft | |
# Install all the extensions we use | |
code --install-extension hashicorp.terraform | |
code --install-extension amazonwebservices.aws-toolkit-vscode | |
code --install-extension ms-toolsai.jupyter | |
code --install-extension ms-python.python | |
# Restore the default 5min sudo timeout | |
sudo rm /private/etc/sudoers.d/disable_timeout |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment