Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,56 @@ jobs:
HOMEBREW_NO_AUTO_UPDATE: 1
steps:
- uses: actions/checkout@v7
- name: Every Brewfile entry still exists in Homebrew
- name: Every Brewfile entry still exists in Homebrew and isn't deprecated
run: |
brew info --formula $(brew bundle list --file=Brewfile --formula) > /dev/null
brew info --cask $(brew bundle list --file=Brewfile --cask) > /dev/null
brew info --json=v2 --formula $(brew bundle list --file=Brewfile --formula) > formulae.json
brew info --json=v2 --cask $(brew bundle list --file=Brewfile --cask) > casks.json
# brew info still succeeds for deprecated and disabled packages, which are about to go away.
retiring="$(jq -r '(.formulae[], .casks[]) | select(.deprecated or .disabled)
| "\(.token // .name): \(if .disabled then "disabled" else "deprecated" end) (\(.disable_reason // .deprecation_reason // "no reason given"))"' \
formulae.json casks.json)"
if [[ -n "$retiring" ]]; then
echo "$retiring"
exit 1
fi

setup:
runs-on: macos-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v7
- name: First run
run: ./setup.sh
- name: Second run changes nothing
run: |
snapshot() {
brew list --formula --versions
brew list --cask --versions
for file in ~/.zprofile ~/.zshrc ~/.gitconfig ~/.config/ghostty/config \
~/.config/herdr/config.toml ~/.docker/config.json; do
echo "== $file"
cat "$file" 2>/dev/null || echo "(missing)"
done
}
snapshot > first-run.txt
./setup.sh
snapshot > second-run.txt
diff -u first-run.txt second-run.txt
- name: An interactive zsh starts without errors
run: |
# Under a pty, because zsh can't switch its line editor on without one
# and says "can't change option: zle" whatever the config. One perl pass
# drops everything a terminal adds by itself: escape sequences (the
# prompt), control characters, and the caret notation the pty echoes for
# the EOF that ends the session. Whatever is left is a real message.
output="$(script -q /dev/null zsh -i -c exit 2>&1 | perl -ne '
s/\e\][^\a\e]*(?:\a|\e\\)//g; # window title
s/\e\[[0-9;?]*[a-zA-Z]//g; # colors, cursor moves
s/\e[=>]//g; # keypad mode
s/[\x00-\x08\x0b-\x1f\x7f]//g; # other control characters
next if /^(?:\^[\x3f\x40-\x5f])*\s*$/; # ^D and friends, blank lines
print')"
if [[ -n "$output" ]]; then
echo "$output"
exit 1
fi
4 changes: 4 additions & 0 deletions Brewfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Everything setup.sh installs. Run on its own with: brew bundle --file=Brewfile
# Comment out anything you don't want before running.

# Take over apps you already installed by hand (like Chrome) instead of failing
# with "It seems there is already an App at ...".
cask_args adopt: true

# --- Shell & terminal ---
cask "ghostty" # fast, native, GPU-accelerated terminal
brew "starship" # fast, minimal prompt (replaces oh-my-zsh themes)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ Want a different selection? Edit the [`Brewfile`](Brewfile) before running `./se
### What `setup.sh` does

- Installs [Homebrew](https://brew.sh/) if it's missing and adds it to your `PATH` in `~/.zprofile`
- Installs everything in the [`Brewfile`](Brewfile) with `brew bundle`
- Installs everything in the [`Brewfile`](Brewfile) with `brew bundle`. Apps you already installed yourself, like Chrome, are handed over to Homebrew rather than installed again
- Adds one `source` line to the end of `~/.zshrc` that loads [`dotfiles/zshrc`](dotfiles/zshrc)
- Adds a `config-file` line to `~/.config/ghostty/config` that loads [`dotfiles/ghostty`](dotfiles/ghostty), which makes **Cmd+K** clear the screen inside herdr and tmux too, and makes the left Option key work as Alt
- Creates `~/.config/herdr/config.toml` from [`dotfiles/herdr.toml`](dotfiles/herdr.toml) if you don't have one, or adds the tab shortcut to the one you have
- Adds an include to the top of `~/.gitconfig` that loads [`dotfiles/gitconfig`](dotfiles/gitconfig)
- Turns on commit signing with your SSH key, if you have one and haven't set up signing already
- Lets the Homebrew `docker` CLI find the `compose` and `buildx` plugins

It never overwrites your existing files, and it's safe to run again: that's also how you install anything you add to the `Brewfile` later. Your own settings in `~/.zshrc` and `~/.gitconfig` still apply, and those in `~/.gitconfig` take precedence. The config is loaded from the cloned repo, so keep it where you cloned it.
If something in the `Brewfile` fails to install, the other steps still run and the failures are listed at the end. It never overwrites your existing files, and it's safe to run again: that's also how you install anything you add to the `Brewfile` later. Your own settings in `~/.zshrc` and `~/.gitconfig` still apply, and those in `~/.gitconfig` take precedence. The config is loaded from the cloned repo, so keep it where you cloned it.

## What gets installed

Expand Down
12 changes: 11 additions & 1 deletion setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ if ! grep -q 'brew shellenv' "$HOME/.zprofile"; then
fi

step "Apps and tools from the Brewfile"
brew bundle --file="$REPO_DIR/Brewfile"
# A failed install doesn't stop the setup: the steps below don't need it.
# The failures are listed at the end.
BUNDLE_FAILED=""
brew bundle --file="$REPO_DIR/Brewfile" || BUNDLE_FAILED=1

step "Shell config"
ZSHRC_LINE="source \"$REPO_DIR/dotfiles/zshrc\""
Expand Down Expand Up @@ -151,3 +154,10 @@ if [[ -z "$(git config --global user.email || true)" ]]; then
note "- Set your git identity: git config --global user.name \"Your Name\""
note " git config --global user.email \"you@example.com\""
fi

if [[ -n "$BUNDLE_FAILED" ]]; then
step "Some Brewfile entries didn't install"
brew bundle check --file="$REPO_DIR/Brewfile" --no-upgrade --verbose 2>&1 | sed 's/^/ /' || true
note "Look for \"Error:\" in the brew bundle output above, fix it, then re-run ./setup.sh"
exit 1
fi
Loading