1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitLabで実現する実践CI/CDパイプライン構築ガイド

Posted at

第2回:ローカル環境での品質チェック:pre-commitフック

前回はCI/CDの基本と全体像について解説しました。もし前回の記事をまだご覧になっていない方は、以下のリンクからぜひご確認ください。

GitLabで実現する実践CI/CDパイプライン構築ガイド【第1回:基本と全体像】

前回、「次回は.gitlab-ci.ymlの書き方を解説する」とお伝えしましたが、より効率的なCI/CDパイプラインを構築するために、今回は先にローカルでコードの品質を担保するpre-commitについて詳しく掘り下げていきます。pre-commitを学ぶことで、CIパイプラインの無駄な実行を減らし、開発をよりスムーズに進められます。


前提環境

本ブログでは、筆者が利用しているWindowsOSとVS Codeを想定して解説を進めます。ターミナルにはBashを使用し、Pythonのバージョンは現時点で最新の3.14.0rc2を前提とします。
コマンドはOSやシェルの種類、Pythonのバージョンによって異なる場合がありますので、ご自身の環境に合わせて適宜読み替えてください。


pre-commitとは?

pre-commitは、Gitのコミットフックという仕組みを利用して、コミット前に自動で特定の処理を実行するフレームワークです。
Gitフックは、Gitの特定イベント(コミット前(pre-commit)、プッシュ前(pre-push)など)をトリガーとして、任意のスクリプトを自動で実行する機能です。pre-commitは、このpre-commitフックを利用し、コードの整形(Formatter)や静的解析(Linter)を自動で実行します。
pre-commitを利用する利点としては以下があります。

  • リポジトリの品質維持
    pre-commitの実行により、コードのスタイルや品質がプロジェクト全体で統一され、軽微なミス(例:空白やインデントなどの修正)がリモートリポジトリにマージされるのを防ぎます。結果として、コードレビューが本質的なロジックの確認となりレビュー効率が向上します。
  • CI/CDパイプラインの無駄な実行を削減
    コードがリモートリポジトリにプッシュ/マージされるたびにCI/CDパイプラインが実行されるよう構築した場合、もしコードのフォーマットエラーや基本的な文法ミスがあった場合、パイプラインは失敗し、時間や計算リソースが無駄になってしまいます。pre-commitを導入すれば、これらの基本的なエラーをローカルのコミット段階で検出し、修正できます。これにより、CI/CDパイプラインをより高度なテストやデプロイに集中させ、結果的にリソースの節約とパイプラインの高速化につながります。
  • 開発者への即時フィードバック
    開発者は、CI/CDの実行を待つまでもなく、ローカルリポジトリへコミットした瞬間にフィードバックが得られます。これにより、小さなミスをその場で修正でき、後からまとめて修正する手間がなくなります。このリアルタイムなフィードバックは、開発者の生産性を高め、よりスムーズな開発体験をもたらします。

pre-commitの導入方法:Pythonプロジェクトの例

それでは、PythonプロジェクトにRuffを使ってpre-commitを導入する具体的な方法を解説します。Ruffは非常に高速で、複数のツール(Black, Flake8, isortなど)の機能を統合しているため、現代のPython開発では非常に人気があります。

  1. 仮想環境の作成と有効化
    まず、プロジェクトごとに隔離された環境を構築するために、仮想環境を作成します。これにより、プロジェクト固有のライブラリやツールをグローバル環境に影響を与えることなく管理できます。
    Bash
    # 仮想環境を作成
    python -m venv venv
    
    # 仮想環境を有効にする
    # WindowsでVS CodeのBashターミナル利用の場合
    . venv/Scripts/activate
    
     
  2. pre-commitとRuffのインストール
    次に、pre-commitRuffを仮想環境にインストールします。
    Bash
    pip install pre-commit ruff
    
     
  3. 設定ファイルの作成
    次に、pre-commitの動作を定義する設定ファイルを作成します。プロジェクトのルートディレクトリに、.pre-commit-config.yamlという名前でファイルを作成してください。このファイルには、Ruffのフックを定義します。
    .pre-commit-config.yaml
    repos:
      - repo: https://github.com/astral-sh/ruff-pre-commit
        rev: v0.13.0 # 最新のリリースバージョンに合わせる
        hooks:
          - id: ruff
            args: [--fix, --exit-non-zero-on-fix]
          - id: ruff-format
    
    • ruffフックは、リンティングと自動修正(--fix)を行います。--exit-non-zero-on-fixを追加することで、自動修正が行われた場合にエラーとして扱い、再コミットを促すことができます。
    • ruff-formatフックは、コードのフォーマットを行います。
       
  4. Gitフックのインストール
    pre-commitはGitリポジトリ内で動作するため、プロジェクトをまだGitリポジトリとして初期化していない場合は、以下のコマンドを先に実行します。
    Bash
    # プロジェクトのルートディレクトリでGitリポジトリを初期化
    git init
    
    次に以下のコマンドを実行してGitフックをインストールします。
    Bash
    pre-commit install
    
    このコマンドを実行すると、.git/hooks/pre-commitファイルが作成され、コミット時に自動でpre-commitが実行されるようになります。

pre-commitの実行と動作

pre-commitのインストールが完了すれば、あとは通常通りgit commitするだけでフックが自動で実行されます。
試しに、意図的にフォーマットエラーを含んだ以下のシンプルなPythonコードをコミットしてみます。このコードは、defと関数名の間に余分なスペースが含まれており、Ruffのフォーマットルールに従っていません。

main.py
def  get_message():
    """Returns a simple greeting message."""
    return "Hello, World!"

def main():
    """Main function to print the greeting."""
    print(get_message())

if __name__ == "__main__":
    main()

このコードは、一見問題がないように見えますが、Ruffのフォーマットルールに従っていません。ここでgit commitを実行してみます。

Bash
$ git add .
$ git commit -m "Initial commit"
ruff (legacy alias)......................................................Passed
ruff format..............................................................Failed
- hook id: ruff-format
- files were modified by this hook

1 file reformatted, 1 file left unchanged

実行結果を見ると、LinterのruffフックはPassedと成功していますが、Formatterのruff-formatフックがFailedと失敗として表示されました。これは、Ruffがコードのフォーマットを自動で修正したことを意味します。この段階ではまだコミットは完了していません。

pre-commitが自動修正する前と後を比べてみましょう。

python_code.png

Ruffは、余分なスペースを削除し、さらに関数の間に空行を挿入してPEP8Pythonのスタイルガイド)に準拠したフォーマットへ自動で修正しました。

pre-commitによる自動修正を受け入れるには、修正されたファイルをステージングエリアに再度追加してコミットをやり直す必要があります。

Bash
$ git add .
$ git commit -m "Initial commit"
ruff (legacy alias)......................................................Passed
ruff format..............................................................Passed

今度はruff formatがPassedとなり、コミットが成功しました。

このように、pre-commitを導入すれば、コードの整形や静的解析といった作業が開発者のローカル環境で自動化できます。開発者はこれらの手作業から解放され、常に高品質で一貫性のあるコードを維持できます。


まとめと次回予告

今回は、CI/CDパイプラインをより効率的に運用するために不可欠なpre-commitフックの導入方法を解説しました。特に、高速で多機能なRuffをフックとして使用することで、基本的なコードの品質をローカルで担保し、CIパイプラインをより重要なタスクに集中させることができます。
次回は、CI/CDの心臓部である .gitlab-ci.yml に話を戻し、実際にGitLab CI上でコードをビルドし、テストを実行する方法を掘り下げていきます。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?