はじめに

私の dotfiles では、ローカルの dry-run と GitHub Actions で、設定の変更を確認できるようにしています。dotfiles の設定適用にはスクリプトを使っていたのですが、手を入れるうちにスクリプトとテストコードが増えてきました。

そこで、シンボリックリンクの作成・解除や、パッケージ・開発ツールの導入を mise bootstrap に寄せました。

この記事では、もともとスクリプトで行っていた処理と、mise に移したあとの設定やコマンドを紹介します。

1. もともとはスクリプトで導入・解除していた

当初、dotfiles のセットアップは PC のリプレイス時などに行う程度で、処理も単純でした。多機能な mise を使うとかえって構成や運用が複雑になると考え、install / uninstall 用のスクリプトを書いていました。やがて動作確認もしたくなり、dry-run や CI の整備にも手を広げました。

その結果、スクリプトやテストコードが増え、想定より構成が複雑になっていきました。シンプルにしたいと考えていたところで mise bootstrap を知り、それまでスクリプトで行っていた導入・解除の処理を任せることにしました。

2. dotfiles の配置とツールの導入を mise bootstrap にまとめる

mise bootstrap は、[dotfiles]、[bootstrap.packages]、[tools] などの設定をまとめて扱います。dotfiles だけを操作するには、mise dotfiles を使えます。

2-1. シンボリックリンクの配置先を [dotfiles] に書く

mise.toml の [dotfiles] に、どのファイルをどこへ配置するかを記述します。下記は一例です。

[dotfiles]
# "<target>" = { source = "<リポジトリをルートとした相対パス>", mode = "<symlink/シンボリックリンクなど指定したいモード>" }

"~/.dotfiles" = { source = ".", mode = "symlink" }
"~/.bashrc" = { source = ".bashrc", mode = "symlink" }
"~/.bash_profile" = { source = ".bash_profile", mode = "symlink" }
"~/.gitconfig" = { source = ".gitconfig", mode = "symlink" }
"~/.config/mise/config.toml" = { source = "mise.toml", mode = "symlink" }

各エントリに mode = "symlink" を明示して、シンボリックリンクで配置するようにしています。たとえば、~/.bashrc にはリポジトリ内の .bashrc へのリンクを作ります。リンクの作成・解除は mise に任せるので、dotfiles 側では配置先の設定をメンテすることになります。

2-2. パッケージや開発ツールを [bootstrap.packages] と [tools] に書く

Homebrew で導入する Git は、同じ mise.toml の [bootstrap.packages] に書いています。

[bootstrap.packages]
"brew:git" = "latest"

Node.js や Python のバージョンは [tools] に指定します。mise bootstrap を実行すると、パッケージの導入、シンボリックリンクの配置、開発ツールの導入をまとめて行えます。私の構成では、Makefile から mise bootstrap を呼び出しています。

3. 一連の操作を Makefile に集約する

Homebrew と mise のセットアップからインストール、状態確認、アンインストールまで、Makefile を共通のエントリポイントにしています。mise 導入後の操作は、Makefile から mise-operations.toml のタスクを経由して mise bootstrap などを呼び出します。

make setup           # Homebrew と mise を準備
make install         # install 内容を確認(dry-run)
make install-apply   # install する
make verify          # install できたか確認
make uninstall       # シンボリックリンクの解除対象を確認(dry-run)
make uninstall-apply # シンボリックリンクを解除

uninstall は実際にアンインストールするわけではなく、dotfiles のファイル群のシンボリックリンクを解除することに留めました。この点は「### 3-5. アンインストールではシンボリックリンクだけを解除する」で後述します。

3-1. 設定と操作を分ける

構成は次のようにしています。

Makefile
  make install / make install-apply / make verify
    │ mise run でタスクを呼び出す
    ▼
mise-operations.toml(操作用のタスク)
  dotfiles:install / dotfiles:install:apply / dotfiles:verify
    │ MISE_CONFIG_FILE で mise.toml を指定
    ▼
mise.toml(配置先・導入するものの設定)
  [dotfiles]           シンボリックリンクの配置先
  [bootstrap.packages] パッケージ
  [tools]              開発ツール

