Skip to main content

Criar e testar o Python

É possível criar um fluxo de trabalho de integração contínua (CI) para criar e testar o seu projeto Python.

Introdução

Este guia mostra como criar, testar e publicar um pacote no Python.

Você precisa instalar o software necessário nos executores auto-hospedados. Para obter mais informações sobre os executores auto-hospedados, confira "Como hospedar seus executores".

Pré-requisitos

Você deve estar familiarizado com o YAML e a sintaxe do GitHub Actions. Para obter mais informações, confira "Aprenda a usar o GitHub Actions".

Recomendamos que você tenha um entendimento básico do Python, PyPy e pip. Para obter mais informações, consulte:

Usando o fluxo de trabalho inicial do Python

GitHub fornece um fluxo de trabalho inicial do Python que deve funcionar na maioria dos projetos do Python. Este guia inclui exemplos que você pode usar para personalizar o fluxo de trabalho inicial. Para obter mais informações, confira o fluxo de trabalho inicial do Python.

Para experimentar uma introdução rápida, adicione o fluxo de trabalho inicial ao diretório .github/workflows do repositório.

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@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        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

Especificar uma versão do Python

Para usar uma versão pré-instalada do Python ou do PyPy em um executor hospedado no GitHub, use a ação setup-python. Essa ação encontra uma versão específica do Python ou do PyPy no cache de ferramentas em cada executor e adiciona os binários necessários a PATH, que é persistente no restante do trabalho. Se uma versão específica do Python não estiver pré-instalada no cache de ferramentas, a ação setup-python vai baixar e configurar a versão apropriada do repositório python-versions.

O uso da ação setup-python é a maneira recomendada de usar o Python com o GitHub Actions, porque garante um comportamento consistente entre diferentes executores e diferentes versões do Python. Se você estiver usando um executor auto-hospedado, precisará instalar o Python e adicioná-lo a PATH. Para obter mais informações, confira a Ação setup-python.

A tabela abaixo descreve os locais para o armazenamento de ferramentas em cada executor hospedado em GitHub.

