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
19 changes: 16 additions & 3 deletions .aliases
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ alias sudo='sudo '
# Get week number
alias week='date +%V'

# Get macOS Software Updates, and update installed Ruby gems, Homebrew, npm, uv, and their installed packages
alias update='sudo softwareupdate -i -a; brew update; brew upgrade; brew cleanup; command -v npm > /dev/null 2>&1 && npm install npm -g; command -v npm > /dev/null 2>&1 && npm update -g; command -v uv > /dev/null 2>&1 && uv tool upgrade --all; [[ $(which ruby) != /usr/bin/ruby ]] && sudo gem update --system; [[ $(which ruby) != /usr/bin/ruby ]] && sudo gem update; [[ $(which ruby) != /usr/bin/ruby ]] && sudo gem cleanup'

# Google Chrome
alias chrome='/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome'
alias canary='/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary'
Expand Down Expand Up @@ -84,6 +81,22 @@ command -v md5sum > /dev/null || alias md5sum="md5"
# macOS has no `sha1sum`, so use `shasum` as a fallback
command -v sha1sum > /dev/null || alias sha1sum="shasum"

# Linux has no `pbcopy`/`pbpaste`, so use `xclip`/`xsel` as fallbacks
if ! command -v pbcopy > /dev/null; then
if command -v xclip > /dev/null; then
alias pbcopy="xclip -selection clipboard"
alias pbpaste="xclip -selection clipboard -o"
elif command -v xsel > /dev/null; then
alias pbcopy="xsel --clipboard --input"
alias pbpaste="xsel --clipboard --output"
fi
fi

# Linux has no `open`, so use `xdg-open` as a fallback
if ! command -v open > /dev/null && command -v xdg-open > /dev/null; then
alias open="xdg-open"
fi

# JavaScriptCore REPL
jscbin="/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc";
[ -e "${jscbin}" ] && alias jsc="${jscbin}";
Expand Down
2 changes: 1 addition & 1 deletion .extra.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# IN DOUBLE CURLY BRACES. The commented examples show the path format;
# to activate one, uncomment it and wrap the op://... path in {{ }}.
# (In the 1Password app: right-click a field -> "Copy Secret Reference".)
# 3. Re-run `source bootstrap.sh`, or just:
# 3. Re-render (bootstrap.sh only renders when ~/.extra is missing):
# op inject -i .extra.tmpl -o ~/.extra -f
#
# With no braced references present, this renders to an (inert) ~/.extra.
Expand Down
20 changes: 20 additions & 0 deletions .functions
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,23 @@ function gh() {
fi;
GH_TOKEN="$(command gh auth token --user "$acct" 2>/dev/null)" command gh "$@";
}

# Get macOS Software Updates, and update installed Ruby gems, Homebrew, npm, uv, and their installed packages
function update() {
# Ask for the administrator password upfront, then keep the sudo time
# stamp alive until the updates finish (same pattern as ~/.macos)
setopt localoptions nomonitor nonotify;
sudo -v || return;
while true; do sudo -n true; sleep 60; done 2>/dev/null &
local keepalive_pid=$!;
trap 'kill "$keepalive_pid" 2>/dev/null' EXIT;

[[ $(uname) == Darwin ]] && sudo softwareupdate -i -a;
command -v brew > /dev/null 2>&1 && { brew update; brew upgrade; brew cleanup; };
command -v npm > /dev/null 2>&1 && npm install npm -g;
command -v npm > /dev/null 2>&1 && npm update -g;
command -v uv > /dev/null 2>&1 && uv tool upgrade --all;
[[ $(which ruby) != /usr/bin/ruby ]] && sudo gem update --system;
[[ $(which ruby) != /usr/bin/ruby ]] && sudo gem update;
[[ $(which ruby) != /usr/bin/ruby ]] && sudo gem cleanup;
}
5 changes: 0 additions & 5 deletions .gitconfig
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,6 @@
changed = green
untracked = cyan

[commit]

# https://help.github.com/articles/signing-commits-using-gpg/
gpgsign = true

[diff]

# Detect copies as well as renames
Expand Down
38 changes: 38 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,41 @@ jobs:
run: brew install bats-core
- name: Run tests
run: bats tests
- name: Apply .macos on the throwaway runner and verify
if: matrix.os == 'macos-latest'
run: MACOS_APPLY_OK=1 bats tests/macos-apply.bats

