[Django+MySQL+GitHub Actions] 使用Matrix功能,在多个Python版本和Ubuntu上运行Pytest
前提 –
这次我们将以使用Matrix为例,使用Django、MySQL和Pytest。关于如何使用Django和MySQL的服务容器来执行Pytest的方法,请参考以下文章,本篇文章不会进行详细解释。
Matrix是什么?
-options:
1. 多个任务共用相同的工作流程
-
- 実行環境(Node.jsなど)
-
- runnerOS (Ubuntuなど)
- 言語(Pythonなど)
使用Matrix,我们可以在更新版本时进行验证和故障排除,以便运行在某个版本上的机制。
默认情况下,我们可以并行执行所有版本,如下所示。

另外,当使用Matrix时,一个任务失败将导致其他任务无法执行,这也是其特点之一(不过,除非添加了continue-on-error)。

Matrix的设置方法
在设置矩阵时,按照以下示例定义策略,然后在策略下定义矩阵。
在矩阵下定义任意变量,并将要测试的版本列表放入数组中。
jobs:
Setup:
name: Run Test Code
# 実行したいバッケージ等のバージョンを配列内にstrategyとmatrixに指定
strategy:
matrix:
python-version: [3.10.5, 3.10.6, 3.10.7]
os: [ubuntu-latest, ubuntu-20.04]
在工作中,要应用已在Matrix中定义的版本,请按照以下方式进行说明。
例如,当想要应用操作系统的版本时,请按照以下方式进行说明。
${{ matrix.os }}
我们来实际操作一下吧!
根据以上所述,如果应用Matrix,将会得到以下的示例
目录结构
❯ tree
.
├── .github
│ └── workflows
│ └── test.yml
└── application # Djangoのプロジェクトファイルおよびpyproject.tomlが入ったディレクトリ
├── project
│ └── settings.py
├── manage.py
├── poetry.lock
└── pyproject.toml
工作流程
name: Run Pytest Using Matrix
# ワークフローのイベントは任意です
# 今回は検証用なので手動でワークフローを実行するようにします
on: workflow_dispatch
env:
SECRET_KEY: test
DJANGO_SETTINGS_MODULE: project.settings
ALLOWED_HOSTS: 127.0.0.1
DEBUG: "True"
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test-db
MYSQL_HOST: 127.0.0.1
MYSQL_PORT: 3306
MYSQL_USER: test
MYSQL_PASSWORD: test
jobs:
Setup:
name: Run Test Code
# 実行したいバッケージ等のバージョンを配列内にstrategyとmatrixに指定
strategy:
matrix:
python-version: [3.10.5, 3.10.6, 3.10.7]
os: [ubuntu-latest, ubuntu-20.04]
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: application
services:
db:
image: mysql:8.0
ports:
- 3306:3306
env:
MYSQL_ROOT_PASSWORD: ${{ env.MYSQL_ROOT_PASSWORD }}
MYSQL_DATABASE: ${{ env.MYSQL_DATABASE }}
MYSQL_USER: ${{ env.MYSQL_USER }}
MYSQL_PASSWORD: ${{ env.MYSQL_PASSWORD }}
options: >-
--health-cmd "mysqladmin ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Chekcout code
uses: actions/checkout@v3
- name: Grant privileges to user
run: mysql --protocol=tcp -h 127.0.0.1 -P 3306 -u root -p$MYSQL_ROOT_PASSWORD -e "GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_USER'@'%'; FLUSH PRIVILEGES;"
- name: Install poetry
run: pipx install poetry
- name: Use cache dependencies
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
cache: 'poetry'
- name: Install Packages
run: poetry install
- name: Run migration
run: |
poetry run python manage.py makemigrations
poetry run python manage.py migrate
- name: Run Pytest
run: poetry run pytest -x -n auto --cov --no-cov-on-fail --suppress-no-test-exit-code
Django的配置
import os
SECRET_KEY = os.environ.get("SECRET_KEY")
DEBUG = os.environ.get("DEBUG") == "True"
ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS").split(" ")
# データベースの設定を行う
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": os.environ.get("MYSQL_DATABASE"),
"USER": os.environ.get("MYSQL_USER"),
"PASSWORD": os.environ.get("MYSQL_PASSWORD"),
"HOST": os.environ.get("MYSQL_HOST", "db"),
"PORT": os.environ.get("MYSQL_PORT", 3306),
}
}

只想添加特定版本。
比如说
-
- Python 3.10.8
- Ubuntu 18.04
当您只想对额外进行验证的时候,可以使用”include”。
如果将这两个都放入数组中,那么会
-
- Python 3.10.8
- Ubuntu 20.04 と latest
为了避免运行不必要的Job版本,甚至包括不需要执行的Job版本,因此在这种情况下使用include。
strategy:
matrix:
python-version: [3.10.5, 3.10.6, 3.10.7]
os: [ubuntu-latest, ubuntu-20.04]
# includeを使って python-version: 3.10.8 と ubuntu-18.04 のみ追加
include:
- python-version: 3.10.8
os: ubuntu-18.04
以以下方式为例:
-
- Python 3.10.8
- Ubuntu 18.04
我只确认了工作已经被添加了。

当需要仅排除特定版本时
本次使用exclude与include相反,仅排除特定版本。
-
- Python 3.10.5
- Ubuntu 20.04
我会让job不被执行。
strategy:
matrix:
python-version: [3.10.5, 3.10.6, 3.10.7]
os: [ubuntu-latest, ubuntu-20.04]
# includeを使って python-version: 3.10.5 と ubuntu-20.04 のみ除外
exclude:
- python-version: 3.10.5
os: ubuntu-20.04
按照下述的方式
-
- Python 3.10.5
- Ubuntu 20.04

请参阅