Skip to content

Migrate from Homebrew to Nix + Home Manager#45

Open
hironow wants to merge 8 commits intomainfrom
hironow/mv-nix
Open

Migrate from Homebrew to Nix + Home Manager#45
hironow wants to merge 8 commits intomainfrom
hironow/mv-nix

Conversation

@hironow
Copy link
Copy Markdown
Owner

@hironow hironow commented Mar 29, 2026

Summary

  • Nix + Home Manager をパッケージ管理とdotfile配置の中心に据える
  • Brewfileの ~120 CLI tools を nix/packages.nix に移行、Brewfileは cask/mas/vscode + tap固有パッケージのみに縮小
  • just deploy / just clean を deprecate し、Home Manager の home.file / xdg.configFile に置き換え
  • mise はプロジェクト別ランタイム版切替として残す
  • install.sh を Nix (Determinate Installer) → home-manager switch フローに書き換え

新ファイル

  • flake.nix / home.nix — Nix flake + Home Manager 設定
  • nix/packages.nix — CLI パッケージリスト (nixpkgs)
  • nix/dotfiles.nix — dotfile symlink 定義
  • nix/shell.nix — activation scripts (sheldon lock, fzf-tab)
  • tests/docker/NixHomeManager.Dockerfile — HM switch の Docker テスト
  • tests/docker/NixInstallTest.Dockerfile — install.sh の Docker E2E テスト
  • .github/workflows/test-nix.yaml — Nix CI ワークフロー

変更ファイル

  • .zshrc — Nix profile source 追加
  • dump/Brewfile — cask/mas/vscode + tap のみに縮小
  • install.sh — Nix install + HM switch フローに書き換え
  • justfile — Nix レシピ追加、deploy/clean deprecate、doctor 更新
  • tests/test_just_sandbox.py — deploy テスト更新

アーキテクチャ

Nix (home.packages)  → "what is installed" (~120 CLI tools)
mise (.mise.toml)    → "which version is active" (per-project)
Homebrew (Brewfile)  → cask/mas/vscode/tap-specific only

Test plan

  • CI: test-nix.yamlnix build + Docker HM test が通ること
  • CI: test-just.yaml — 既存テストが壊れていないこと
  • CI: shellcheck.yaml — install.sh が lint パス
  • マージ後: 実機で home-manager switch --flake . が動作すること

🤖 Generated with Claude Code

hironow and others added 8 commits March 29, 2026 22:14
- Add flake.nix, home.nix, nix/{packages,dotfiles,shell}.nix for
  declarative package management and dotfile symlink deployment
- Move ~120 CLI tools from Brewfile to nix/packages.nix (nixpkgs)
- Shrink dump/Brewfile to cask/mas/vscode + tap-specific packages only
- Archive original Brewfile as dump/Brewfile.full
- Rewrite install.sh: Nix (Determinate Installer) → home-manager switch
- Add .zshrc Nix profile sourcing at top
- Add justfile Nix recipes: hm-switch, hm-build, nix-update, nix-gc,
  test-nix-hm, test-nix-install
- Deprecate `just deploy` and `just clean` (Home Manager handles symlinks)
- Add doctor checks for nix and home-manager
- Add NixHomeManager.Dockerfile and NixInstallTest.Dockerfile for CI
- Add .github/workflows/test-nix.yaml CI workflow
- Update test_just_sandbox.py for deprecated deploy/clean
- mise retained for project-level runtime version switching

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JustSandbox Docker (Alpine) does not have Nix installed,
so doctor must not fail when nix is absent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
JustSandbox (Alpine) cannot install Nix, so add INSTALL_SKIP_NIX=1
and INSTALL_SKIP_HM=1 to install test scripts. Symlink verification
removed since Home Manager handles symlinks (not install.sh).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
P0-1: NixInstallTest.Dockerfile now runs as root (matching flake.nix
default Linux config "root@<system>") instead of testuser which had
no matching homeConfiguration.

P0-2: Add docker-install-test job to test-nix.yaml CI workflow to
exercise install.sh E2E (was missing per plan requirements).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Determinate Nix Installer requires --init none in containers
without systemd. Detect via /run/systemd/system presence.
Also add single-user nix.sh fallback for _source_nix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Determinate Nix Installer requires 'install linux --init none --no-confirm'
(linux is a subcommand, --init is its option). Previous order had --init
appended after --no-confirm which was rejected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
home-manager script requires $USER to be set. Docker RUN as root
does not automatically set this variable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
First install.sh run generates flake.lock in ~/dotfiles. The second
run's git stash fails because flake.lock is untracked/modified.
Commit it between runs to test idempotency correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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