弁護士ドットコム株式会社 Creators’ blog

弁護士ドットコムがエンジニア・デザイナーのサービス開発事例やデザイン活動を発信する公式ブログです。

合計 3600 行の .gitlab-ci.yml から 70 %重複コードを削減しつつ、必須のテストを必ず実装できるようにした

こんにちは。弁護士ドットコム クラウドサイン事業本部で SRE をしています、大内と申します。 クラウドサイン事業本部の SRE ではサービスの可用性、信頼性の向上や開発の高速化、省力化を目指した開発を日々行っています。

クラウドサインの本体アプリケーション(以下本体)のソースコードは GitLab で管理しており、 関連サービス、バッチなども 1 つのリポジトリで管理するモノレポ構成を取っています。

2022 年 9 月当時、バッチのソースコードだけで 43 個も管理していました。 バッチはいずれも GitLab CI で自動テストを実装しており、その CI コード行数はすべて合わせると 3600 行もありました。

今回は、そんな .gitlab-ci.yml を CI テンプレートを使って改善した話をご紹介します。

CI テンプレート導入以前の CI

GitLab CI では CI ジョブの定義を YAML(.gitlab-ci.yml)で行います。

2022 年 7 月に、巨大なひとつの .gitlab-ci.yml を分割して CI を高速化しました。 詳細は 1400 行の一枚岩な .gitlab-ci.yml を分割して CI を高速化したを参照してください。

上記対応により、CI が高速化したものの、ほとんど同じ構成の .gitlab-ci.yml がバッチの数だけ量産されました。

アプリケーションの改修とは異なり、CI は一度作り込んで安定したら、その後はほとんど変更が入りません。 よって、コピー&ペーストの設定ファイルが量産されることの弊害はあまり無く、 それ以上に、時間のかかる CI の待ち時間が他の CI をブロックする問題を解決するほうが先決と判断しました。 結果として、重複コードを受け入れる形で CI を分割しました。

実際この見通しは正しくて、.gitlab-ci.yml の設定値の変更(Docker イメージのバージョン更新など)が数ヶ月に一度入る程度でした。

以下のコマンドで、.gitlab-ci.yml のコミットログから日付を取得して、前回のコミットから次のコミットまでの経過日数を計算しました。

