【Github】Github Actions ~ Python関連 ~

■ はじめに

* Pythonにまつわる以下の事項について扱う

[1] egg / wheel ファイルをGithub Actionsを使って作成する
 その際に学べたことメモする。
[2] Python の Linter について実装する

なお、Pythonを実行させる場合は、以下の関連記事を参照のこと

Github Actions ~ Pythonを使うには ~
https://dk521123.hatenablog.com/entry/2024/02/04/011205

目次

【1】egg / wheel ファイル作成
 1)今回やりたいこと
 2)今回Github Actionsで学べたこと
 3)サンプル
 4)動作確認
【2】Python の Linterを組み込む
 1)flake8/black/isort を使う
 2)Ruff を使う

【1】egg / wheel ファイル作成

1)今回やりたいこと

* egg / wheel ファイルをGithub Actionsを使って作成する
* その際、ファイルサイズを確認
 + 一定サイズ以下であれば、エラー
 + 一定サイズを超えていたら、Githubにコミット&プッシュ

2)今回Github Actionsで学べたこと

[1] 環境変数 GITHUB_ENV

以下の関連記事を参照のこと

Github Actions ~ GITHUB_ENV ~
https://dk521123.hatenablog.com/entry/2023/12/29/000840

[2] if

ファイルサイズの大きさによっては、中断させたいので
分岐になる if が必要

https://zenn.dev/matken/articles/github-actions-if-and-env#if

以下の関連記事を参照のこと

Github Actions ~ if ~
https://dk521123.hatenablog.com/entry/2024/03/11/000000

3)サンプル

前提条件
https://dk521123.hatenablog.com/entry/2020/02/09/234350

で、egg / wheel ファイルを作成したが、それを Push のタイミングで、
「python setup.py bdist_egg」/「python setup.py bdist_wheel」を
実行するようにする

なお、以下のサイトを参考にして実装した。

https://andrewpwheeler.com/2022/05/10/building-wheel-files-in-github-actions/

