Как настроить действия GitHub и интеграцию PyPI для проектов Python
5 сентября 2024 г.Как использовать действия GitHub и создать интеграцию с pypi для проектов Python
Введение
Когда я создавал свой первый пакет Python,dataclass-sqlalchemy-mixins
(гитхабилиpypi), я столкнулся с интересной проблемой:
как настроитьCI/CD
на GitHub, чтобы гарантировать, что ничего не сломается, когда я публикую новые изменения, и автоматически публиковать кодPyPI
. Я обсуждал, как опубликовать свой собственный пакет, используяpoetry
в этомстатья.
Обычно для проверки любого коммита, сделанного в главной ветке посредством запроса на извлечение, необходимо запустить тесты.
Кроме того, полезно использовать линтеры для проверки стиля кода, особенно когда над проектом работают несколько разработчиков.
*CI (непрерывная интеграция) — практика автоматического создания и тестирования изменений кода после их слияния в репозиторий.*
*CD (непрерывная доставка) — автоматизированная доставка кода в среду разработки или производства*
Создание рабочих процессов
GitHub поддерживает действия, которые представляют собой автоматизированные процессы, способные выполнять одну или несколько задач, включаяCI/CD
трубопроводы.
Подробнее о них можно прочитать вДокументация GitHub.
Рабочие процессы — это то, что GitHub будет запускать в соответствии с вашей конфигурацией. Они должны быть расположены в.github/workflows
каталог и быть.yaml
файлы.
Например, если мы хотим запускать тесты после каждого коммита, нам нужно создать файл с именемtest.yml
.
Я выбрал имяtest
для удобства и для указания того, что этот конкретный рабочий процесс отвечает за тесты, но это может быть что угодно.
name: "Test"
on:
pull_request:
types:
- "opened"
- "synchronize"
- "reopened"
push:
branches:
- '*'
workflow_dispatch:
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
id: setup-python
uses: actions/setup-python@v5
with:
python-version: 3.12
- name: Cache poetry install
uses: actions/cache@v4
with:
path: ~/.local
key: poetry-${{ steps.setup-python.outputs.python-version }}-1.7.1-0
- uses: snok/install-poetry@v1
with:
version: 1.7.1
virtualenvs-create: true
virtualenvs-in-project: true
- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}
- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction
- name: Run tests
run: poetry run pytest --cov-report=xml
Позвольте мне объяснить ключевые элементы файла:
name
- Это название рабочего процесса.pull request
- Указывает типы запросов на извлечение, которые запускают рабочий процесс. Рекомендуемые значения по умолчанию:opened
,synchronize
, иreopened
.Подробнее об этих типах вы можете прочитатьздесь.
push
- Указывает ветви, запускающие рабочий процесс.jobs
- Рабочий процесс может состоять из одного или нескольких заданий, которые по умолчанию выполняются параллельно, но также могут быть настроены на последовательное выполнение.
Я хотел бы обсудить, что происходит во время выполнения заданий с этим кодом.
Во-первых, имя задания может использоваться для настройки наборов правил для репозитория или определенных ветвей. В этом случае единственное задание, которое будет запущено, — это test. Подробности наборов правил будут рассмотрены позже.
Theruns-on
ключ указывает, в какой операционной системе будут выполняться задания.
Стратегия настройки:fail-fast: false
означает, что GitHub не будет отменять все текущие и поставленные в очередь задания вmatrix
если какая-либо работа в матрице не выполняется.
Thematrix
параметр будет рассмотрен позже.
Как вы можете видеть, в коде много похожих кодов.uses
введите шаги. Например:
actions/setup-python@v5
actions/cache@v4
snok/install-poetry@v1
На первый взгляд названия действий могут показаться запутанными, но на самом деле это пути к репозиториям GitHub для этих действий,
исключая@v
часть.
Например, вы можете просмотреть исходный код первого действия, посетивhttps://github.com/actions/setup-python
.
То же самое можно сделать и для других действий.@v
используется для указания того, какую версию действия следует использовать.
Ключ with используется для передачи параметров действию.
Например, если мы хотим установитьPython 3.12
, мы проходимpython-version: 3.12
вSet up Python 3.12
шаг. Тот же подход применим и к другим шагам.
Короче говоря, тестовое задание выполняет следующие шаги:
- Устанавливает
Python
с требуемой версией. - Устанавливает
Poetry
1.7.1 зависимость с использованием кэша GitHub. - Создает Python .venv в корневом каталоге, если кэш не найден. Кэш виртуальной среды зависит от
Python
версия иpoetry.lock
. - Если кэшированная виртуальная среда не найдена, устанавливаются зависимости проекта.
- Проводит тесты.
Использование служб в рабочих процессах
Созданный рабочий процесс довольно прост и может не подойти для тестирования более сложных приложений или проектов.
Это связано с тем, что такие проекты часто требуют, чтобы такие сервисы, как базы данных или кэширование, функционировали правильно. Хотя можно писать тесты, которые имитируют запросы к этим сервисам, я бы не рекомендовал этого делать, так как это может снизить эффективность тестового покрытия.
Я продемонстрирую, как включить услугу в рабочий процесс, используяPostgreSQL
в качестве примера.
jobs:
test:
services:
postgres:
image: postgres:latest
env:
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
Добавлениеservices
ключ с требуемым именем сервиса позволяет настроить его во время работы.
Более того, вы можете передавать ему настройки аналогично при использованииdocker
.
Использование нескольких параметров во время выполнения задания
И последнее, но не менее важное — ситуация, когда вам необходимо выполнить задание с использованием других параметров.
Например, вам может потребоваться выполнить задание с несколькими конкретнымиPython
версии, а не только последние, или с различными зависимостями.
Это может быть особенно полезно, когда вам необходимо обеспечить обратную совместимость со старыми зависимостями.GitHub
дает стратегический ключ для решения этой проблемы.matrix
параметр позволяет запустить задание с несколькими значениями.
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12"]
sqlalchemy-version: ["1.4.52", "2.0.31"]
Задание с матрицей, настроенной таким образом, будет сравнивать каждое значение списка параметров с каждым другим значением.
В результате будет четыре запуска задания со следующими комбинациямиPython
иSQLAlchemy
версии соответственно:
3.11
,1.4.52
3.11
,2.0.31
3.12
,1.4.52
3.12
,2.0.31
Вы можете получить доступ к параметрам в ходе выполнения задания, используя${{ matrix.python-version }}
или${{ matrix.sqlalchemy-version }}
.
- name: Set up Python ${{ matrix.python-version }}
id: setup-python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install sqlalchemy ${{ matrix.sqlalchemy-version }}
run: pip install sqlalchemy==${{ matrix.sqlalchemy-version }}
Использование наборов правил GitHub
Но иногда простого выполнения заданий по вашему проекту недостаточно.
Бывают ситуации, когда вам может потребоваться ограничить слияние коммитов в ветке master. Хотя это может быть необязательно, когда вы работаете над проектом в одиночку, это настоятельно рекомендуется, когда несколько человек работают над одной и той же кодовой базой. Это помогает предотвратить ситуации, когда кто-то случайно объединяет коммит, который нарушает код, даже если конвейеры выходят из строя.
GitHub предоставляет для этого полезный инструмент, называемый наборами правил.
Доступ к нему можно получить из меню настроек репозитория по адресуhttps://github.com/{Author}/{Repository}/settings/rules
.
После создания нового набора правил прокрутите вниз доRequire status checks to pass
, включите его и укажите, какие задания необходимо сдать.
Чтобы найти проверку, введите название нужной работы, и GitHub предоставит предложения.
Обратите внимание, что каждая работа в матрице будет иметь свое собственное название, что позволит вам выбирать их по отдельности.
Публикация в pypi
В последней части я хотел бы рассказать о том, как создать интеграцию с pypi и публиковать новые версии с релизом.
Для этого необходимо создать новый файл Yaml с рабочими процессами публикации.
name: Upload Python Package to PyPi on release
on:
release:
types: [published]
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/dataclass-sqlalchemy-mixins/
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.x'
- uses: snok/install-poetry@v1
with:
version: 1.7.1
virtualenvs-create: true
virtualenvs-in-project: true
- name: Build package
run: poetry build
- name: Publish package
uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
Этот рабочий процесс:
- Устанавливает
Python
. - Устанавливает
Poetry
1.7.1 зависимость с использованием кэша GitHub. - Создайте исходный код и архивы колес.
- Публикует пакет в pypi
Да, это так просто, как кажется.
Вам просто нужно добавитьPYPI_API_TOKEN
в хранилище секретов(https://github.com/{Author}/{Repository}/settings/secrets/actions
).
Наконец, создайте новый релиз (https://github.com/{Author}/{Repository}/releases
), и пакет будет загружен.
Оригинал