すべての開発者は、ソフトウェア開発ライフサイクルにおいてバージョン管理がいかに重要であるかを理解しています。これにより、複数の人が単一のプロジェクトで同時に作業できるようになり、各自がコードの独自のコピーを保持し、チームの他のメンバーと共有するタイミングを選択できます。これを実現するために、開発者はGitリポジトリを利用してバージョン管理を行います。GitLabは、単なるバージョン管理ツールにとどまらない、WebベースのGitリポジトリです。さらに、DevOpsツール、課題追跡、継続的インテグレーション、およびデプロイメントを提供します。
GitLabには、GitLab Community Edition (CE)、GitLab Enterprise Edition (EE)、およびGitLab SaaSの3つの選択肢があります。GitLab CEとGitLab EEはセルフマネージド(自己管理型)ソリューションです。つまり、GitLabインスタンスをご自身でダウンロード、インストール、管理することになります。GitLab SaaSはGitLab Inc.によってホストされています。そのため、使用するために何かをインストールすることを心配する必要はありません。必要なのは、GitLabアカウントを作成し、開始することだけです。
このチュートリアルでは、次のツールを使用して継続的インテグレーション(CI)パイプラインを構築する方法を紹介します:GitLab CI。これにより、リポジトリの変更を監視し、自動テストを実行して新しいコードを検証できるようになります。まず、コードをホストするためのGitリポジトリをセットアップすることから始めます。次に、リポジトリへのコミットを監視するCIプロセスを構成し、隔離されたDockerコンテナ内でテストを実行するためのCIランナーを起動します。
前提条件
まず、GitLabバージョン管理ソフトウェアを実行しているサーバーが必要になります。GitLabのセルフマネージドとSaaSの両方で自動テストを実行できます。ただし、無料のSaaSオプションでは、テストに利用できる時間(分)やリソースにいくつかの制限があります。セルフマネージドオプションを使用している場合は、GitLabインスタンスに希望するだけのリソースを割り当てることができるため、より自由度が高くなります。次のチュートリアル「GitLabで独自のGitリポジトリをホストする」に従って、独自のGitLabインスタンスをセットアップする方法を学んでください。
GitLab CIランナーとして使用するサーバーが少なくとも1つ必要になります。ただし、必要に応じて複数のサーバーを用意することもできます。セルフマネージドのGitLabインスタンスをセットアップしている場合は、同じサーバーを使用することもできますが、CIランナー用には別のサーバーを設定することをお勧めします。次のチュートリアル「Ubuntuサーバーのセットアップ方法」が良いスタートガイドになります。
Dockerコンテナ内でテスト環境を隔離するために、GitLab CIランナーサーバーにDockerをインストールする必要があります。次のチュートリアル「UbuntuにDockerをインストールして操作する方法」が、この要件を満たすのに役立ちます。
必要なものがすべて揃ったので、始めましょう!
ステップ 1: GitLabインスタンスにプロジェクトを作成する
まず、GitLabにプロジェクトリポジトリを作成することから始めます。このチュートリアルでは、Node.jsアプリケーションをベースにします。プロジェクトファイルをゼロから作成したくないため、GitLabが提供する他のバージョン管理リポジトリからプロジェクトをインポートするツールを利用します。インポートするアプリケーションは、シンプルな「hello world」アプリで、Express.js – Node.jsアプリケーション向けのミニマリストWebフレームワークを使用して構築されています。テストの実装には、MochaとChai – これらはユニットテストに使用されるJavaScriptフレームワークです。Mochaは非同期テストやテストカバレッジレポートを可能にし、他のアサーションライブラリと組み合わせることができます。Chaiはアサーションライブラリです。任意のテストフレームワークと組み合わせることができますが、今回のケースではMochaとChaiを組み合わせます。
プロジェクトの基本が理解できたところで、GitLabインスタンス(セルフマネージドまたはSaaS)にログインし、上部ナビゲーションバーにある「プラス」アイコンをクリックして、「New project」を選択します。または、アカウントのホームページの最上部までスクロールして、「New project」ボタンをクリックすることもできます:
新規プロジェクトページで、Import projectタブをクリックします:
次に、開いたページで、Repo by URLボタンをクリックします:
GitHubのインポートオプションもありますが、パーソナルアクセストークンが必要になるため、今回は使用しません。公開リポジトリを使用しているため、パーソナルアクセストークンを設定する必要はなく、URLだけでインポートする方が簡単です。
その後、次のURLをコピーして「Git Repository URL」フィールドに貼り付けます:
|
1 |
https://github.com/jaymoh/node_pipeline.git |
次のようになるはずです:
リポジトリは Private のままにして、Create project ボタンをクリックします。プロジェクトがGitHubからインポートされるまで数秒待ちます。インポートが完了すると、GitLabのリポジトリ一覧に表示されます。GitLabは、GitHubリポジトリプロジェクトと同じ詳細情報でプロジェクトをインポートします。
ステップ 2: .gitlab-ci.yml ファイルの分析
GitLab CIは、自動テストの実行方法を認識するために、GitLab上のすべてのリポジトリから .gitlab-ci.yml という名前のファイルをスキャンします。今インポートしたリポジトリのプロジェクトファイルの中に、.gitlab-ci.yml ファイルがあることが確認できます。GitLab CIの yml に関する詳細情報は、公式の 「.gitlab-ci.ymlファイル用のキーワード参照」ドキュメント.
GitLabのリポジトリインターフェースで、.gitlab-ci.yml ファイルをクリックしてブラウザページで開きます。次のようになるはずです:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
image: node:latest stages: - build - test cache: paths: - node_modules/ install_dependencies: stage: build script: - npm install artifacts: paths: - node_modules/ test_with_mocha: stage: test script: npm test |
行のインデントに注意してください。このファイルは、特定の条件下で指定された順序で実行されるさまざまなアクションを定義するために、厳格な GitLab CI YAML 設定構文に従っています。設定ファイルが正しいことを確認するために、GitLabは検証用のテストユーティリティを提供しています。GitLabインスタンス内のプロジェクトリポジトリで、CI lintインターフェースにアクセスして、.gitlab-ci.yml を検証できます。左側のナビゲーションメニューで CI/CD をクリックし、表示されるページで CI lint ボタンをクリックします:
設定ファイル内のディレクティブについて以下で説明します。
-
ベースDockerイメージ
設定ファイルの最初の行は、テストの実行に使用するDockerイメージを宣言しています。ここではNode.jsアプリケーションを構築しているため、最新のNode.jsイメージを使用します:
|
1 |
image: node:latest |
-
ステージ
次に、継続的インテグレーションテストが通過するさまざまなステージを定義します。ここでは2つのステージのみを定義しています:
|
1 2 3 |
stages: - build - test |
ステージ名を定義する際、build や test のような名前は任意に選択されたものであり、好きな名前を付けることができます。ただし、ステージの順序は実行フローを決定するため、適切に並べる必要があります。今回のケースでは、build ステージのジョブが、test ステージのジョブよりも前に実行されます。GitLab Runnerは同じステージ内のジョブを並行して実行し、すべてのジョブが完了するのを待ってから次のステージのジョブの実行を開始します。
-
キャッシュ
ジョブの実行間で後で再利用するためにキャッシュまたは保存されるファイルやディレクトリを指定するために、cache 定義が含まれています:
|
1 2 3 |
cache: paths: - node_modules/ |
キャッシュを定義することで、実行間で変更される可能性が低いリソースに依存するジョブの実行時間を最小限に抑えることができます。ここでは、キャッシュするディレクトリとして node_modules ディレクトリを指定しています。これは、npm がプロジェクトの依存関係をインストールするディレクトリです。
-
ジョブ
設定には2つのジョブがあります:
- install_dependencies
|
1 2 3 4 5 6 7 |
install_dependencies: stage: build script: - npm install artifacts: paths: - node_modules/ |
npm installテストステージのコマンドと一緒に。これは非常に小さなプロジェクトであるため、ジョブがどのように相互作用するかを示すためにこれらを分けただけです。このstageディレクティブはこのジョブをbuildとしてマークします。これはbuildステージ.
The scriptディレクティブは、このジョブの実行で実行するコマンドを指定します。複数のコマンドを指定するには、scriptブロック内に行を追加します。もちろん、適切にインデントすること、およびスクリプトが実行される順序を念頭に置くことに注意する必要があります。
The artifactsディレクティブは、ステージ間で保存および共有するファイルまたはディレクトリパスを指定します。繰り返しになりますが、他のファイルが実行に必要なものを確実に取得できるようにするには、ステージを適切に順序付けることが重要です。npm installコマンドは、依存関係をnode_modulesディレクトリにインストールします。artifactsで宣言することで、後続のステージで実行されるジョブで利用できるようになります。ファイルをダウンロードしたい場合は、GitLab UIでも利用できます。
- test_with_mocha
|
1 2 3 4 5 |
test_with_mocha: stage: test script: -npm start -npm test |
testステージで実行されます。このジョブはbuildステージのジョブが実行された後に実行されるため、buildステージで宣言されたアーティファクト(アプリの依存関係)がtestステージで利用可能になります。scriptブロックは、テストを実行するためのnpmコマンドを指定します。まずアプリケーションを起動し、次にアプリケーションに対してテストを実行します。これらのコマンドを実行すると、package.jsonのスクリプトブロックセクションで指定されたコマンドが実行されます。|
1 2 3 4 |
"scripts": { "start": "node app.js", "test": "mocha" }, |
.gitlab-ci.ymlファイルの基本的な理解が得られたはずです。これが静的なhello worldアプリにすぎないため、基本と言っています。次に、新しいCI実行をトリガーする方法を見てみましょう。
ステップ3:GitLab CI実行のトリガー
リポジトリに.gitlab-ci.ymlファイルが含まれると、そこにプッシュする新しいコミットが新しい継続的インテグレーション(CI)実行をトリガーします。セルフマネージドGitLabインスタンスの場合、GitLab Runnerを設定していないと、CI実行は「pending(保留中)」に設定されます。
GitLab SaaSは、ジョブを取得して自動的に実行できる共有ランナー(shared runners)をユーザーに提供します。これは、共有ランナーが空いており、クォータを超えていない場合にのみ可能です。GitLab SaaSでは、リポジトリでshared runnersを使用するかどうかを、プロジェクトのSettings > CI / CDページ(下のスクリーンショットを参照)に移動して選択できます。このページには、次のステップで詳しく説明するGitLab Runnerのインストール手順に関する情報も記載されています。
では、CI実行をトリガーするために小さな変更を加えてみましょう。GitLabプロジェクトリポジトリのnode_pipelineに戻ります。
上にハイライトされているREADME.mdファイルをクリックして表示します。
Click on the ‘Edit’ボタンをクリックしてブラウザで編集用にファイルを開き、テキストを追加します。
テキストを追加したら、下にスクロールしてCommit changesボタンをクリックして変更を保存します。コミットメッセージは自由に変更できます。パイプラインの実行中にGitLab UIにタイトルとして表示されます。ここでは、内容が分かりやすいため、UpdateREADME.mdのままにしています。
変更をコミットしたら、メインのプロジェクトページに戻ります。最新のコミットに小さなpaused iconが表示されていることに気づくでしょう。アイコンの上にマウスを置くと、次のように表示されます。‘Pipeline:pending’:
これは、CI実行がトリガーされたことを意味します。ただし、テストはまだ実行されていません。左側のナビゲーションメニューでCI/CD,をクリックし、Pipelines.を選択します。これにより、パイプラインに関する詳細情報を示すページが開きます。CIが保留中(pending)であり、スタック(stuck)としてマークされていることがわかります。
実行に関する詳細情報を取得するには、pendingステータスをクリックします。以下のようなビューが表示され、実行のさまざまなステージと、各ステージにリンクされた個々のジョブが表示されます。
個々のジョブをクリックして、遅延の原因などの詳細を確認することもできます。実行に失敗した場合は、ここでジョブが失敗した原因を確認できます。
このメッセージは、このジョブを実行できるアクティブなランナーが設定されていないため、ジョブがスタックしていることを示しています。これについては次のステップで行います。ランナーを利用可能にすると、ジョブは自動的に実行を開始します。ジョブが実行されると、このインターフェース上に出力が表示されるほか、ジョブの実行中に生成されたその他のダウンロード可能なアーティファクトも表示されます。
ステップ 4: GitLab CIランナーサービスの設定
それでは、このチュートリアルの「前提条件」セクションで宣言した2番目のサーバーを使用します。このサーバーにGitLabランナーサービスをインストールして設定します。このサービスをデプロイして、GitLab上の異なるプロジェクトに対して複数のランナーインスタンスを実行できます。
セルフマネージドGitLabインスタンスをホストしているのと同じサーバーにランナーをデプロイすることもできます。ただし、インスタンスがリソースによって制限されないようにするために、別のCIランナーインスタンスを設定することが望ましいです。どちらの構成を選択する場合でも、Dockerがインストールされている必要があります。テスト環境を隔離するためです。
GitLab CIランナーをインストールするプロセスは、セルフマネージドGitLabをインストールするプロセスと同様です。まず、次のコマンドを使用して、公式のGitLabリポジトリをaptソースに追加するスクリプトをダウンロードします。
|
1 |
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash |
プロンプトが表示されたら、rootパスワードを入力します。次に、最新のGitLab CIランナーをインストールするコマンドを実行できます。
|
1 |
sudo apt-get install gitlab-runner |
上記のコマンドにより、プロジェクトで使用できる状態のランナーサービスがインストールおよび登録されます。
ステップ 5: 登録トークンの取得とGitLabランナーの連携
GitLab CIランナーを設定してジョブの受け入れを開始するには、GitLabランナートークンが必要です。これは、ランナーがGitLabサーバーインスタンスで認証を行うために必要です。ランナーの用途に応じて、次の2種類のトークンがあります。プロジェクト固有 および 共有ランナー。
プロジェクト固有のランナーは、ランナーに独自の要件がある場合に適しています。たとえば、gitlab-ci.ymlに一意のトークンを含むデプロイ定義がある場合、デプロイ環境に対して正しく認証を行うために、特定のランナーが推奨される場合があります。もう1つの考慮事項は、継続的インテグレーションのステージにリソースを大量に消費するプロセスがある場合です。その場合は、プロジェクト固有のランナーを使用するのが理想的です。なお、プロジェクト固有のランナーは、他のプロジェクトからのジョブは受け入れません。
共有ランナーは汎用であり、複数のプロジェクトで使用できます。GitLab IncでホストされているGitLab SaaSインスタンスには、ステップ 3で説明されているように、パイプラインを自動的に取得する共有ランナーがいくつかあります。ランナーは、各プロジェクトで現在実行されているジョブの数を考慮したアルゴリズムに基づいて、設定からジョブを取得します。共有ランナーは、特定のランナーよりも柔軟性があります。これは、GitLabインスタンスの管理者アカウントから設定できます。両方のランナーのトークンを取得する方法を見てみましょう。
- プロジェクト固有のランナーの登録
プロジェクト固有のランナーを登録するには、GitLabインスタンスまたはGitLab SaaSアカウントでプロジェクトを開きます。左側のナビゲーションメニューから、Settings 項目をクリックし、CI/CD オプションを選択します。
その後、Runners セクションまでスクロールダウンし、ボタンをクリックしてセクションを展開します。
左側には、プロジェクト固有のランナーを登録する方法が説明されています。これはGitLab SaaSインスタンスの表示です。Kubernetesを使用して自動ランナーを設定することもできますが、このチュートリアルでは手動ランナーを設定します。
次に、このプロジェクトのトークンが表示されているセクションに注目する必要があります。セルフマネージドのGitLabインスタンスの場合、URLにはGitLabインスタンスが実行されているサーバーのドメインが表示されます:
右側のセクションの Shared Runners の下にあるスイッチを切り替えることで、このプロジェクトの共有ランナーを無効にすることができます。その後、表示されている登録トークンをメモ帳にコピーしてください。これは後で使用します。
- 共有ランナーの登録
共有ランナーを登録するには、管理者としてセルフマネージドGitLabインスタンスにログインする必要があります。管理パネルにアクセスするには、上部ナビゲーションメニューの レンチ/スパナ アイコンをクリックします:
In the 管理パネルにて、左側メニューのRunners(Overviewセクション内)をクリックします。これにより、Shared Runnersの設定手順が表示されたページが開きます:
右側の Set up a shared Runner manually の下にある表示された登録トークンをコピーします。このトークンは、次のステップでランナーを登録するために使用します。
- GitLab CIランナーとGitLabインスタンスの連携
このステップでは、GitLabインスタンスをCIランナーと連携させます。 ステップ4でGitLabランナーサービスをインストールしたサーバーに再度ログインします。ランナーの登録プロセスを開始するには、ターミナルで次のコマンドを入力します:
|
1 |
sudo gitlab-runner register |
コマンドを実行すると、一連の質問が表示されます:
- GitLabインスタンスのURLを入力してください(例: https://gitlab.com/):
SSLを指定するために、https://を使用してGitLabインスタンスのドメイン名を入力します。
- 登録トークンを入力してください:
登録トークンを入力します。ここで、このランナーをプロジェクト専用にするか、共有にするかを選択します。どちらかのオプションに対して、先ほどコピーしたトークンのいずれか1つのみを入力できます。
- ランナーの説明を入力してください:
GitLabインスタンスのUIに表示される、CIランナーのわかりやすい名前を選択します。
- エグゼキューターを入力してください: custom, docker-ssh, parallels, virtualbox, docker, shell, ssh, docker+machine, docker-ssh+machine, kubernetes:
ここでは、ジョブを実行するためのエグゼキューターを選択するオプションが表示されます。Docker.
- ランナーのタグを入力してください(カンマ区切り):
これは任意です。このランナーに含まれる依存関係などのタグ名を入力できます。今は空白のままでも構いません。
- デフォルトのDockerイメージを入力してください(例: ruby:2.6):
ここでは、gitlab-ci.ymlファイルでイメージが指定されていない場合に、ジョブの実行に使用されるデフォルトの汎用イメージを指定します。軽量で汎用性が高く、安全なイメージであるalpine:latestを入力してください。Enterキーを押すと、ランナーが登録され、自動的に起動します:
現在利用可能なランナーの一覧を表示するには、次のコマンドを入力します:
|
1 |
sudo gitlab-runner list |
ステップ6: GitLabでCIランナーが正常に連携されていることの確認
次に、ブラウザに戻り、GitLabインスタンスのプロジェクトページにアクセスします。ランナーを登録してから経過した時間によっては、ジョブが現在実行中であるのが確認できる場合があります:
または、すでに完了している場合もあります:
その後、左メニューのPipelinesページに移動するか、CI/CD > Pipelinesを経由するか、またはrunning、passed、またはfailedアイコン(パイプラインでエラーが発生した場合)をクリックして、CI実行の状態を確認します。ここでは、ステージの1つ(build stage)がパスし、もう1つがまだ実行中であることがわかります:
テーブルのStagesヘッダーの下にあるステージアイコンの1つをクリックして、関連するジョブを表示します:
次に、ポップアップ内のジョブをクリックして詳細を表示します:
ジョブが実行され、npmコマンドが依存関係をインストールしているときの進行状況を確認できます。右側には、その他の関連情報が表示されます。ジョブからアーティファクトをダウンロードするオプションもあります。また、ドロップダウンからステージを切り替えて他のジョブを表示することもできます。
ここでは、テストステージでジョブを選択したときに表示されるテストケースを確認できます:
利用可能なランナー
左側のメニューで、Settings > CI/CDをクリックして、以下を展開します:Runners セクションの下に表示され、登録したばかりのランナーを確認できるはずです。プロジェクト固有のトークンを指定したか、共有トークンを指定したかに応じて、ランナーはそれぞれのセクションに表示されます。
ここでは、プロジェクト固有のトークンを登録したことが確認できます。ランナーは、Specific Runners:
まとめ
このチュートリアルでは、GitLab CIを使用してテストを自動化する方法を学びました。まず、GitLab上でNode.jsアプリのプロジェクトをセットアップすることから始めました。このプロジェクトには、いくつかのテストケースと gitlab-ci.yml が含まれていました。GitLabが gitlab-ci.yml ファイルを使用して、トリガーされたときに何を実行するかを決定することを学びました。 gitlab-ci.yml ファイルは、アプリケーションのビルドとテストに関する指示が含まれている単なる設定ファイルであり、YAML 形式で記述されているため、GitLab CIランナーが理解することができます。
また、別のホスト上にGitLab CIランナーをセットアップすることもできました。トリガーが発生するたびにGitLabインスタンスからジョブを取得するように登録しました。これはシンプルなプロジェクトでしたが、この情報を基にして複雑なプロジェクトのパイプラインを構築することができます。GitLabにプロジェクトを追加し、GitLab CIランナーをリンクする手順は同じです。変更されるのは、gitlab-ci.yml ファイル内の指示とステージです。
Happy Computing!




























コメント
コメントはまだありません。最初のコメントを投稿しましょう。