github-actions-demo2.yml

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "develop" branch
  push:
    branches: [ "develop" ]
  pull_request:
    branches: [ "develop" ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v3

      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.7'
          architecture: 'x64'
      - name: Get Python version
        run: python -V
      - name: Build wheel and install
        run: |
          python -m pip install --upgrade pip --user
          pip install wheel
          pip install PasteScript
      # Wheelファイル作成およびファイルサイズをWHL_FILE_SIZEに格納
      - name: Run Python
        run: |
          python ./DemoLib/setup.py bdist_wheel
          cp ./dist/*.whl ./DemoLib/dist/*.whl
          echo "WHL_FILE_SIZE=$(wc -c ./dist/*.whl | awk '{print $1}')" >> $GITHUB_ENV
      # Wheelファイルサイズを確認(2000byte以下であれば中断)
      - name: File size check
        if: ${{ env.WHL_FILE_SIZE <= 2000 }}
        run: exit 1
      - name: Configure Git
        run: |
          git config --global user.email "xxxxx@gmail.com"
          git config --global user.name "xxxxx"
      # Git コミット&プッシュ
      - name: Commit and push wheel
        run: |
          git add -f ./DemoLib/dist/*.whl
          git commit -m 'pushing new wheel'
          git push

4)動作確認

[1] ダウンロード

[1] Github で、[Code]-[Download ZIP]でモジュールをダウンロード
 => 今回は「github-actions-demo-develop.zip」
[2] ダウンロードしたモジュールを解凍する

[2] インストール

# インストール
pip install DemoLib-0.1.dev0-py3-none-any.whl 

# 確認1:pip list
pip list
・・・
DemoLib            0.0
・・・

# 確認2:pip show <package>
pip show DemoLib

[3] 動作確認

from demolib.demo_lib import *

if __name__=='__main__':
  result = say_hello('Mike')
  print('Result = {}'.format(result)) # Result = Hello, Mike.

[4] アンインストール

# アンインストール
pip uninstall DemoLib

# 動作確認(DemoLibが存在しないことを確認)
pip list

【2】Python の Linterを組み込む

1)flake8/black/isort を使う

Github Actionsで「flake8」「black」「isort」を使いたい
=> 各ツールの詳細については、以下の関連記事を参照のこと。

Python を奇麗に書くためのツール群
https://dk521123.hatenablog.com/entry/2021/11/08/221219
flake8 ~ Pythonコードチェック ~
https://dk521123.hatenablog.com/entry/2020/02/07/000000
black ~ Python formatter ~
https://dk521123.hatenablog.com/entry/2021/11/10/095258

サンプル

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the develop branch
  push:
    branches: [develop]
  pull_request:
    branches: [develop]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    env:
      PYTHON_VERSION: 3.7
      MAX_LINE_LENGTH: 120
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2
      - name: Set up Python 3.X
        uses: actions/setup-python@v2
        with:
          python-version: ${PYTHON_VERSION}
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install flake8 isort black
      - name: Lint
        run: |
          flake8 . --max-line-length=${MAX_LINE_LENGTH}
          isort --check --diff .
          black --check --line-length ${MAX_LINE_LENGTH} .

2)Ruff を使う

* Ruff に関する詳細は、以下の関連記事を参照のこと

Python解析ツール ~ Ruff ~
https://dk521123.hatenablog.com/entry/2024/03/13/000021

name: DemoWorkflowLinter

on:
  workflow_dispatch:

jobs:
  sample-job:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install ruff
      - name: Lint with Ruff
        run: |
          ruff check --output-format=github .
        continue-on-error: true

DemoLib/setup.py

from setuptools import setup, find_packages
import sys, os

version = '0.0'

setup(name='DemoLib',
      version=version,
      description="",
      long_description="""\
""",
      classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
      keywords='',
      author='',
      author_email='',
      url='',
      license='',
      packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
      include_package_data=True,
      zip_safe=False,
      install_requires=[
          # -*- Extra requirements: -*-
      ],
      entry_points="""
      # -*- Entry points: -*-
      """,
      )

main.py

from demolib.demo_lib import *

if __name__=='__main__':
  result = say_hello('Mike')
  print('Result = {}'.format(result))

https://docs.github.com/ja/actions/automating-builds-and-tests/building-and-testing-python#using-ruff-to-lint-code

出力結果

Error: DemoLib/setup.py:2:1: E401 Multiple imports on one line
Error: DemoLib/setup.py:2:8: F401 `sys` imported but unused
Error: DemoLib/setup.py:2:13: F401 `os` imported but unused
Error: main.py:1:1: F403 `from demolib.demo_lib import *` used; unable to detect undefined names
Error: main.py:4:12: F405 `say_hello` may be undefined, or defined from star imports
Error: Process completed with exit code 1.

関連記事

Github ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2019/07/18/234652
Github Actions ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2021/11/04/142835
Github Actions ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2022/06/16/151443
Github Actions ~ Pythonを使うには ~
https://dk521123.hatenablog.com/entry/2024/02/04/011205
Github Actions ~ GITHUB_ENV ~
https://dk521123.hatenablog.com/entry/2023/12/29/000840
Github Actions ~ ワークフロー制御 ~
https://dk521123.hatenablog.com/entry/2024/01/28/004128
Github Actions ~ if ~
https://dk521123.hatenablog.com/entry/2024/03/11/000000
Github Actions ~ SQL Linter ~
https://dk521123.hatenablog.com/entry/2024/03/04/180308
Github Actions ~ reviewdog ~
https://dk521123.hatenablog.com/entry/2024/04/13/232832
egg / wheel ファイルを作成する
https://dk521123.hatenablog.com/entry/2020/02/09/234350
大きいファイルを扱う際のコマンド
https://dk521123.hatenablog.com/entry/2020/06/12/000000
Python解析ツール ~ Ruff ~
https://dk521123.hatenablog.com/entry/2024/03/13/000021