Taskfile - новый стандарт локальных сценариев
Расскажу про автоматизацию рутинных задач, а точнее, про проект taskfile.dev.
Историческая справка
В 1976 году (почти 50 лет назад!) была создана утилита make, которая по сей день прекрасно выполняет свою задачу.
Разработчик может описать какие-то шаблонные действия в файле Makefile и получить набор именованных сценариев.
Набираем make build, и оно собирается.
Набираем make test, и оно тестируется.
Благолепие.
Makefile устарел
В современной разработке, с Makefile встречается ряд неудобств:
Адепты env-подхода из 12-factor app могут встретить сложности в сценариях, когда нужно использовать значение из env-переменной или, если его нет, то значение по умолчанию
Нет возможности группировать сценарии, вроде
build:all, который включал бы в себяbuild:deb, и прочиеbuild:dockerнадо писать отдельный сценарийbuild-allи вручную поддерживать актуальный список наследниковНет механизмов дедупликации, чтобы не гонять дважды одну и ту же долгую сборку, когда поменялся только README
И, наконец, нет удобных свистоперделок!
В общем, ручная дрель делает свою работу, но каким-то условным перфоратором от Bosch (у меня такой) оно как-то сподручней.
И вот приходит Taskfile
На этот прекрасный проект я наткнулся в октябре 2022 года.
Вот тут его GitHub: go-task/task. Конечно же, там внутри Golang.
Суть проекта сводится к попытке пересмотреть Makefile на более современный лад.
Ставится в виде одного бинаря, обычно пакет называется task или go-task, из-за пересечения с проектом Taskwarrior.
Что Taskfile умеет?
Ну, во-первых, теперь надо писать не странный свой-собственный-синтаксис, а прекрасный/богомерзкий YAML.
Оно умеет в глобальные и per task env-переменные, а также в .env-файлы:
env:
ENV: testing
GREETING: Hey, there!
dotenv:
- '.env'
- '{{.ENV}}/.env.'
- '{{.HOME}}/.env'
tasks:
greet:
cmds:
- 'echo "$ENV: $GREETING"'
Оно умеет в platform-specific таски:
tasks:
build-windows:
platforms:
- windows
cmds:
- echo 'Running command on Windows'
Оно умеет в зависимости, когда мы хотим выполнить таску test только после таски build:
tasks:
build:
deps: [assets]
cmds:
- go build -v -i main.go
assets:
cmds:
- minify -o public/style.css src/css
Оно умеет в предусловия, когда мы хотим перед выполнением таски build проверить, что в системе есть всякие там gcc, make и прочие maven-ы:
tasks:
up:
dir: '{{.USER_WORKING_DIR}}'
preconditions:
- test -f docker-compose.yml
cmds:
- docker-compose up -d
Ну и множество всего другого прочего, дока с примерами доступна по ссылке.
Реальный пример
Вот живой кусок из одного pet-проекта:
---
version: '3'
vars:
KUBE_CONTEXT: my-k8s
KUBE_CONFIG: ~/.kube/my-k8s.yaml
tasks:
secrets:seal:
desc: Seal secrets
deps: []
preconditions:
- kubeseal --version
- test -f kubernetes/config.secret.yaml
cmds:
- >-
kubeseal \
--context {{.KUBE_CONTEXT}} \
--controller-name sealed-secrets -o yaml \
< kubernetes/config.secret.yaml \
> kubernetes/config.sealedsecret.yaml
sources:
- ./kubernetes/*.secret.yaml
generates:
- ./kubernetes/*.sealedsecret.yaml
...
Кажется, всё интуитивно понятно:
- По
task secrets:sealпроизойдет запечатывание секретов - Команда
kubesealбудет вызвана с нужным kubernetes context - Команда не будет повторяться, если не поменялись source-файлы или если уже существуют актуальные generated-файлы
Разве что в последнем пункте надо знать, что актуальность будет проверена по timestamp generated vs source.
Примеры запуска
Список сценариев:
> task --list
task: Available tasks for this project:
* dev: Run dev mode
* secrets:seal: Seal secrets
Обзор отдельной команды:
> task secrets:seal --summary
task: secrets:seal
Seal secrets
commands:
- kubeseal \
--context my-k8s \
--controller-name sealed-secrets -o yaml \
< kubernetes/config.secret.yaml \
> kubernetes/config.sealedsecret.yaml
Выполнение таски:
> task secrets:seal
task: [secrets:seal] kubeseal \
--context my-k8s \
--controller-name sealed-secrets -o yaml \
< kubernetes/config.secret.yaml \
> kubernetes/config.sealedsecret.yaml
Или, если уже запечатано, то:
> task secrets:seal
task: Task "secrets:seal" is up to date
А если не выполняется какое-то условие, то ошибочка:
> task secrets:seal
task: `kubeseal --version` failed
task: precondition not met
Подытожим
Taskfile - классная штука.
Пользуйтесь в проектах, рекомендуйте друзьям и коллегам.