setup 以外の操作は mise-operations.toml のタスクを経由します。配置先や導入対象は mise.toml に置き、操作用のタスクとは分けています。

3-2. Makefile から操作用のタスクを呼び出す

Makefile では MISE_CONFIG_FILE に操作用の mise-operations.toml を指定し、mise run で対応するタスクを呼び出します。

MISE := mise
MISE_CONFIG := $(CURDIR)/mise-operations.toml
MISE_RUN = MISE_CONFIG_FILE="$(MISE_CONFIG)" MISE_TRUSTED_CONFIG_PATHS="$(CURDIR)" $(MISE)

.PHONY: install install-apply

install:
	$(MISE_RUN) run dotfiles:install

install-apply:
	$(MISE_RUN) run dotfiles:install:apply

3-3. タスクから mise.toml を読み込む

mise-operations.toml には、mise bootstrap を呼び出すタスクを定義しています。タスク内では MISE_CONFIG_FILE に mise.toml を指定し、dotfiles の配置先や導入するパッケージ・ツールの設定を読み込みます。

以下は、設定の主要部分を簡略化した例です。

[env]
DOTFILES = "{{ config_source | canonicalize | dirname }}"

[task_config]
dir = "{{ env.DOTFILES }}"

[tasks."dotfiles:install"]
run = 'MISE_CONFIG_FILE="$DOTFILES/mise.toml" mise bootstrap --dry-run'

[tasks."dotfiles:install:apply"]
run = 'MISE_CONFIG_FILE="$DOTFILES/mise.toml" mise bootstrap --yes'

DOTFILES には mise-operations.toml が置かれたディレクトリを設定し、タスクの実行ディレクトリにも指定しています。

mise.toml は ~/.config/mise/config.toml にシンボリックリンクで配置しますが、操作用の mise-operations.toml はグローバル設定にはせず、Makefile から明示的に指定しています。

3-4. dry-run、適用、状態確認を使い分ける

install 時は、適用内容の確認・実際の適用・適用後の状態確認でコマンドを分けています。

  • make install:mise bootstrap --dry-run で変更内容を確認する
  • make install-apply:mise bootstrap --yes で適用する
  • make verify:mise bootstrap status --missing で不足しているものを確認する

3-5. アンインストールではシンボリックリンクだけを解除する

アンインストールでは、環境全体を元に戻すのではなく、mise が管理しているシンボリックリンクだけを解除します。

  • make uninstall:mise bootstrap dotfiles unapply --dry-run で解除内容を確認する
  • make uninstall-apply:mise bootstrap dotfiles unapply --yes で管理しているシンボリックリンクを解除する

パッケージや開発ツールは残るため、環境全体を導入前の状態に戻す操作ではありません。

4. GitHub Actions では何を確認する?

GitHub Actions では、mise 自体の挙動をテストするのではなく、mise.toml の設定と Makefile からの呼び出しを組み合わせて、想定どおりに動作するかを確認しています。

主に、bootstrap の dry-run と、dotfiles の導入・解除を検証しています。

dotfiles の検証では、Ubuntu と macOS のそれぞれで一時的な HOME ディレクトリを用意し、シンボリックリンクの適用・状態確認・解除を一通り試しています。

パッケージやツールの実際の導入は行わず、dotfiles のファイルのシンボリックリンクの作成・解除に絞っています。

5. 補足:リポジトリに載せたくない設定

最後に、リポジトリに載せたくない設定の扱いにも少し触れておきます。Git の設定では、そうしたものを ~/.gitconfig.local に分け、リポジトリ内の .gitconfig から include で読み込んでいます。

[include]
    path = ~/.gitconfig.local

リポジトリには記入例として .gitconfig.local.example を置き、実際の値は手元の ~/.gitconfig.local に記入する形です。

6. まとめ

dotfiles の導入・解除に使っていたスクリプトの処理を mise に寄せました。dry-run と GitHub Actions で変更を確認する流れは残しつつ、シンボリックリンクの作成・解除やパッケージ、開発ツールの導入は mise に任せています。

7. 参考リンク