UbuntuMacWindows
Diretório de cache da ferramenta/opt/hostedtoolcache/*/Users/runner/hostedtoolcache/*C:\hostedtoolcache\windows\*
Cache da ferramenta do Python/opt/hostedtoolcache/Python/*/Users/runner/hostedtoolcache/Python/*C:\hostedtoolcache\windows\Python\*
Cache da ferramenta do PyPy/opt/hostedtoolcache/PyPy/*/Users/runner/hostedtoolcache/PyPy/*C:\hostedtoolcache\windows\PyPy\*

Se você estiver usando um executor auto-hospedado, poderá configurar o executor para usar a ação setup-python a fim de gerenciar suas dependências. Para obter mais informações, confira Como usar o setup-python com um executor auto-hospedado no README de setup-python.

O GitHub é compatível com a sintaxe semântica de versionamento. Para obter mais informações, confira "Como usar o controle de versão semântico" e "Especificação de controle de versão semântico".

Usar várias versões do 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 and pypy3
      matrix:
        python-version: ["2.7", "3.7", "3.8", "3.9", "3.10"]

    steps:
      - uses: actions/checkout@v2
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        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)"

Usar uma versão específica do Python

Você pode configurar uma versão específica do python. Por exemplo: 3.9. Como alternativa, você pode usar a sintaxe da versão semântica para obter a última versão secundária. Este exemplo usa a última versão secundária do Python 3.

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Set up Python 3.x
        uses: actions/setup-python@v2
        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)"

Excluir uma versão

Se você especificar uma versão do Python que não está disponível, setup-python falhará com um erro como: ##[error]Version 3.4 with arch x64 not found. A mensagem de erro inclui as versões disponíveis.

Use também a palavra-chave exclude no fluxo de trabalho se houver uma configuração do Python que não deseja executar. Para obter mais informações, confira "Sintaxe de fluxo de trabalho do 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", pypy2, pypy3]
        exclude:
          - os: macos-latest
            python-version: "3.7"
          - os: windows-latest
            python-version: "3.7"

Usar a versão padrão do Python

Recomendamos usar setup-python para configurar a versão do Python usada nos fluxos de trabalho porque ele ajuda a tornar as dependências explícitas. Se você não usar setup-python, a versão padrão do Python definida em PATH será usada em qualquer shell quando você chamar python. A versão-padrão do Python varia entre executores hospedados no GitHub, o que pode causar mudanças inesperadas ou usar uma versão mais antiga do que o esperado.

Executor hospedado em GitHubDescrição
UbuntuOs executores do Ubuntu têm várias versões do Python no sistema instaladas em /usr/bin/python e /usr/bin/python3. As versões do Python que vêm empacotadas com o Ubuntu são adicionais às versões que o GitHub instala na cache das ferramentas.
WindowsExcluindo as versões do Python que estão na cache de ferramentas, o Windows não é compatível com uma versão equivalente do sistema do Python. Para manter um comportamento consistente com outros executores e permitir que o Python seja usado sem a ação setup-python, o GitHub adiciona algumas versões do cache de ferramentas a PATH.
macOSOs executores do macOS têm mais de uma versão do sistema do Python instalada, além das versões que fazem parte da cache de ferramentas. As versões do Python no sistema estão localizadas no diretório /usr/local/Cellar/python/*.

Instalar dependências

Os executores hospedados em GitHub têm instalado o gerenciador do pacote pip. Você pode usar o pip para instalar dependências do registro de pacotes do PyPI antes de criar e testar o seu código. Por exemplo, o YAML abaixo instala ou atualiza o instalador de pacote pip e os pacotes setuptools e wheel.

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

Arquivo de requisitos

Depois que você atualizar pip, uma próxima etapa típica será instalar dependências do requirements.txt. Para obter mais informações, confira pip.

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

Testar seu código

Você pode usar os mesmos comandos usados localmente para criar e testar seu código.

Testar com pytest e pytest-cov

Este exemplo instala ou atualiza pytest e pytest-cov. Em seguida, os testes são executados e retornados no formato JUnit enquanto os resultados da cobertura do código são emitidos em Cobertura. Para obter mais informações, confira JUnit e Cobertura.

YAML
steps:
- uses: actions/checkout@v2
- name: Set up Python
  uses: actions/setup-python@v2
  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

UsarFlake8 para código lint

O exemplo a seguir instala ou atualiza o flake8 e o usa para fazer lint de todos os arquivos. Para obter mais informações, confira Flake8.

YAML
steps:
- uses: actions/checkout@v2
- name: Set up Python
  uses: actions/setup-python@v2
  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

A etapa de lint tem continue-on-error: true definido. Isto impedirá que o fluxo de trabalho falhe se a etapa de limpeza de código não for bem-sucedida. Após corrigir todos os erros de limpeza de código, você poderá remover essa opção para que o fluxo de trabalho capture novos problemas.

Executar testes com tox

Com GitHub Actions, você pode executar testes com tox e distribuir o trabalho para vários trabalhos. Você precisará invocar o Tox usando a opção -e py para escolher a versão do Python no PATH, em vez de especificar uma versão. Para obter mais informações, confira 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@v2
      - name: Setup Python
        uses: actions/setup-python@v2
        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

Empacotar dados do fluxo de trabalho como artefatos

Você pode fazer o upload de artefatos para visualização após a conclusão de um fluxo de trabalho. Por exemplo, é possível que você precise salvar os arquivos de registro, os despejos de núcleo, os resultados de teste ou capturas de tela. Para obter mais informações, confira "Como persistir dados de fluxo de trabalho usando artefatos".

O exemplo a seguir demonstra como usar a ação upload-artifact para arquivar os resultados do teste da execução de pytest. Para obter mais informações, confira a Ação 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@v2
      - name: Setup Python # Set Python version
        uses: actions/setup-python@v2
        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@v2
        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() }}

Publicar nos registros do pacote

Você pode configurar seu fluxo de trabalho para publicar seu pacote do Python em um pacote de registro assim que seu CI teste passar. Esta seção demonstra como usar o GitHub Actions para carregar seu pacote no PyPI sempre que você publicar uma versão.

Para este exemplo, você precisará criar dois tokens de API do PyPI. Você pode usar segredos para armazenar os tokens de acesso ou credenciais necessárias para publicar o seu pacote. Para obter mais informações, confira "Como criar e usar segredos criptografados".

YAML
# Esse fluxo de trabalho usa ações que não são certificadas pelo GitHub.
# São fornecidas por terceiros e regidas por
# termos de serviço, política de privacidade e suporte separados
# online.

# O GitHub recomenda fixar ações em um SHA de commit.
# Para obter uma versão mais recente, você precisará atualizar o SHA.
# Você também pode fazer referência a uma marca ou branch, mas a ação pode ser alterada sem aviso.

name: Upload Python Package

on:
  release:
    types: [published]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python
        uses: actions/setup-python@v2
        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 }}

Para obter mais informações sobre o fluxo de trabalho inicial, confira python-publish.