Skip to main content
We publish frequent updates to our documentation, and translation of this page may still be in progress. For the most current information, please visit the English documentation.

Building and testing Python

You can create a continuous integration (CI) workflow to build and test your Python project.

Введение

В этом руководстве описано, как создавать, тестировать и публиковать пакет Python.

Размещенные в GitHub средства выполнения имеют кэш инструментов с предварительно установленным программным обеспечением, включающим в себя Python и PyPy. Вам ничего устанавливать не нужно. Полный список актуального программного обеспечения и предварительно установленных версий Python и PyPy см. в разделе About GitHub-hosted runners.

Предварительные требования

Требуются знания YAML и синтаксиса GitHub Actions. Дополнительные сведения см. в разделе Изучение GitHub Actions.

Рекомендуется иметь базовое представление о Python, PyPy и pip. Дополнительные сведения см. в разделе:

Использование начального рабочего процесса Python

GitHub предоставляет начальный рабочий процесс Python, который должен работать для большинства проектов Python. В этом руководстве приведены примеры, которые можно использовать для настройки начального рабочего процесса. Дополнительные сведения см. в разделе Начальный рабочий процесс Python.

Чтобы быстро приступить к работе, добавьте начальный рабочий процесс в каталог .github/workflows своего репозитория.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.7", "3.8", "3.9", "3.10"]

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install flake8 pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
      - name: Lint with flake8
        run: |
          # stop the build if there are Python syntax errors or undefined names
          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
          # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
          flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
      - name: Test with pytest
        run: |
          pytest

Указание версии Python

Чтобы использовать предустановленную версию Python или PyPy в размещенном в GitHub средстве выполнения, используйте действие setup-python. Это действие находит определенную версию Python или PyPy из кэша инструментов в каждом средстве запуска и добавляет необходимые двоичные файлы в переменную PATH, которая сохраняется до конца задания. Если определенная предустановленная версия Python отсутствует в кэше инструментов, действие setup-python скачивает и настраивает соответствующую версию из репозитория python-versions.

Применение действия setup-python представляет собой рекомендуемый способ использования Python с GitHub Actions, так как он обеспечивает согласованное поведение в разных средствах выполнения и различных версиях Python. При использовании локального средства выполнения необходимо установить Python и добавить его в PATH. Дополнительные сведения см. в описании действия setup-python.

В приведенной ниже таблице описаны расположения для кэша инструментов в каждом размещенном в GitHub средстве выполнения.

