# https://taskfile.dev version: '3' vars: PROJECT: "transcriber" # База диффа для шагов, которым нужна разница с основной веткой. BASE: '{{.BASE | default "origin/master"}}' # Пути скриптов проверки. Умолчания — канонические пути маркетплейса, чтобы # переустановка плагина не меняла Taskfile. Шаги независимы: каждый ловит # дрейф своего каталога, и выпадение одного не подменяется другим. # # Недостающий скрипт — отказ окружения у всех обёрток ниже, и код у него 3 по # общему словарю (CLAUDE.md, раздел «Гейт»). Прежний код 1 значил «дрейф» и # отправлял читателя искать разъехавшееся там, где просто неполно дерево. Сам # `task` отдаёт наружу свой 201 на любой отказ шага, поэтому словарь читается # по коду скрипта, а не по коду `task`. DOCS_PY: '{{.DOCS_PY | default "~/.claude/plugins/marketplaces/av-dev-skills/av-dev-docs/skills/canon/scripts/docs.py"}}' TASKS_PY: '{{.TASKS_PY | default "~/.claude/plugins/marketplaces/av-dev-skills/av-dev-tasks/skills/tasks/scripts/tasks.py"}}' OPENSPEC_PY: '{{.OPENSPEC_PY | default "~/.claude/plugins/marketplaces/av-dev-skills/av-dev-code/skills/openspec/scripts/openspec.py"}}' tasks: gate: desc: 'Все проверки разом. База диффа: task gate BASE=' cmds: - go build ./... - go vet ./... - | unformatted=$(gofmt -l .) if [ -n "$unformatted" ]; then echo "$unformatted" echo "gofmt: файлы выше не отформатированы" exit 1 fi - go test ./... - golangci-lint run - task: go-version - task: docs - task: tasks - task: openspec # Последним: единственный шаг, которому нужна сеть, и самый долгий. - task: vulns go-version: desc: 'Одна версия Go в go.mod, Dockerfile, CLAUDE.md и README.md' cmds: # Скрипт лежит в самом репозитории, а не в плагине: его отсутствие значит # сломанное дерево, а не непоставленный плагин, и переопределять путь # нечем и незачем. Код отсутствия — 3, как у прочих обёрток. - | py=scripts/check-go-version.sh if [ ! -f "$py" ]; then echo "$py не найден: дерево репозитория неполно" exit 3 fi sh "$py" docs: desc: 'Раскладка docs/ против канона' cmds: # Шаг обязан краснеть внятно, если скрипта нет, а не пропускаться молча. - | py=$(eval echo {{.DOCS_PY}}) if [ ! -f "$py" ]; then echo "docs.py не найден: $py" echo "поставь плагин av-dev-docs либо задай путь: task docs DOCS_PY=<путь>" exit 3 fi python3 "$py" check --base {{.BASE}} tasks: desc: 'Согласованность каталога задач' cmds: - | py=$(eval echo {{.TASKS_PY}}) if [ ! -f "$py" ]; then echo "tasks.py не найден: $py" echo "поставь плагин av-dev-tasks либо задай путь: task tasks TASKS_PY=<путь>" exit 3 fi python3 "$py" check --dir tasks openspec: desc: 'Форма openspec/config.yaml' cmds: - | py=$(eval echo {{.OPENSPEC_PY}}) if [ ! -f "$py" ]; then echo "openspec.py не найден: $py" echo "поставь плагин av-dev-code либо задай путь: task openspec OPENSPEC_PY=<путь>" exit 3 fi python3 "$py" check --dir . vulns: desc: 'Достижимые из кода уязвимости в зависимостях' cmds: # `govulncheck` — внешний инструмент, а не плагин и не файл репозитория: # ставится `go install golang.org/x/vuln/cmd/govulncheck@latest`. Его # отсутствие — отказ окружения, код 3, как у прочих обёрток. # # Свой код 3 у самого инструмента значит «уязвимость найдена» и с кодом # обёртки совпадает; различает их сообщение — обёртка называет недостающий # инструмент. Шагу нужна сеть: база уязвимостей живёт на vuln.go.dev, и без # сети шаг краснеет, а не пропускается молча. - | if ! command -v govulncheck >/dev/null 2>&1; then echo "govulncheck не найден в PATH" echo "поставь: go install golang.org/x/vuln/cmd/govulncheck@latest" exit 3 fi govulncheck ./... # Контракт роли app_image (pet-project-server): собрать полный образ и затегать # его $BUILD_ID. Деплой целиком: `inv pl -- transcriber` в pet-project-server. image: desc: 'Docker-образ. Тег из $BUILD_ID (по умолчанию dev)' cmds: - docker build --pull --file Dockerfile --tag "{{.PROJECT}}:${BUILD_ID:-dev}" .