はじめに
このガイドは、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: [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: |
# Python 構文エラーまたは未定義の名前がある場合はビルドを停止する
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zeroはすべてのエラーを警告として扱う。 GitHubのエディタの幅は127文字
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-action
の利用は、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:
# python-version内のPyPyのバージョンが利用できる。
# 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 }}
# 現在の Python バージョンを印刷して、マトリックスをテストできます
- 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:
# セマンティックバージョン範囲構文もしくは厳密なPythonのバージョン
python-version: '3.x'
# オプション - x64もしくはx86アーキテクチャ、デフォルトはx64
architecture: 'x64'
# 現在のPythonのバージョンを出力して、マトリクスをテストできる
- 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 のワークフロー構文」を参照してください。
name: Python package
on: [push]
jobs:
build:
runs-on: ${{ matrix.os }}
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の利用
依存関係を明示的にしやすくなるので、ワークフロー中で使う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/* mディレクトリにあります。 |
依存関係のインストール
GitHubホストランナーには、パッケージマネージャーのpipがインストールされています。 コードのビルドとテストに先立って、pipを使ってパッケージレジストリのPyPIから依存関係をインストールできます。 たとえば以下のYAMLはpip
パッケージインストーラーとsetuptools
及びwheel
パッケージのインストールやアップグレードを行います。
GitHubホストランナーを使用する場合、依存関係をキャッシュしてワークフローの実行を高速化することもできます。 詳しい情報については、「ワークフローを高速化するための依存関係のキャッシュ」を参照してください。
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
Requirementsファイル
pip
をアップデートした後、次の典型的なステップはrequirements.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
依存関係のキャッシング
GitHub ホストランナーを使用する場合、一意のキーを使用して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@v2
with:
# このパスは Ubuntu に固有です
path: ~/.cache/pip
# 対応する要件ファイルにキャッシュヒットがあるかどうかを確認する
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でのテスト
以下の例では、pytest
及びpytest-cov
をインストールあるいはアップグレードします。 そしてテストが実行され、JUnit形式で出力が行われ、一方でコードカバレッジの結果がCoberturaに出力されます。 詳しい情報についてはJUnit及びCoberturaを参照してください。
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を使ったコードのlint
以下の例は、flake8
をインストールもしくはアップグレードし、それを使ってすべてのファイルをlintします。 詳しい情報については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 Actionsでは、toxでテストを実行し、その処理を複数のジョブに分散できます。 toxを起動する際には、特定のバージョンを指定するのではなく、-e py
オプションを使って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
# 「PATH」で Python のバージョンを使用して tox を実行する
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 }}
# pip及び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
# テストに失敗があった場合でもテスト結果が公開されるよう、always()を使って常にこのステップを実行する
if: ${{ always() }}
パッケージレジストリへの公開
CIテストにパスしたなら、Pythonパッケージを任意のパッケージレジストリに公開するようにワークフローを設定できます。
パッケージを公開するのに必要なアクセストークンや認証情報は、シークレットを使って保存できます。 以下の例では、twine
とdist
を使ってパッケージを作成して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-publish
を参照してください。