Skip to main content
Мы публикуем частые обновления нашей документации, и перевод этой страницы может все еще выполняться. Актуальные сведения см. в документации на английском языке.

Создание и тестирование для Python

Вы можете создать рабочий процесс непрерывной интеграции для сборки и тестирования проекта Python.

Введение

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

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

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

Требуются знания 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", "3.11"]

    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 ruff pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
      - name: Lint with ruff
        run: |
          # stop the build if there are Python syntax errors or undefined names
          ruff --format=github --select=E9,F63,F7,F82 --target-version=py37 .
          # default set of ruff rules with GitHub Annotations
          ruff --format=github --target-version=py37 .
      - 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, pypy2.7 and pypy3.9
      matrix:
        python-version: ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"]

    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.10. Кроме того, можно использовать синтаксис семантической версии, чтобы получить последний дополнительный выпуск. В этом примере используется последний дополнительный выпуск 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.6 with arch x64 not found. Сообщение об ошибке содержит доступные версии.

Вы также можете использовать ключевое слово exclude в рабочем процессе, если существует конфигурация Python, которую не нужно запускать. Дополнительные сведения см. в разделе Синтаксис рабочего процесса для 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", "3.11", pypy2.7, pypy3.9]
        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.

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

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.11'
    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 pytest-cov
    pytest tests.py --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html

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

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

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 Ruff
  run: |
    pip install ruff
    ruff --format=github --target-version=py37 .
  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.9", "3.10", "3.11"]

    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

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

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

В следующем примере показано, как использовать действие 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", "3.11"]

    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.