find */* -name .gitlab-ci.yml |
  while read -r file; do
    git log --date='short' --format='%cd' "$file" |
      ruby -rtime -lane 'd ||= []; d.append($F[0]); END{ puts "| 2022-09-22 | " + d[-1] + " | " + ((Time.parse("2022-09-22") - Time.parse(d[-1])) / 60 / 60 / 24).to_i.to_s + " | " + d.map.with_index{|v,i| ((Time.parse(v) - Time.parse(d[i+1])) / 60 / 60 / 24).to_i if i < d.length - 1 }.join(", ") + "|"}'
  done |
  awk 'BEGIN{ print "| 計測日 | ファイルの最初のコミット日 | 最初のコミット日から計測日までの差分日数 | コミット間の差分日数 |\n| --- | --- | --- | --- |"} {print}'

結果は次のとおりです。

計測日 ファイルの最初のコミット日 最初のコミット日から計測日までの差分日数 コミット間の差分日数
2022-09-22 2021-12-02 294 0, 159,
2022-09-22 2022-04-06 169 0, 29, 5,
2022-09-22 2022-04-06 169 0, 28, 6,
2022-09-22 2022-04-07 168 0, 28, 5,
2022-09-22 2022-04-01 174 0, 33, 6,
2022-09-22 2022-03-18 188 0, 36, 12, 5,
2022-09-22 2022-07-07 77
2022-09-22 2021-12-23 273 0, 138,
2022-09-22 2021-12-02 294 0, 159,
2022-09-22 2021-11-24 302 0, 167,
2022-09-22 2022-08-26 27
2022-09-22 2021-12-22 274 0, 139,
2022-09-22 2021-11-18 308 0, 173, 0, 0,
2022-09-22 2022-04-01 174 0, 34, 5,
2022-09-22 2022-08-18 35
2022-09-22 2022-08-18 35
2022-09-22 2021-11-26 300 0, 165,
2022-09-22 2022-08-05 48
2022-09-22 2022-08-17 36
2022-09-22 2022-03-16 190 0, 46, 3, 6,
2022-09-22 2022-02-25 209 0, 62, 2, 0, 3, 7,
2022-09-22 2021-11-24 302 0, 167,
2022-09-22 2022-01-21 244 0, 91, 18,
2022-09-22 2021-11-24 302 0, 167,
2022-09-22 2022-01-31 234 0, 99,
2022-09-22 2021-11-12 314 0, 174, 5, 0, 0,
2022-09-22 2022-01-19 246 0, 0, 111,
2022-09-22 2022-02-25 209 0, 0, 64, 6, 4, 0,
2022-09-22 2022-02-17 217 0, 0, 82,
2022-09-22 2022-05-24 121
2022-09-22 2022-01-21 244 0, 0, 109,
2022-09-22 2022-01-31 234 0, 0, 99,
2022-09-22 2021-12-14 282 0, 0, 147,
2022-09-22 2022-05-10 135
2022-09-22 2022-01-04 261 0, 0, 126,
2022-09-22 2022-08-12 41
2022-09-22 2021-12-02 294 0, 0, 159,
2022-09-22 2021-11-05 321 0, 0, 174, 5, 2, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0,
2022-09-22 2021-12-15 281 0, 0, 146,
2022-09-22 2022-01-21 244 0, 1, 84, 0, 0, 109,
2022-09-22 2021-11-22 304 0, 0, 169, 0,
2022-09-22 2021-12-20 276 0, 0, 141,
2022-09-22 2022-03-11 195 0, 0, 60,

以上の結果から次のことが分かります。

  1. 最初に .gitlab-ci.yml が作成されてから 100 日以上経過しているが、コミット回数は少ない
  2. 最初に作成されてから、一度も更新されていないファイルもある
  3. 1 ヶ月以上更新されていないファイルが多々ある

よって、コミットログからも .gitlab-ci.yml は一度安定すると、以降は更新頻度が非常に低くなるファイルと言えます。

特に .gitlab-ci.yml に大きな変更が入ることもなく安定していたのですが、 将来を見越して改善したい箇所が見つかったため、さらに CI 改善を進めることにしました。

CI の改善するべき点

重複するコード行数が多い

前述のとおり、バッチそれぞれに .gitlab-ci.yml を個別に定義しています。それらの CI ジョブ定義はほとんど同じで、重複コードが大半を占めていました。1 ファイルは 80 行程度ですが、合計すれば 3600 行にもなります。

これは、今後 CI に大きな変更を加える際の改修コストを増大させる可能性がありました。

必ず実施したいテストを漏れなく実装したい

アプリケーション開発時に、最低限 CI で常にテストしたいものとして、以下の 4 つがあります。

  1. 静的解析をパスすること
  2. コードフォーマット済みであること
  3. ユニットテストがパスすること
  4. ビルドできること

各バッチに個別で .gitlab-ci.yml を実装する場合、 基本的には既存の .gitlab-ci.yml をコピーしてから個別のバッチ用に設定値を調整して実装します。

よって、コピー元でそれらがすべて実装されていれば、実装が漏れることはないはずです。 しかし確実とは言い切れません。 レビューでも、実装が漏れていることに気づけない可能性もあります。

こういった実装漏れは、CI の実装ガイドラインを整備するよりも、 テンプレートなどで実装を使い回せる形にしたほうがより確実だと考えました。

include 機能で CI テンプレートを使う

前述の課題を解決するために GitLab CI の include 機能を使用する方針にしました。

参考:Use CI/CD configuration from other files - GitLab Docs

include 機能は、外部の YAML ファイルを読み込むための機能で、 .gitlab-ci.yml をテンプレートとして使い回せるようになります。 以降、このテンプレートとしての .gitlab-ci.yml を CI テンプレートと呼称します。

なお以下の記事で使用した Parent-child pipelines でも include キーワードを使用していますが、別物の機能である点に注意してください。

include の使い方

include で使用する CI テンプレートは、通常の .gitlab-ci.yml とほぼ変わりません。

例として、以下の template-a.gitlab-ci.yml を作成して、 ci-template ディレクトリに配置します。

---

stages:
  - test
  - deploy

test:
  stage: test
  image: alpine:3
  script:
    - echo test
  rules:
    - when: on_success

deploy:
  stage: deploy
  image: alpine:3
  script:
    - echo deploy

そしてリポジトリ直下の .gitlab-ci.yml から include してみます。

---

include:
  - project: {Group}/{Project}
    file: /ci-template/template-a.gitlab-ci.yml

これらのファイルの配置関係をまとめると、以下のとおりです。

リポジトリ/
  ci-template/
    template-a.gitlab-ci.yml

  .gitlab-ci.yml

これで GitLab CI を動作させると、test ジョブと deploy ジョブが実行されます。 include した .gitlab-ci.yml の内容がそのまま呼び出し元に展開されるものと考えてください。

複数のアプリケーションで CI テンプレートを使い回す

基本的な include の使い方は分かりました。 次はもう少し踏み込んで、異なるアプリケーションで 1 つの CI テンプレートを使い回す方法を説明します。

以下のようなディレクトリ構造とファイルを用意します。

リポジトリ/
  ci-template/
    template-a.gitlab-ci.yml

  app/
    app1/
      .gitlab-ci.yml
      main.go
    app2/
      .gitlab-ci.yml
      main.go

  .gitlab-ci.yml

template-a.gitlab-ci.yml の内容を以下に変更します。

---

stages:
  - test
  - deploy

test:
  stage: test
  image: golang:1.20-alpine
  script:
    - cd "$APP_DIR"
    - pwd
    - go build
  rules:
    - when: on_success

deploy:
  stage: deploy
  image: alpine:3
  script:
    - echo deploy

次に、app1/.gitlab-ci.yml を作成します。内容は以下です。 main.go はビルドできれば何でも良いです。

---

include:
  - project: {Group}/{Project}
    file: /ci-template/template-a.gitlab-ci.yml

variables:
  APP_DIR: app/app1 # <- ディレクトリのパスを指定

app2/.gitlab-ci.yml は以下の内容にします。

---

include:
  - project: {Group}/{Project}
    file: /ci-template/template-a.gitlab-ci.yml

variables:
  APP_DIR: app/app2 # <- ディレクトリのパスを指定

最後に、リポジトリ直下の .gitlab-ci.yml から各アプリケーションの .gitlab-ci.yml を参照します。

---

app1:
  stage: test
  trigger:
    include: app/app1/.gitlab-ci.yml
    strategy: depend
  rules:
    - when: on_success

app2:
  stage: test
  trigger:
    include: app/app2/.gitlab-ci.yml
    strategy: depend
  rules:
    - when: on_success

これで各 .gitlab-ci.yml の依存関係は次のようになります。

.gitlab-ci.yml の依存関係

GitLab CI を実行すると、出力はそれぞれ次のようになります。

# app1

$ cd "$APP_DIR"
$ pwd
/builds/Group/Project/app/app1
$ go build
# app2

$ cd "$APP_DIR"
$ pwd
/builds/Group/Project/app/app2
$ go build

各アプリケーションのディレクトリに移動して、各アプリケーションをビルドできていることが分かります。

このように、変数を利用してディレクトリを移動して、 移動先でテストを実行するようにすれば、1 つの CI テンプレートを使い回せます。

改善のために実施した改修の詳細

include 機能の使い方について簡単に解説しました。 次に、include 機能を使ううえで工夫した 3 つのポイントについて説明します。

  1. CI テンプレートを定義する
  2. バージョン情報は変数で渡す
  3. タグで CI テンプレートのバージョンを固定する

1. CI テンプレートを定義する

まず最初に、各バッチの .gitlab-ci.yml から参照する CI テンプレートを定義しました。

前述の「必ず実施したいテストを漏れなく実装したい」にも書いたとおり、静的解析といったコード品質を高めるための処理も CI に組み込みます。 加えて、以下の 3 つの処理も CI テンプレートのテストジョブに追加しました。

  1. テストで使用する依存サービスの起動(DB 類など)
  2. docker イメージのビルド
  3. ビルドしたイメージを使用して、ユニットテストやビルドを実行

必要な依存サービスだけ起動

ユニットテストを実装するとき、そのアプリケーションだけでテストを実施できない場合があります。 主に、外部のサービスを必要とするケースです。

Web サービスであれば、外部のデータベースに対して取得・更新を発行することが多々あります。 こういったテストを実装する場合、モックを使用してテストをすることもあれば、実際の依存サービスを立ち上げてテストすることもあります。

テストで必要になるサービスは、そのアプリケーションが提供する機能によって変わります。 バッチ処理でデータベースを使うことは多いです。 しかし、それだけとは限りません。

例えば、以下のサービスも追加で必要になるケースを考えてみます。

  • ドキュメント指向データベース (MongoDB)
  • キャッシュ用データベース (memcached)
  • 検索エンジン (Elasticsearch)

ここで、以下のようにバッチごとに必要なサービスが異なるケースを考えます。

  1. バッチ A では memcached だけ必要
  2. バッチ B では MongoDB と Elasticsearch が必要

単純な解決方法としては「すべての依存サービスを常に立ち上げてしまうこと」です。 こうすればバッチのユニットテストで必要なサービスだけテストコードから参照すれば良くなり、他は無視できます。

しかし、これには以下の 2 つの問題があります。

  1. 使わない依存サービスのために余計なネットワーク転送が発生する
  2. 使わない依存サービスの起動と安定化まで余計に待つ必要がある

これらはランニングコストの観点や、CI の待ち時間の観点からも避けたいです。 そこで「必要なサービスだけ起動できるように、CI テンプレートの変数で制御できる」ようにテンプレートを実装するようにしました。

通常、複数の docker コンテナを起動する場合、起動コンテナの設定を compose.yaml に記述して使用します。

$ ls compose.yaml
compose.yaml

$ docker compose up -d

この docker compose up は、コマンドライン引数にて起動するサービスを明示的に指定できます。

$ docker compose up --help

Usage:  docker compose up [OPTIONS] [SERVICE...]

$ docker compose up -d memcached mongodb

この仕様を利用して、必要なサービスだけコンテナを立ち上げられるようにします。

まず、CI で使用する compose.yaml を配置します。 バッチと、compose.yaml、CI テンプレートのディレクトリ関係は以下のようになります。

リポジトリ/
  ci/
    compose.yaml
    docker_login.sh

  ci-template/
    batch-golang.gitlab-ci.yml

  batch/
    batch-a/
      .gitlab-ci.yml
      Dockerfile
      main.go
    batch-b/
      .gitlab-ci.yml
      Dockerfile
      main.go
    batch-c/
      .gitlab-ci.yml
      Dockerfile
      main.go

以下のように CI テンプレートを実装します。

test:
  stage: test
  image: '使用するイメージ'
  services:
    - name: docker:${DOCKER_DIND_VERSION}
      command: ["--tls=false"]
  before_script:
    - pushd ci
    - ./docker_login.sh
    - docker info
    - SERVICES=""
    - if [ "${ENABLE_MONGODB}" = true ]; then SERVICES="${SERVICES} mongodb"; fi
    - if [ "${ENABLE_MEMCACHED}" = true ]; then SERVICES="${SERVICES} memcached"; fi
    - if [ "${ENABLE_ELASTICSEARCH}" = true ]; then SERVICES="${SERVICES} elasticsearch"; fi
    - echo "${SERVICES}"
    - docker compose -f compose.yaml up -d ${SERVICES}
    - sleep 10
    - popd
  script:
    - cd "$APP_DIR"
    - # 省略
  rules:
    - when: on_success

そして、例えば batch-a では MongoDB だけ必要だと仮定して CI テンプレートを呼び出します。 以下のように実装します。

---
# batch/batch-a/.gitlab-ci.yml

include:
  - project: {Group}/{Project}
    file: /ci-template/batch-golang.gitlab-ci.yml

variables:
  APP_DIR: batch/batch-a
  DOCKER_DIND_VERSION: 'dindイメージのバージョンなど'
  ENABLE_MONGODB: 'true' # variables は文字列型でないといけないので、クオートでくくること

必要なサービスを起動するための環境変数 ENABLE_* を定義して、有効・無効を切り替えられるようにしました。 これで、MongoDB が必要であれば、その変数を true にすれば、必要なサービスだけ起動できるようになります。

ビルドしたイメージを使ってテストを実行する

テストジョブ上で docker イメージをビルドしてテストを実行するようにします。 具体的には、以下のように実装します。

test:
  # 省略
  before_script:
    - # 省略
    - docker compose -f compose.yaml up -d ${SERVICES}
    - # 省略
  script:
    - cd "$APP_DIR"
    - docker build --target base --no-cache -t dev .
    - docker run -d --name dev --network ci_default -t dev tail -f /dev/null
    - sleep 3
    - docker exec dev sh -c "go vet ."
    - docker exec dev sh -c 'if [ $(gofmt -s -l .| wc -l) -ne 0 ]; then echo "[ERR] go fmt . してください"; exit 1; fi'
    - docker exec dev sh -c "go test -cover ./..."
    - docker exec dev sh -c "go build"

before_script で依存サービスを起動した後、script で docker イメージをビルドします。 ビルドしたイメージを使用し、先に起動していたコンテナ郡の docker ネットワークに追加する形でコンテナを起動します。 起動したコンテナに対して docker exec でコマンドを送信し、コンテナ内で各種コマンドを実行します。

ここで実行しているコマンドは以下の 4 つです。

コマンド 意味 備考
go vet 静的解析
go fmt コードフォーマット go fmt の結果を数えて、1 つでもフォーマットされたファイルが存在したらエラーにしている
go test ユニットテスト
go build ビルド

GitLab CI では、CI ジョブを実行する際の環境を docker イメージで指定できます。

例えば Go アプリケーションのユニットテストの CI を実装したい場合、 imagegolang:1.21.3 などを設定すれば、script でそのまま go test を実行できます。 以下のように実装するだけです。

test:
  stage: test
  image: golang:1.21.3
  script:
    - go test ./...
  rules:
    - when: on_success

ライブラリ目的のパッケージであれば、こちらの実装方法でも良いでしょう。 しかし、今回はバッチ用アプリケーションのユニットテストであったため、この方法は採用しませんでした。 理由は、 CI 環境と本番環境で、動作する環境に差異が発生するから です。

例えば、タイムゾーンを設定する環境変数 TZ を例に挙げますと、 この設定値の有無で時刻に関係する挙動が変わり得ます。

タイムゾーンを統一するために Dockerfile で ENV TZ='Asia/Tokyo' を設定していた場合、 本番環境や検証環境では東京のタイムゾーンで動作します。 しかし、CI 環境でこの設定が漏れていると、ユニットテストでは UTC で動作してしまう場合があります。

こうなったとき、ユニットテストをパスして検証環境で動作させたときに時差の関係で不具合が発生する、といったことが起こります。 このような環境差異を可能な限り防ぐため、同じ Dockerfile からビルドしたイメージを使ってユニットテストを実施するようにしました。

2. バージョン情報は変数で渡す

バージョン情報は CI テンプレートには含めず、テンプレート外から渡すようにします。 主に docker イメージのタグを指します。

test:
  services:
    - name: docker:${DOCKER_DIND_VERSION} # <- これ
      command: ["--tls=false"]

このように実装することで、バージョン情報を CI ごとに個別で指定可能となります。 これには以下の 3 つのメリットがあります。

  1. バッチ 1 つずつバージョン更新を進められる(全部同時にテストしなくて良い)
  2. バージョン更新の MR の生存期間が短くなる(1 つバージョン更新が完了したらすぐにマージできる)
  3. 複数人に作業を分担できる

特筆したいのは 1 の「バッチ 1 つずつバージョン更新を進められる」点です。

もし CI テンプレートがバージョン情報を保持していた場合、 バージョン情報を更新すると CI テンプレートを使っているすべての CI を同時にテストし直さなければなりません。 これはバージョン更新時のテストの負担を増大させ得る要素です。

「複数のアプリケーションで CI テンプレートを使い回す」セクションでは、 例として 2 つのアプリケーションが 1 つの CI テンプレートを使用する例を説明しました。

2 つのアプリケーションが 1 つの CI テンプレートを使用する例

この例では、CI テンプレートを使用している CI が 2 つしかありません。 よって、仮に CI テンプレートがバージョン情報を抱えていたとして、 バージョン更新をしても同時にテストする必要があるのはたった 2 つです。

しかしながら、クラウドサインでは 43 個ものバッチが動作しています。 よって、依存関係は以下のようになります。

43 個のアプリが CI テンプレートを使用する例

サービス規模が大きく、多数の CI を動かす必要がある場合は、バージョン情報を CI テンプレートで保持しないほうが良いでしょう。

3. タグで CI テンプレートのバージョンを固定する

CI テンプレートを include する際に、git tag のタグバージョンを必ず指定するようにします。 以下のようにします。

 ---
 include:
   - project: {Group}/{Project}
     file: /ci-template/batch-golang.gitlab-ci.yml
+    ref: 1.0.0-ci-template-batch-golang.gitlab-ci.yml

ref を指定しなかった場合、デフォルトブランチの最新が参照されます。

CI テンプレート自体に大きな変更が発生したときに、多数の CI を同時にテストするのは難しいです。 1 つずつ動作確認しながら、更新後の CI テンプレートに切り替えていけるように、CI テンプレートのバージョン固定は必須です。

また 1 つのリポジトリで複数の CI テンプレートを管理するため、 発行するタグバージョンにファイルパスも含めるようにしました。

もし、タグバージョンが 1.0.0 などだけだった場合、 新しいタグ 2.0.0 などが発行されたときに、 どのテンプレートに破壊的変更が追加されたのか読み取れなくて混乱するでしょう。

CI テンプレート導入の結果得られた効果測定

何行コード削減できたか

CI テンプレートの導入後のコード行数を集計してみます。

集計する手順は以下の流れになります。

  1. その当時のコミットに git switch する
  2. バッチ用 .gitlab-ci.yml のファイルパス一覧を取得する
  3. 最新のブランチに git switch する
  4. ファイルパスの一覧で行数を数える

以上の流れをコマンドで実行します。

$ git switch -d 'コミットハッシュ'

# 当時 43 個バッチ用の CI が存在した
$ find * -name '.gitlab-ci.yml' | nl | tail -n 1 | awk '{print $1}'
43

# 当時 43 個のバッチ用の CI の合計コード行数は 3554 行あった
$ find * -name '.gitlab-ci.yml' | xargs wc -l | tail -n 1
    3554 total

# 当時存在したバッチ用 CI のファイル名のリストを取得
$ find * -name '.gitlab-ci.yml' > /tmp/gitlab-ci-yaml.list

# 最新ブランチに切り替え
$ git switch master

# 当時存在したバッチ用 CI のファイルパスのリストに対して行数をカウント
$ cat /tmp/gitlab-ci-yaml.list | xargs wc -l | tail -n 1
     804 total

以上の結果から、コード行数が 3554 行から 804 行になったことがわかります。 この 804 行には CI テンプレート自体の行数が含まれていません。

バッチは種類が複数存在しており、種類毎にテンプレートを用意しています。 それらテンプレートすべての行数を数えたところ 281 行ありました。 これら CI テンプレートのコード行数も加算した改善後のバッチ用 .gitlab-ci.yml の合計コード行数は 1085 行です。

よって、2469 行のコード削減となりました。 百分率で表現すると 69.5 %の削減です。 なかなかの削減率ですね。

CI テンプレートを使っていなかったら何行になっていたか

2023 年 10 月 26 日時点でバッチを数えたところ 62 個ありました。 2022 年 9 月時点では 43 個だったため、1 年間で 19 個バッチが増えたことになります。

せっかくなので、もし CI テンプレートを使っていなかったらどうなっていたかも見積もってみます。

2022 年 9 月時点でバッチは 43 個、コード行数は 3554 行だったため、 平均すると 1 ファイルあたり 82.6 行のコードが書かれています。 なお CI テンプレート使用後の 1 ファイルあたりのコード行数は平均 19.1 行でした。

このコード行数のまま 62 個までバッチが増えていた場合、合計は 5121.2 行になります。 そして、2023 年 10 月 26 日現在の実際のコード行数を集計すると 1187 行でした。

$ find * -name '.gitlab-ci.yml' | xargs wc -l | tail -n 1
    1187 total

これに前述の CI テンプレートの行数を加算すると 1468 行です。

よって、CI テンプレートを使っていなかった場合、 コード行数は 5121 行になっていて、 現在よりも 3653 行も余分な重複コードを保守していた可能性があります。

謝辞

さて、ここまで「CI テンプレートを使用した CI 改善」の話を紹介しました。 こちらの活動は私一人で実現したものではありません。

私が行った活動としましては、主に以下の 2 つです。

  1. CI テンプレートの設計と実装
  2. CI テンプレートを切り替えるための参考実装として、いくつかの CI で CI テンプレートを使うように修正

そして、残りの 40 個近くあるバッチの CI で、 CI テンプレートを使うように切り替えてくださったのは、開発エンジニアの皆様です。

完遂するまでの長い旅路を歩んでこれたのは、ひとえにエンジニアの皆様の協力あってこそです。

あらためて、この場を借りて感謝申し上げます。 ありがとうございました。

SRE NEXT の宣伝

「謝辞」でも書きましたとおり弊社の SRE は開発エンジニアと日々協力しながら開発・改善活動を進めています。

これら DevOps を実現した活動に尽きましては、弊社 SRE の上田が SRE NEXT にて登壇しておりますため、 興味がありましたらこちらの発表もご覧ください。

まとめ

話した内容をまとめると、以下のとおりです。

  • CI テンプレート使用以前の状況について説明しました
    • 重複コードが非常に多い
    • 実装漏れを防ぎたい
  • GitLab CI の include 機能について説明しました
    • 単純に include する例
    • 複数の .gitlab-ci.yml から include する例
  • CI テンプレートを使用した改善の詳細について説明しました
    • CI テンプレートに実装したテストの詳細
    • バージョン情報を変数で渡すことで、大量の CI から参照されていても 1 つずつ慎重にテストできる
    • CI テンプレート呼び出しをバージョン固定することで、テンプレートを更新する際も 1 つずつ慎重にテストできる
  • 改善結果の計測をしました
    • 2469 行 (69.5%) のコードを削減した

以上です。