注: GitHub ホステッド ランナーは、現在 GitHub Enterprise Server でサポートされていません。 GitHub public roadmap で、今後の計画的なサポートの詳細を確認できます。
はじめに
このガイドは、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 のワークフロー テンプレートを提供します。 このガイドの以降のセクションでは、このワークフロー テンプレートをカスタマイズする方法の例を示します。
-
GitHub で、リポジトリのメイン ページに移動します。
-
リポジトリ名の下にある [アクション] をクリックします。
-
ワークフローが既にリポジトリ内にある場合は、 [新しいワークフロー] をクリックします。
-
[ワークフローの選択] ページには、推奨されるワークフロー テンプレートの選択が表示されます。 「Python アプリケーション」を検索します。
-
[Python アプリケーション] ワークフローで、[構成] をクリックします。
「Python アプリケーション」ワークフロー テンプレートが見つからない場合は、次のワークフロー コードをリポジトリの
.github/workflows
ディレクトリでpython-app.yml
を呼び出した新しいファイルにコピーします。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.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
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.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
-
必要に応じてワークフローを編集します。 たとえば、Python のバージョンを変更します。
-
[変更をコミットする] をクリックします。
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ホストランナー内でのツールキャッシュの場所です。
Ubuntu | Mac | Windows | |
---|---|---|---|
ツール キャッシュ ディレクトリ | /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
README のセルフホスト ランナーでの setup-python の使用に関するページを参照してください。
GitHubは、セマンティックバージョン構文をサポートしています。 詳細については、「セマンティック バージョニングの使用」および「セマンティック バージョニングの仕様」を参照してください。
Pythonの複数バージョンの利用
次の例では、ジョブのマトリックスを使用して、複数の Python バージョンを設定します。 詳しくは、「ワークフローでのジョブのバリエーションの実行」を参照してください。
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@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.10", "3.9", "3.10", "3.11", "3.12", "3.13"]
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)"
特定のバージョンのPythonの利用
特定のバージョンの Python を設定することができます。 たとえば、3.12 などです。 あるいは、最新のマイナーリリースを取得するためにセマンティックバージョン構文を使うこともできます。 以下の例では、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)"
バージョンの除外
使用できない Python のバージョンを指定すると、setup-python
が ##[error]Version 3.7 with arch x64 not found
などのエラーで失敗します。 このエラーメッセージには、利用できるバージョンが含まれます。
実行したくない Python の構成がある場合は、ワークフローで exclude
キーワードを使用することもできます。 詳しくは、「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.11", "3.13", "pypy3.10"] exclude: - os: macos-latest python-version: "3.11" - os: windows-latest python-version: "3.11"
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の利用
依存関係を明示的にしやすくなるので、ワークフローで使用する Python のバージョンの構成には setup-python
を使うことをお勧めします。 setup-python
を使わない場合は、python
の呼び出し時にいずれかのシェルで PATH
に設定された既定のバージョンの Python が使用されます。 デフォルトバージョンのPythonは、GitHubホストランナーによって様々なので、予想外の変更が生じたり、期待しているよりも古いバージョンが使われたりするかもしれません。
GitHubホストランナー | 説明 |
---|---|
Ubuntu | Ubuntu ランナーでは、/usr/bin/python および /usr/bin/python3 の下に複数のバージョンのシステム Python がインストールされています。 GitHubがツールキャッシュにインストールしエチルバージョンに加えて、UbuntuにパッケージングされているバージョンのPythonがあります。 |
Windows | ツールキャッシュにあるPythonのバージョンを除けば、WindowsにはシステムPythonに相当するバージョンは含まれていません。 他のランナーとの一貫した動作を保ち、setup-python アクションなしですぐに Python が使えるようにするために、GitHub ではツール キャッシュからいくつかのバージョンを PATH に追加します。 |
macOS | macOSランナーには、ツールキャッシュ内のバージョンに加えて、複数バージョンのシステムPythonがインストールされています。 システム Python バージョンは /usr/local/Cellar/python/* ディレクトリにあります。 |
依存関係のインストール
GitHubホストランナーには、パッケージマネージャーのpipがインストールされています。 コードのビルドとテストに先立って、pipを使ってパッケージレジストリのPyPIから依存関係をインストールできます。 たとえば、以下の YAML では、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
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
Requirementsファイル
pip
の更新後の一般的な次の手順は、requirements.txt から依存関係をインストールすることです。 詳しくは、「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
依存関係のキャッシング
setup-python
アクションを使用して依存関係をキャッシュおよび復元できます。
次の例では pip の依存関係をキャッシュします。
steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.12' 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.12'
cache: 'pip'
- run: pip install -r requirements.txt
- run: pip test
既定で、setup-python
アクションでは、リポジトリ全体で依存関係ファイル (pip の場合は requirements.txt
、pipenv の場合は Pipfile.lock
、poetry の場合は poetry.lock
) を検索します。 詳細については、setup-python
README のパッケージの依存関係のキャッシュに関するページを参照してください。
カスタム要件がある場合、またはキャッシュに対してより細かい制御が必要な場合は、cache
アクションを使用できます。 ランナーのオペレーティングシステムによって、pipは依存関係を様々な場所にキャッシュします。 キャッシュする必要があるパスは、使用するオペレーティング システムによって、上記の Ubuntu の例とは異なる場合があります。 詳細については、cache
アクション リポジトリの Python キャッシュの例に関するページを参照してください。
コードのテスト
ローカルで使うのと同じコマンドを、コードのビルドとテストに使えます。
pytest及びpytest-covでのテスト
この例では、pytest
および pytest-cov
をインストールまたはアップグレードします。 そしてテストが実行され、JUnit形式で出力が行われ、一方でコードカバレッジの結果がCoberturaに出力されます。 詳細については、JUnit と 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
Ruff を使用してコードのリントや書式設定を行う
以下の例では、ruff
をインストールまたはアップグレードし、それを使ってすべてのファイルを lint します。 詳しくは、「Ruff」を参照してください。
steps: - uses: actions/checkout@v4 - 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
steps:
- uses: actions/checkout@v4
- 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でテストを実行し、その処理を複数のジョブに分散できます。 tox を起動する際には、特定のバージョンを指定するのではなく、-e py
オプションを使って PATH
の Python のバージョンを選択する必要があります。 詳細については、tox に関するページを参照してください。
name: Python package on: [push] jobs: build: runs-on: ubuntu-latest strategy: matrix: python: ["3.9", "3.11", "3.13"] 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.11", "3.13"]
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
成果物としてのワークフローのデータのパッケージ化
ワークフローの完了後に、成果物をアップロードして見ることができます。 たとえば、ログファイル、コアダンプ、テスト結果、スクリーンショットを保存する必要があるかもしれません。 詳しくは、「ワークフローからのデータの格納と共有」を参照してください。
以下の例は、upload-artifact
アクションを使って pytest
の実行によるテスト結果をアーカイブする方法を示しています。 詳細については、「upload-artifact
アクション」を参照してください。
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@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.9", "3.10", "3.11", "3.12", "3.13"]
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() }}
PyPI への発行
CI テストにパスしたら、Python パッケージを PyPI に公開するようにワークフローを構成できます。 このセクションでは、GitHub Actions を使用して、リリースを公開するたびにパッケージを PyPI にアップロードする方法について説明します。 詳しくは、「リポジトリのリリースを管理する」を参照してください。
次のワークフロー例では、信頼された出版を設定する を使用して PyPI で認証を行います。これには、手動で構成された API トークンは不要です。
# このワークフローは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@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@6f7e8d9c0b1a2c3d4e5f6a7b8c9d0e1f2a3b4c5d
# このワークフローは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@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@6f7e8d9c0b1a2c3d4e5f6a7b8c9d0e1f2a3b4c5d