メインコンテンツへスキップ
  1. Blogs/

Gitlab CI/CDでPythonのDevOps 2 -Gitlab CI/CD-

·2225 文字·
Blog Gitlab Python
hiroki
著者
hiroki
クラウドを作るお仕事をしてます。
目次
gitlab-cicd-python - 関連記事
2: << この記事 >>

はじめに
#

第1回で開発環境ができたので、開発とCI環境の統一に注力しつつ、Gitlab CI/CDを利用できる様にします。

またGitlabにはただCI/CDを実行するだけでなく、開発を支援する機能がいくつも存在するのでこの利用法についても解説します。

1. 今回のdirectory構成
#

今回解説するコードはGitlabのrepositryのbranchseries-2で公開しています。

.
├── app
│   ├── main.py
│   └── tests
│       └── small
│           └── test_main.py
├── compose.yml
├── dockerfiles
│   ├── ci
│   │   └── python.Dockerfile
│   └── Makefile
├── .gitlab-ci.yml ### NEW ###
├── Makefile
├── poetry.lock
├── pyproject.toml
└── README.md

2. lintとtest環境の整備
#

開発環境でlintとtestに成功したら.gitlab-ci.ymlを作成して、CI/CDを実施します。

.gitlab-ci.yml

# reference: https://docs.gitlab.com/ee/ci/caching/#cache-python-dependencies
stages:
    - cache
    - lint
    - test

.python_cache:
  image: $CI_REGISTRY_IMAGE/ci/python:latest
  cache:
    key:
      files:
        - poetry.lock
      prefix: ci-python # Want to change the scope of the cache -> https://docs.gitlab.com/ee/ci/caching/#common-use-cases-for-caches
    policy: pull
    paths:
      - .venv
      # - mypy_cache # Uncomment if you use mypy

prepare_cache:
  extends: 
    - .python_cache
  stage: cache
  cache:
    policy: pull-push
  script:
    - poetry install -v

lint:
  extends: .python_cache
  stage: lint
  script:
    - make lint

small-test:
  extends: .python_cache
  stage: test
  script:
    - make small
  coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
  artifacts:
    reports:
      junit: junit.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml

3. 開発とCI環境の同一化
#

最初の注目ポイントは「開発とCI環境の同一化」です。第一回で紹介したようにここを注力ポイントにしているので、同じ環境で同じコマンドを使えるようにします。

  • $CI_REGISTRY_IMAGE/ci/python:latestと開発環境と同じimageを使っている。
  • make lintmake smallと開発環境と同じimageを使っている。

4. キャッシュによる高速化
#

次の注目ポイントは、prepare_cache.python_cacheです。

docker image内部にpipのパッケージを入れなかったので、CI/CD毎にpoetry installを実施してpipパッケージをインストールする必要があります。 しかしlintで1回、testで1回、更にpipeline毎にinstallをするのは時間の無駄になります。

そこでjobprepare_cacheと、template.python_cache作成してキャッシュ + 使い回すことで毎回のpoetry installを避けつつpoetry.lockが変わったら再度installするという手法を利用します。

pipのパッケージ管理をimage外部で実施して毎回のimage buildを避けつつ、cacheを使うことで毎回のpoetry installを避けるという良いとこどりをします。

こちらの手法については以前解説していますので、以下を参照ください。

Gitlab CI/CDでpoetryの環境をキャッシュする方法
·953 文字
Memo Gitlab

5. test結果の可視化
#

ここまででlintとtestは自動化できましたが、Gitlabには更に便利な機能が備わっています。 pytestpytest-covを利用していれば、簡単に導入ができるので設定しておきましょう。

5-1. coverageの%表示
#

coverageの%表記を正規表現で取得することで、m-rに記載することができます。 公式docsでは、正規表現の例やカバレッジヒストリーの確認方法などが他の活用法も紹介されています。

coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'

alt text

5-2. coverageの可視化
#

Cobertura XML形式のcoverageレポートをartifacts:reports:coverage_reportに保存することで、m-rの差分画面にcoverage結果を可視化することができます。 特にpytest-covを使っている場合であれば、--cov-report xml:coverage.xmlと指定するだけで、レポートを生成できるので非常に簡単に表示ができます。

For the coverage analysis to work, you have to provide a properly formatted Cobertura XML report to artifacts:reports:coverage_report. https://docs.gitlab.com/ee/ci/testing/test_coverage_visualization/cobertura.html

alt text

5-3. Unit test結果の表示
#

Junit形式のUnit testレポートをartifacts:reports:junitに配置することで、Pipeline画面にUnit testの結果を可視化することができます。 pytest-covを使っている場合は、--junitxml=junit.xmlと指定するだけで、こちらも簡単にGitlab上で確認することができます。

First, GitLab Runner uploads all JUnit report format XML files as artifacts to GitLab. Then, when you visit a merge request, GitLab starts comparing the head and base branch’s JUnit report format XML files https://docs.gitlab.com/ee/ci/testing/unit_test_reports.html

他にもcodeのQualityチェックや、パフォーマンステストなどのテストに関する支援機能が備わっています。 https://docs.gitlab.com/ee/ci/testing/

おわりに
#

すごいsimpleですが、「開発環境で開発 → CI/CDでチェック → review」という一連の開発を実施できるようになりました。

次回は開発できた内容をリリースする手法を紹介したいと思います。

おまけ -github actionの場合-
#

CIのjob毎にimageを使わずubuntu-latest等のbase-imageに対して1つずつsetupコマンドを実施していくのが一般的の模様

poetryではなくuvだがenable-cache: trueによって、ubuntu-latestに対して素早く展開できる模様

Makefileではなく専用のscriptを配置することで、開発環境とCI中で同じコマンドを実行するようになっている

jobs:
  test-backend:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.10"
      - name: Install uv
        uses: astral-sh/setup-uv@v3
        with:
          version: "0.4.15"
          enable-cache: true
      - run: docker compose down -v --remove-orphans
      - run: docker compose up -d db mailcatcher
      - name: Migrate DB
        run: uv run bash scripts/prestart.sh
        working-directory: backend
      - name: Run tests
        run: uv run bash scripts/tests-start.sh "Coverage for ${{ github.sha }}"
        working-directory: backend
      - run: docker compose down -v --remove-orphans
      - name: Store coverage files
        uses: actions/upload-artifact@v4
        with:
          name: coverage-html
          path: backend/htmlcov
          include-hidden-files: true
gitlab-cicd-python - 関連記事
2: << この記事 >>

Related

Gitlab CI/CDでPythonのDevOps 1 -開発環境の作成-
·4405 文字
Blog Gitlab Python
Gitlab CI/CDでseleniumを利用する方法
·2155 文字
Blog Gitlab Python
pyvmomiで自動化8 -情報をまとめて取得-
·2484 文字
Blog VMware VSphere Pyvmomi Python