CI/CD ディープダイブデモ

CI/CD ディープダイブ

GitLab CI/CD パイプラインをより詳しく見ていきましょう。

構成と統合

最上位の CI の構成と必要な統合のセットアップから始めましょう。

リポジトリへの接続(ミラーリング)

すでに GitLab はインストール済みなので、ソースコードリポジトリへの接続に進みます。私たちのお客様の大多数は、その豊富な機能セットと CI/CD とのシームレスな統合により、組み込みの Git リポジトリ機能を利用しています。ただし、別の SCM ツールを使用したい場合は、ミラーリングを構成するだけで Git ベースのリポジトリに接続できます。

Project Settings > Repository > Pull from a remote repository

組み込みリポジトリと、2 つの部分で構成されたシンプルな Java アプリから始めます。Java ライブラリと、そのライブラリに依存してユーザーに簡単な挨拶を返すフロントエンドサービスです。

アジャイル計画ツールとの統合(JIRA & Slack)

リポジトリと同様に、GitLab には先ほど見たように強力な計画ツールセットも含まれています。ただし、ここでも JIRA や Slack のような優れた統合オプションがあります。これらがどのように構成されるか見てみましょう。

JIRA の構成は、ほんの 1〜2 分で完了します。サーバーの URL、認証用の認証情報、そしてプロジェクト情報(キーと Issue を閉じるためのトランジション)を提供しました。これだけです!

Project Settings > Integrations > JIRA

Slack 通知と ChatOps コマンドの有効化も同様に簡単です。通知については、チャンネルにプッシュしたいイベントを選択し、Slack サーバーの webhook を提供します。この場合、すべてのブランチで成功・失敗したパイプラインの両方について Pipeline イベントをプッシュしています。

Project Settings > Integrations > Slack Notifications

.gitlab-ci.yml の操作(バージョン管理、編集方法)

Repository

ダウンストリームツールの統合は、実行したいステージ、ジョブ、アクションを指定するパイプライン定義ファイル .gitlab-ci.yml を操作することで実現します。

その前に、このファイルを操作する様々なオプションについて簡単に話しましょう。ご覧の通り、このファイルはリポジトリにチェックインされており、これにはいくつかの利点があります:

  • ファイルがバージョン管理されているということは、アプリコードの変更をサポートする形でブランチでパイプラインの変更をテストできるということです。同様に、古いバージョン(例えばセキュリティリリースを出すため)に戻る必要がある場合、関連するパイプラインはその特定のリリース時点のままです。
  • これはまた、このファイルを操作する方法が多数あることも意味します。ほぼすべての IDE には Git との直接統合があるので、好きなエディタを使えます。クラシックな CLI も常に可能ですし、ここに見える統合された Web ベースのエディタも使えます。

このファイルと、パイプラインを定義してさまざまなツールと統合する方法を詳しく見てみましょう。

.gitlab-ci.yml の設定(セルフサービス、Bash スクリプト、テンプレート)

.gitlab-ci.yml ファイルをクリックして表示

ファイルの先頭でいくつかのグローバルデフォルトを定義しています:

  • コマンドを実行する Docker イメージ。この場合は公式 Maven イメージ
  • いくつかの環境変数
  • ジョブ間でフォルダーを永続化してパフォーマンスを向上できるキャッシュ設定

次に、ステージとジョブの定義を始めます。GitLab CI では、Pipeline は一連のステージで構成されます。各ステージには 1 つ以上のジョブが含まれます。1 つのステージに含めることができるジョブの数に制限はありません。

stages キーワードはステージが実行される順序を定義します。フローは: build、test、generate docs、release、deploy となります。

Build ステージ(Maven、Bash スクリプト)

次にジョブ、つまり実行したいアクションを定義し始めます。

最初のジョブはライブラリをビルドすることで、Maven を使います。ご覧の通り、自分のマシンで実行するかのように単純に Maven を呼び出します。これは、ここで見えるスクリプトが実は Bash スクリプトに過ぎないからです。これは、自分のマシンで普段行うことなら何でも自動化できるため、大きな柔軟性を提供します。

