CI/CD Python – Часть 3: идём дальше с Poetry, Docker и продвинутой публикацией
Опубликовано 19 July 2025
В первых двух частях этой серии мы имеем: - Успешно настроен рабочий CI/CD пайплайн для приложения Python с использованием GitHub Actions и PyPI. Осуществил индустриализацию этого пайплайна с помощью многоверсионных тестов, постепенного выпуска через Test PyPI и инструментов качества и безопасности.
В этой третьей части мы пойдемза пределами простой публикации на PyPIдля построения полной, надежной и профессиональной цепочки CI/CD: - поэзияpour современной упаковки и оптимизированного управления зависимостями. - Dockerдля создания воспроизводимых и кроссплатформенных сборок. - Условная публикациядля обработки сценариев, таких как кандидаты в релиз. - Инструменты автоматизации(Renovate, Dependabot) для поддержания пайплайна актуальным без усилий.
Интеграция с Poetry
Poetry заменяет старые инструменты пакетирования (setup.py, requirements.txt), централизуя управление зависимостями и сборкой в`pyproject.toml`.
Установка Poetry
# Installer Poetry
curl -sSL https://install.python-poetry.org | python3 -
# Vérifier la version
poetry --version
Инициализация проекта
# Initialiser un nouveau projet avec Poetry
poetry init
# Suivre l'assistant pour renseigner : nom, version, description, licence, dépendances.
Это создает файл`pyproject.toml`:
[tool.poetry]
name = "playlist-downloader"
version = "0.1.0"
description = "CLI tool for managing YouTube playlists"
authors = ["Christophe Hérolivier <[email protected]>"]
[tool.poetry.dependencies]
python = ">=3.8"
typer = "^0.9.0"
yt-dlp = "^2023.7.6"
google-api-python-client = "^2.0.0"
google-auth-oauthlib = "^1.0.0"
[tool.poetry.group.dev.dependencies]
pytest = "^7.0"
mypy = "^1.0"
bandit = "^1.7"
safety = "^2.3"
black = "^23.0"
ruff = "^0.1"
Добавление и установка зависимостей
poetry add typer yt-dlp google-api-python-client google-auth-oauthlib
poetry add --group dev pytest mypy black bandit safety ruff
Публикация с Poetry
Poetry управляет публикацией нативно :
# Publication sur Test PyPI
poetry publish --build --repository test-pypi
# Publication sur PyPI
poetry publish --build
Эта команда автоматически использует информацию, содержащуюся в`pyproject.toml`.
Воспроизводимые сборки с Docker
Для обеспечения одинаковых запусков в разработке, CI/CD и производстве Docker идеально интегрируется с Poetry.
Пример Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY pyproject.toml poetry.lock ./
RUN pip install poetry
RUN poetry install --no-root --only main
COPY . .
CMD ["poetry", "run", "python", "cli.py"]
Это гарантирует: - Фиксированное окружение Python. Заблокированные зависимости через`poetry.lock`. - Выполняемый образ на любой системе поддерживающей Docker.
Интеграция в GitHub Actions
name: Docker Build
on:
push:
branches: [main]
jobs:
build-docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t ghcr.io/${{ github.repository }}:latest .
- name: Push Docker image
run: docker push ghcr.io/${{ github.repository }}:latest
Условная публикация
В профессиональном пайплайне нужно иметь возможность публиковать только в определенных случаях : - Release candidates к Test PyPI. - Стабильные версии в PyPI. - Сборки Docker, запускаемые только для`main`.
- name: Publish to Test PyPI
if: contains(github.ref, '-rc')
run: poetry publish --build --repository test-pypi
- name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags/v')
run: poetry publish --build
Этот подход предотвращает случайные публикации.
Автоматизация зависимостей с помощью Renovate и Dependabot
Чтобы ваши зависимости не устарели, интегрируйте инструменты автоматического обновления.
Dependabot
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
Dependabot открывает PR каждую неделю для обновления зависимостей Python и GitHub Actions.
ремонтировать
{
"extends": ["config:base"],
"packageRules": [
{
"matchManagers": ["pip"],
"groupName": "python-dependencies",
"schedule": ["before 6am on monday"]
}
]
}
Renovate обеспечивает более тонкий контроль: группировка зависимостей, планирование и расширенные правила.
Диаграммы PlantUML
Вариант использования – продвинутый CI/CD
@startuml actor Developer actor GitHub as "GitHub Actions" actor PyPI actor DockerRegistry as "Реестр Docker" actor Automation as "Renovate/Dependabot" Developer --> (Push code) (Trigger CI) --> GitHub GitHub --> (Run Tests & Lint) GitHub --> (Build Docker Image) GitHub --> DockerRegistry GitHub --> (Publish to Test PyPI) GitHub --> (Promote to PyPI) Automation --> (Update Dependencies) @enduml
Последовательность – условная публикация
@startuml !theme vibrant left to right direction Developer -> GitHub: Push tag v1.2.3-rc GitHub -> CI: Run tests CI -> CD: Check release type CD -> Test PyPI: Publish RC Developer -> GitHub: Push tag v1.2.3 GitHub -> CD: Publish to PyPI CD -> Docker Registry: Push Docker image @enduml
Состояния – Конвейер CI/CD
@startuml [*] --> Idle Idle --> CI_Running : push CI_Running --> CI_Success : tests ok CI_Running --> CI_Failed : tests fail CI_Success --> CD_Running : tag detected CD_Running --> CD_Success : publish ok CD_Running --> CD_Failed : error CD_Success --> [*] @enduml
Развертывание – Архитектура CI/CD
@startuml
node "Машина разработчика" {
component "Клиент Git"
}
node "GitHub Actions" {
component "Рабочий процесс CI"
component "рабочий процесс CD"
}
node "Репозитории пакетов" {
artifact "Тест PyPI"
artifact "PyPI"
artifact "Реестр Docker"
}
"Машина разработчика" --> "GitHub Actions"
"GitHub Actions" --> "Тест PyPI"
"GitHub Actions" --> "PyPI"
"GitHub Actions" --> "Реестр Docker"
@enduml
Вывод
В этой третьей части мы видели, как: Модернизировать упаковку Python с Poetry. - Обеспечить воспроизводимые сборки через Docker. - Внедрить условную публикацию. - Автоматизировать обновление зависимостей.
Теперь у вас есть CI/CD-пайплайнполный, индустриализированный и защищённый, готовый к развитию вместе с вашими проектами.