miseとは
ミーズと読むらしいです。
miseは
- asdfやvoltaなどのバージョン管理ツール
- makefileやcargo-makeなどの環境変数・タスクランナー
を併せ持つツールです。
バージョン管理としてのmiseの記事はたくさん見つかりましたが、
タスクランナーとして使っている記事はあまりなかったので書いてみます。
バージョン管理ツールとしてのmiseは以下の記事を書いています。
(余談):自分はもともとcargo-makeを使っていました
もともとタスクランナーはcargo-makeというツールを利用していました。
cargo-makeも非常に便利で、環境変数管理やタスクを記述できるだけでなく、
cargo installできるコマンドがタスク実行時にinstallされていなければ自動的にinstallしてくるように設定できたり(install_create)、
タスクランナー内にrustのコードを記述できたりできます。
しかし、Rustのコードをmakefile内にインラインで記述したいことがあまりないのと、
intall_crateもmiseで同等のことを実現できるので移行してみました。
基本的な使いかた
基本的な記述
-
runで実行したいコマンドを埋め込みます。 -
aliasでtaskのaliasを貼れます。下の例ではmise run format:writeでもmise run fmtでも実行できるようになります。 - usageで引数を取れます。下記の例ではargという変数に設定しています。runで
${usage_{変数名}}とすることで使用できるようになります。 - dependsで指定したタスクは run より先に実行されます。複数指定可能です。それぞれのタスクは並列で実行されます。これらがすべて正常実行されると、その後にrunが走るようにすることができます。
-
descriptionでタスクの概要の説明を記述できます
[tasks."format:write"]
run = "cargo fmt ${usage_arg?}"
alias = "fmt"
usage = '''
arg "<arg>" default=""
'''
depends = ["task1", "task2"]
description = "cargo fmt"
タスクグループ
- タスクをまとめて実行できます。(下の例ではbefore-ci, ciというタスクがそれに当たります)
- 配列で指定した順に直列に実行されます。tasksで定義したタスクは並列で実行されます。
[tasks.build]
run = "cargo build ${usage_arg?}"
usage = '''
arg "<arg>" default=""
'''
[tasks."format:check"]
alias = "fmtc"
run = "cargo fmt --all -- --check"
[tasks.clippy]
alias = "c"
run = "cargo clippy --all --all-targets --all-features --locked -- -D warnings"
[tasks.test]
depends = ["before-ci"]
run = "cargo nextest run --workspace --status-level all"
[tasks.before-ci]
run = [
{ task = "compose-up-db" },
{ task = "migrate" },
]
[tasks.ci]
depends = ["before-ci"]
run = [
{ task = "build" },
{ tasks = [
"format:check",
"clippy",
"test",
] },
]
実行方法
タスクを記述して、mise runを叩くことで現在実行可能なタスクの一覧がfizzy finderで表示されます。
選択・実行します。
モノレポでの使い方
mise.tomlは再帰的に親を探索して、よしなにマージしてくれます。
そのため、親ディレクトリにhogeというタスクを定義しておけば 子のディレクトリでもhogeが使えます(子のmise.tomlでhogeを上書きすることも可能です)
自分はこれによって、git pushする前にbackend/, frontend/のそれぞれのコードについてCIで走らせているテスト等をパスすることを確認してからgit pushするようにしています。
まず、backend/, frontend/の中のタスクciでタスクを定義します。
[tasks.ci]
depends = ["before-ci"]
run = [
{ task = "build" },
{ tasks = [
"format:check",
"clippy",
"test",
] },
]
[tasks.ci]
run = [
{ tasks = [
"type-check",
"fmt:check",
"lint",
"check",
] },
]
その後、リポジトリルートのmise/tomlで これら二つを拾って、
これらを並列に実行できるようにbefore-pushのタスクを定義します。
リポジトリルートに宣言しておくことで、どこにいても mise run gitpush が実行できるようになります。
git rev-parse --abbrev-ref HEAD でHEADが指差しているブランチ名を取得して、そのブランチめがけてpushしています。
これで、formatterかけ忘れたからテスト落ちた!とかのうっかりが格段に減って嬉しいです。
[tasks."frontend:ci"]
description = "ci for frontend"
dir = "frontend"
run = "mise run ci"
[tasks."backend:ci"]
description = "ci for backend"
dir = "backend"
run = "mise run ci"
[tasks.before-push]
run = [
{ tasks = ["frontend:ci", "lint:ci", "backend:ci"] },
]
[tasks.gitpush]
depends = ["before-push"]
run = '''
branch=$(git rev-parse --abbrev-ref HEAD)
git push origin $branch
'''
GitHubActionsでのmise
miseをCIで使いたいひとのために公式がactionを用意してくれています。
READMEに丁寧に記載してくれているのでほとんどのことは読めばわかります。
モノレポの場合はworking_directoryを設定する必要があるのと、
cache_key_prefixを設定しないと複数miseを使ってactionsを回した時にcachekeyがコンフリクトするので注意してください。
あとは以下のようにinstall: true, cache: trueを設定しておくだけで、mise.tomlの[tools]で記載したものたちが勝手にinstallされ、
初回以降では勝手にcacheしてくれてinstallがスキップされます。とても便利です。
あとは定義したタスクを実行するでもmise installしたコマンドを実行するでもなんでもできるようになります。
jobs:
build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v3
with:
version: 2025.11.4
install: true
cache: true
cache_key_prefix: "mise-cache-frontend"
experimental: false
working_directory: frontend
終わりに
もっと良い使い方があればコメントください!