Test ステージ(2 ジョブ、コードカバレッジ出力、アーティファクト)

ライブラリをビルドした後、それをテストします。

テストステージには 2 つのジョブが含まれます: ユニットテストと codeclimate による静的解析です。テストの実行に再び Maven を活用しますが、コードカバレッジレポートを生成するために jacoco も含めます。次にカバレッジパーセンテージをビルドログに出力します。このジョブの最後のステップは、コードカバレッジレポートを取得し、GitLab の統合アーティファクトリポジトリで永続化することです。これは保存したいフォルダーを指定するだけで実現できます。

その間に、codeclimate による静的解析も実行します。ここでは、公式 Docker イメージを利用するためにデフォルトイメージを上書きします。これを使って Docker-in-Docker を実行し、ソースを解析するために codeclimate イメージを実行します。それが完了したら、JSON レポートを取得してアーティファクトとして永続化します。

Doc ステージ(生成、アーティファクト)

ここでは、javadoc を生成し、再びアーティファクトとして保持しているだけです。

Release ステージ(保護された変数)

ライブラリをテストしたので、リリースの準備ができました。再び Maven を使用して、ライブラリを Packagecloud サーバーに公開します。よく注意していると、上で定義していない変数を使っていることに気づくでしょう。これは認証情報トークンであり、リポジトリにチェックインすべきではありません。代わりに、これをプロジェクト設定で保護された変数として追加し、管理者のみが閲覧できるようにします。

Deploy ステージ(Pages、クロスプロジェクトパイプライン)

最後に、deploy ステージがあり、2 つのジョブが含まれます。

Pages ジョブは少しユニークで、これは静的サイトホスティング機能である GitLab Pages と連携する特別なジョブです。Pages を使えば、静的サイトのデプロイはアーティファクトを作成するのと同じくらい簡単です。ここでは、ユニットテストと javadoc という 2 つのジョブのアーティファクトを利用することを指定して実現しています。このジョブはそれらを 1 つのディレクトリ構造にコピーし、アーティファクトとして永続化します。GitLab Pages はこれを取り、統合ホスティングサービスにデプロイし、コードカバレッジとドキュメントを投稿する簡単で自動化された方法を提供します。

最後のジョブですが、Java アプリは 2 つのコンポーネント、つまりこのライブラリとそれを使用するフロントエンドサービスで構成されていることを思い出してください。この時点で、すべてのテストが通ることが確認できており、これは良いスタートです。しかし、これを利用するダウンストリームプロジェクトはどうでしょうか? このジョブは、私たちがクロスプロジェクトパイプラインと呼ぶものを起動します。ストックの alpine イメージを取得し、curl をインストールし、それを使って webhook をトリガーして新しいフロントエンドサービスのパイプラインを開始します。アップストリームの変更がダウンストリームプロジェクトに悪影響を与えないことを確認するのは、数行の YML だけで済みます。

まとめ(セルフサービス: プラグイン不要、柔軟: Bash スクリプト、テンプレート)

ご覧の通り、これは GitLab のより大きな目標であるスケーラビリティ、柔軟性、セルフサービスをサポートしています:

  • 開発者は、プラグインのインストールを心配したり、管理者を関与させたりすることなく、必要な任意のツールと統合できます。スクリプトを実行するために必要なコンテナや VM を提供するか、関連する要件を満たすマシンに独自のランナーをインストールするだけです。
  • 静的解析やユニットテストフレームワークとの統合は数行のコードで済みます。
  • パート 2 に進めば、Maven のようなビルド自動化ツールとの統合も同様に簡単であることがわかります。
  • ユーザーが始めるのに役立つテンプレートのコレクションもあります。

深いツール統合とインテリジェンス(Code Climate、コードカバレッジ、JIRA Issue)

