我们经常发布文档更新,此页面的翻译可能仍在进行中。有关最新信息,请访问英文文档。如果此页面上的翻译有问题,请告诉我们

将 Python 与 GitHub 操作一起使用

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

本文内容

简介

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

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

基本要求

您应该熟悉 YAML 和 GitHub 操作 的语法。 更多信息请参阅“GitHub 操作 的工作流程语法”。

建议您对 Python、PyPy 和 pip 有个基本的了解。 更多信息请参阅:

从 Python 工作流程模板开始

GitHub 提供有 Python 工作流程模板,应该适用于大多数 Python 项目。 本指南包含可用于自定义模板的示例。 更多信息请参阅 Python 工作流程模板

要快速开始,请将模板添加到仓库的 .github/workflows 目录中。

name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [2.7, 3.5, 3.6, 3.7, 3.8]

    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,这可继续用于作业的其余部分。 If a specific version of Python is not pre-installed in the tools cache, the setup-python action will download and set up the appropriate version from the python-versions repository.

使用 setup-action 是 Python 与 GitHub 操作 结合使用时的推荐方式,因为它能确保不同运行器和不同版本的 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\*

If you are using a self-hosted runner, you can configure the runner to use the setup-python action to manage your dependencies. For more information, see using setup-python with a self-hosted runner in the setup-python README.

GitHub 支持语义版本控制语法。 更多信息请参阅“使用语义版本控制”和“语义版本控制规范”。

使用多个 Python 版本

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.5, 3.6, 3.7, 3.8]

    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.8。或者,您也可以通过语义版本语法来获得最新的次要版本。 此示例使用 Python 3 最新的次要版本。

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 操作 的工作流程语法”。

name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        python-version: [2.7, 3.6, 3.7, 3.8, pypy2, pypy3]
        exclude:
          - os: macos-latest
            python-version: 3.6
          - os: windows-latest
            python-version: 3.6

使用默认 Python 版本

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

GitHub 托管的运行器Description
UbuntuUbuntu 运行器有多个版本的系统 Python 安装在 /usr/bin/python/usr/bin/python3 下。 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 软件包。

您也可以缓存依赖项来加快工作流程。 更多信息请参阅“缓存依赖项以加快工作流程”。

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 后,下一步通常是从 requires.txt 安装依赖项。

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

缓存依赖项

您可以使用唯一密钥缓存 pip 依赖项,并在使用 cache 操作运行未来的工作流程时恢复依赖项。 更多信息请参阅“缓存依赖项以加快工作流程”。

Pip 根据运行器的操作系统将依赖项缓存在不同的位置。 您需要缓存的路径可能不同于下面的 Ubuntu 示例,具体取决于您使用的操作系统。 更多信息请参阅 Python 缓存示例

steps:
- uses: actions/checkout@v2
- name: Setup Python
  uses: actions/setup-python@v2
  with:
    python-version: '3.x'
- name: Cache pip
  uses: actions/cache@v1
  with:
    # This path is specific to Ubuntu
    path: ~/.cache/pip
    # Look to see if there is a cache hit for the corresponding requirements file
    key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-
      ${{ runner.os }}-
- name: Install dependencies
  run: pip install -r requirements.txt

注意:取决于依赖项的数量,使用依赖项缓存可能会更快。 有很多大型依赖项的项目应该能看到性能明显提升,因为下载所需的时间会缩短。 依赖项较少的项目可能看不到明显的性提升,甚至可能由于pip 安装缓存依赖项的方式而看到性能略有下降。 性能因项目而异。

测试代码

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

使用 pytest 和 pytest-cov 测试

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

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 并用它来嵌入所有文件。 更多信息请参阅 Flake8

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 .

使用 tox 运行测试

通过 GitHub 操作,您可以使用 tox 运行测试并将工作分散到多个作业。 您需要使用 -e py 选项调用 tox,以在 PATH 中选择 Python 版本,而不是指定特定版本。 更多信息请参阅 tox

name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python: [2.7, 3.7, 3.8]

    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 操作

name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [2.7, 3.5, 3.6, 3.7, 3.8]

      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@v1
        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 包发布到您想要的任何包注册表。

您可以使用仓库密码存储发布软件包所需的访问令牌或凭据。 下面的示例使用 twinedist 创建包并发布到 PyPI。 更多信息请参阅“创建和使用加密密码”。

name: Upload Python Package

on:
  release:
    types: [created]

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 setuptools wheel twine
    - name: Build and publish
      env:
        TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
        TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
      run: |
        python setup.py sdist bdist_wheel
        twine upload dist/*

有关模板工作流程的更多信息,请参阅 python-published

问问别人

找不到要找的内容?

联系我们