Расскажу про автоматизацию рутинных задач, а точнее, про проект 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 - классная штука.
Пользуйтесь в проектах, рекомендуйте друзьям и коллегам.