--- title: "Cómo usar Taskfile como alternativa a Make en Ubuntu 24.04" description: "Instala Task en Ubuntu 24.04 y automatiza tu proyecto con un Taskfile.yml: dependencias, variables, .env, precondiciones, includes y CI en GitHub Actions." category: "Automatización Avanzada" language: es source: https://cubepath.com/es/docs/automatización-avanzada/taskfile-como-alternativa-a-makefile updated: 2026-09-25 --- # Cómo usar Taskfile como alternativa a Make en Ubuntu 24.04 Task es un ejecutor de tareas escrito en Go que lee sus instrucciones de un archivo `Taskfile.yml`. Cubre el uso más habitual de Make (tener a mano los comandos de compilar, probar y desplegar un proyecto) con una sintaxis YAML legible, variables explícitas y sin las trampas de los tabuladores ni de los objetivos que coinciden con nombres de archivo. En este tutorial instalarás Task en Ubuntu 24.04 y construirás paso a paso un Taskfile para un proyecto de ejemplo. Los ejemplos solo usan herramientas del sistema (`cp`, `tar`, `rsync`) para que puedas ejecutarlos sin instalar ningún lenguaje. En tu proyecto real sustituirás esos comandos por `go build`, `npm run build`, `pytest` o lo que corresponda. ## Requisitos previos - Un servidor o equipo con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con un usuario no root con privilegios `sudo`. - `git` instalado (algunas variables del ejemplo leen el commit actual). - Conocimientos básicos de YAML y de la terminal. ## Paso 1: Instalar Task El proyecto publica un paquete `.deb` en cada versión de GitHub. Descárgalo e instálalo con `apt`, que así queda registrado en el sistema y se puede desinstalar limpiamente: ```bash cd /tmp curl -fsSLO https://github.com/go-task/task/releases/latest/download/task_linux_amd64.deb sudo apt install -y ./task_linux_amd64.deb ``` En servidores arm64 usa `task_linux_arm64.deb`. Si prefieres actualizaciones automáticas, Task también está disponible como snap con `sudo snap install task --classic`. Comprueba la instalación: ```bash task --version ``` ```output Task version: v3.x.y ``` > Nota: el binario se llama `task`. No lo confundas con Taskwarrior, un gestor de listas de tareas que también usa ese nombre en algunos repositorios. Activa el autocompletado en bash añadiendo esta línea a tu `~/.bashrc`: ```bash echo 'eval "$(task --completion bash)"' >> ~/.bashrc source ~/.bashrc ``` ## Paso 2: Crear el proyecto de ejemplo y el primer Taskfile Crea un proyecto mínimo con un par de archivos fuente: ```bash mkdir -p ~/demo-task/src && cd ~/demo-task git init -q echo '

Hola desde Task

