Промт для генерации GitHub Actions CI/CD пайплайнов

YAML для CI — благодарный жанр для генерации: структура жёсткая, ошибки видны сразу, цена проверки низкая. Но у сгенерированного по умолчанию пайплайна три типичные болезни: он ничего не кеширует, запрашивает больше прав, чем нужно, и ссылается на действия плавающими тегами.
Промт
Напиши workflow для GitHub Actions. ПРОЕКТ: [язык, версия, менеджер зависимостей] ЧТО ДЕЛАТЬ: линтер, тесты, сборка, [публикация образа / деплой] КОГДА ЗАПУСКАТЬ: [push в main, pull request, тег] ГДЕ РАЗВОРАЧИВАТЬ: [если есть] ТРЕБОВАНИЯ: 1. Действия закреплять по коммиту (uses: owner/action@) с комментарием версии рядом. Никаких @v3 и @main. 2. permissions задать явно на уровне workflow, минимально необходимые. Если нужен доступ на запись — только в том job, где он требуется. 3. Кеш зависимостей с ключом по хешу файла блокировки и разумным restore-keys. 4. Быстрые проверки отдельным job перед долгими: линтер и типы должны падать раньше тестов. 5. concurrency с отменой предыдущих запусков для одной ветки. 6. timeout-minutes на каждом job. 7. Секреты только через secrets, никогда не в echo и не в имени артефакта. 8. Матрица версий, только если она нужна, — не размножай сборки без причины. 9. Деплой — отдельный job с условием по ветке или тегу и с environment для ручного подтверждения. Прокомментируй каждый неочевидный блок одной строкой. Отдельно: что в этом пайплайне будет самым долгим и как это сократить.
Первое требование иногда вызывает споры: закрепление по SHA неудобно обновлять. Но действие, взятое по плавающему тегу, может измениться между запусками, а у него есть доступ к вашему репозиторию и секретам. Компромисс — закреплять по SHA и обновлять ботом обновления зависимостей.
Что обычно тормозит
| Причина | Что делать |
|---|---|
| Зависимости ставятся заново | Кеш по хешу lock-файла |
| Тесты идут одним потоком | Разделить по группам в матрицу |
| Docker собирается без кеша | Кеш слоёв между запусками |
| Полное клонирование истории | fetch-depth: 1, если история не нужна |
| Долгие шаги выполняются всегда | Условия по изменённым путям |
Промт для разбора медленного пайплайна
Вот workflow [вставить] и длительности шагов из последнего запуска [вставить]. Найди три самых дорогих места и объясни, из-за чего. Для каждого — вариант ускорения с оценкой выигрыша и риска. Отдельно: какие job можно выполнять параллельно, а какие обязаны идти последовательно и почему. Не предлагай убирать проверки ради скорости.
Безопасность, о которой стоит помнить
- Пул-реквесты из форков. Триггер
pull_request_targetвыполняется с правами целевого репозитория — в связке с checkout кода из форка это прямой путь к утечке секретов. Модель об этой тонкости часто не предупреждает. - Секреты в логах. GitHub маскирует известные значения, но производные от них — например, base64 — уже нет.
- Права токена. По умолчанию щедрые. Явные
permissionsс минимальным набором — самая дешёвая мера из всех. - Сторонние действия. Каждое — чужой код в вашем пайплайне. Чем их меньше, тем лучше; часть заменяется тремя строчками shell.
Проверка до коммита
- Синтаксис. Ошибку в YAML проще увидеть локально, чем ждать запуска.
- Прогон на черновой ветке. Не в main. Особенно если пайплайн умеет деплоить.
- Проверка условий. Убедитесь, что деплой действительно не запускается с обычной ветки, — до того, как это выяснится случайно.
- Повторный запуск. Второй прогон без изменений должен быть заметно быстрее первого. Если нет, кеш не работает.
Что не стоит автоматизировать сразу
Автоматический деплой в бой из main выглядит красиво и оправдан, когда есть тесты, которым доверяют, и отработанный откат. Пока их нет, полезнее промежуточный вариант: пайплайн собирает и готовит артефакт, а нажатие кнопки остаётся за человеком. Это не отсталость, а разумная последовательность — автоматизация выкладки имеет смысл после автоматизации проверки, а не до.