Skip to main content

Enterprise Server 3.21 は、現在リリース候補として使用できます。

Pythonの構築とテスト

継続的インテグレーション (CI) ワークフローを作成して、Python プロジェクトをビルドしてテストする方法について説明します。

メモ

GitHub Enterprise Server ホステッド ランナーは、現在 GitHub ではサポートされていません。

はじめに

このガイドでは、Python パッケージをビルド、テスト、発行する方法について説明します。

GitHub ホストランナーには、Pythonと PyPy を含む、プレインストールされたソフトウェアを含むツール キャッシュがあります。 自分では何もインストールする必要がありません! 最新のソフトウェアと、Python および PyPy のプリインストール済みのバージョンの完全な一覧については、GitHub ホステッド ランナー を参照してください。

前提条件

YAML と GitHub Actionsの構文について理解している必要があります。 詳しくは、「ワークフローの書き込み」をご覧ください。

Pythonと pip の基本的な理解をお勧めします。 詳細については、以下を参照してください:

GitHub Enterprise Server上でのセルフホストランナーの利用

GitHub Enterprise Server でセルフホスト ランナーと合わせてセットアップ アクション (actions/setup-LANGUAGE など) を使用するときに、インターネットにアクセスできないランナー上にツール キャッシュを設定する必要がある場合があります。 詳しくは、「インターネットにアクセスできないセルフホストランナーにツールキャッシュを設定する」をご覧ください。

Python ワークフロー テンプレートの使用

すぐに開始するには、リポジトリの .github/workflows ディレクトリにワークフロー テンプレートを追加します。

GitHub には、リポジトリに少なくとも 1 つの .py ファイルが既に含まれている場合に機能するPythonのワークフロー テンプレートが用意されています。 このガイドの以降のセクションでは、このワークフロー テンプレートをカスタマイズする方法の例を示します。

  1. GitHub で、リポジトリのメイン ページに移動します。

  2. リポジトリ名の下にある [ Actions] をクリックします。

    "github/docs" リポジトリのタブのスクリーンショット。 [アクション] タブがオレンジ色の枠線で強調表示されています。

  3. ワークフローが既にリポジトリ内にある場合は、 [新しいワークフロー] をクリックします。

  4. [ワークフローの選択] ページには、推奨されるワークフロー テンプレートの選択が表示されます。 "Python アプリケーション" を検索します。

  5. [Python アプリケーション] ワークフローで、Configure をクリックします。

    "Python アプリケーション" ワークフロー テンプレートが見つからない場合は、リポジトリの python-app.yml ディレクトリにある .github/workflows という名前の新しいファイルに次のワークフロー コードをコピーします。

    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@v6
        - name: Set up Python 3.13
          uses: actions/setup-python@v5
          with:
            python-version: "3.13"
        - 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 and format Python code with ruff
          run: |
           # Lint with the default set of ruff rules with GitHub Annotations
           ruff check --format=github --target-version=py39
           # Verify the code is properly formatted
           ruff format --diff --target-version=py39
        - name: Test with pytest
          run: |
            pytest
    
  6. 必要に応じてワークフローを編集します。 たとえば、Pythonバージョンを変更します。

  7. [Commit changes] をクリックします。

Python バージョンの指定

GitHub ホストランナーでプレインストールされたバージョンのPythonまたは PyPy を使用するには、setup-python アクションを使用します。 このアクションでは、各ランナーのツール キャッシュから特定のバージョンのPythonまたは PyPy を検索し、必要なバイナリを PATH に追加します。このバイナリはジョブの残りの部分で保持されます。 特定のバージョンのPythonがツール キャッシュにプレインストールされていない場合、setup-python アクションは、python-versions リポジトリから適切なバージョンをダウンロードして設定します。

setup-python アクションを使用すると、GitHub Actions でPythonを使用することをお勧めします。これは、異なるランナーと異なるバージョンの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 README を参照してください。

GitHub では、セマンティック バージョン管理構文がサポートされています。 詳細については、セマンティック バージョニングの使用セマンティック バージョニングの仕様に関するページを参照してください。

複数のPython バージョンの使用

次の例では、ジョブのマトリックスを使用して、複数のPython バージョンを設定します。 詳しくは、「ワークフローでのジョブのバリエーションの実行」をご覧ください。

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["pypy3.10", "3.9", "3.10", "3.11", "3.12", "3.13"]

    steps:
      - uses: actions/checkout@v6
      - 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)"

特定のPython バージョンの使用

特定のバージョンのPythonを構成できます。 たとえば、3.12 などです。 あるいは、最新のマイナーリリースを取得するためにセマンティックバージョン構文を使うこともできます。 この例では、Python 3 の最新のマイナー リリースを使用します。

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v6
      - 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)"

バージョンの除外

使用できないPythonのバージョンを指定した場合、setup-python は次のようなエラーで失敗##[error]Version 3.7 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.9", "3.11", "3.13", "pypy3.10"]
        exclude:
          - os: macos-latest
            python-version: "3.11"
          - os: windows-latest
            python-version: "3.11"

既定のPython バージョンの使用

setup-python を使用して、ワークフローで使用されるPythonのバージョンを構成することをお勧めします。これは、依存関係を明示的にするのに役立ちます。 setup-python を使用しない場合、PATH を呼び出すときに、python で設定された既定のバージョンのPythonが任意のシェルで使用されます。 Pythonの既定のバージョンは、GitHub ホストランナーによって異なります。これにより、予期しない変更が発生したり、予想よりも古いバージョンが使用されたりする可能性があります。

