Перейти к содержанию

Практикум: report-periods от шаблона до установленного пакета

Создаём report-periods из шаблона Bedrock, добавляем расчёт границ месяца в UTC, проверяем его, собираем версию 0.1.0 и устанавливаем оба формата пакета. Запускаемый пример к статье «Python-библиотека от шаблона до релиза».

Запуск

Нужны Git, uv и доступ к сети для загрузки шаблона, интерпретаторов Python и зависимостей. Запустите из корня репозитория сайта:

uv run --no-project --python 3.13 --with-requirements docs/blog/lab/2026-09-07-twelve-libraries-one-standard/requirements.txt python docs/blog/lab/2026-09-07-twelve-libraries-one-standard/generate_and_check.py --output build/report-periods-lab

Каталог результата не должен существовать. Без --output скрипт создаст новый временный каталог и сохранит его после завершения. Первым позиционным аргументом можно передать путь к локальной копии python-library-template; в ней должен быть коммит a1a1e7d5eafdcac08aeed7c1a0daaff31c67ac8c. Это избавит от загрузки шаблона, но для зависимостей сеть всё ещё может понадобиться. generate_and_check.sh просто вызывает тот же Python-скрипт из shell.

Практикум включает доверенный режим Copier для расширения Jinja и задачи после генерации в зафиксированном шаблоне. Эта задача только печатает инструкции. Скрипт создаёт локальный Git-репозиторий, чтобы изолировать правила игнорирования файлов. Он не делает коммитов, не меняет GitHub, не создаёт тегов и не загружает пакеты на PyPI.

Что проверяем

Этап Ожидаемый результат
Исходная заготовка Ruff, форматирование, mypy, один тест версии; выбор интеграционных тестов возвращает 5
Полезное поведение Семь тестов на Python 3.11, 3.12 и 3.13, включая перевод в UTC и переход года
Намеренные ошибки Ruff обнаруживает DTZ005; неверный переход из декабря ломает тест
Итоговое задание CI Условие вычисляется для всех 64 сочетаний результатов; проходит только полный успех, исходное пропускало ещё семь сочетаний с пропущенной задачей
Тег и версия Новый шаг публикации принимает два формата тега и отклоняет четыре значения, сверяясь с закоммиченной версией
Сборка Модули в wheel и sdist совпадают; метаданные и py.typed на месте
Потребитель Wheel и sdist установлены отдельно на Python 3.11; проверены изолированный импорт, публичный API и версия

Скрипт восстанавливает намеренно испорченные файлы, заменяет в созданном проекте итоговое задание CI и шаг публикации и локально воспроизводит изменения версии из релизного PR. GitHub Actions и Trusted Publishing он не запускает, а workflow публикации по-прежнему не ждёт CI на коммите с тегом.

Файлы и результаты

  • generate_and_check.py: генерация, проверки, намеренные ошибки, сборка и установка.
  • periods.py, test_periods.py: поведение библиотеки и шесть сценариев; с тестом версии из шаблона их семь.
  • ci-gate.yml: замена итогового задания; скрипт вычисляет его условие для всех сочетаний результатов.
  • release-check.yml: замена шага публикации, который перезаписывал __version__.py по тегу; скрипт исполняет его Python-код.
  • artifact_smoke.py: проверки установленного пакета в каждом чистом окружении.
  • requirements.txt: Copier 9.18.2, jinja2-time 0.2.0 и PyYAML 6.0.3.

В результате сохраняются report-periods/ с uv.lock и dist/, исходные YAML для CI и публикации, каталог потребителя, два чистых окружения, пронумерованные логи команд и report.json. Зависимости для разработки выбираются по ограничениям шаблона, а не фиксируются в requirements практикума; выбранные версии записываются в созданный lock-файл и отчёт. Проверочный запуск 16.10.2026 использовал uv 0.10.2, Ruff 0.17.1, mypy 2.4.0, pytest 9.1.1 и pytest-cov 7.1.0.