Как интегрировать 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, обязательно [проверьте!] (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)*
Оригинал