- Lua 59.2%
- Shell 40.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Rework bootstrap-minimal.sh from a fixed minimal installer into an environment-adaptive provisioner: - Detect context: Jamf/MDM enrollment, brew/Workbrew presence, admin. - Inline manifest: CLI tools (mise), GUI apps with a per-app method chain (cask -> jamf-ss), and a user-maintained MDM_ALLOWED allow-list. On a managed Mac, GUI apps not on the allow-list are skipped; non-automatable installs (Self-Service-only, Workbrew-refused casks) are collected into a manual to-do report printed at the end. - git is now optional: repo, oh-my-zsh and plugins fetched via tarball when git is absent (no Xcode CLT dependency). - eza pinned to aqua backend (git-free + checksum-verified); its registry default is asdf which requires git. - Enable mise lockfile + paranoid + aqua cosign/slsa before installing tools. - bash 3.2 compatible (fresh Macs ship /bin/bash 3.2): no associative arrays, guarded empty-array expansions under `set -u`. Verified: shellcheck clean, parses under /bin/bash 3.2.57, detection correct. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
| .githooks | ||
| files | ||
| roles | ||
| secrets | ||
| .gitignore | ||
| .sops.yaml | ||
| ansible.cfg | ||
| bootstrap-minimal.sh | ||
| bootstrap.sh | ||
| inventory | ||
| playbook.yml | ||
| PROJECT_MISSION.md | ||
| README.md | ||
| update_secrets.sh | ||
Dotfiles 🚀
Automated, reproducible macOS development environment setup using Ansible, GNU Stow, Mise, and SOPS.
⚡️ Quick Start
One-Liner (Recommended)
/bin/bash -c "$(curl -fsSL https://git.smlit.de/samuel/dotfiles/raw/branch/main/bootstrap.sh)"
Adaptive / MDM-aware Bootstrap
For a "fresh" or MDM-managed Mac. Detects the environment and installs the tools permitted in that context — the userspace tier needs no sudo, no Homebrew, no git:
/bin/bash -c "$(curl -fsSL https://git.smlit.de/samuel/dotfiles/raw/branch/main/bootstrap-minimal.sh)"
Tier 0 — always (userspace):
miseself-installs to~/.local/binand providesstarship, eza, direnv, zoxide, bat, ripgrep, fzf, fd, atuin, zellij, jqas static binaries via the aqua backend (checksum-verified;lockfileparanoid+ cosign/slsa are enabled before install).
- oh-my-zsh + plugins, JetBrainsMono Nerd Font (
~/Library/Fonts), and the same.zshrc/.zprofileas the full setup — guarded withcommand -vso they degrade gracefully when a tool is missing. - git is optional: repo, oh-my-zsh and plugins are fetched via tarball when git is absent (no Xcode Command Line Tools needed).
GUI layer — environment-dependent (detects Jamf/MDM, brew/Workbrew, admin):
- unmanaged + brew → installs casks (Raycast, Ghostty, kitty).
- Jamf-managed + Workbrew → installs only casks on the MDM allow-list
(edit
MDM_ALLOWEDin the script); everything else (Self-Service-only apps, or casks Workbrew refuses) is collected into a manual to-do report. - locked (no brew) → GUI apps reported for manual install.
The tool manifest and MDM allow-list live in a clearly-marked block at the top
of bootstrap-minimal.sh. Run ./bootstrap.sh (Ansible) for the full
unmanaged environment incl. SOPS secrets and language runtimes.
Manual Setup
- Clone the repository:
git clone https://git.smlit.de/samuel/dotfiles.git ~/development/dotfiles
cd ~/development/dotfiles
-
Ensure Age Key exists: Place your Age secret key at
~/.config/sops/age/keys.txt. This is required to decrypt secrets (Git identities, etc.). -
Run Bootstrap:
./bootstrap.sh
- Installs Homebrew & Ansible (if missing).
- Installs Core Tools & Apps.
- Symlinks Dotfiles.
- Decrypts Secrets.
✋ Manual Steps
Due to macOS security restrictions (TCC/SIP), some things cannot be automated:
- Full Disk Access: Grant "Full Disk Access" to your terminal (Ghostty/Kitty/WezTerm) in System Settings -> Privacy & Security.
- WireGuard: Open the WireGuard app and import tunnels from
~/development/dotfiles/files/wireguard/. - Safari Extensions: Enable 1Password and AdGuard extensions in Safari Settings.
🏗 Architecture
- Orchestration: Ansible (Local Playbook).
- Package Management:
- Homebrew: GUI Apps (Casks) & CLI Utilities (
git,starship,atuin). - Mise: Runtimes (
node,python,go) & Infra Tools (sops,age,direnv). pinned versions.
- Homebrew: GUI Apps (Casks) & CLI Utilities (
- Dotfile Management: GNU Stow.
- Symlinks configurations from
files/to~/.config/or~/.
- Symlinks configurations from
- Secrets: SOPS + Age.
- Encrypted files live in
secrets/. - Decrypted on bootstrap to
files/(gitignored).
- Encrypted files live in
🛠 Features
Shell & Terminal
- Terminals: Configurations for Ghostty, Kitty, and WezTerm.
- Shell: Zsh with
starshipprompt,atuinhistory,zoxidenavigation, andezals-replacement.
Git Setup
- Identity Management: Context-aware configs via
[includeIf]. - Signing: SSH Signing configured via 1Password.
- Aliases: Pre-configured shortcuts (
git s,git co,git lg).
🔐 Secrets Workflow
To update a secret:
- Edit the plaintext file locally (e.g.
files/git/.config/git/identity-work). - Run the update script to re-encrypt into
secrets/:./update_secrets.sh - Commit the changes in
secrets/.
📂 Repository Structure
├── bootstrap.sh # Entry point
├── playbook.yml # Main Ansible Playbook
├── inventory # Localhost definition
├── roles/
│ ├── core/ # Brew, Mise, MAS
│ ├── dotfiles/ # Stow, Secrets, Backups
│ └── term/ # (Deprecated/Merged)
├── files/ # Plaintext Configs (Stow Source)
└── secrets/ # Encrypted Secrets (SOPS Source)