Observação: no momento, não há suporte para os executores hospedados no GitHub no GitHub Enterprise Server. Você pode ver mais informações sobre o suporte futuro planejado no GitHub public roadmap.
Introdução
Este guia mostra como criar, testar e publicar um pacote no Python.
Executores hospedados em GitHub têm um cache de ferramentas com software pré-instalado que inclui Python e PyPy. Você não precisa instalar nada! Para ver a lista completa de programas de software atualizados e as versões pré-instaladas do Python e do PyPy, confira "Usar executores hospedados no GitHub".
Pré-requisitos
Você deve estar familiarizado com o YAML e a sintaxe do GitHub Actions. Para obter mais informações, confira "Escrevendo fluxos de trabalho".
Recomendamos que você tenha um conhecimento básico sobre Python e pip. Para saber mais, veja:
Usar executores auto-hospedados no GitHub Enterprise Server
Ao usar ações de instalação (como actions/setup-LANGUAGE
) no GitHub Enterprise Server com executores auto-hospedados, talvez seja necessário configurar o cache de ferramentas nos executores que não têm acesso à Internet. Para obter mais informações, confira "Configurar o cache de ferramentas em executores auto-hospedados sem acesso à internet".
Usando um fluxo de trabalho inicial em Python
Para experimentar uma introdução rápida, adicione um fluxo de trabalho inicial ao diretório .github/workflows
do repositório.
O GitHub fornece um fluxo de trabalho inicial para Python que deve funcionar se o seu repositório já contém pelo menos um arquivo .py
. As seções subsequentes deste guia fornecem exemplos de como você pode personalizar esse fluxo de trabalho inicial.
-
No sua instância do GitHub Enterprise Server, navegue até a página principal do repositório.
-
No nome do repositório, clique em Ações.
-
Se você já tiver um fluxo de trabalho no repositório, clique em Novo fluxo de trabalho.
-
A página "Escolher um fluxo de trabalho" mostra uma seleção de fluxos de trabalho iniciais recomendados. Pesquise por "aplicativo Python".
-
No fluxo de trabalho "Aplicativo Python", clique em Configurar.
Se não encontrar o fluxo de trabalho inicial "aplicativo Python", copie o seguinte código de fluxo de trabalho para um novo arquivo chamado
python-app.yml
no diretório.github/workflows
do seu repositório.YAML name: Python application on: push: branches: [ "main" ] pull_request: branches: [ "main" ] permissions: contents: read jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python 3.10 uses: actions/setup-python@v5 with: python-version: "3.10" - 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
name: Python application on: push: branches: [ "main" ] pull_request: branches: [ "main" ] permissions: contents: read jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python 3.10 uses: actions/setup-python@v5 with: python-version: "3.10" - 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
-
Edite o fluxo de trabalho conforme necessário. Por exemplo, altere a versão do Python.
-
Clique em Confirmar alterações.
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.
Ubuntu | Mac | Windows | |
---|---|---|---|
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
O exemplo a seguir usa uma matriz para que o trabalho configure várias versões do Python. Para obter mais informações, confira "Running variations of jobs in a workflow".
name: Python package on: [push] jobs: build: runs-on: ubuntu-latest strategy: matrix: python-version: ["pypy3.9", "pypy3.10", "3.9", "3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 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)"
name: Python package
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["pypy3.9", "pypy3.10", "3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
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.10. 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.
name: Python package on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python # This is the version of the action for setting up Python, not the Python version. uses: actions/setup-python@v5 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)"
name: Python package
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
# This is the version of the action for setting up Python, not the Python version.
uses: actions/setup-python@v5
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.6 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 para o GitHub Actions".
name: Python package on: [push] jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.9", "3.10", "3.11", "pypy3.9", "pypy3.10"] exclude: - os: macos-latest python-version: "3.9" - os: windows-latest python-version: "3.9"
name: Python package
on: [push]
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.10", "3.11", "pypy3.9", "pypy3.10"]
exclude:
- os: macos-latest
python-version: "3.9"
- os: windows-latest
python-version: "3.9"
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 GitHub | Descrição |
---|---|
Ubuntu | Os 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. |
Windows | Excluindo 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 . |
macOS | Os 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
.
Você também pode armazenar as dependências em cache para acelerar o fluxo de trabalho. Para obter mais informações, confira "Memorizar dependências para acelerar os fluxos de trabalho".
steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install dependencies run: python -m pip install --upgrade pip setuptools wheel
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
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.
steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
Memorizar dependências
Você pode armazenar em cache e restaurar as dependências usando a setup-python
ação.
O exemplo a seguir armazena dependências para pip.
steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.11' cache: 'pip' - run: pip install -r requirements.txt - run: pip test
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- run: pip install -r requirements.txt
- run: pip test
Por padrão, a ação setup-python
pesquisa so arquivo de dependência (requirements.txt
para o pip, Pipfile.lock
para o pipenv, ou poetry.lock
para poetry) em todo o repositório. Para obter mais informações, confira "Como armazenar dependências de pacotes em cache" no README setup-python
.
Se você tiver um requisito personalizado ou precisar ter controles mais refinados para o cache, use a ação cache
. O Pip armazena dependências em diferentes locais, dependendo do sistema operacional do executor. O caminho que você precisa efetuar o armazenamento em cache pode ser diferente do exemplo do Ubuntu acima, dependendo do sistema operacional que você usa. Para obter mais informações, confira Exemplos de cache do Python no repositório de ações cache
.
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.
steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 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
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
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
Como usar o Ruff para efetuar lint do código
O exemplo a seguir instala ou atualiza o ruff
e o usa para fazer lint de todos os arquivos. Para obter mais informações, confira Ruff.
steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 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 check --output-format=github . continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
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 check --output-format=github .
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.
name: Python package on: [push] jobs: build: runs-on: ubuntu-latest strategy: matrix: python: ["3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v4 - name: Setup Python uses: actions/setup-python@v5 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
name: Python package
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python: ["3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
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 "Armazenando e compartilhando dados de um fluxo de trabalho".
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
.
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@v4 - name: Setup Python # Set Python version uses: actions/setup-python@v5 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() }}
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@v4
- name: Setup Python # Set Python version
uses: actions/setup-python@v5
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() }}
Publicando no PyPI
Você pode configurar seu fluxo de trabalho para publicar seu pacote do Python no PyPI 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 obter mais informações, confira "Gerenciar versões em repositórios".
O fluxo de trabalho de exemplo abaixo usa a Publicação Confiável para autenticar com o PyPI, eliminando a necessidade de um token de API configurado manualmente.
# 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] permissions: contents: read jobs: release-build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.x" - name: Build release distributions run: | # NOTE: put your own distribution build steps here. python -m pip install build python -m build - name: Upload distributions uses: actions/upload-artifact@v3 with: name: release-dists path: dist/ pypi-publish: runs-on: ubuntu-latest needs: - release-build permissions: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write # Dedicated environments with protections for publishing are strongly recommended. environment: name: pypi # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status: # url: https://pypi.org/p/YOURPROJECT steps: - name: Retrieve release distributions uses: actions/download-artifact@v3 with: name: release-dists path: dist/ - name: Publish release distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1
# 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]
permissions:
contents: read
jobs:
release-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Build release distributions
run: |
# NOTE: put your own distribution build steps here.
python -m pip install build
python -m build
- name: Upload distributions
uses: actions/upload-artifact@v3
with:
name: release-dists
path: dist/
pypi-publish:
runs-on: ubuntu-latest
needs:
- release-build
permissions:
# IMPORTANT: this permission is mandatory for trusted publishing
id-token: write
# Dedicated environments with protections for publishing are strongly recommended.
environment:
name: pypi
# OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
# url: https://pypi.org/p/YOURPROJECT
steps:
- name: Retrieve release distributions
uses: actions/download-artifact@v3
with:
name: release-dists
path: dist/
- name: Publish release distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1