LoginSignup
0
3

More than 1 year has passed since last update.

python-gitlabでGitLabのパイプライン状況を一覧表示するHTMLをGitLab Pagesにデプロイする

Last updated at Posted at 2023-02-23

はじめに

GitLabのサブグループ以下にある複数プロジェクトのCI/CDパイプラインの実行状況を一覧化したいなーと思ったときのメモ。

やりたいこと

GitLab CI/CDパイプライン上でGitLab APIを叩いて、結果をPagesにデプロイします。
このとき、APIの結果を集計したかったので、python-gitlabを使用します。

環境

GitLab.comで構築・実行

やったこと

用意したのは以下の3つのファイル。

  • monitor.py ... GitLab APIを叩いて、HTMLを作成
  • .gitlab-ci.yml ... パイプライン定義
  • Dockerfile ... monitor.pyを動かすcontainer imageの定義(なくてもいい)
monitor.py
import gitlab
import pandas as pd
import datetime
from zoneinfo import ZoneInfo
import os

GITLAB_URL = os.getenv('CI_SERVER_URL')
TOKEN = os.getenv('TOKEN')
GITLAB_GROUP_ID = os.getenv('GITLAB_GROUP_ID')

html_template = '''
<html>
<head>
<meta charset="utf-8">
<title>GitLab Pipeline Monitor</title>
</head>
<body>
<h1>GitLab Pipeline Monitor</h1>
GitLab URL: {GITLAB_URL} <br>
GitLab Group: {GITLAB_GROUP} <br>
Updated: {UPDATED_AT} <br>
Summary:
{SUMMARY}
<hr>
{TABLE}
</body>
</html>
'''


def main():
    attr = ['project_id', 'project_name', 'pipeline_updated_at', 'pipeline_status']
    gl = gitlab.Gitlab(url=GITLAB_URL, private_token=TOKEN)
    df_all = pd.DataFrame(columns=attr)
    gl_group = gl.groups.get(id=GITLAB_GROUP_ID)
    dt_now = datetime.datetime.now(ZoneInfo("Asia/Tokyo")).strftime('%Y年%m月%d日 %H:%M:%S')
    for i in gl_group.projects.list(iterator=True):
        data = {x: '' for x in attr}
        data['project_id'] = [i.id]
        data['project_name'] = [i.name]
        pipelines = gl.projects.get(i.id).pipelines.list(order_by='updated_at', sort='desc')
        if len(pipelines) == 0:
            data['pipeline_updated_at'] = ['not run']
            data['pipeline_status'] = ['not run']
        else:
            latest_pipeline = pipelines[0]
            data['pipeline_updated_at'] = [latest_pipeline.updated_at]
            data['pipeline_status'] = [latest_pipeline.status]
        df_tmp = pd.DataFrame(data, columns=attr)
        df_all = pd.concat([df_all, df_tmp], axis=0)
    df_counts = pd.DataFrame(df_all['pipeline_status'].value_counts())
    html = html_template.format(
        GITLAB_URL=GITLAB_URL,
        GITLAB_GROUP=gl_group.name,
        UPDATED_AT=dt_now,
        SUMMARY=df_counts.to_html(),
        TABLE=df_all.to_html(index=False))

    with open('index.html', mode='w') as f:
        f.write(html)


if __name__ == '__main__':
    main()

環境変数は以下の2つ。

  • TOKEN ... GitLabのパーソナルトークン。
  • GITLAB_GROUP_ID ... 取得対象のサブグループID

処理内容ですが、
gl = gitlab.Gitlab(url=GITLAB_URL, private_token=TOKEN)
でGitLabインスタンスを作成。
gl_group = gl.groups.get(id=GITLAB_GROUP_ID)
で対象のサブグループを取得しています。
gl_group.projects.list(iterator=True)
でサブグループ以下のプロジェクトを全量取得してループしています。
ここで、公式ドキュメントにも記載されていますが、iterator=Trueあるいはget_all=Trueをオプションで指定しないと、全プロジェクト取得できないところが注意。

あとは、結果をpandasDataFrameに入れて集計、整理してto_html()でHTMLとして取得しています。

.gitlab-ci.yml
stages:
    - build
    - monitor
    - deploy

variables:
    IMAGE: ${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-pipeline-monitor

docker-build:
    stage: build
    image: docker:19.03
    services:
        - name: docker:19.03-dind
    only:
        - tags
    script:
        - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY
        - docker build -t ${IMAGE} .
        - docker images
        - docker push ${IMAGE}:latest

monitor:
    stage: monitor
    image: ${IMAGE}:latest
    only:
        - web
        - schedule
    script:
        - python monitor.py
    artifacts:
        paths:
            - ./index.html

pages:
    stage: deploy
    only:
        - web
        - schedule
    script:
        - mkdir public
        - mv ./index.html public/
        - ls public/
    artifacts:
        paths:
            - public

CI/CDパイプライン定義については大したことはしておらず、monitor.pyで出力されたindex.htmlpagesジョブでGit Lab Pagesとしてデプロイしています。
GitLab Pagesはpagesというジョブ名、deployというステージにする必要があるところだけ注意です。

FROM python:3.11
RUN pip install --no-cache-dir python-gitlab==3.13.0
RUN pip install --no-cache-dir pandas==1.5.3

Dockerfileはこのくらいならなくてもいいですし、本来requirements.txtとかを用意しておくのが普通かと思いますが、2つだけだしいっか、ということで、少し雑です。

結果

パイプラインで実行した結果、Pagesにデプロイできました。

スクリーンショット 2023-02-23 21.09.08.png

スクリーンショット 2023-02-23 21.08.15.png

まとめ

python-gitlabでGitLabのパイプライン状況を一覧表示するHTMLをGitLab Pagesにデプロイしてみました。
パイプラインをスケジュール実行すれば、定期的に状況が可視化できるかと。
なお、ソースコードはGitLab.comで公開しています。
ご参考までに。

0
3
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
0
3