こんにちは、 Omni Hub チームの shunten31 です.
先日は、 最適なアーキテクチャをどう描くか。|アーキテクチャConference 2025 に参加するために東京に行っており、 旅の疲れで少し体調を崩しています. 気温差の大きい時期なので、 皆さんも体調にはお気をつけください.
カンファレンス参加に関する記事も後日まとめる予定ですが、 今回は最近導入している タスクランナーについて書いていきます.
Taskfile とは
Taskfile.dev とは、 Makefile に代わるタスクランナーです.
Omni Hub チームではこれまで Makefile を使っていましたが、 最近 Taskfile への移行を進めています.
今回は、 なぜ Taskfile を使い始めたのか、 どのような恩恵を受けているのか、紹介します.
なぜ Taskfile か
Makefile は広く利用されている一方で、 以下のような制限があります.
これに対して、 Taskfile は、 上記の点を解決し、 一般に普及している yaml の syntax を用いて書け、 また機能的にモダンな開発フローにも対応できる機能を備えています.
メリット
タスクの説明を書いて LLM に優しく
タスクには、 desc で説明を書くことができます.
tasks: hello: desc: 挨拶をする cmd: echo "hello"
task list コマンドで、 利用可能なタスクの一覧が出ますが、 その際に説明も出力されます. 細かいところですが、 新しいメンバーのオンボーディングだけでなく、 LLM から利用する場合にも役立ちそうです.
task: Available tasks for this project: * hello 挨拶をする
不要なタスクは省略できる
タスクには sources, generates が存在しており、 これを指定しておくことでファイルのフィンガープリントを保存しておくことで、変更がなければタスクをスキップしてくれます.
tasks: install: sources: - package.json - package-lock.json generates: - node_modules/** cmd: npm ci
また、 ファイル生成以外の副作用のあるタスクに対しても、 status を使ってスキップ条件をかけます.
status コマンドの exit code が ゼロでない場合のみ、 タスクが実行されます.
下記は、 localstack の docker コンテナが起動していなければ起動するタスクになっています.
tasks: container-running: cmds: - docker compose up -d status: - docker ps --filter "status=running" --format '{{.Names}}' | grep -Eq 'localstack'
依存を記述し、 非同期で処理する
タスク間の依存関係は deps に記載できます. deps に記載された複数のタスクは 非同期で実行されることに注意が必要です.
tasks: assets: deps: [js, css] js: cmds: - esbuild --bundle --minify js/index.js > public/bundle.js css: cmds: - esbuild --bundle --minify css/index.css > public/bundle.css
順番に実行したい場合は、 cmds からタスクを呼び出すことで順番に処理できます.
tasks: main-task: cmds: - task: task-to-be-called - task: another-task - echo "Both done" task-to-be-called: cmds: - echo "Task to be called" another-task: cmds: - echo "Another task"
ファイル分割によって関心事を分離する
レポジトリがモノレポ形式で、サブディレクトリごとに別のシステムとなっている場合、 サブディレクトリごとに Taskfile.yml を作成することで、 タスクの管理が楽になります.
なお、 Taskfile から別の Taskfile の include もできるので、 ルートディレクトリにある Taskfile から、 サブディレクトリにあるTaskfile に定義されたタスクを呼び出すこともできます.
たとえば、 以下のようなファイル構成の場合, task hello-root で、 hello world と出力されます.
Taskfile.yml
includes: sub-a: taskfile: ./submodule_a/Taskfile.yml dir: ./submodule_a tasks: hello-root: cmds: - task: sub-a:hello
submodule_a/Taskfile.yml
hello: cmd: echo "hello world"
このように分離しておくと、 submodule_a から、その上位のディレクトリ構造に関する知識を排除できるメリットがあります.
デプロイに使う
Taskfile は、 GitHub Actions でも簡単に利用できます. 現在我々のチームでは、 徐々に Makefile を呼び出すデプロイから、 Taskfile を利用するデプロイに移行しています.
- name: Install Task uses: go-task/setup-task@v1
最後に
Taskfile を導入していく際には、少しつまずくところもありましたが、 Makefile より圧倒的にタスク定義がしやすいですし、 使いやすいツールと感じています.
皆さんも、 ぜひ利用してみてください!