UbuntuMacWindows
Каталог кэша инструментов/opt/hostedtoolcache/*/Users/runner/hostedtoolcache/*C:\hostedtoolcache\windows\*
Кэш инструментов Python/opt/hostedtoolcache/Python/*/Users/runner/hostedtoolcache/Python/*C:\hostedtoolcache\windows\Python\*
Кэш инструментов PyPy/opt/hostedtoolcache/PyPy/*/Users/runner/hostedtoolcache/PyPy/*C:\hostedtoolcache\windows\PyPy\*

Если вы используете локальное средство выполнения, его можно настроить для управления зависимостями с помощью действия setup-python. Дополнительные сведения см. в разделе об использовании setup-python с локальным средством выполнения в файле сведений setup-python.

GitHub поддерживает синтаксис семантического версионирования. Дополнительные сведения см. в разделах Использование семантического версионирования и Спецификация семантического версионирования.

Использование нескольких версий Python

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      # You can use PyPy versions in python-version.
      # For example, pypy-2.7 and pypy-3.8
      matrix:
        python-version: ["2.7", "3.7", "3.8", "3.9", "3.10"]

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      # You can test your matrix by printing the current Python version
      - name: Display Python version
        run: python -c "import sys; print(sys.version)"

Использование определенной версии Python

Вы можете настроить определенную версию Python. Например, 3.9. Кроме того, можно использовать синтаксис семантической версии, чтобы получить последний дополнительный выпуск. В этом примере используется последний дополнительный выпуск Python 3.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python 3.x
        uses: actions/setup-python@v4
        with:
          # Semantic version range syntax or exact version of a Python version
          python-version: '3.x'
          # Optional - x64 or x86 architecture, defaults to x64
          architecture: 'x64'
      # You can test your matrix by printing the current Python version
      - name: Display Python version
        run: python -c "import sys; print(sys.version)"

Исключение версии

Если указать версию Python, которая недоступна, setup-python завершается сбоем и выводится ошибка, например ##[error]Version 3.4 with arch x64 not found. Сообщение об ошибке содержит доступные версии.

Вы также можете использовать ключевое слово exclude в рабочем процессе, если существует конфигурация Python, которую не нужно запускать. Дополнительные сведения см. в разделе Workflow syntax for GitHub Actions.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        python-version: ["3.7", "3.8", "3.9", "3.10", pypy-2.7, pypy-3.8]
        exclude:
          - os: macos-latest
            python-version: "3.7"
          - os: windows-latest
            python-version: "3.7"

Использование версии Python по умолчанию

Мы рекомендуем использовать setup-python для настройки версии Python, используемой в рабочих процессах, так как это помогает сделать зависимости явными. Если вы не используетеsetup-python, при вызове python в любой оболочке используется версия Python по умолчанию, заданная в PATH. Версия Python по умолчанию зависит от конкретных размещенных в GitHub средств выполнения, что может привести к непредвиденным изменениям или использованию более ранней версии по сравнению с ожидаемой.

Размещенное в GitHub средство выполненияОписание
UbuntuСредства выполнения Ubuntu имеют несколько версий системного Python, установленных в /usr/bin/python и /usr/bin/python3. Версии Python, упакованные вместе с Ubuntu, являются дополнением к версиям, которые GitHub устанавливаем в кэше инструментов.
WindowsЗа исключением версий Python, которые находятся в кэше инструментов, Windows не содержит эквивалентной версии системного Python. Чтобы обеспечить согласованную работу с другими средствами выполнения и обеспечить использование Python в исходном виде без действия setup-python, GitHub добавляет несколько версий из кэша инструментов в PATH.
macOSСредства выполнения macOS имеют несколько установленных версий системного Python в дополнение к версиям, входящим в состав кэша инструментов. Версии системного Python находятся в каталоге /usr/local/Cellar/python/*.

Установка зависимостей

Для размещенных в GitHub средств выполнения установлен диспетчер пакетов pip. Вы можете использовать pip для установки зависимостей из реестра пакетов PyPI перед созданием и тестированием кода. Например, приведенный ниже код YAML устанавливает или обновляет установщик пакетов pip и пакеты setuptools и wheel.

Можно также кэшировать зависимости, чтобы ускорить рабочий процесс. Дополнительные сведения см. в разделе Caching dependencies to speed up workflows.

YAML
steps:
- uses: actions/checkout@v3
- name: Set up Python
  uses: actions/setup-python@v4
  with:
    python-version: '3.x'
- name: Install dependencies
  run: python -m pip install --upgrade pip setuptools wheel

Файл требований

Типичным следующим шагом после обновления pip является установка зависимостей из requirements.txt. Дополнительные сведения см. в описании pip.

YAML
steps:
- uses: actions/checkout@v3
- name: Set up Python
  uses: actions/setup-python@v4
  with:
    python-version: '3.x'
- name: Install dependencies
  run: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt

Кэширование зависимостей

Можно кэшировать и восстанавливать зависимости с помощью действияsetup-python.

В следующем примере кэшируются зависимости для pip.

YAML
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
  with:
    python-version: '3.10'
    cache: 'pip'
- run: pip install -r requirements.txt
- run: pip test

По умолчанию действие setup-python ищет файл зависимостей (requirements.txt для pip, Pipfile.lock для pipenv или poetry.lock для poetry) во всем репозитории. Дополнительные сведения см. в разделе Кэширование зависимостей пакетов в файле README setup-python.

Если у вас есть особые требования или вам нужно управлять кэшированием более детально, можно использовать действие cache. Pip кэширует зависимости в разных расположениях в зависимости от операционной системы средства выполнения. Путь, по которому требуется выполнить кэширование, может отличаться от приведенного выше примера Ubuntu в зависимости от используемой операционной системы. Дополнительные сведения см. в примерах кэширования Python в репозитории действия cache.

Тестирование кода

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

Тестирование с помощью pytest и pytest-cov

В этом примере устанавливаются или обновляются pytest и pytest-cov. Затем выполняются тесты, выходные данные выводятся в формате JUnit, а результаты по объему протестированного кода выводятся в Cobertura. Дополнительные сведения см. в описании JUnit и Cobertura.

YAML
steps:
- uses: actions/checkout@v3
- name: Set up Python
  uses: actions/setup-python@v4
  with:
    python-version: '3.x'
- name: Install dependencies
  run: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt
- name: Test with pytest
  run: |
    pip install pytest
    pip install pytest-cov
    pytest tests.py --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html

Использование Flake8 для анализа кода

В следующем примере выполняется установка или обновление flake8 и его использование для анализа кода всех файлов. Дополнительные сведения см. в описании Flake8.

YAML
steps:
- uses: actions/checkout@v3
- name: Set up Python
  uses: actions/setup-python@v4
  with:
    python-version: '3.x'
- name: Install dependencies
  run: |
    python -m pip install --upgrade pip
    pip install -r requirements.txt
- name: Lint with flake8
  run: |
    pip install flake8
    flake8 .
  continue-on-error: true

На шаге анализа кода задан параметр continue-on-error: true. Это предотвратит сбой рабочего процесса, если шаг анализа кода завершится неудачно. Когда вы устраните все ошибки анализа кода, можете удалить этот параметр, чтобы рабочий процесс регистрировал новые проблемы.

Выполнение тестов с помощью tox

В GitHub Actionsможно выполнять тесты с помощью tox и распределять работу между несколькими заданиями. Чтобы выбрать версию Python в PATH, а не указывать конкретную версию, нужно вызвать tox с использованием -e py. Дополнительные сведения см. в описании tox.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python: ["3.8", "3.9", "3.10"]

    steps:
      - uses: actions/checkout@v3
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python }}
      - name: Install tox and any other packages
        run: pip install tox
      - name: Run tox
        # Run tox using the version of Python in `PATH`
        run: tox -e py

Упаковка данных рабочего процесса в виде артефактов

Вы можете отправить артефакты для просмотра после завершения рабочего процесса. Например, может потребоваться сохранить файлы журналов, основные дампы, результаты теста или снимки экрана. Дополнительные сведения см. в разделе Storing workflow data as artifacts.

В следующем примере показано, как использовать действие upload-artifact для архивации результатов теста при выполнении pytest. Дополнительные сведения см. в описании действия upload-artifact.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.7", "3.8", "3.9", "3.10"]

    steps:
      - uses: actions/checkout@v3
      - name: Setup Python # Set Python version
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      # Install pip and pytest
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install pytest
      - name: Test with pytest
        run: pytest tests.py --doctest-modules --junitxml=junit/test-results-${{ matrix.python-version }}.xml
      - name: Upload pytest test results
        uses: actions/upload-artifact@v3
        with:
          name: pytest-results-${{ matrix.python-version }}
          path: junit/test-results-${{ matrix.python-version }}.xml
        # Use always() to always run this step to publish test results when there are test failures
        if: ${{ always() }}

Публикация в реестрах пакетов

Вы можете настроить рабочий процесс для публикации пакета Python в реестре пакетов после прохождения тестов CI. В этом разделе показано, как использовать GitHub Actions для отправки пакета в PyPI при каждой публикации выпуска.

В этом примере потребуется создать два маркера API PyPI. Вы можете использовать секреты для хранения маркеров доступа или учетных данных, необходимых для публикации пакета. Дополнительные сведения см. в разделе Зашифрованные секреты.

YAML
# Этот рабочий процесс использует действия, которые не сертифицированы GitHub.
# Они предоставляются сторонним поставщиком, и на них распространяются
# отдельные условия обслуживания, политика конфиденциальности и поддержка
# документации.

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

name: Upload Python Package

on:
  release:
    types: [published]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.x'
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install build
      - name: Build package
        run: python -m build
      - name: Publish package
        uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
        with:
          user: __token__
          password: ${{ secrets.PYPI_API_TOKEN }}

Дополнительные сведения о начальном рабочем процессе см. в описании python-publish.