[Django+MySQL+GitHub Actions] 使用Matrix功能,在多个Python版本和Ubuntu上运行Pytest

前提 –

这次我们将以使用Matrix为例,使用Django、MySQL和Pytest。关于如何使用Django和MySQL的服务容器来执行Pytest的方法,请参考以下文章,本篇文章不会进行详细解释。

 

Matrix是什么?

-options:
1. 多个任务共用相同的工作流程

    • 実行環境(Node.jsなど)

 

    • runnerOS (Ubuntuなど)

 

    言語(Pythonなど)

使用Matrix,我们可以在更新版本时进行验证和故障排除,以便运行在某个版本上的机制。
默认情况下,我们可以并行执行所有版本,如下所示。

スクリーンショット 2023-02-12 11.54.17.png

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

スクリーンショット 2023-02-12 11.55.03.png

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),
    }
}
スクリーンショット 2023-02-12 11.59.39.png

只想添加特定版本。

比如说

    • 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

我只确认了工作已经被添加了。

スクリーンショット 2023-02-12 12.14.17.png

当需要仅排除特定版本时

本次使用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
スクリーンショット 2023-02-12 12.17.24.png

请参阅

 

bannerAds