GitHub-ホステッド ランナー説明
UbuntuUbuntu ランナーには、/usr/bin/python および /usr/bin/python3 の下に複数のバージョンのシステム Pythonがインストールされています。 Ubuntu と共にパッケージ化されたPythonバージョンは、ツール キャッシュに GitHub インストールされるバージョンに追加されます。
Windowsツール キャッシュ内のPythonのバージョンを除き、Windowsには同等のバージョンのシステム Pythonが付属していません。 他のランナーとの一貫性のある動作を維持し、setup-python アクションなしでPythonをすぐに使用できるようにするには、GitHub はツール キャッシュから PATH にいくつかのバージョンを追加します。
macOSmacOS ランナーには、ツール キャッシュの一部であるバージョンに加えて、複数のバージョンのシステム Pythonがインストールされています。 システム Pythonバージョンは、/usr/local/Cellar/python/* ディレクトリにあります。

依存関係のインストール

GitHubホステッド ランナーには pip パッケージ マネージャーがインストールされています。 コードのビルドとテストに先立って、pipを使ってパッケージレジストリのPyPIから依存関係をインストールできます。 たとえば、以下の YAML では、pip パッケージ インストーラーと、setuptools および wheel パッケージがインストールまたはアップグレードされます。

ワークフローの速度を上げるために、依存関係をキャッシュすることもできます。 詳しくは、「依存関係キャッシュのリファレンス」をご覧ください。

YAML
steps:
- uses: actions/checkout@v6
- 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

要件ファイル

pip の更新後、一般的な次の手順は、requirements.txt から依存関係をインストールすることです。 詳しくは、「pip」をご覧ください。

YAML
steps:
- uses: actions/checkout@v6
- 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

依存関係のキャッシング

setup-pythonアクションを使用して依存関係をキャッシュおよび復元できます。

次の例では pip の依存関係をキャッシュします。

YAML
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v5
  with:
    python-version: '3.12'
    cache: 'pip'
- run: pip install -r requirements.txt
- run: pip test

既定で、setup-python アクションでは、リポジトリ全体で依存関係ファイル (pipは requirements.txt、pipenvは Pipfile.lock、poetryは poetry.lock) を検索します。 詳細については、 の README の「setup-python」をご覧ください。

カスタム要件がある場合、またはキャッシュに対してより細かい制御が必要な場合は、cache アクションを使用できます。 ランナーのオペレーティングシステムによって、pipは依存関係を様々な場所にキャッシュします。 キャッシュする必要があるパスは、使用するオペレーティング システムによって、上記の Ubuntu の例とは異なる場合があります。 詳細については、 アクション リポジトリのcacheを参照してください。

コードのテスト

ローカルで使うのと同じコマンドを、コードのビルドとテストに使えます。

pytest及びpytest-covでのテスト

この例では、pytest および pytest-cov をインストールまたはアップグレードします。 そしてテストが実行され、JUnit形式で出力が行われ、一方でコードカバレッジの結果がCoberturaに出力されます。 詳細については、JUnitCobertura に関するページを参照してください。

YAML
steps:
- uses: actions/checkout@v6
- 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

Ruff を使用してコードのリントや書式設定を行う

以下の例では、ruff をインストールまたはアップグレードし、それを使ってすべてのファイルを lint します。 詳しくは、「Ruff」を参照してください。

YAML
steps:
- uses: actions/checkout@v6
- name: Set up Python
  uses: actions/setup-python@v5
  with:
    python-version: '3.x'
- name: Install the code linting and formatting tool Ruff
  run: pipx install ruff
- name: Lint code with Ruff
  run: ruff check --output-format=github --target-version=py39
- name: Check code formatting with Ruff
  run: ruff format --diff --target-version=py39
  continue-on-error: true

書式設定ステップが 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.9", "3.11", "3.13"]

    steps:
      - uses: actions/checkout@v6
      - 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

成果物としてのワークフローのデータのパッケージ化

ワークフローの完了後に、成果物をアップロードして見ることができます。 たとえば、ログファイル、コアダンプ、テスト結果、スクリーンショットを保存する必要があるかもしれません。 詳しくは、「ワークフロー成果物を使ったデータの格納と共有」をご覧ください。

以下の例は、upload-artifact アクションを使って pytest の実行によるテスト結果をアーカイブする方法を示しています。 詳細については、「upload-artifactアクション」を参照してください。

YAML
name: Python package

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]

    steps:
      - uses: actions/checkout@v6
      - 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() }}

PyPI への発行

CI テストに合格したら、Python パッケージを PyPI に発行するようにワークフローを構成できます。 このセクションでは、リリースを発行するたびに、 GitHub Actions を使用してパッケージを PyPI にアップロードする方法について説明します。 詳しくは、「リポジトリのリリースを管理する」をご覧ください。

次のワークフロー例では、信頼された出版を設定する を使用して PyPI で認証を行います。これには、手動で構成された API トークンは不要です。

YAML
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。

# GitHub では、コミット SHA にアクションをピン留めすることが推奨されます。
# 新しいバージョンを取得するには、SHA を更新する必要があります。
# タグまたはブランチを参照することもできますが、アクションは警告なしに変更される可能性があります。

name: Upload Python Package

on:
  release:
    types: [published]

permissions:
  contents: read

jobs:
  release-build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v6

      - 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@6f7e8d9c0b1a2c3d4e5f6a7b8c9d0e1f2a3b4c5d