ユニットテストと静的解析の実行がどれほど簡単かはすでに示しましたが、私たちの統合はもっと深く入っていきます。レビュー待ちのマージリクエストがあるので、見てみましょう。

保留中のマージリクエストを開く

コードレビュアーとしての私の仕事は本当に重要です: 高品質で基準を満たしたコードのみがマージされるようにすることです。手動レビューを支援するために、静的解析やコードカバレッジなどの自動ツールを含めることがよくあります。しかし、これらのレポートは長くて退屈なことが多く、使用率が低下することにつながります。GitLab の包括的なビジョンにより、これらの課題を解決するユニークな機会があります。

開発者の 1 人が、すでに対処済みの放置された FIXME コメントをクリーンアップし忘れたようです。パイプラインは成功しているので、これは有望です。コードをビルドし、ユニットテストと静的解析を実行し、javadoc を生成しました。ここまではかなりシンプルですが、ご覧の通り、私たちの統合は追加のインテリジェンスでさらに進みます。

ここでは、ユニットテストジョブからコードカバレッジを抽出し、インターフェースに直接表示しています。codeclimate レポートの解析も行いました。このブランチの結果と、マージしようとしているブランチの結果を比較することで、これが受け入れられた場合のコード品質のデルタをレビュアーに提供できます。大量の結果をふるいにかける代わりに、この変更に関連するものが提示されます。

もちろん下では、実際のコード変更をレビューしてコラボレーションできます。しかし、これはすべて良さそうなので、マージしましょう。

Merge

統合された Issue 機能で先ほど見たのと同様に、関連する JIRA Issue も閉じます。この Issue を簡単に見てみましょう。

すでにリンクされており、現在は閉じられていることを示します。タブを閉じて MR に戻ります。

ビルド自動化の実行

master に変更をコミットしたことで、新しいパイプラインが実行されます。それがどのように実行され、どのような通知を受け取るか見てみましょう。

Command-Click で Pipelines を新しいタブで開き、Master で開始したばかりのパイプラインをクリックして概要を表示

進行中のパイプラインのリアルタイム概要が表示されます。ビルドステージが完了したばかりで、2 つのテストステージが並列で実行されているのが見えます。ユニットテストジョブを詳しく見てみましょう。

ユニットテストジョブ(Maven、コードカバレッジ、アーティファクト)

unit tests ジョブをクリック

以前のように、Runner によって実行されているビルドログをライブで見ることができます。Maven が実行され、最終的にテストが通っていることがわかります。これは GitLab が解析しているコードカバレッジ出力と、アーティファクトです。右側には、コードカバレッジが表示され、アーティファクトを参照する方法も提供されます。これらは将来、他のジョブからもアクセスできます。

次に、codequality ジョブを見てみましょう。

Code Climate ジョブ(Docker、アーティファクト)

右ペインから codeclimate ジョブをクリック

このジョブでは、codeclimate イメージをダウンロードして実行する様子が見えます。次に、出力を収集してアーティファクトとして永続化します。これだけで簡単です。

パイプライン概要に戻り、進捗を確認しましょう。

ページ上部のパイプライン番号をクリックして概要に戻る

リリースジョブが実行中です。それがどう進んでいるか見てみましょう。

リリースジョブ(保護された変数、Maven デプロイ)

Maven を利用して、Packagecloud サーバーにライブラリを公開する準備ができました。これに保護された変数を使用し、セキュアトークンがリポジトリにコミットされないようにしていることを思い出してください。

ビルドログをスクロールして環境変数が機能していることを示す

これで完了です。ライブラリは他のユーザーが利用できるようになりました。

パイプライン概要に戻る

Pages ジョブ(成功通知のために時間を稼ぐために必要なら)

Pages ジョブでは、以前のステージで収集したアーティファクトを活用しています。ここでは、それらを 1 つのディレクトリ構造にコピーし、新しいアーティファクトに永続化するだけです。GitLab Pages サービスがここから引き継ぎ、コードカバレッジとドキュメントを静的サイトにコピーします。これは、任意の静的サイトジェネレーターでも機能します。

通知 - 成功: ブラウザ、Slack、Favicon、メール(デフォルトでオフ)

通知からわかるように、パイプラインは成功しました。その怒涛の中で見逃した場合のために、簡単に確認しましょう:

  • GitLab 自体は、パイプラインが成功または失敗するとブラウザ通知でアラートします。
  • Slack 通知を構成したので、そこにも通知が届きました。見てみましょう。

Slack タブに切り替え、通知を表示

  • GitLab は MR とパイプラインビューの両方で favicon も更新し、成功したことを示します。
  • 最後に、メールを受信することもできましたが、デフォルトでは成功したパイプラインに対してメールは送信されません。

パイプライン概要に戻る

クロスプロジェクトパイプライン(環境画面、レジストリ)

フロントエンドサービスのクロスプロジェクトパイプラインの状況を確認しましょう。

downstream ステージをクリック

ここで、比較的シンプルなパイプラインが見えます:

  • プロジェクトをビルド
  • テストを実行
  • JAR ファイルをパッケージ化
  • Docker コンテナをビルド
  • Production にデプロイ

Production をクリック

素晴らしい、デプロイが完了し、環境が利用可能になったようです。環境をクリックすると常により多くの情報が得られ、デプロイ履歴やモニタリング・トラブルシューティングのオプションが表示されます。

統合されたコンテナレジストリも詳しく見ることができます。

Registry タブをクリック

ここでは、現在レジストリにプッシュしているすべてのコンテナと、それに関連するタグのビューが見えます。必要なら、不要なものを手動で削除できます。コンテナを一括管理するツールも提供しています。

統合された UI に加えて、レジストリを統合する重要な利点の 1 つは、統一された認証アーキテクチャです。認証情報とセキュリティを自分で管理する代わりに、GitLab は非常にシンプルにします。ジョブが実行されている間有効な、レジストリにアクセスするためのシンプルな環境変数を提供します。

パイプラインのまとめ(柔軟、セルフサービス)

これが「ハッピーパス」です。わずか数行の YML で以下を達成しました:

  • Maven、ユニットテスト、コードカバレッジ、Code Climate との統合
  • Javadoc の生成
  • ライブラリの Package Cloud へのリリース
  • 最新ドキュメントのチームサイトへの公開
  • 否定的影響がないことを確認するためのダウンストリームプロジェクトパイプラインのトリガー

そしてこれを、管理者を関与させたりチケットを開いたりすることなく、すべて行いました。開発者による完全なセルフサービスです。

ネガティブパス

しかし、ライブラリにいくつか改善ができると思います。

dep.java に戻り、bye のテキストを編集

ご覧の通り、このライブラリはユーザーに挨拶をしてさよならを言います。「Goodbye」と言うことで、もう少し丁寧にしましょう。

これを新しいブランチにコミットし、新しいマージリクエストを作成します。

新しいブランチにコミットし、新しいマージリクエストを作成

失敗したマージリクエスト(MWPS、GitLab、Slack、Favicon、メール)

新しいブランチを作成したので、新しいパイプラインが実行されています。私がレビュアーで、すでに変更をチェックアウトしている場合、Auto-merge ボタンをクリックするだけです。これにより、緑のパイプラインを含むすべてのチェックが通れば、Issue は自動的にマージされます。ただし、失敗して開発者がさらに変更を加える必要がある場合は、もちろん再レビューが必要になります。これは、レビュアーがパイプラインの完了を待たずに次に進めるよう、時間を節約する素晴らしい方法です。

新しいバージョンのライブラリをビルドしており、次にテストを実行します。ユニットテストがどう進んでいるか見てみましょう。

Command-Clickunit tests ジョブを開く

おっと、通知からわかるように、テストが失敗したようです。この場合、メッセージを変更しましたが、テストの更新を忘れていました。