' > src/index.html echo 'body { font-family: sans-serif; }' > src/style.css git add . && git commit -qm "Primer commit" ``` Crea el `Taskfile.yml` en la raíz del proyecto: ```bash nano Taskfile.yml ``` ```yaml version: '3' vars: APP: demo-web DIST: dist tasks: default: desc: Mostrar las tareas disponibles cmds: - task --list build: desc: Copiar los fuentes a la carpeta de distribución cmds: - mkdir -p {{.DIST}} - cp -r src/. {{.DIST}}/ clean: desc: Borrar los archivos generados cmds: - rm -rf {{.DIST}} *.tar.gz ``` Las variables se referencian con la sintaxis de plantillas de Go, `{{.NOMBRE}}`. Solo las tareas con `desc` aparecen en `task --list`. Lista y ejecuta las tareas: ```bash task --list task build ``` ```output task: Available tasks for this project: * build: Copiar los fuentes a la carpeta de distribución * clean: Borrar los archivos generados * default: Mostrar las tareas disponibles task: [build] mkdir -p dist task: [build] cp -r src/. dist/ ``` Task muestra cada comando antes de ejecutarlo con el prefijo `task: [nombre]`. Si un comando falla, la tarea se detiene con el mismo código de salida, igual que Make. ## Paso 3: Evitar trabajo repetido con sources y generates Make decide si recompilar comparando fechas de archivos. Task hace lo mismo con `sources` y `generates`, pero por defecto compara sumas de verificación del contenido. Cambia la tarea `build`: ```yaml build: desc: Copiar los fuentes a la carpeta de distribución sources: - src/**/* generates: - '{{.DIST}}/index.html' cmds: - mkdir -p {{.DIST}} - cp -r src/. {{.DIST}}/ ``` Ejecuta la tarea dos veces seguidas: ```bash task build task build ``` ```output task: [build] mkdir -p dist task: [build] cp -r src/. dist/ task: Task "build" is up to date ``` La segunda vez no hace nada porque los fuentes no han cambiado. Modifica `src/index.html` y vuelve a ejecutarla para ver que se repite. Para forzarla aunque esté al día, usa `task --force build`. Task guarda las sumas en el directorio `.task/`; añádelo a tu `.gitignore`. ## Paso 4: Encadenar tareas con dependencias Una tarea puede depender de otras. Las indicadas en `deps` se ejecutan antes y **en paralelo**; si necesitas un orden estricto, llámalas desde `cmds` con `task:`. Añade una tarea que empaquete el resultado: ```yaml package: desc: Crear un tar.gz con la versión actual deps: [build] vars: COMMIT: sh: git rev-parse --short HEAD cmds: - tar -czf {{.APP}}-{{.COMMIT}}.tar.gz -C {{.DIST}} . - ls -lh {{.APP}}-{{.COMMIT}}.tar.gz ``` La variable `COMMIT` es dinámica: su valor es la salida del comando indicado en `sh`. Ejecuta el empaquetado: ```bash task package ``` ```output task: Task "build" is up to date task: [package] tar -czf demo-web-a1b2c3d.tar.gz -C dist . task: [package] ls -lh demo-web-a1b2c3d.tar.gz -rw-rw-r-- 1 usuario usuario 312 sep 25 10:00 demo-web-a1b2c3d.tar.gz ``` Para ver qué haría una tarea sin ejecutarla, usa `task --dry package`. ## Paso 5: Variables desde la línea de comandos y desde .env Las variables se pueden pasar al invocar Task, y tienen prioridad sobre las del Taskfile. Además, la clave `dotenv` carga archivos `.env` como variables de entorno. Crea un archivo `.env` con el destino del despliegue: ```bash echo 'DEPLOY_PATH=/tmp/demo-deploy' > .env ``` Añade `dotenv` al principio del Taskfile, justo después de `version`: ```yaml version: '3' dotenv: ['.env'] ``` Y una tarea de despliegue que exige una variable `ENV`: ```yaml deploy: desc: Publicar dist en DEPLOY_PATH (uso, task deploy ENV=staging) deps: [build] requires: vars: [ENV] preconditions: - sh: git diff --quiet msg: Hay cambios sin confirmar en git. Haz commit antes de desplegar. cmds: - mkdir -p "$DEPLOY_PATH/{{.ENV}}" - rsync -a --delete {{.DIST}}/ "$DEPLOY_PATH/{{.ENV}}/" - echo "Desplegado {{.APP}} en $DEPLOY_PATH/{{.ENV}}" ``` - `requires.vars` detiene la tarea si falta la variable, con un mensaje claro. - `preconditions` ejecuta comprobaciones previas; si alguna devuelve un código distinto de 0, muestra `msg` y aborta. - `$DEPLOY_PATH` es una variable de entorno que viene del `.env`, por eso se usa con la sintaxis del shell. Prueba primero sin la variable y después con ella: ```bash task deploy task deploy ENV=staging ``` ```output task: Task "deploy" cancelled because it is missing required variables: ENV task: Task "build" is up to date task: [deploy] mkdir -p "$DEPLOY_PATH/staging" task: [deploy] rsync -a --delete dist/ "$DEPLOY_PATH/staging/" task: [deploy] echo "Desplegado demo-web en $DEPLOY_PATH/staging" Desplegado demo-web en /tmp/demo-deploy/staging ``` Si tienes cambios sin confirmar, la precondición lo impedirá. Añade `.task/`, `dist/`, `*.tar.gz` y `.env` a `.gitignore` y haz commit para que el árbol quede limpio. ## Paso 6: Ejecutar una tarea solo cuando haga falta con status `status` es lo contrario de `preconditions`: si todos sus comandos terminan con éxito, la tarea se considera hecha y se omite. Es útil para pasos de preparación idempotentes: ```yaml setup: desc: Crear el .env a partir de la plantilla si no existe status: - test -f .env cmds: - cp .env.example .env ``` Con `.env` ya presente, `task setup` responde `task: Task "setup" is up to date` sin tocar nada. ## Paso 7: Dividir el Taskfile con includes En proyectos grandes conviene separar las tareas por área. Crea un Taskfile para las tareas de servidor: ```bash mkdir -p taskfiles nano taskfiles/servidor.yml ``` ```yaml version: '3' tasks: espacio: desc: Mostrar el espacio libre en disco cmds: - df -h / servicios: desc: Listar los servicios de systemd que han fallado cmds: - systemctl --failed --no-pager ``` Inclúyelo en el `Taskfile.yml` principal, al mismo nivel que `vars` y `tasks`: ```yaml includes: srv: taskfile: ./taskfiles/servidor.yml optional: true ``` Las tareas incluidas se invocan con el espacio de nombres como prefijo: ```bash task srv:espacio ``` ```output task: [srv:espacio] df -h / Filesystem Size Used Avail Use% Mounted on /dev/vda1 39G 4.2G 35G 11% / ``` Con `optional: true`, Task no falla si el archivo incluido no existe. ## Paso 8: Usar Task en GitHub Actions Como el Taskfile es la única fuente de verdad de cómo se compila el proyecto, el pipeline de CI solo tiene que instalar Task y llamar a las mismas tareas que usas en local. Crea `.github/workflows/ci.yml`: ```yaml name: CI on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Instalar Task uses: arduino/setup-task@v2 with: version: 3.x repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Empaquetar run: task package ``` En otros sistemas de CI instala el `.deb` del paso 1 en la imagen del runner o usa una imagen que ya incluya `task`. ## Taskfile frente a Makefile | Aspecto | Make | Task | |---|---|---| | Formato | Sintaxis propia, recetas con tabulador obligatorio | YAML | | Recompilar solo si hay cambios | Por fecha de archivos | Por suma de verificación (o fecha, con `method: timestamp`) | | Variables | Expansión en varias fases, difícil de depurar | Plantillas Go, dinámicas con `sh:` | | Archivos `.env` | No | `dotenv` | | Dependencias en paralelo | Con `make -j` | Por defecto en `deps` | | Disponibilidad | Preinstalado en casi todos los sistemas | Hay que instalar un binario | Si tu proyecto compila C o C++ y depende del grafo de archivos de Make, sigue con Make. Si lo usas solo como lista de comandos del proyecto, Task es más fácil de leer y mantener. ## Solución de problemas **`task: No Taskfile found`.** Task busca `Taskfile.yml` (o `Taskfile.yaml`, `taskfile.yml`) en el directorio actual y en los superiores. Comprueba el nombre del archivo o indica la ruta con `task --taskfile ruta/Taskfile.yml`. **Una variable aparece vacía.** Las variables del Taskfile y de la línea de comandos se usan con `{{.VAR}}`; las de entorno y las del `.env`, con `$VAR` dentro del comando. Revisa el comando final con `task --dry nombre`. **La tarea dice `is up to date` pero quieres ejecutarla.** Usa `--force`, o borra el directorio `.task/` para reiniciar todas las sumas de verificación. **Error de YAML al cargar el Taskfile.** Los valores que contienen `{{ }}` al principio o dos puntos deben ir entre comillas, por ejemplo `- '{{.DIST}}/index.html'`. ## Conclusión Tienes Task instalado y un Taskfile que compila solo cuando cambian los fuentes, empaqueta con el commit actual, despliega con variables obligatorias y precondiciones, se divide en archivos incluidos y se reutiliza tal cual en CI. Como siguientes pasos, traslada los comandos de tu `Makefile` actual tarea por tarea, usa `task --summary nombre` para documentar las tareas más complejas y añade `task --list` al README del proyecto.