test-rocky:
# No hosted Rocky runners exist; run in a container on the ubuntu host.
runs-on: ubuntu-latest
container: rockylinux:9
steps:
- name: Install dependencies
run: dnf install -y git zsh rsync
- uses: actions/checkout@v3
- name: Install Bats
run: |
git clone --depth 1 https://github.com/bats-core/bats-core.git /tmp/bats-core
/tmp/bats-core/install.sh /usr/local
- name: Run tests
run: bats tests

test-wsl:
runs-on: windows-2025
defaults:
run:
shell: wsl-bash {0}
steps:
# Line-ending normalization is disabled in .gitattributes, and Windows
# runners default to core.autocrlf=true β€” without this, every shell
# file checks out with CRLF and breaks inside WSL.
- name: Force LF line endings on checkout
shell: pwsh
run: git config --global core.autocrlf false
- uses: actions/checkout@v3
- uses: Vampire/setup-wsl@v5
with:
distribution: Ubuntu-24.04
additional-packages: bats zsh rsync
- name: Run tests
run: bats tests
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ Thumbs.db
# Scratch pads
scratch.*

# GPG β€” only track agent config, never keys or trust database
.gnupg/*
!.gnupg/gpg-agent.conf
# GPG β€” never track anything under .gnupg; agent config is machine-local
# (pinentry program paths differ per OS and Homebrew prefix)
.gnupg/

# Generated zsh completion cache
.zcompdump
Expand Down
3 changes: 0 additions & 3 deletions .gnupg/gpg-agent.conf

This file was deleted.

29 changes: 18 additions & 11 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ bats tests/macos.bats
bats tests/bootstrap.bats
```

CI runs tests on both `ubuntu-latest` and `macos-latest` via `.github/workflows/tests.yml`.
CI (`.github/workflows/tests.yml`) runs the suite on `ubuntu-latest`,
`macos-latest`, Rocky Linux 9 (container), and WSL Ubuntu (windows runner).
The macOS job additionally executes `.macos` for real and asserts settings
stuck (`tests/macos-apply.bats`) β€” safe there because runners are throwaway
VMs; the test skips everywhere else unless `MACOS_APPLY_OK=1` is set.

## Architecture

Expand All @@ -60,21 +64,24 @@ CI runs tests on both `ubuntu-latest` and `macos-latest` via `.github/workflows/

### Commit signing

Commits are signed with **SSH-format signatures via 1Password**, not GPG. The
repo sets `commit.gpgsign = true` (format-agnostic); the actual mechanism lives
in untracked machine-local files:
Commits are signed with **SSH-format signatures via 1Password**, not GPG.
Signing is entirely machine-local: the tracked `.gitconfig` does NOT enable
it, so a fresh machine defaults to unsigned commits instead of failing on a
missing signer. Each machine opts in via untracked files:

- `~/.gitconfig.local` / `~/.gitconfig-ica` set `gpg.format = ssh`,
`gpg.ssh.program = .../op-ssh-sign`, and `user.signingkey = ~/.ssh/*.pub`.
- `~/.gitconfig.local` / `~/.gitconfig-ica` set `commit.gpgsign = true`,
`gpg.format = ssh`, `gpg.ssh.program = .../op-ssh-sign`, and
`user.signingkey = ~/.ssh/*.pub`.
- `~/.ssh/config` points `IdentityAgent` at the 1Password agent socket; the
private keys live in 1Password and never touch disk. The `.pub` files are
just selectors.

On a machine without 1Password (e.g. a remote Linux box), `op-ssh-sign` doesn't
exist and the agent socket is absent. Either forward your local 1Password SSH
agent over the connection, or disable signing there with
`git config commit.gpgsign false`. There is **no GPG keypair** in this setup
despite the `gpgsign` name.
On a machine without 1Password (e.g. a remote Linux box), nothing needs
disabling β€” signing is simply never enabled there. To sign on a remote you
keep around, forward your local 1Password SSH agent over the connection and
set `user.signingkey` to the literal public key (not `op-ssh-sign`, which
only exists locally). There is **no GPG keypair** in this setup despite the
`gpgsign` name.

### Machine-local customization

Expand Down
Loading
Loading