はじめに
このガイドは、Pythonパッケージのビルド、テスト、公開の方法を紹介します。
GitHub ホスト ランナーには、Python と PyPy を含む、ソフトウェアがプレインストールされたツール キャッシュがあります。 自分では何もインストールする必要がありません! 最新のソフトウェアと、Python および PyPy のプレインストールされたバージョンの完全なリストについては、「GitHub ホステッド ランナーの概要」を参照してください。
前提条件
YAMLとGitHub Actionsの構文に馴染んでいる必要があります。 詳しくは、「GitHub Actions について」を参照してください。
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: ["3.7", "3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- 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 with ruff
run: |
# stop the build if there are Python syntax errors or undefined names
ruff --format=github --select=E9,F63,F7,F82 --target-version=py37 .
# default set of ruff rules with GitHub Annotations
ruff --format=github --target-version=py37 .
- name: Test with pytest
run: |
pytest
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の複数バージョンの利用
name: Python package
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
# You can use PyPy versions in python-version.
# For example, pypy2.7 and pypy3.9
matrix:
python-version: ["2.7", "3.7", "3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
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.10 です。 あるいは、最新のマイナーリリースを取得するためにセマンティックバージョン構文を使うこともできます。 以下の例では、Python 3の最新のマイナーリリースを使います。
name: Python package
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.x
uses: actions/setup-python@v4
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.6 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.7", "3.8", "3.9", "3.10", "3.11", pypy2.7, pypy3.9]
exclude:
- os: macos-latest
python-version: "3.7"
- os: windows-latest
python-version: "3.7"
デフォルトバージョンの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@v3
- name: Set up Python
uses: actions/setup-python@v4
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@v3
- name: Set up Python
uses: actions/setup-python@v4
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@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
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@v3
- name: Set up Python
uses: actions/setup-python@v4
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
コードの lint に Ruff を使う
以下の例では、ruff
をインストールまたはアップグレードし、それを使ってすべてのファイルを lint します。 詳しくは、「Ruff」を参照してください。
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
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 --format=github --target-version=py37 .
continue-on-error: true
リンティング ステップには continue-on-error: true
が設定されています。 これにより、リンティング ステップが成功しなかった場合にワークフローが失敗しなくなります。 すべてのリンティング エラーに対処したら、ワークフローで新しい Issue を見つけられるようにこのオプションを削除できます。
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.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Setup Python
uses: actions/setup-python@v4
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.7", "3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Setup Python # Set Python version
uses: actions/setup-python@v4
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() }}
パッケージレジストリへの公開
CI テストにパスしたら、Python パッケージをパッケージ レジストリに公開するようにワークフローを構成できます。 このセクションでは、GitHub Actions を使用して、リリースを公開するたびにパッケージを PyPI にアップロードする方法について説明します。
この例では、2 つの PyPI API トークンを作成する必要があります。 パッケージを公開するのに必要なトークンまたは資格情報を格納するために、シークレットを使用することができます。 詳しくは、「暗号化されたシークレット」を参照してください。
# このワークフローはGitHubによって認定されていないアクションを使用します。
# それらはサードパーティによって提供され、
# 別個の利用規約、プライバシーポリシー、
# ドキュメントを参照してください。
# GitHub では、コミット SHA にアクションをピン留めすることが推奨されます。
# 新しいバージョンを取得するには、SHA を更新する必要があります。
# タグまたはブランチを参照することもできますが、アクションは警告なしに変更される可能性があります。
name: Upload Python Package
on:
release:
types: [published]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
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
」を参照してください。