受け取った通知を簡単に確認しましょう:

  • GitLab 自体がブラウザ通知を送り、失敗したパイプラインを示しました
  • Slack 統合により、そこでもアラートを受け取りました(Slack を表示)
  • 見てみると、favicon もエラーを示すように更新されています
  • そして最後に、これは失敗したパイプラインだったので、メールアラートも受信しました

メールタブを表示 ユニットテストのジョブログに戻る

失敗したマージのフォローアップ(新しい Issue、新しい Todo)

ご覧の通り、ユーザーにパイプラインが失敗したことを通知する幅広い方法があります。しかし、通知と少なくとも同じくらい重要なのはフォローアップです。

失敗したジョブに戻ると、新しいボタンが現れていることに気づきます。この問題に対する Issue を簡単に作成できます。クリックすると、ビルドログのような有用な情報がすでに記入された Issue が開きます。

画面の右上隅を見ると、新しい To Do があることに気づくかもしれません。To do は、物事が漏れないようにユーザーを支援するための、本質的に自動的に組み込まれたツールです。例えば、Issue やコメントで言及された場合、または今回のように失敗したパイプラインがあった場合などです。

これにより、繰り返しを減らし、ミスを減らして、ユーザーが日々を過ごすことが容易になります。

これが「ネガティブパス」と呼ばれるものの簡単なレビューです。パイプラインのパフォーマンスをレビューするための利用可能なオプションをいくつか見てみましょう。

CI のモニタリング(パイプライン履歴、Prometheus による CI モニタリング)

すべてのパイプラインのリストの Pipelines タブをクリック

まず、GitLab はすべての現在および古いパイプライン、ステージ、ジョブの完全なパイプライン履歴を保持しています。各ジョブのステータスを追跡しますが、ビルドログも永続的に保持します。アーティファクトについては、容量を管理するためにデフォルトの有効期限を設定できますが、.gitlab-ci.yml ファイル内から簡単に上書きできます。

このページは、さまざまなブランチのパイプラインのステータスをチェックし、CI システムが何をしているかについての洞察を得るのに最適です。

しかし、それは CI システムが現在実行している内容を理解する唯一の方法ではありません。統合された Prometheus モニタリングシステムで追跡される豊富なメトリクスも提供しています。GitLab.com のパブリックモニタリングダッシュボードを見てみましょう。

dashboards.gitlab.com を表示

ここでは、各状態のジョブ数から、特定のランナーが実行している並列ジョブ数まで、幅広いメトリクスが見えます。これらのメトリクスはすべて、SaaS だけでなくセルフマネージドでも利用可能です。

アナリティクス(Charts、静的解析、コードカバレッジ、サイクル分析、APM)

GitLab は、特定のジョブの CI パイプラインの健全性を理解する方法も提供します。Charts と呼ばれる専用のアナリティクスページがあり、各プロジェクトの追加情報を表示します。

Pipelines > Charts を開く

ここでは、パイプラインの平均成功率と実行時間についての洞察を得ることができます。私たちの場合、かなり迅速で、通常 2 分未満で実行されます。

成功率が時間とともにどう変化しているかや、過去 1 週間、1 か月、1 年間に実行されたジョブ数の履歴的な洞察も提供します。

CI の一部として提供する他のアナリティクスサービスもいくつか見てきました:

  • codeclimate による静的解析インテリジェンス
  • コードカバレッジの解析
  • そして、チームの健全性と効率のためのサイクル分析。

GitLab Runner(共有、固有、オートスケーリング)

Runner について何度か触れましたが、ほとんどそれが何ができるかを見てきました。次に、GitLab CI のこの重要な部分について少し時間をとって話しましょう。

GitLab Runner は、幅広いプラットフォーム向けにビルドする小さなポータブルアプリです。本質的に、パイプラインで指定したジョブを取得して実行する働き蜂です。

Pipelines 設定ページでは、開発者がプロジェクトの Runner 構成を確認できます。ここに見えるように、Runner には共有と固有の 2 つのカテゴリがあります。

Settings、Pipelines に移動

共有(容易さ、速度、効率的な管理)

