Taskfile : l'alternative moderne au Makefile en YAML

Le Makefile est omniprésent mais souffre de nombreuses subtilités : tabulations obligatoires, comportement différent selon l’OS, syntaxe archaïque. Taskfile propose la même fonctionnalité — définir des tâches exécutables depuis la ligne de commande — avec une syntaxe YAML moderne, un comportement cohérent sur tous les systèmes, et des fonctionnalités pensées pour les projets de développement actuels.

Ce que fait Taskfile

Taskfile (go-task/task) est un runner de tâches. Vous définissez dans un fichier Taskfile.yml à la racine du projet les commandes que l’équipe utilise fréquemment — build, test, deploy, migration, seed — et les exécutez avec task <nom>. Il gère les dépendances entre tâches, les variables, les conditions d’exécution, et les includes.

Installation

# macOS
brew install go-task

# Windows (Winget)
winget install Task.Task

# Windows (Scoop)
scoop install task

# Linux (script officiel)
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d

# Go
go install github.com/go-task/task/v3/cmd/task@latest

Taskfile.yml de base

version: "3"

tasks:
  default:
    desc: "Afficher les tâches disponibles"
    cmd: task --list

  dev:
    desc: "Démarrer le serveur de développement"
    cmd: npm run dev

  build:
    desc: "Compiler le projet"
    cmd: npm run build

  test:
    desc: "Lancer les tests"
    cmd: npm test

  lint:
    desc: "Vérifier le code"
    cmd: npm run lint

  clean:
    desc: "Supprimer les artefacts de build"
    cmd: rm -rf dist/ .cache/
task dev
task build
task --list   # affiche toutes les tâches avec leur description

Dépendances entre tâches

tasks:
  build:
    desc: "Build complet"
    deps: [lint, test]   # lint et test s'exécutent en parallèle avant build
    cmd: npm run build

  deploy:
    desc: "Déployer en production"
    deps: [build]
    cmd: rsync -avz dist/ user@serveur:/var/www/

  ci:
    desc: "Pipeline complet (comme en CI)"
    deps: [lint, test, build]

Par défaut, les dépendances s’exécutent en parallèle. Pour une exécution séquentielle :

tasks:
  setup:
    cmds:
      - task: install-deps
      - task: migrate-db
      - task: seed-db

Variables

version: "3"

vars:
  APP_NAME: mon-api
  DOCKER_REGISTRY: registry.mon-domaine.com
  VERSION:
    sh: git describe --tags --always  # valeur dynamique depuis une commande shell

tasks:
  docker-build:
    desc: "Construire l'image Docker"
    cmd: docker build -t {{.DOCKER_REGISTRY}}/{{.APP_NAME}}:{{.VERSION}} .

  docker-push:
    desc: "Pousser l'image Docker"
    deps: [docker-build]
    cmd: docker push {{.DOCKER_REGISTRY}}/{{.APP_NAME}}:{{.VERSION}}

Variables d’environnement et fichiers .env

version: "3"

dotenv: [".env", ".env.local"]  # chargement automatique des fichiers .env

tasks:
  migrate:
    desc: "Exécuter les migrations"
    cmd: npx prisma migrate deploy
    env:
      NODE_ENV: production
      DATABASE_URL: "{{.DATABASE_URL}}"  # depuis .env

Conditions d’exécution (sources / generates)

Taskfile peut éviter de reexécuter une tâche si les fichiers sources n’ont pas changé :

tasks:
  build:
    sources:
      - src/**/*.ts
      - package.json
    generates:
      - dist/**/*.js
    cmd: npm run build

Si dist/ est plus récent que tous les fichiers src/, task build affiche “Task is up to date” et ne reexécute pas le build.

Multi-plateforme

tasks:
  clean:
    desc: "Nettoyer les artefacts"
    platforms: [linux, darwin]
    cmd: rm -rf dist/ node_modules/.cache/

  clean:
    platforms: [windows]
    cmd: rmdir /s /q dist

Taskfile choisit automatiquement la bonne commande selon l’OS.

Taskfiles inclus (sous-fichiers)

Pour les projets monorepo ou complexes :

# Taskfile.yml (racine)
version: "3"

includes:
  api:
    taskfile: ./api/Taskfile.yml
    dir: ./api
  front:
    taskfile: ./front/Taskfile.yml
    dir: ./front
task api:dev    # exécute la tâche "dev" du Taskfile de l'API
task front:build

Tâches interactives et prompts

tasks:
  release:
    desc: "Créer une nouvelle release"
    vars:
      TAG:
        sh: echo "v$(date +%Y.%m.%d)"
    prompt: "Créer la release {{.TAG}} ?"
    cmds:
      - git tag {{.TAG}}
      - git push --tags

Exemple complet pour un projet Astro

version: "3"

vars:
  NODE_VERSION:
    sh: node --version

tasks:
  default:
    cmd: task --list

  install:
    desc: "Installer les dépendances"
    sources: [package.json, package-lock.json]
    generates: [node_modules/.package-lock.json]
    cmd: npm ci

  dev:
    desc: "Démarrer le serveur de dev (port 4321)"
    deps: [install]
    cmd: npm run dev

  build:
    desc: "Build de production"
    deps: [install]
    cmd: npm run build

  preview:
    desc: "Prévisualiser le build"
    deps: [build]
    cmd: npm run preview

  deploy:
    desc: "Déployer via FTP"
    deps: [build]
    cmd: |
      lftp -e "set ssl:verify-certificate no; \
               mirror -R --delete --parallel=5 dist/ $FTP_PATH; \
               quit" -u $FTP_USER,$FTP_PASS $FTP_HOST

  check:
    desc: "Vérifier types et build"
    cmds:
      - npx astro check
      - task build

Comparaison avec les alternatives

TaskfileMakefilenpm scriptsjust
SyntaxeYAMLPropriétaireJSONPropre
Multi-plateforme⚠️
Dépendances entre tâches
Parallélisme✅ (avec &)
Variables dynamiques✅ (complexe)
Fichier .env
Inclusions
Cache / sources

+ Les points forts

  • Syntaxe YAML lisible — accessible à toute l’équipe sans connaître les subtilités du Makefile
  • Multi-plateforme native — même Taskfile.yml sous Windows, macOS et Linux
  • Dépendances parallèles — lint et test s’exécutent simultanément avant le build
  • Variables dynamiques — calculer la version Git, l’IP locale, ou n’importe quelle valeur shell à la volée
  • Cache intelligent — ne reexécute pas un build si les sources n’ont pas changé

- Les points faibles

  • Moins universel que makemake est disponible partout par défaut. Taskfile doit être installé
  • Pas d’évaluation lazy des variables — toutes les variables sont évaluées au démarrage, pas à l’utilisation
  • Moins de puissance que make pour les règles de fichiers — les règles %.o: %.c du Makefile n’ont pas d’équivalent direct dans Taskfile

En résumé

Taskfile est le runner de tâches à adopter pour tout nouveau projet. Sa syntaxe YAML est compréhensible sans documentation par tous les membres de l’équipe, son comportement est cohérent sur tous les OS, et ses fonctionnalités couvrent les besoins du développement moderne. Un task --list suffit à documenter les commandes du projet.


Voir aussi :

  • Mise — garantir que toute l’équipe utilise les mêmes versions d’outils
  • git worktree — combiner Taskfile et worktrees pour les workflows multi-branches