Skip to content

refactor: replace ansible with plain bash scripts#8

Merged
laermannjan merged 22 commits intomainfrom
bash-migration
Apr 21, 2026
Merged

refactor: replace ansible with plain bash scripts#8
laermannjan merged 22 commits intomainfrom
bash-migration

Conversation

@laermannjan
Copy link
Copy Markdown
Owner

@laermannjan laermannjan commented Apr 17, 2026

why

ansible chain rotted after months idle. bash + curl + git always work. replacing with plain bash, sourced scripts, one file per concern.

decisions worth keeping

  • fail-fast, not best-effort. brew bundle failure aborts run. caller sees real error, doesn't limp on.
  • platform detection inline in sysconf.sh. no lib/ dir. helpers live next to callers, one file to read.
  • dotfile symlinks. edits in repo reflected immediately, no sync step.
  • ssh/config symlinked too. ~/.ssh is 700, config is public on GitHub. 0600 copy was cargo-cult.
  • brew shellenv must be invoked with bash arg. default emits fish syntax after chsh, breaks the script.
  • beancount via uv tool install, not brew. brew wants bison ≥3.8 from source. uv ships wheels.
  • unknown CLI args hard-fail. --skipp ssh should error, not silently do nothing.
  • SYSCONF_SKIP env var. lets fish aliases and CI pass skips without reworking argv.
  • sudo keepalive loop. single prompt at start, stays alive for whole run. dies when script dies.
  • CI runs each platform twice. second run verifies idempotency.

rejected

  • ansible, chezmoi, pyinfra - all add a dependency chain that breaks after months idle
  • preserving lib/platform.sh split - one sysconf.sh is simpler to read
  • --no-build beancount in CI - bandaid, removed in favor of uv wheels

test plan

  • CI green: ubuntu, fedora, macOS, shellcheck
  • second run idempotent on all three
  • live macOS machine

Drop the ansible/uv/bcrypt/galaxy dependency chain. All setup logic is now
in bash scripts sourced by sysconf.sh. Same functionality, zero runtime
dependencies beyond bash, curl, and git.

- setup/{packages,dotfiles,shell,ssh,system}.sh replace ansible roles
- Platform helpers (is_mac, is_debian, etc.) inlined in sysconf.sh
- SYSCONF_SKIP env var for skipping steps (e.g. fish alias)
- Colored semantic logging (log, log_ok, log_skip, log_warn)
- CI: shellcheck replaces ansible-lint, idempotency test (run twice)
- sudo keepalive loop prevents mid-run password prompts
- TouchID uses sudo_local (survives macOS updates)
- Homebrew always installs noninteractively
- SSH moved to last step (only interactive part)
- Reorder: dotfiles before packages (brew bundle needs Brewfile symlink)
- Use $GITHUB_WORKSPACE for SYSCONF_DIR (resolves correctly in containers)
- Skip git pull on detached HEAD (CI checkouts)
- Remove @"Development Tools" and @multimedia dnf groups (build tools
  already in prerequisites, multimedia handled by brew)
- Remove postgresql dnf package (libpq from brew covers psql)
- Remove man-db and procps (pre-installed on desktop systems)
- Always install build tools on Linux, not just when git is missing
- Let brew bundle fail hard instead of swallowing errors
- Remove flatpak WSL2 skip, add flatpak metadata fetch
- Add brew update before bundle, use quiet for noisy commands
- Restore @"Development Tools" and add c-development, development-libs
- Remove apt-get update || true, let it fail visibly
- Use SYSCONF_DIR for Brewfile path (no dotfiles dependency)
- Prefix all logs with [sysconf], full-line color, terse language
- Remove postinstall from uv/rustup in Brewfile, run explicitly in packages.sh
- Remove flatpak section (desktop distros ship flathub, brew skips if not installed)
- Guard mas entries behind ENV[CI] (mas hangs in headless environments)
@laermannjan laermannjan merged commit 86bedef into main Apr 21, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant