Как интегрировать GitHub Actions и CI/CD в ваш следующий проект Python

Как интегрировать GitHub Actions и CI/CD в ваш следующий проект Python

13 февраля 2022 г.

Введение


В этой статье мы собираемся создать базовый конвейер CI/CD для типичного пакета Python. Текст сосредоточен на практических аспектах, и его должно быть достаточно для начала.


Что такое CI/CD


Пролистайте этот абзац, если вы ветеран.


CI/CD означает непрерывная интеграция/непрерывное развертывание. Это подход к разработке программного обеспечения, целью которого является создание и развертывание кода при каждом изменении (т. е. постоянно).


Преимущества конвейера CI/CD


Хотя внедрение автоматического рабочего процесса может быть технической проблемой для непривычной команды, оно дает достаточно преимуществ, чтобы обеспечить значительную окупаемость инвестиций. К ним относятся:


  • Вы можете автоматизировать скучные, повторяющиеся, ручные действия

  • Качество можно поддерживать за счет внедрения автоматических проверок (статический анализ, линтинг, тестирование)

  • Разработка может происходить быстрее, если у вас есть процессы

  • Инженеры могут сосредоточиться на фактической разработке

Что должен содержать конвейер?


Этапы хорошего конвейера непрерывной интеграции


Я провел опрос среди разработчиков, с которыми работал, чтобы достичь разумного консенсуса в отношении того, что следует автоматизировать в конвейере непрерывной интеграции. Мы основываем наши стандарты на двадцати пяти ответах в опросе.


CI/CD tools (free!)


Хорошо, это звучит здорово, но сколько я заплачу за все это? Могу ли я использовать это в личном проекте? Будет ли это дорогостоящим выбором для моей компании?


К счастью, в эпоху SaaS внедрение автоматизированного конвейера CI/CD проще и дешевле, чем когда-либо.


GitHub и Gitlab поддерживают конкурирующие механизмы рабочих процессов: GitHub Actions и Gitlab CI. Эта статья посвящена использованию первого.


Сколько это стоит? Это бесплатно! Ну, по крайней мере, до какого-то момента. В обоих продуктах пайплайны для публичных проектов бесплатны. Для частных есть бесплатная квота CI-минут. Если вам нужно больше, вам нужно заплатить или развернуть runner в своей собственной инфраструктуре.


Давайте напишем конвейер!


Кодинг — это преувеличение. Давайте определим наши шаги CI/CD в файле yaml.


Если вы решите расширить конвейер, вы можете разделить его конфигурацию на несколько файлов рабочего процесса. В нашем случае достаточно одного файла.


Вы можете изучить окончательный код и образец кода пакета Python, который использовался на [github] (https://github.com/horosin/python-standard-ci).


Секреты


Мы собираемся определить несколько секретных переменных для аутентификации с помощью внешних сервисов. Всякий раз, когда вы видите следующее в yaml ниже


секреты.SECRET_NAME


определите секрет в настройках вашего проекта. Просто перейдите в «Секреты» > «Действия» и нажмите «Новый секрет репозитория». Вы также можете определить секреты на уровне команды.


Определение рабочего процесса


Стандартная конфигурация рабочего процесса должна включать имя и условия, запускающие действия, описанные в файле. Наш ключ «on» указывает, что конвейер будет запускаться при отправке в основную ветку.


``ямл


имя: Рабочий процесс Python


на:


толкать:


ветки: [ мастер ]


Конфигурация задания


Далее нам нужно настроить детали задания. Мы называем нашу работу python_ci и говорим, что она должна работать под последней версией Ubuntu.


``ямл


вакансии:


python_ci:


запуски: ubuntu-последняя


стратегия:


матрица:


Python-версия: [3.7]


Вы можете заметить параметр matrix в конфигурации. Он используется для указания стратегии запуска конвейера в разных средах с разными конфигурациями. Я запускаю код только в Python 3.7, но вы можете добавить больше версий, просто добавив элементы в массив — [3.7, 3.8, 3.9].


Базовая настройка


Во-первых, нам нужно получить код нашего проекта и настроить Python. Мы можем сделать это, используя готовые шаги конвейера, предоставленные GitHub. Всякий раз, когда шаг содержит ключевое слово uses, он использует шаг, сделанный кем-то другим. Относительные пути к репозиторию указываются для ключевого слова uses и следуют формату {user}/{step-name}@{version}.


``ямл


шаги:


  • использует: action/checkout@v2

  • имя: Настройка Python ${{ matrix.python-version }}

использует: действия/настройка-python@v2


с участием:


Python-версия: ${{ matrix.python-версия }}


Установить зависимости


Затем нам нужно установить зависимости. Чтобы сделать эту конфигурацию применимой к большему количеству проектов, я явно устанавливаю flake8 и pytest, если они не включены в файл requirements.txt. Файл будет использоваться, если он существует.


``ямл


  • имя: Установить зависимости

запустить: |


python -m pip install --upgrade pip


python -m pip установить flake8 pytest


если [ -f требования.txt ]; затем pip install -r requirements.txt; фи


Ворс


Давайте тогда проверим наш код. Flake8 проверит наличие очевидных ошибок, плохого стиля кода и подозрительных конструкций кода. Первый вызов проверяет наличие критических ошибок. Второй ищет некритические ошибки и выводит только предупреждения.


``ямл


  • название: Lint with flake8

запустить: |


чешуйка8 . --count --select=E9,F63,F7,F82 --show-source --statistics


чешуйка8 . --count --exit-zero --max-complexity=10 --max-line-length=120 --statistics


Контрольная работа


Другой важной частью конвейера является тестирование. В этом случае я предполагаю, что вы используете pytest для запуска своих проверок. Я также сохраняю отчет о покрытии в формате xml, чтобы позже загрузить его в службу отслеживания результатов теста. При необходимости измените это соответствующим образом.


``ямл


  • имя: Тест с помощью pytest

запустить: |


pytest --cov --cov-отчет = xml


Отслеживание покрытия с помощью codecov


Взгляд на панель управления Codecov


Если вы не знакомы с Codecov, обязательно [проверьте!] (https://about.codecov.io). Это отличный инструмент для отслеживания результатов тестирования, улучшения качества и предоставления полезных показателей. Мы используем готовый шаблон действия codecov/codecov-action@v1 и снабжаем его необходимой конфигурацией.


``ямл


  • название: Загрузить покрытие в Codecov

среда:


CODECOV_TOKEN: ${{ секреты.CODECOV_TOKEN }}


если: ${{ env.CODECOV_TOKEN }}


использует: codecov/codecov-action@v1


с участием:


токен: ${{ secrets.CODECOV_TOKEN }}


файл: покрытие.xml


имя: ${{ matrix.os }}, python ${{ matrix.python-версия }}


Проверка типов с помощью mypy


Еще одна проверка, которую мы собираемся использовать, — это проверка типов с помощью mypy. Не волнуйтесь, мы не будем аннотировать наш код Python типами. Mypy может помочь вам, даже если ваш код не аннотирован. Он может обнаружить множество распространенных ошибок или несоответствий.


``ямл


  • имя: Проверка типов с помощью mypy

запустить: mypy src


Допустим, вы пишете код, который переключает тип переменной, что широко считается плохой практикой.


```питон


если name == 'main':


тст = 'омг'


тст = 0


Mypy сообщит вам, что это ошибка.


$ mypy источник


src/main.py:3: ошибка: несовместимые типы при назначении (выражение имеет тип «int», переменная имеет тип «str»)


Найдена 1 ошибка в 1 файле (проверено 1 исходный файл)


Собрать пакет


Если ваш проект представляет собой пакет Python, вы можете собрать его, используя следующую конфигурацию. В других случаях используйте команды, специфичные для вашего проекта.


``ямл


  • имя: Установить pypa/сборка

запустить: python -m pip установить сборку


  • название: Сборка бинарного колеса и исходного архива

запустить: >-


питон -м


строить


--sdist


--рулевое колесо


--outdir dist/


Опубликовать пакет


В этом случае мы собираемся опубликовать пакет в pypi. Опять же, мы используем существующий шаблон действия из pypa.


``ямл


  • имя: Опубликовать пакет

использует: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29


с участием:


пользователь: токен


пароль: ${{ секреты.PYPI_API_TOKEN }}


Отправить уведомление в Slack-канал


Если наша сборка и публикация прошли успешно, мы можем уведомить себя или нашу команду в Slack.


``ямл


  • использует: act10ns/slack@v1

с участием:


статус: ${{ job.status }}


шаги: ${{ toJson(шаги) }}


канал: '#рабочие процессы'


среда:


SLACK_WEBHOOK_URL: ${{ секреты.SLACK_WEBHOOK_URL }}


Создание и публикация документации


Если вы используете стандартный инструмент документирования, такой как Sphinx, вы также можете создавать и развертывать документацию в действиях. В этом случае мы используем стандартную команду make html. Затем следует развертывание на страницах GitHub с использованием заранее подготовленного действия.


Взгляните на исходные страницы документации по шагам развертывания, если хотите узнать больше:


https://github.com/peaceiris/actions-gh-pages


Примечание. secrets.GITHUB_TOKEN автоматически создается GitHub, вам не нужно определять его самостоятельно.


``ямл


  • название: Документация

выполнить: cd docs && make html


  • имя: Развернуть документацию

использует: Peaceiris/actions-gh-pages@v3


с участием:


github_token: ${{ секреты.GITHUB_TOKEN }}


publish_dir: ./docs/_build/html


Резюме


Вот и все! В вашем репозитории теперь есть базовая настройка CI/CD. Имейте в виду, что это всего лишь пример, и ваш пробег может отличаться. Мы рассмотрели многие детали и нюансы реализации, поэтому обязательно ознакомьтесь с [официальной документацией] (https://docs.github.com/en/actions) и погрузитесь глубже.


Полный код


https://github.com/horosin/python-standard-ci


Обсуждение


Есть ли что-то еще, что вы автоматизируете в своем CI/CD? Хотели бы вы автоматизировать то, что я не описал? Давайте поговорим об этом в комментариях!


Вы также можете присоединиться ко мне в моем новом блоге! https://horosin.com


  • Впервые опубликовано [здесь] (https://horosin.com/python-project-cicd-with-github-actions)*


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE