Open21

GitLabの活用

nabetsunabetsu

Alertの外部サービスとの連携

GitLabにはAlert機能が存在するが、PrometheusやHTTP Endpointを利用した外部サービスとの連携ができる。

AWSの場合にはCloudWatch Alarmが上がったタイミングでLambdaを呼べば自動でGitLabにアラートとして登録ができる。

デフォルトで定義されている項目

  • fingerprint
    • これが同じもの同士はグループにまとめてくれるらしい

CloudWatch AlarmのEvent形式

メトリクスとしてLambdaのErrorsを使った場合の例。

{
    "Records": [
        {
            "EventSource": "aws:sns",
            "EventVersion": "1.0",
            "EventSubscriptionArn": "arn:aws:sns:ap-northeast-1: 111111111111:CloudWatchAlert:a662f1f3-2f18-48da-97bd-c0808d575e74",
            "Sns": {
                "Type": "Notification",
                "MessageId": "268fd7d0-acba-54fd-bcf9-8f10a563a56c",
                "TopicArn": "arn:aws:sns:ap-northeast-1: 111111111111:CloudWatchAlert",
                "Subject": "ALARM: \"GitLabSampleFunc\" in Asia Pacific (Tokyo)",
                "Message": {
                    "AlarmName": "GitLabSampleFunc",
                    "AlarmDescription": "顧客通知",
                    "AWSAccountId": "111111111111",
                    "NewStateValue": "ALARM",
                    "NewStateReason": "Threshold Crossed: 1 out of the last 1 datapoints [1.0 (08/03/21 11:15:00)] was greater than or equal to the threshold (1.0) (minimum 1 datapoint for OK -> ALARM transition).",
                    "StateChangeTime": "2021-03-08T11:16:41.353+0000",
                    "Region": "Asia Pacific (Tokyo)",
                    "AlarmArn": "arn:aws:cloudwatch:ap-northeast-1:111111111111:alarm:GitLabSampleFunc",
                    "OldStateValue": "OK",
                    "Trigger": {
                        "MetricName": "Errors",
                        "Namespace": "AWS/Lambda",
                        "StatisticType": "Statistic",
                        "Statistic": "AVERAGE",
                        "Unit": null,
                        "Dimensions": [
                            {
                                "value": "ErrorFunctionSample",
                                "name": "FunctionName"
                            },
                            {
                                "value": "ErrorFunctionSample",
                                "name": "Resource"
                            }
                        ],
                        "Period": 60,
                        "EvaluationPeriods": 1,
                        "ComparisonOperator": "GreaterThanOrEqualToThreshold",
                        "Threshold": 1.0,
                        "TreatMissingData": "- TreatMissingData:                    notBreaching",
                        "EvaluateLowSampleCountPercentile": ""
                    }
                },
                "Timestamp": "2021-03-08T11: 16: 41.412Z",
                "SignatureVersion": "1",
                "Signature": "bW8dVpMJcQwcaYd3bqgG/WzHJQcMOXj2RvTcdDXWyDb+vYHAcmFpfAk23AuMmQ6C2jZfTVaJaG5NgSzBOpV9PjU2dOHJFoo1zI7LFGyPlwCtu+qta/fGaq5HKRk86Utzcq74E4gFt2F5gQJ3EYtxJtXuQsLK9LHw42W664I8Edoxsw1vHoPoLr3gZ+ib6wn6H4UoFlA93mEc4WTktQWiLH7ML0wnfilbEve+BUFmSQbWIfWqINhwR8sRPXSxtFwtRE8mAwNN1v+3yYBH+QPVsBa3vPmSMvgnzJL131LwohEyc4kImQmG0r8KIpv6ARlTy6Ffay/55ELwjzRwXQFG8g==', 'SigningCertUrl': 'https: //sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-010a507c1833636cd94bdb98bd93083a.pem', 'UnsubscribeUrl': 'https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:ap-northeast-1:111111111111:CloudWatchAlert:a662f1f3-2f18-48da-97bd-c0808d575e74",
                "MessageAttributes": {}
            }
        }
    ]
}

How to use GitLab's Incident Management with AWS CloudWatch

Incident Management - Integrations

Alerts

nabetsunabetsu

CIで使えそうな機能

Browser Performance Testing[Premium]

Browser Performance Testing

CodeQuality

循環度やコードの重複など、コードの質に関する部分を判定してくれる。
実体としてはCodeClimateで、これをGitLab CI内で使えるようにしてくれている。

また、GitLabの機能として以下のようにマージリクエスト時に品質の増減や具体的な変更点をわかりやすく表示してくれる。


Code Quality

include:
  - template: Code-Quality.gitlab-ci.yml

code_quality:
  artifacts:
    paths: [gl-code-quality-report.json]

参考資料

GitLab CIでテスト・ビルド・デプロイを自動化する

GitLabではじめる一人DevOps

nabetsunabetsu

Test

  • 特に設定をしなければMerge Requestの画面には何も表示されない

  • GitLab RunnerはJUnitのXMLファイルをすべて集めてarfifactsとしてアップロードしてくれる。そして、base branch(マージリクエスト先。masterなど)とhead branch(マージリクエスト元。feature/xxxなど)の比較を行い、比較結果をマージリクエストの画面に表示してくれる(以下がイメージ画像)

  • 以下の要領で設定を行えばマージリクエスト画面にテストの概要が表示され、リンク先よりテスト全体の結果が確認できる

    • GitLab CIの設定
      • 前述の通りJunit形式のXMLファイルをpytestの結果として出力し、artifacsとして設定すればOK
      • また、Pytestの結果をHTMLで出力すればGitLab Pagesを利用してブラウザから結果を確認することも可能
pytest:
 stage: test
 script:
   - pytest --junitxml=report.xml
 artifacts:
   when: always
   reports:
     junit: report.xml
  • マージリクエスト画面
  • レポート全体
  • アーティファクトは実行結果より完全なものをダウンロードできる

カバレッジ

  • カバレッジをログに出力するようにした上でプロジェクトの設定から正規表現を指定することでカバレッジとカバレッジの差分をマージリクエストに表示できる
    • コード
- pytest tests --junitxml=report.xml --cov=src -v
  • 設定画面

  • マージリクエストの画面

また、複数のジョブでテストカバレッジが取得できた場合、マージリクエスト画面には平均値が表示される。

include:
  - template: Code-Quality.gitlab-ci.yml
- 実行タイミング
    - デフォルト(テンプレート)の条件は以下になっており、プッシュのタイミングでしか実行されない
code_quality:
  rules:
    - if: '$CODE_QUALITY_DISABLED'
      when: never
    - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
    - マージリクエストの時に実行するようにしたければ、以下の設定を追加する
code_quality:
  rules:
    - if: '$CODE_QUALITY_DISABLED'
      when: never
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # Run code quality job in merge request pipelines
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'      # Run code quality job in pipelines on the master branch (but not in other branch pipelines)
    - if: '$CI_COMMIT_TAG'                               # Run code quality job in pipelines for tags

詳細は以下参照https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html
- 初回実行時は比較元がないので以下の表示がでて結果が表示されない?

nabetsunabetsu

Badge機能


Badges

  • パイプラインの状態やカバレッジ率など、何らかの指標や状態をバッジとして表示できる機能(GitHubにも同様の機能がある)
  • プロジェクト単位、グループ単位で設定ができる
  • カバレッジとパイプラインステータスについてはGitLab側でイメージが提供されている

手順

[設定] - [一般]のバッジから設定ができる。

プロジェクトごとの設定の場合

カバレッジとパイプラインステータスであれば以下の設定をすればOK。

  • カバレッジ
    • リンク
      • https://gitlab.com/%{project_path}/commits/%{default_branch}
    • バッジ画像のURL
      • https://gitlab.com/%{project_path}/badges/%{default_branch}/coverage.svg
  • パイプライン
    • リンク
      • https://gitlab.com/%{project_path}/-/commits/%{default_branch}
    • バッジ画像のURL
      • https://gitlab.com/%{project_path}/badges/%{default_branch}/pipeline.svg

グループごとの設定の場合

参考資料

nabetsunabetsu

memo

Frontendなど条件を絞ってカバレッジを指定できる?

Custom badge text

Job単位でカバレッジの設定

Keyword reference for the .gitlab-ci.yml file - Coverageに記載されている通りジョブ単位でカバレッジの設定を指定できる。
以下のようにgitlab-ci.ymlのジョブごとの定義にcoverageと対応する正規表現を指定すれば対象ジョブの出力結果からカバレッジの値を取得してくれる。

job1:
  script: rspec
  coverage: '/Code coverage: \d+\.\d+/'

具体的な仕様としては以下の通り。

  • ジョブのアウトプットで正規表現に一致する箇所が一つでもあればそれが対象ジョブのカバレッジとして使用される
  • 複数一致する箇所があれば最後に一致しているものが使われる
  • 子パイプラインの値は適用されない

メリット

同一プロジェクトで複数言語によるカバレッジの測定を可能にしてくれる。
UIからの設定だとプロジェクトごとに単一言語しか設定ができないため、特に同一リポジトリで複数の言語を使用するモノレポなどで有効な機能

注意点

Test coverage parsingに一般的なテストフレームワークでカバレッジの取得に使用する正規表現がまとめられている。

GitLabのUI([設定]-[CI/CD]-[一般のパイプライン]-[テストカバレッジ解析])から入力する場合は上記の正規表現をそのまま使って問題ないが、ジョブに指定する場合にはデリミタとして「/」が必要になるので注意

例えばpytest-covの場合、正規表現をそのままcoverageに指定すると

coverage: '^TOTAL.+?(\d+\%)$'

以下の通りエラーになる。

デリミタを入れてい以下の通りに修正すると上記のエラーは発生しなくなる。

coverage: '/^TOTAL.+?(\d+\%)$/'
nabetsunabetsu

GitLab CIの便利な機能

Extendsを活用してジョブのテンプレート化

extendsキーワードでテンプレートとして定義した設定を他のジョブで継承できる。
挙動としては以下の通り。

  • 同じ定義を行っている箇所は上書き
  • 異なる定義はテンプレートの定義がそのまま適用

挙動

実際にGItLabの公式ドキュメントに記載されている例で見てみると、

# テンプレート部分
.tests: 
  script: rake test
  stage: test
  only:
    refs:
      - branches

rspec:
  extends: .tests # extendsでテンプレートを継承
  script: rake rspec
  only:
    variables:
      - $RSPEC

継承の結果実行されるrspecジョブの定義は以下の通りになる。

rspec:
  script: rake rspec # rspecでも定義しているため上書きされている箇所
  stage: test
  only:
    refs: # rspecで指定されていないためテンプレートの定義が適用されている箇所
      - branches 
    variables: # rspecで指定されているため上書きされている箇所
      - $RSPEC 

GitLab.comの活用の仕方

extendsの機能をフルに活用して効率的な.gitlab-ci.ymlの定義を行っている。
規模が大きくないとここまで厳密に管理するメリットは薄いかもしれないが、extendsの活用事例として参考までに。

リポジトリの内容を細かく把握しているわけではないが、目についたものとして以下のような活用の仕方をしていた。

  • グローバルにプロジェクト内の各ジョブで使用するテンプレートを.gitlab/ci/global.gitlab-ci.ymlで定義
  • ジョブの実行条件に関するルールを.gitlab/ci/rules.gitlab-ci.ymlで定義
  • 各ジョブから上記2つのルールをextendsで継承して利用
.gitlab/ci/frontend.gitlab-ci.yml
.frontend-base:
  extends:
    - .default-retry
    - .default-before_script
  variables:
    SETUP_DB: "false"
    # we override the max_old_space_size to prevent OOM errors
    NODE_OPTIONS: --max_old_space_size=3584

.yarn-install: &yarn-install
  - source scripts/utils.sh
  - run_timed_command "retry yarn install --frozen-lockfile"

.compile-assets-base:
  extends:
    - .frontend-base
    - .assets-compile-cache
  image: registry.gitlab.com/gitlab-org/gitlab-build-images:ruby-2.7.2-git-2.29-lfs-2.9-node-14.15-yarn-1.22-graphicsmagick-1.3.34
  variables:
    WEBPACK_VENDOR_DLL: "true"
  stage: prepare
  script:
    - *yarn-install
    - run_timed_command "bin/rake gitlab:assets:compile"
    - run_timed_command "scripts/clean-old-cached-assets"

compile-production-assets:
  extends:
    - .compile-assets-base
    - .frontend:rules:compile-production-assets
  variables:
    NODE_ENV: "production"
    RAILS_ENV: "production"
    WEBPACK_REPORT: "true"
  artifacts:
    name: webpack-report
    expire_in: 31d
    paths:
      # These assets are used in multiple locations:
      # - in `build-assets-image` job to create assets image for packaging systems
      # - GitLab UI for integration tests: https://gitlab.com/gitlab-org/gitlab-ui/-/blob/e88493b3c855aea30bf60baee692a64606b0eb1e/.storybook/preview-head.pug#L1
      - public/assets/
      - webpack-report/
    when: always
  after_script:
    - rm -f /etc/apt/sources.list.d/google*.list  # We don't need to update Chrome here


.gitlab/ci/frontend.gitlab-ci.yml

.gitlab/ci/global.gitlab-ci.yml
.default-retry:
  retry:
    max: 2  # This is confusing but this means "3 runs at max".
    when:
      - unknown_failure
      - api_failure
      - runner_system_failure
      - job_execution_timeout
      - stuck_or_timeout_failure

.gitlab/ci/global.gitlab-ci.yml

.gitlab/ci/rules.gitlab-ci.yml
##################
# Frontend rules #
##################
.frontend:rules:compile-production-assets:
  rules:
    - <<: *if-not-canonical-namespace
      when: never
    - <<: *if-default-refs
      changes: *code-qa-patterns

.gitlab/ci/rules.gitlab-ci.yml

nabetsunabetsu

GitLab CI内でDBを利用したテストを実施

servicesキーワードを指定すると、GitLab CIが実行されているコンテナと指定されたサービス間で接続を可能にしてくれる。
以下のように指定すればGitLab CIの中でmysqlに接続できるようになる。

# 最新版を使用
services:
  - mysql:latest

# バージョンを指定
services:
  - mysql:5.7.12

DBの接続情報については以下の通り.gitlab-ci.ymlの環境変数で設定すればOK

variables:
  # Configure mysql environment variables (https://hub.docker.com/_/mysql/)
  MYSQL_DATABASE: $MYSQL_DB
  MYSQL_ROOT_PASSWORD: $MYSQL_PASS

後は認証情報として以下を渡せばservicesで起動させたDBのコンテナに接続ができる。

Host: mysql
User: runner
Password: <your_mysql_password>
Database: <your_mysql_database>

参考資料

GitLab - What is a service
GitLab CI services examples
Gitlab CI + DockerでRuby on Railsのテストを自動化

nabetsunabetsu

タスクの確認

Todoリストの活用

Headerに表示されているTodoリストからIssueでのメンションやレビュー依頼等が確認できる。
公式ドキュメント

GitLab上でアクションが必要なケース(例えば自分がアサインされていないIssueでメンションされた時や自分が提出したマージリクエストでパイプラインが落ちた時など)に対応しており、有効に使うことで対応漏れを防ぐことができる。

Todoリストに追加される条件

Todoリストに追加されるアクションの種類としては以下がある。

  • Assigned
    • Issueにアサインされた時
    • Merge RequestのAssigneeに指定された時
  • Review requested
    • Merge RequestのReviewerに指定された時
  • Mentioned
    • Issue、Epic、Merge Request等でメンションされた時
  • Added
    • Issue画面のサイドバーから「To Doを追加」を選択した時
  • Pipelines
    • 自分で提出した?マージリクエストのパイプラインが落ちた時
  • Directory Addressed
    • Issue等の先頭行でメンションされた時

Todoリストを確認する手順

  • ヘッダーに表示されているTodoリストをクリック

  • Todoリストには以下のようにIssueでのメンションやマージリクエストの内容がリストで表示される(デフォルトで更新日時順でソートされている)

GitLabのホーム画面に設定

ユーザ設定(Preferences)からGitLabのホーム画面にToDoリストを追加することも可能。

手順としては以下の通り。

  • [ユーザ設定] - [基本設定] - [Homepage content]から「あなたのTo Doリスト」を選択し、保存

  • GitLabのホーム画面に移動すると以下の通りToDoリストが表示される

nabetsunabetsu

テンプレートファイルの活用

IssueとMerge Requestのテンプレートを作成して、利用することができる。

# この配下にIssueのテンプレートを格納する
.gitlab/issue_templates/

# この配下にMerge Requestのテンプレートを格納する
.gitlab/merge_request_templates/

利用方法

  • 作成時もしくは作成後に指定が可能

設定方法

Group Levelでの設定[Premium]

グループでテンプレートの参照元として利用するプロジェクトを指定できる。

デフォルトで使用するテンプレートの設定[Premium]

プロジェクトでデフォルトで使用するテンプレートを設定することができる。

参考資料

nabetsunabetsu

Plan

Issueをまとめて編集

[イシュー] - [リスト]から複数のIssueをまとめて編集できる。
[リスト]の画面ではマイルストーンやラベル等で絞り込みができるので、指定した条件で絞り込んだIssueに対してまとめて更新を行うことができる。

設定可能な項目は以下の通り。

  • 状態(オープン or クローズ)
  • 担当者
  • マイルストーン
  • イテレーション(Premum以上のみ)
  • エピック(Premum以上のみ)
  • ラベル

詳細については[公式ドキュメント](Bulk editing issues and merge requests at the project level)参照

手順

手順としては、以下の通り[リスト]画面に遷移を、右上の「イシューを編集」をクリック

編集をしたいイシューを選択し、設定する項目を選択後に「全て更新」をクリックすればOK

nabetsunabetsu

Value Stream Analysis

ソフトウェア開発の目的は顧客に対する価値提供を最大化することにある

GitLabのValue Stream Analysis機能は価値提供にあたる一連のプロセスを可視化し、
非効率になっている箇所の特定に使用できる

Value Stream Mapping

Value Stream Mappingのススメ
VSM (Value Stream Mapping) のススメ〜開発プロセス可視化〜

GitLabにおける考え方

デフォルトの設定ではGitLab Flowを前提としている。

  • Issue
  • Plan
    • Issueが起票されてから最初にコミットするまでの時間
  • code
    • 最初にコミットしてからマージリクエストを提出するまでの時間
  • Test
    • GitLab CIでテストを実行するのにかかった時間
  • Review
    • Code Reviewにかかった時間
  • Staging

GitLabにおける環境の判定

  • デフォルトではenvironmentの名前から自動で判断する

  • 明示的にProduction環境やStaging環境だと指定したい時には、Deployment Tierを指定すればOK

  • production

  • gtaging

  • testing

  • development

  • other

Crosslinking Issues

参考資料

nabetsunabetsu

GitLabにおけるプロジェクト管理の基本

GroupとProject

GitLabにおいてプロジェクトやチームの管理をするにあたって一番基本となる要素がGroupとProject。
この2つはリポジトリ管理やタスク(後述するIssue)、レビュー(後述するMerge Request)といった実際の活動を入れておくための箱のようなもの。

GitLabで何かしらの対応(ソースコードの管理、プロジェクトの管理など)を始める際にはまずこの2つのどちらかを作成する必要がある。

どのようにGroupとProjectを利用するか検討するにあたっては以下の特性を考慮する必要がある。

  • GroupとProjectで利用できる機能が異なる
  • Group配下にGroup(子Group)またはProject(子Project)を作成できる
  • 子Groupまたは子Projectの内容は親Groupで確認できる

GroupとProjectで利用できる機能が異なる

○が作成可能、×が作成不可を示す。

機能 用途 Group Project
リポジトリ ソースコード等の管理 ×
Issue 要求事項やタスクの管理 ×
Epic 複数の要求事項をまとめて管理。1つのEpicに複数のIssueを紐付けられる ×
Merge Request レビュー ×
Milestone Iterationより長い期間(例えば次のバージョンのリリースなど)の進捗管理
Iteration アジャイルのイテレーションの管理 ×
Roadmap EpicとMilestoneを組み合わせた製品ロードマップの管理(Milestoneより長い期間) ×

Group配下にGroup(子Group)またはProject(子Project)を作成できる

Groupの配下にはGroupまたはProjectを作成することが可能(Projectの配下にはGroupやProjectの作成は不可)。

子Groupまたは子Projectの内容は親Groupで確認できる

表題の通り、親Groupからは子Groupまたは子Projectで作成したもの(IssueやMilestone等すべて)が確認できる。

例として以下のような構成のグループが存在した場合、親グループであるgroup_aからは配下の(子Groupであるgroup_bの配下にあるproject_c含め)すべての情報を確認できる。
一方でgroup_bからは親子関係にないproject_aやproject_bの情報は確認できない。

.
└── group_a
    ├── project_a
    │   └── issue
    └── project_b
        ├── issue
        └── milestone
    └── group_b
        └── project_c
          ├── issue
          └── milestone

そのため、管理したいスコープに応じてグループで親子関係を構成するのがGitLabにおけるプロジェクト管理の基本になる。

※全てをトップレベルのグループ(上記の例だとgroup_a)で管理するのも可能だが、プロジェクトの数が増えて来ると管理が煩雑になるので、適切な単位でGroupを作成する方が管理はしやすいと考えられる。
(例えば上記の例でgroup_aの直下にプロジェクトが100個あり、group_bの直下にプロジェクトが5個あった場合、group_aからは105個のプロジェクトの情報が集まるが、groub_bからは5個のプロジェクトの情報だけを確認できる)

GitLabにおける計画と進捗の確認

前述のProjectとGroupがGitLabにおける管理の箱となるが、実際に個別の要求事項(アジャイルにおけるユーザストーリー)やイテレーションなどの管理を行うための機能として以下がある。

  • Issue
  • Epic
  • Iteration
  • Milestone
  • Roadmap

そして、上記で最も小さな単位であるIssueにはEpicとMilestoneとIterationの設定が可能。
これを図に起こしてみると以下のようなイメージで、IterationやMilestone、Epicといった機能を利用することで、要求事項を異なる単位(時間軸や機能の集合)で管理することが可能になる。

異なる単位(特に時間軸)で管理するというのはアジャイルにおける計画策定で使用される概念である「プランニングオニオン」の考え方を表したものである。


アジャイルでよく聞くプランニングオニオンとは?

プランニングオニオンとGitLabの機能を対応づけると以下の通りになり、GitLabの機能がアジャイル開発におけるプランニングの考え方に即して提供されていることがわかる。

GitLabの機能 プランニングオニオン 用途
Issue(Issue Board) Daily その日やることを管理する
Iteration Iteration イテレーション(通常1から4週間)でやることを管理する
Milestone Release リリースごとにやることを管理する
Epic なし イテレーションやリリースを跨いだ機能開発を管理する
Roadmap Product, Portfolio 複数リリース(製品ロードマップ)を管理する

実際にプロダクトやプロジェクトの管理をどのように行うかは利用者次第だが、これらの機能を活用することで特にアジャイルの計画を容易に実施することができる。

nabetsunabetsu

Label

GitLabにおけるLabel

以下に作成できる

  • Issue

  • Merge Request

  • Epic(Premium以上で利用可能)

  • 識別のため

    • Issueの識別
  • ワークフローの構築

    • Scoped Labelの機能を利用すれば

作成の単位

以下2つの単位で作成できる

  • Project Label
    • Labelの作成を行ったプロジェクトでのみ使用できる
  • Group Label
    • Labelの作成を行ったグループもしくはグループ配下で利用できる

また、Projectで作成したLabelについては後からGroup Labelへの昇格が可能

Scoped Label

Scoped Labelの特徴は

Nested Scoped Label

Label Priority

nabetsunabetsu

Python-gitlab

基本的な使い方

認証(GitLab objectの生成)

まず、gitlab.GitLab objectを生成する。
この際に認証を実施することができるが、基本的にAPIを直接呼んだ時と同様の認証方法が実施できるはず(未確認)。
Exampleに載っていたものでは以下3種類があった。

  • Personal Access Token
  • Oauth Token
  • Job Token

それぞれのやり方についてはGetting started with the API参照。

Personal Access Tokenを利用する場合には以下のようにすればOK

import gitlab

gl = gitlab.Gitlab('https://gitlab.com', private_token=API_KEY)

情報へのアクセス

例外はあると思うが、基本的にはGroup or Project単位でobjectを取得して、その中でIssueやMerge Reuqestsの情報にアクセスする。

# Group Objectの取得
GROUP_ID = 'xxxxxxxxxx'
group = gl.groups.get(GROUP_ID)

# 対象Group内のIssueの取得
issues = group.issues.list()
print(issues)
[<GroupIssue id:xxxxxxxxxx>,
 <GroupIssue id:xxxxxxxxxx>,
 <GroupIssue id:xxxxxxxxxx>,
 <GroupIssue id:xxxxxxxxxx>,
 <GroupIssue id:xxxxxxxxxx>,
 <GroupIssue id:xxxxxxxxxx>,
 ...
]

# 対象Group内のMergeRequestsを取得
mrs = group.mergerequests.list()

どのような情報にアクセスできるかは公式のAPI Exampleで確認すればOK。

Pagination

GitLabのAPI自体にPaginationの仕組みが導入されており、デフォルトでは全件を返してはくれない(Issueで20件ずつとか)。
pageper_pageを設定可能なのでページネーションをするか、all=Trueを指定して全件取得ができる。

# 
issues = group.issues.list(page=1, per_page=30)
len(issues) # 30

# 全件を取得
issues = group.issues.list(all=True)
len(issues) # 195

詳細については公式のPaginationの項を参照。

ユースケース

ProjectIDを指定して情報を取得

# Project Objectの取得
PROJECT_ID = '123456789'
project = gl.projects.get(PROJECT_ID)

# Issueの一覧を取得
project.issues.list(page=1, per_page=30)

リポジトリのファイルを取得

# repository_treeでファイルの情報を取得
items = project.repository_tree(path='', all=True)

# files.getでファイルの内容を取得
import pandas as pd
import io

file_data = project.files.get('temp.csv', 'main')
# file_data.decode()でbytes型のデータが得られるので、.decodeでstrに変換
csv_string = file_data.decode().decode('utf-8')
# bufferから直接読み込みを行うため、strをStringIOでbufferに変換
pd.read_csv(io.StringIO(csv_string))
nabetsunabetsu

GraphQL

FullPathでグループ名やプロジェクト名を指定する

