Python プロジェクトをReviewdogでチェックする

前回追加した black, mypy, flake8 などを GitHub Actions でチェックできるようにします。
GitHub Actions では Reviewdog を使います。PR にコメントを残してくれます。

Reviewdog

ついでに ruff を追加インストールします。Ruff は Rust で書かれた linter です。

Ruff

  • OS: Xubuntu
  • Python: 3.10.x
  • Shell: zsh

1. black

.github/workflowsディレクトリを作り、その中にreviewdog.ymlファイルを作成します。

公式ページ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
---
name: Reviewdog
on: [pull_request]
permissions:
pull-requests: write
jobs:
python_check:
strategy:
matrix:
workdir:
- .
name: python_check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10"

- uses: reviewdog/action-setup@v1
with:
reviewdog_version: latest

- run: pip install black==23.1.0
- run: pip install poetry==1.4.0
- run: poetry install

- name: black
uses: reviewdog/action-black@v3
with:
black_args: "--config ./pyproject.toml"
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
fail_on_error: true
filter_mode: nofilter
workdir: ${{ matrix.workdir }}
  • GitHub Actions が pull request にコメントをつけるのでpull-requests: writeが必要です。
  • strategy は今回必要ありませんが、今後モノレポを扱う関係で追加しています。

2. mypy

tsuyoshicho/action-mypyを動かす方法がわからなかったので自前で設定します。

以下を.github/workflows/reviewdog.ymlに追加します。

1
2
3
4
5
6
- name: mypy
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.github_token }}
run: |
poetry run mypy . | reviewdog -efm="%f:%l: %m" -name=mypy -reporter=github-pr-review -fail-on-error=true -filter-mode=nofilter
working-directory: ${{ matrix.workdir }}

オプションについて補足します。
mypy のエラーは以下のようにファイルパス,行番号,エラーメッセージの順に出力されます。なので%f:%l: %mを指定しています。

1
python_my_app/main.py:11: error: Unsupported operand types for + ("str" and "int") [operator]

3. flake8

公式ページ

以下を.github/workflows/reviewdog.ymlに追加します。

1
2
3
4
5
6
7
8
- name: flake8
uses: reviewdog/action-flake8@v3
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
fail_on_error: true
filter_mode: nofilter
workdir: ${{ matrix.workdir }}

特に説明はありません。

4. Ruff

まず仮想環境を有効にします。

1
. venv/bin/activate

Ruff をインストールします。

1
poetry add --group dev ruff

以下を.github/workflows/reviewdog.ymlに追加します。

1
2
3
4
5
6
- name: ruff
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.github_token }}
run: |
poetry run ruff check . | reviewdog -efm="%f:%l:%c: %m" -name=ruff -reporter=github-pr-review -fail-on-error=true -filter-mode=nofilter
working-directory: ${{ matrix.workdir }}

Ruff の場合は以下のようにカラム番号も出力されます。なので efm には%f:%l:%c: %mを指定しています。

1
python_my_app/main.py:1:8: F401 [*] `os` imported but unused

5. まとめ

最終的な.github/workflows/reviewdog.ymlは次のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
---
name: Reviewdog
on: [pull_request]
permissions:
pull-requests: write
jobs:
python_check:
strategy:
matrix:
workdir:
- .
name: python_check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10"

- uses: reviewdog/action-setup@v1
with:
reviewdog_version: latest

- run: pip install black==23.1.0
- run: pip install poetry==1.4.0
- run: poetry install

- name: ruff
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.github_token }}
run: |
poetry run ruff check . | reviewdog -efm="%f:%l:%c: %m" -name=ruff -reporter=github-pr-review -fail-on-error=true -filter-mode=nofilter
working-directory: ${{ matrix.workdir }}

- name: mypy
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.github_token }}
run: |
poetry run mypy . | reviewdog -efm="%f:%l: %m" -name=mypy -reporter=github-pr-review -fail-on-error=true -filter-mode=nofilter
working-directory: ${{ matrix.workdir }}

- name: black
uses: reviewdog/action-black@v3
with:
black_args: "--config ./pyproject.toml"
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
fail_on_error: true
filter_mode: nofilter
workdir: ${{ matrix.workdir }}

- name: flake8
uses: reviewdog/action-flake8@v3
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
fail_on_error: true
filter_mode: nofilter
workdir: ${{ matrix.workdir }}

以上です。