Problem
My shell setup depends on oh-my-zsh, antidote plugins and a set of CLI tools, and I need it on both Ubuntu servers and dev machines. Installing all of that by hand on every machine is repetitive and easy to get wrong, so I wanted one installer with a lean profile for servers and a fuller one for development.
What I built
install.sh clones the repo to ~/.dotfiles and re-runs itself from there. It has two profiles: server installs zsh, oh-my-zsh, antidote plugins and CLI tools such as git, curl, fzf, zoxide, eza, tmux, jq and ripgrep, while dev adds the development toolchain on top. On Ubuntu, dev adds build-essential, gh and Task; both profiles also get nvm, the latest Node LTS and global npm packages.
It is safe to run again: installed packages are skipped, correct symlinks are left alone, and any file it would replace is moved to ~/.dotfiles-backup/<timestamp>/ first. Options cover --links-only, --no-chsh, DOTFILES_DIR and DOTFILES_BRANCH. Machine-specific settings go in ~/.config/zsh/local.zsh, which isn’t tracked.

Stack
Shell, zsh, oh-my-zsh, antidote, apt on Ubuntu, Homebrew on macOS, and GitHub Actions.