# Write your query or mutation here
query {
  group(fullPath: "gitlab-org") {
    timelogs (startDate: "2021-01-01", endDate: "2021-01-22") {
      nodes {
        user {
          name
        }
        issue {
          title
        }
        spentAt
        timeSpent
        note {
          body
        }
      }
    }
  }
}
{
  "data": {
    "group": {
      "timelogs": {
        "nodes": [
          {
            "user": {
              "name": "Lee Tickett"
            },
            "issue": {
              "title": "Document `/spend` quick action date parameter"
            },
            "spentAt": "2021-01-01T00:00:00Z",
            "timeSpent": 3600,
            "note": null
          },
          {
            "user": {
              "name": "John McGuire"
            },
            "issue": {
              "title": "Display search results number/count next to filtering options in Global Search results page"
            },
            "spentAt": "2021-01-19T00:00:00Z",
            "timeSpent": 1800,
            "note": null
          },
          {
            "user": {
              "name": "John McGuire"
            },
            "issue": {
              "title": "Search API docs quick links do not work for project search"
            },
            "spentAt": "2021-01-15T00:00:00Z",
            "timeSpent": 3600,
            "note": null
          },
          {
            "user": {
              "name": "John McGuire"
            },
            "issue": {
              "title": "Determine cause for gradual increase in Elasticsearch latency since 2020-11-02"
            },
            "spentAt": "2021-01-14T00:00:00Z",
            "timeSpent": 10800,
            "note": null
          },
          {
            "user": {
              "name": "Achilleas Pipinellis"
            },
            "issue": null,
            "spentAt": "2021-01-14T00:00:00Z",
            "timeSpent": 1800,
            "note": null
          },
          {
            "user": {
              "name": "Achilleas Pipinellis"
            },
            "issue": null,
            "spentAt": "2021-01-13T00:00:00Z",
            "timeSpent": 1800,
            "note": null
          },
          {
            "user": {
              "name": "Achilleas Pipinellis"
            },
            "issue": null,
            "spentAt": "2021-01-13T00:00:00Z",
            "timeSpent": 3600,
            "note": null
          },
          {
            "user": {
              "name": "Achilleas Pipinellis"
            },
            "issue": null,
            "spentAt": "2021-01-12T00:00:00Z",
            "timeSpent": 14400,
            "note": null
          },
          {
            "user": {
              "name": "Achilleas Pipinellis"
            },
            "issue": null,
            "spentAt": "2021-01-12T00:00:00Z",
            "timeSpent": 1200,
            "note": null
          },
          {
            "user": {
              "name": "Achilleas Pipinellis"
            },
            "issue": null,
            "spentAt": "2021-01-11T00:00:00Z",
            "timeSpent": 18000,
            "note": null
          }
        ]
      }
    }
  }
}

認証

Graphql Playgroundの場合以下のようにHTTP Headersのタブなどで設定を入れればOK

nabetsunabetsu

APIでIssue Templateの内容を使ってIssueを起票

Project templates API | GitLab が提供されているので、これを使うことでTemplateの内容を取得することが出来ます。

TEMPLATE_URL = 'https://gitlab.com/api/v4/projects/xxxxxxx/templates/issues/xxxxx'
POST_ISSUE_URL = 'https://gitlab.com/api/v4/projects/xxxxxxx/issues'
API_KEY = 'xxxxxxx'

headers = {'Authorization': 'Bearer {}'.format(API_KEY)}

# Template APIを呼んでTemplateの内容を文字列で取得
res = requests.get(TEMPLATE_URL, headers=headers)
description = res.json()['content']

# 取得したTemplateの内容をdescriptionに設定することでTemplateを適用
post_params = {
    "title": 'sample',
    "description": description
}
res = requests.post(POST_ISSUE_URL, headers=headers, params=post_params)
nabetsunabetsu

ジョブの実行タイミングの制御

rulesを使って定義する。

実行要否の判定

ifに記載する。

  • 環境変数
  • $CI_PIPELINE_SOURCE

$CI_PIPELINE_SOURCE

説明
push 説明
web 説明
trigger 説明
schedule 説明
api 説明
external 説明
pipelines 説明
chat 説明
merge_request,event 説明
説明
parent_piepline 説明

環境変数

  • GitLab CIでデフォルトで定義されているもの
  • 自分が定義した環境変数

'$CI_COMMIT_BRANCH

実行タイミング

  • on_success
  • delayed
  • never
  • always

参考資料

GitLabのCI/CDで超重要なrulesの全てを理解する | DevelopersIO

nabetsunabetsu

環境変数

GitLab CI/CD variables | GitLab

dotenvとしてキーペアを渡すことで後続のジョブに環境変数を渡せる。

build:
  stage: build
  script:
    - echo "BUILD_VARIABLE=value_from_build_job" >> build.env
  artifacts:
    reports:
      dotenv: build.env

deploy:
  stage: deploy
  variables:
    BUILD_VARIABLE: value_from_deploy_job
  script:
    - echo "$BUILD_VARIABLE"  # Output is: 'value_from_build_job' due to precedence

複数行で渡す場合