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.

此版本的 GitHub Enterprise 已停止服务 2023-01-18. 即使针对重大安全问题,也不会发布补丁。 为了获得更好的性能、更高的安全性和新功能,请升级到最新版本的 GitHub Enterprise。 如需升级帮助,请联系 GitHub Enterprise 支持

构建和测试 Python

您可以创建持续集成 (CI) 工作流程来构建和测试您的 Python 项目。

注意:GitHub Enterprise Server 目前不支持 GitHub 托管的运行器。 可以在 GitHub public roadmap 上查看有关未来支持计划的更多信息。

简介

本指南介绍如何构建、测试和发布 Python 包。

GitHub 托管的运行器有一个带有预装软件的工具缓存,其中包括 Python 和 PyPy。 您无需安装任何项目! 有关最新版软件以及 Python 和 PyPy 预安装版本的完整列表,请参阅“GitHub 托管的运行器规范”。

先决条件

您应该熟悉 YAML 和 GitHub Actions 的语法。 有关详细信息,请参阅“了解 GitHub Actions”。

建议您对 Python、PyPy 和 pip 有个基本的了解。 有关详细信息,请参阅:

在 GitHub Enterprise Server 上使用自托管的运行器

在包含自承载运行器的 GitHub Enterprise Server 上使用设置操作(例如 actions/setup-LANGUAGE)时,可能需要在无法访问 Internet 的运行器上设置工具缓存。 有关详细信息,请参阅“在无法访问 Internet 的自承载运行器上设置工具缓存”。

使用 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@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

指定 Python 版本

若要在 GitHub 托管的运行器上使用 Python 或 PyPy 的预安装版本,请使用 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 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)"

使用特定的 Python 版本

您可以配置 python 的特定版本。 例如,3.9。 或者,您也可以使用语义版本语法来获得最新的次要版本。 此示例使用 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)"

排除版本

如果指定的 Python 版本不可用,则 setup-python 将失败并出现错误,例如:##[error]Version 3.4 with arch x64 not found。 错误消息包含可用的版本。

如果存在不想运行的 Python 配置,也可以在工作流中使用 exclude 关键字。 有关详细信息,请参阅“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"

使用默认 Python 版本

建议使用 setup-python 来配置工作流中使用的 Python 版本,因为它有助于明确依赖项。 如果不使用 setup-python,当调用 python 时,将在任何 shell 中使用 PATH 中设置的默认 Python 版本。 GitHub 托管的运行器之间有不同的 Python 默认版本,这可能导致非预期的更改或使用的版本比预期更旧。

GitHub 托管的运行器说明
UbuntuUbuntu 运行器在 /usr/bin/python/usr/bin/python3 下安装了多个版本的系统 Python。 GitHub 除了安装在工具缓存中的版本,还有与 Ubuntu 一起打包的 Python 版本。
Windows不包括工具缓存中的 Python 版本,Windows 未随附同等版本的系统 Python。 为保持与其他运行器一致的行为,并允许 Python 在没有 setup-python 操作的情况下开箱即用,GitHub 将从工具缓存中添加几个版本到 PATH
macOS除了作为工具缓存一部分的版本外,macOS 运行器还安装了多个版本的系统 Python。 系统 Python 版本位于 /usr/local/Cellar/python/* 目录中。

安装依赖关系

GitHub 托管的运行器安装了 pip 软件包管理器。 在构建和测试代码之前,您可以使用 pip 从 PyPI 软件包注册表安装依赖项。 例如,下面的 YAML 安装或升级 pip 包安装程序以及 setuptoolswheel 包。

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

要求文件

更新 pip 后,下一步通常是从 requirements.txt 安装依赖项。 有关详细信息,请参阅 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

测试代码

您可以使用与本地相同的命令来构建和测试代码。

使用 pytest 和 pytest-cov 测试

此示例安装或升级 pytestpytest-cov。 然后进行测试并以 JUnit 格式输出,而代码覆盖结果则以 Cobertura 输出。 有关详细信息,请参阅 JUnitCobertura

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

使用 Flake8 嵌入代码

以下示例安装或升级 flake8 并使用它对所有文件执行 lint 操作。 有关详细信息,请参阅 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

Lint 分析步骤设置了 continue-on-error: true。 这可防止在嵌入步骤不成功时工作流程失败。 解决所有嵌入错误后,您可以删除此选项,以便工作流程捕获新问题。

使用 tox 运行测试

通过 GitHub Actions,您可以使用 tox 运行测试并将工作分散到多个作业。 需要使用 -e py 选项调用 tox,以选择 PATH 中的 Python 版本,而不是指定特定版本。 有关详细信息,请参阅 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

将工作流数据打包为构件

您可以在工作流程完成后上传构件以查看。 例如,您可能需要保存日志文件、核心转储、测试结果或屏幕截图。 有关详细信息,请参阅“使用项目持久保存工作流数据”。

以下示例演示如何使用 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@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() }}

发布到包注册表

您可以配置工作流程在 CI 测试通过后将 Python 包发布到包注册表。 本部分演示如何在每次发布版本时使用 GitHub Actions 将包上传到 PyPI。

对于此示例,需要创建两个 PyPI API 令牌。 您可以使用机密来存储发布软件包所需的访问令牌或凭据。 有关详细信息,请参阅“创建和使用已加密的机密”。

YAML
# <a name="this-workflow-uses-actions-that-are-not-certified-by-github"></a>此工作流使用未经 GitHub 认证的操作。
# <a name="they-are-provided-by-a-third-party-and-are-governed-by"></a>它们由第三方提供,并受
# <a name="separate-terms-of-service-privacy-policy-and-support"></a>单独的服务条款、隐私政策和支持
# <a name="documentation"></a>文档。

# <a name="github-recommends-pinning-actions-to-a-commit-sha"></a>GitHub 建议将操作固定到提交 SHA。
# <a name="to-get-a-newer-version-you-will-need-to-update-the-sha"></a>若要获取较新版本,需要更新 SHA。
# <a name="you-can-also-reference-a-tag-or-branch-but-the-action-may-change-without-warning"></a>还可以引用标记或分支,但该操作可能会更改而不发出警告。

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 }}

有关起始工作流的详细信息,请参阅 python-publish