今回は Python のプロジェクトで GitHub Actions を導入する方法をご紹介します。実際に動くかんたんなサンプルを使って説明します。
追記 2020/07/23:
Poetry をインストールするアクション dschep/install-poetry-action
を使う方法を紹介していましたが、こちらはメンテナンスされなくなっているようなので、使わない形での説明に変更しました。
GitHub Actions とは
最初に GitHub Actions についてかんたんに説明します。
GitHub Actions とは GitHub 公式のワークフロー自動化ツールです。
2018 年 10 月にパブリックベータ版が公開され、 2019 年の 11 月に一般公開されました。それまで GitHub で CI/CD を行うには外部のサービスを利用する必要がありましたが、 GitHub Actions が導入されたことでコード管理と CI/CD を GitHub 内で一元的に行えるようになりました。
GitHub Actions は、 GitHub で管理されているリポジトリにディレクトリ .github/workflows/
を作成してその下に自動化したい処理を記述した YAML 形式の設定ファイルを置けばすぐに利用し始めることができます。処理を実行するプラットフォームは Linux / macOS / Windows の中からひとつ(または複数)選ぶことができます。
GitHub Actions の特徴のひとつに、 GitHub や他の人が作成し GitHub 上に公開したアクションを利用できる点があります。たとえば、次の内容を設定ファイルに記述すると、 actions/checkout
と actions/setup-python
というアクションをかんたんに利用することができます。
name: pytest
on:
push:
jobs:
pytest:
name: Run tests with pytest
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
汎用度の高いアクションは誰かがオープンソースとして公開してくれていたりもするので、必ずしもすべての手順を自分でゼロから書く必要はありません。 CI/CD の経験があまり無い方やプログラミング初心者の方にも始めやすいかと思います。
Python プロジェクトでの GitHub Actions の使い方
Python プロジェクトでの GitHub Actions の使い方を説明します。
といっても、公式のドキュメントを読めば大体のことは書かれているので、スラスラと読んで理解できる方は公式のドキュメントを読むのがいちばんです。ここでは動くサンプルを使ってさわりの部分だけ説明します。
お話の前提として、 GitHub にアカウントを持っていて Python プロジェクトのリポジトリを置いているものとします。
GitHub Actions を使い始める方法は 2 つあります。
- ブラウザで Actions のページを開く
- ファイル
.github/workflows/xxx.yml
をコミットする
ブラウザで Actions のページを開くにはリポジトリの「 Actions 」タブをクリックします。ファイル .github/workflows/xxx.yml
をコミットする場合は、手元のテキストエディタとターミナルをそのまま使います。どちらの形を選んでも最終的にできることは同じです。
以下、テストとスタイルチェックを行うかんたんなサンプルを使って説明します。次のツールを使用します。
poetry
: 依存パッケージを管理するpytest
: テストを実行するblack
: コーディングスタイルのチェックを行う
最初に GitHub 上に空のリポジトリを作成して、次の内容のファイル hello.py
をコミットします。
hello.py
:
"""関数 `hello()` を提供する"""
def hello(name: str = "world") -> None:
"""`Hello, xxx.` のメッセージを出力する"""
print(f"Hello, {name}.")
続いて、テストファイルを作成します。 tests/test_hello.py
あたりに作るのがよいでしょうか。
tests/test_hello.py
:
from hello import hello
def test_hello_default(capsys):
hello()
out, err = capsys.readouterr()
assert out == "Hello, world.\n"
def test_hello_with_name(capsys):
hello("サザエ")
hello("カツオ")
out, err = capsys.readouterr()
assert out == "Hello, サザエ.\n" "Hello, カツオ.\n"
これは pytest
用に作ったテストなので pytest
をインストールします。私は Python のパッケージには poetry
をよく使いますがここは pip
でもそれ以外のものでもかまいません。
poetry add --dev pytest
pytest
が無事にインストールできたら、 setup.py
を作成してからテストを実行します。
setup.py
:
from setuptools import setup, find_packages
setup(name="hello-github-actions", version="1.0", packages=find_packages())
poetry run pytest tests/test_hello.py
============================= test session starts ---===========================
platform linux -- Python 3.7.4, pytest-5.4.1, py-1.8.1, pluggy-0.13.1
rootdir: /app
collected 2 items
tests/test_hello.py .. [100%]
============================== 2 passed in 0.13s ---============================
成功することが確認できました。
続いて、このテストを GitHub Actions で実行するように設定ファイルを書きます。
リポジトリのルートに .github/workflows/ci.yml
というファイルを作成し以下の内容で保存します。
.github/worflows/ci.yml
:
name: pytest
on:
push:
pull_request:
jobs:
pytest:
name: Run tests with pytest
# 実行環境として `ubuntu-latest` という名前のものを選ぶ
runs-on: ubuntu-latest
# 複数の Python のバージョンでテストするために `strategy.matrix` を設定する
strategy:
matrix:
python-version: [3.7, 3.8]
steps:
# リポジトリをチェックアウトする
# See: https://github.com/actions/checkout
- name: Checkout
uses: actions/checkout@v2
# Python のランタイムをセットアップする
# バージョンは `strategy.matrix` に並べたものを指定する
# See: https://github.com/actions/setup-python
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
# Poetry そのものをインストールする
- name: Install Poetry
run: |
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python
# Poetry へのパスを通す
- name: Add path for Poetry
run: echo "::add-path::$HOME/.poetry/bin"
# インストールした Poetry を使って必要な Python パッケージをインストールする
- name: Install Dependencies
run: poetry install --no-interaction
# pytest を実行する
- name: Run Tests
run: poetry run pytest tests/
メインは jobs.pytest.steps
の部分です。ここに指定したアクションが上から順に実行されます。
Python プロジェクトで GitHub Actions を使う場合はおそらく最初の 2 ステップ(チェックアウトと Python ランタイムのセットアップ)はほぼ共通になると思います。
各アクションがどういうことをしているかについてはインラインのコメントを見てください。
ちなみに、ディレクトリ .github/worflows/
はそのままこの名前にする必要がありますが、 ci.yml
はこの名前でないといけないわけではありません。適当にわかりやすい名前を付けるとよいと思います。
ファイルが作成できたらコミットします。 poetry
を使っている場合は pyproject.toml
と poetry.lock
を、 pip
を使っている場合は requirements.txt
も忘れずにコミットしましょう。
コミットができたら GitHub に push します。すると、リポジトリの Actions のページに yaml ファイルで設定したワークフローが追加されていてテスト用のタスクが実行されるはずです。
これがうまく行ったら、おまけで black
を使ったスタイルチェックも追加します。 poetry add
をして、先ほどの .github/workflows/ci.yml
を編集します。
poetry add --dev black
ファイルの末尾に以下の内容を追加します( black:
の行が jobs
の下に来るようにします)。インデントがおかしいと正しく動かないので注意してください。
black:
name: Check code style with Black
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python 3.7
uses: actions/setup-python@v1
with:
python-version: 3.7
- name: Install Poetry
uses: dschep/install-poetry-action@v1.3
- name: Install Dependencies
run: poetry install --no-interaction
- name: Check code style with Black
run: poetry run black --check --diff .
コードに問題がなければ、このワークフローも GitHub Actions で実行され、結果が success として報告されるはずです。
ということで、かんたんではありましたが、 Python プロジェクトでの GitHub Actions の使い方についてでした。 GitHub Actions について深く知りたい方は公式のドキュメントその他を確認していただければと思います。
今回使ったサンプルを少し整理して GitHub にあげているので、興味のある方は参考にしてみてください:
この記事を書いている時点で GitHub Actions は無料で利用できますが、金額等は時間が経つと変わると思うので、ここには載せません。 GitHub 公式の情報を確認してみてください。
参考リンク
- Features • GitHub Actions · GitHub
- GitHub Actions Documentation - GitHub Help
- Using Python with GitHub Actions - GitHub Help
- GitHub Marketplace · Actions to improve your workflow · GitHub
- GitHub Actions now supports CI/CD, free for public repositories
- GitHub Actions: built by you, run by us - The GitHub Blog