共有ランナーは、GitLab インスタンスの管理者によって提供されたランナーです。ここで見えるように 1 つを使っています。管理者が共有プールを提供できるようにすることで、いくつかの利点があります:

  • インフラストラクチャ(クラウドまたはオンプレミス)の統合。クラスタと認証情報を中央で管理できます。
  • 各チームの CI セットアップに必要な労力を削減

しかし、管理者が共有プールを提供していない場合や、ニーズを満たさない場合があります。

固有(セルフサービス、インストール)

これらの場合のために、開発チームが独自のランナーを接続できる機能があります。Runner をダウンロードし、URL とキーを入力するだけで準備完了です。

そのプロセスを今見てみましょう。時間の都合上、すでに macOS 版をダウンロードしています。

最初に行いたいアクションは、Runner を登録することです:

gitlab-runner register

登録中に、Runner のいくつかの側面を構成します:

  • URL とトークンを設定
  • Runner ページに表示したい名前
  • そして、指定したい任意のタグ。タグを使用すると、特定のプロパティを持つランナーを一意に識別できます。たとえば、ここでは osxxcode8 を設定して、何をインストールしているかを識別できます。これらは、実行したいジョブの .gitlab-ci.yml で指定されます。

Runner アーキテクチャ(Shell/SSH、VM、コンテナ、オートスケーリング)

最後に行う選択は、Runner の動作モードです。最もシンプルなのは Shell で、インストールされているマシンとアカウントでスクリプトを実行します。

次に、virtual box、parallels、もちろん Docker を介してイメージとコンテナを操作するサポートがあります。Runner は指定されたイメージを開始し、ジョブを実行し、クリーンアップします。これらのモードは共有ランナーに最適で、開発チームは引き続き独自のベースイメージを持ち込めるからです。

最後の動作モードは、オートスケーリングランナーと呼ぶものです。これは Docker Machine と Kubernetes でサポートされており、Runner は CI キューを処理するために必要に応じてエラスティックにジョブを処理します。

まとめ(セルフサービス、柔軟、スケーラブル)

これが構成のすべてです。Runner を起動するだけで、ジョブを処理する準備が整います。

gitlab-runner start Runner 設定ページを更新

開発チームが独自の CI インフラストラクチャをセットアップできるようにする GitLab CI のこの能力は、本当に変革的です。

まず、セルフサービス: 新しいハードウェアの依頼を提出し、応答を待ち、変更とコストを正当化し、PO を提出する必要があり… 開発チームは古いマシンを倉庫から取り出して 2 分で進められます。開発チームは満足し、より生産的になり、インフラストラクチャはデータセンターの iOS チーム用 Mac Mini の群れの管理を心配する必要がないため満足します。

第 2 に、多くの柔軟性を提供します。Android やディープラーニングのために ARM デバイスでジョブを実行する必要がある場合、Android に Runner をインストールするだけです。Linux on Z のようなメインフレームで何かを実行する必要がある? Runner をビルドして進めるだけです。コンテナのようなものが不可能な場合のハードウェアとソフトウェアの依存関係の管理は、これ以上簡単になりません。

最後に、スケーラビリティです。GitLab.com のオートスケーリングランナーのほんの一握りで、日常的に 1000 以上の並行 CI ジョブを処理しています。さらに必要なら、ダイヤルを上げるだけです。

GitLab Pages

最後に話したいのは GitLab Pages です。先ほどパイプラインで見たように、わずか数行の YML で javadoc とコードカバレッジレポートをここにプッシュしました。このサイトは、GitLab によって特定のドメインでホストされ、CI で技術コンテンツやウェブサイト全体を簡単に公開できるようになります。

締めくくり(柔軟: bash でも script でも、セルフサービス: ランナー、プラグイン不要、スケーラブル: SaaS スケールの CI)

要約すると、GitLab CI は柔軟です。bash でできるなら、自動化できます。セルフサービスのランナー、プラグイン不要。そしてオートスケーリングを備えた SaaS スケールの CI。