Собери файл .github/workflows/ci.yml по описанию проекта ниже. Верни готовое содержимое файла одним блоком YAML.
Стек: [СТЕК: Python, FastAPI, зависимости из pyproject ставятся командой pip install -e ".[dev]", тесты на pytest, линтер ruff]
Триггеры: [ТРИГГЕРЫ: push в main и любой pull request в main]
Шаги: [ШАГИ: ruff check, mypy, pytest с отчётом покрытия, сборка Docker-образа без публикации]
Раннер: [РАННЕР: ubuntu-latest, матрица по версиям языка 3.10, 3.11 и 3.12]
Требования: каждый шаг — рабочая команда, а не заглушка; кеш зависимостей включён и привязан к файлу, где они перечислены; у каждого `uses` закреплена мажорная версия; токены и пароли только через ${{ secrets.ИМЯ }}; комментарий строкой выше — только там, где шаг неочевиден.
Отсечка. Не выдумывай названия и версии действий: не уверен, что action существует именно под таким именем, — замени шаг обычным `run` с командой из моего стека. Не подставляй `echo "здесь будут тесты"` вместо настоящего запуска и не добавляй того, чего нет в списке шагов: деплоя, публикации образа, уведомлений в мессенджер.
Проверка. Пройди по готовому файлу сверху вниз и убедись: отступы кратны двум пробелам, у каждого job есть runs-on, каждый шаг из моего списка встречается ровно один раз. Отдельным списком под файлом перечисли все секреты, которые нужно завести в репозитории, — по одному имени в строке. Если какой-то шаг не удалось выразить командой, не молчи: вынеси его строкой «не покрыто» и укажи, чего не хватает.
Собрать под себя — поля заполнены рабочими значениями, меняйте их и промпт выше обновится сам