This repo is my personal collection of dotfiles, configuration settings, templates, and productivity tools. The intention is to be able to automate the installation and setup of a new developer workbench as much as possible. This represents the culmination of numerous iterations across various companies to automate developer onboarding.
The only required software is bash (or Git Bash for Windows). Everything else — including Python and Ansible — is bootstrapped automatically by the setup script.
Set these before running setup.sh. Variables without a default must be set.
| Variable | Default | Description |
|---|---|---|
DEV_HOME |
~/developer |
Root developer directory |
REPO_HOME |
$DEV_HOME/repos |
Git repository directory |
DEVTOOLS_HOME |
$DEV_HOME/devtools |
Devtools installation directory |
TOOLS_HOME |
$DEV_HOME/tools |
Shared tools directory |
TOOLS_BIN_HOME |
$TOOLS_HOME/bin |
Tools binary directory (added to PATH) |
GITHUB_USERNAME |
(required) | Your GitHub username |
GIT_EMAIL |
(optional) | Git commit email |
GIT_NAME |
(optional) | Git commit display name |
GIT_SIGNING_KEY |
(optional) | SSH public key path for commit signing |
GIT_SSH_AGENT |
1p |
SSH agent type (1p for 1Password) |
ONEPASSWORD_SSH_KEY |
(optional) | 1Password SSH key selector for agent.toml ([[ssh-keys]].item), defaults to GIT_SIGNING_KEY |
CONTEXT7_API_KEY |
(optional) | Context7 API key |
NODE_VERSION |
24.14.1 |
Node.js version to install via nvm |
GITHUB_TOKEN |
(optional) | GitHub personal access token |
Windows only:
| Variable | Description |
|---|---|
ANSIBLE_PASSWORD |
Windows user account password (required for WinRM authentication) |
# Set required environment variables
export GITHUB_USERNAME="your-username"
export GIT_EMAIL="you@example.com"
export GIT_NAME="Your Name"
export GIT_SIGNING_KEY="~/.ssh/id_ed25519.pub"
# Run directly from the repo
./setup.sh
# Or bootstrap from scratch with curl (clones the repo automatically)
bash $(curl -fsSL https://raw.githubusercontent.com/andrew-codes/devtools/main/setup.sh)Setup logs are written to workbench.log in the repository root.
The setup is driven by Ansible playbooks. setup.sh is the single entry point:
- Detects the OS and CPU architecture
- Bootstraps Python 3 and Ansible (via
pip) - On Windows: installs Chocolatey and configures WinRM for local Ansible connections
- Runs the appropriate site playbook for the detected platform
| Platform | Site Playbook |
|---|---|
| macOS arm64 (Apple Silicon) | ansible/site-macos-arm64.yml |
| Windows 11 amd64 | ansible/site-windows-amd64.yml |
ansible/
setup.sh # Bootstrap entry point
requirements.yml # Ansible Galaxy collections
inventory-macos.yml # macOS localhost inventory (connection: local)
inventory-windows.yml # Windows localhost inventory (connection: winrm)
group_vars/
all.yml # Variables resolved from environment variables
site-macos-arm64.yml # macOS arm64 entry playbook
site-windows-amd64.yml # Windows amd64 entry playbook
playbooks/
devtools-bash-env.yml # Dev directory structure + PATH export
bash-profile.yml # ~/.bash_profile → sources ~/.bashrc
brew.yml # Homebrew (macOS only)
git-config.yml # Git globals, signing, editor
uvx.yml # uv / uvx (Python tool runner)
shfmt.yml # Shell script formatter
jq.yml # JSON processor
git-completion.yml # Bash tab-completion for git
git-prompt.yml # Git branch info in shell prompt
gh.yml # GitHub CLI
yq.yml # YAML processor
git-shortcuts.yml # Custom git shortcut scripts
projects.yml # Project navigation scripts
bash-utilities.yml # Custom bash utility scripts
1p-ssh-agent.yml # 1Password SSH agent
nodejs.yml # Node.js via nvm
claude-code.yml # Claude Code CLI
vscode.yml # VS Code + extensions
docker.yml # Docker Desktop + bin utilities
raycast.yml # Raycast + macOS Spotlight disable
ghostty.yml # Ghostty terminal (macOS)
logi-options-plus.yml # Logi Options+ (macOS/Windows)
lens.yml # Lens IDE (macOS)
Each playbook is self-contained, idempotent, and uses when: guards for platform-specific tasks. macOS tasks use Homebrew; Windows tasks use Chocolatey.
| Tool | Description | macOS | Windows |
|---|---|---|---|
| Homebrew | Package manager | ✓ | |
| Chocolatey | Package manager | ✓ | |
| Shell environment | Dev directory structure, PATH exports, and ~/.bash_profile → ~/.bashrc wiring |
✓ | ✓ |
| Git | Global config — user identity, commit signing, default editor | ✓ | ✓ |
| Git completion | Bash tab-completion for git commands | ✓ | ✓ |
| git-prompt | Git branch and status info in the shell prompt | ✓ | ✓ |
| git-shortcuts | Custom git shortcut scripts (co, nb, push, pull, st, glg, …) |
✓ | ✓ |
GitHub CLI (gh) |
GitHub CLI for PRs, issues, and repo management | ✓ | ✓ |
| uv / uvx | Fast Python package and tool runner | ✓ | ✓ |
| shfmt | Shell script formatter | ✓ | ✓ |
| jq | Command-line JSON processor | ✓ | ✓ |
| yq | Command-line YAML processor | ✓ | ✓ |
| Node.js | Node.js installed and managed via nvm | ✓ | ✓ |
| Claude Code | Anthropic Claude Code CLI (@anthropic-ai/claude-code) and default MCP servers |
✓ | ✓ |
| Visual Studio Code | Editor + configured extension set | ✓ | ✓ |
| Docker Desktop | Docker Desktop + denv / dka bin utilities |
✓ | ✓ |
| Raycast | Launcher and productivity app; disables Spotlight indexing on macOS; installed from vendor installer URL on Windows | ✓ | ✓ |
| Ghostty | Terminal emulator | ✓ | |
| Logi Options+ | Logitech device customization software | ✓ | ✓ |
| Lens | Kubernetes IDE | ✓ | |
| 1Password SSH Agent | SSH agent integration via 1Password | ✓ | ✓ |
| projects | Project navigation scripts (proj, projs, oproj) |
✓ | ✓ |
| bash-utilities | Custom bash utility scripts (aup, kaup) |
✓ | ✓ |
Create a new playbook in ansible/playbooks/ following this pattern:
---
- name: Install my-tool
hosts: localhost
gather_facts: true
tasks:
- name: Install my-tool (macOS via Homebrew)
community.general.homebrew:
name: my-tool
state: present
when: ansible_system == 'Darwin'
- name: Install my-tool (Windows via Chocolatey)
chocolatey.chocolatey.win_chocolatey:
name: my-tool
state: present
when: ansible_os_family == 'Windows'Then add it to the appropriate site playbook(s):
# ansible/site-macos-arm64.yml
- import_playbook: playbooks/my-tool.ymlOn Windows, Ansible connects to localhost via WinRM. setup.sh will configure WinRM automatically, but the Windows user account must have administrator rights. Set ANSIBLE_PASSWORD to your Windows account password before running:
export ANSIBLE_PASSWORD="your-windows-password"
./ansible/setup.sh