GitHubActionsでFormatter,Linter(black,flake8)を自動化

black,flake8を使ってのpythonのコードの自動整形をGitHubActionsで動作させようと思い調べて、検証してみました

### 使用するもの
- GitHubActions
pushなどする際にテスト等を自動化できるGitHubの機能
- black
Pythonのコードフォーマッター。コードを保存時に自動的に整形してくれるツールです。コードを整形せずに検証だけすることも可能です
- flake8
Pythonコードの静的解析を行うためのツール。コードのエラーチェックや`PEP8(Pythonのコーディング規約)`に沿ってコードが書かれているかを検証してくれます
[flake8エラーコード](https://flake8.pycqa.org/en/latest/user/error-codes.html)
[pep8エラーコードチートシート](https://qiita.com/KuruwiC/items/8e12704e338e532eb34a)

black,flake8はどちらも`PEP8`に沿ったコーディングを手助けしてくれるツールです

## ワークフローの設定
``` yaml:code-check.yaml
name: Code Check

on:
  push:
    branches:
      - "**"

jobs:
  format:
      runs-on: ubuntu-latest
      steps:
        - name: Checkout code
          uses: actions/checkout@v4
        - name: Set up Python
          uses: actions/setup-python@v4
          with:
            python-version: "3.11"
        - name: Install dependencies
          run: |
            python -m pip install --upgrade pip
            pip install --no-cache-dir -r requirements.txt
        - uses: psf/black@stable
          with:
            options: "--verbose"
            src: "./"
       # もしくは
       # - name: Run Black
       #  run: black .
        - name: Commit changes
          uses: stefanzweifel/git-auto-commit-action@v4
          with:
            commit_message: "Black format applied"
        - name: Run Flake8
          run: flake8 .
```

### ■ jobs内の処理
#### actions/checkout：チェックアウトしてコードにアクセス
#### actions/setup-python：Pythonの環境をセットアップ
#### psf/black：Blackを使用するActions(<span>@</span>stableで最新の安定版Blackを使用できます)
**psf/blackのパラメータ**
- **「options: "--verbose"」** optionを`--verbose`のみに指定しています
(デフォルトだと--checkが設定されているためコードが整形されません)
`--verbose` 除外パターンにより変更されなかったファイルまたは無視されたファイルに関するメッセージを出力します
- **「src: "./"」** フォーマット対象のディレクトリを指定します

[Black公式ドキュメント](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html)
[psf/blackのパラメータ定義](https://github.com/psf/black/blob/main/action.yml)


:::note warn
`psf/black`と`run: black .`はどちらもBlackを使用するものですが`psf/black`の方だと`actions/setup-python`などの環境構築をしなくても使えます。
:::

#### stefanzweifel/git-auto-commit-action：変更を自動的にコミットし、リポジトリにプッシュする
ワークフロー中に変更されたファイルを自動的にコミットし、リポジトリにプッシュするアクションです

**stefanzweifel/git-auto-commit-actionのパラメータ**
- **「commit_message」** コミットメッセージを指定します
- **「file_pattern」** コミット対象のファイルを絞り込むためのパターンを指定します（例: 「app/*.py」「*.py *.yaml *.md」など）

[stefanzweifel/git-auto-commit-actionのパラメータ定義](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/action.yml)

#### run: flake8 .：flake8を実行してコードを検証
Blackで整形した後のコードをさらに検証しています

**flake8のオプション**
(例：flake8 main.py --ignore E402 E403 --max-line-length 100)
- **「--ignore」** 無視するerrorを指定します
- **「--max-line-length」** 1行あたりの最大文字数を指定します

[flake8の使い方とオプション](https://qiita.com/raku_taro/items/93dacae018fb192d05b5)

#### run: black .：Blackを使用する

## black,flake8の設定
どちらもルートディレクトリに設定ファイルを置いておけばGitHubActionsの際に読み込まれます
- **blackの場合**
`pyproject.toml`ファイルでの設定
``` .toml:pyproject.toml
[tool.black]
line-length = 120
include = '\.pyi?$'
exclude = '''
/(
    \.git
  | \.hg
  | \.mypy_cache
  | \.tox
  | \.venv
  | _build
  | buck-out
  | build
  | dist
)/
'''
```
[Black公式ドキュメント](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html)
[blackのpyproject.toml](https://github.com/psf/black/blob/main/pyproject.toml)

- **flake8の場合**

1\. `.flake8`ファイルでの設定
``` .flake8:.flake8
[flake8]
max-line-length = 120
max-complexity = 10
exclude = tests/*
ignore=C901, E501
```
2\. pyproject.tomlファイルでの設定
flake8は`pyproject.toml`に対応していないので
`pyproject-flake8`を導入します
``` : コマンドライン
pip install pyproject-flake8
```
``` .toml:pyproject.toml
[tool.flake8]
max-line-length = 120
max-complexity = 10
exclude = tests/*
ignore = "C901, E501"
```
[flake8の使い方とオプション](https://qiita.com/raku_taro/items/93dacae018fb192d05b5)

両方使う場合は、`pyproject.toml`ファイルまとめてしまったほうが綺麗になると思います

https://data.gunosy.io/entry/linter_option_on_pyproject

## 実際に使って分かった注意点
:::note alert
コードがBlackで整形され、コミット、プッシュされた場合にはGitHubActionsの後にプルをしないとコンフリクトが起こる可能性があります
:::

一旦、修正途中でGitHubにプッシュする(GitHubActions作動)
↓
Blackでコードが整形される
↓
気づかずにプルせずそのまま修正を進める
↓
プッシュする際にコンフリクト発生

ということが起こりました

#### 代替案

blackによる整形はローカルで実行し、GitHubActionsではチェックのみを行う
``` : コマンドライン
black .
```
↓
``` yaml:code-check.yaml
#- uses: psf/black@stable
#          with:
#            options: "--verbose"
#            src: "./"
# もしくは
# - name: Run Black
#  run: black .
↓
- uses: psf/black@stable
  with:
    options: "--check --verbose"
    src: "./"
# もしくは
- name: Run Black
　run: black --check .
```

こちらの方がフォーマット以外の修正を邪魔することがないので良いかもしれません

## 参考にさせていただいた記事、サイト
https://black.readthedocs.io/en/stable/

https://github.com/psf/black

https://github.com/psf/black/tree/main

https://github.com/stefanzweifel/git-auto-commit-action/tree/master

https://flake8.pycqa.org/en/latest/index.html

https://qiita.com/KuruwiC/items/8e12704e338e532eb34a

https://qiita.com/raku_taro/items/93dacae018fb192d05b5

https://data.gunosy.io/entry/linter_option_on_pyproject