
[!] この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
前回は、GitLabのCI/CDと連携してパイプラインの実行が可能になるGitLab Runnerの構築方法について紹介しました。
今回は、GitLab Runnerの一般的な利用方法について紹介します。
前回構築した環境の構成では、GitLab Runnerの種類はShared Runnerで、executorはDockerになります。
以下の点について説明します。
GitLab Runnerの利用手順
作業端末でソースファイルを修正してGitLabにgit pushすると、GitLab Runnerが動作し修正したソースファイルに対してアクションを起こすことができます。
このときGitLabのリポジトリの内容がコンテナ内の/builds/配下に展開されます。
コンテナ起動時の作業ディレクトリは/builds/group01/project01/になります。
実行させるDockerイメージは、利用者がコンテナ内で行いたいことに合わせて独自のDockerイメージを作成して利用することができます。
プロジェクトの作成
GitLab Runnerを説明するため、runnersというグループにprojectjavaというプロジェクトを作成します。
今回は簡単なJavaのソースファイルを用いて説明していきます。
Dockerイメージの作成・登録
JavaのソースコードをビルドするためのDockerイメージを作成し、GitLab Container Registryに登録します。
-
元となるDockerイメージをdocker pullで取得
Terminal window # docker image pull docker.io/openjdk:11 -
Dockerイメージを作成
- docker image tagで作成する場合
Terminal window # docker image tag docker.io/openjdk:11 <GitLabのFQDN>:5050/runners/projectjava/openjdk:11- docker image buildで作成する場合
Terminal window # docker image build -t <GitLabのFQDN>:5050/runners/projectjava/openjdk:11 . -
GitLab Container Registryに登録
3.1. docker loginでGitLab Container Registryにログイン
Terminal window # docker login <GitLabのFQDN>:5050Username: <GitLabのアカウント>Password: <GitLabのアカウントのパスワード>Login Succeeded3.2. Dockerイメージをdocker image pushで登録
Terminal window # docker image push <GitLabのFQDN>:5050/runners/projectjava/openjdk:113.3. プロジェクト画面で左ペインの「Packages & Registries」->「コンテナレジストリ」を選択
コンテナレジストリ画面でDockerイメージが登録されていることを確認します。3.4. GitLab Container Registryからログアウト
Terminal window # docker logout <GitLabのFQDN>:5050Removing login credentials for <GitLabのFQDN>:5050
ソースファイルと設定ファイルの登録
GitLabのリポジトリに登録したJavaのソースファイルを、GitLab Container Registryに登録したDockerイメージを使用してビルドします。
GitLab Runnerを実行するには、.gitlab-ci.ymlをGitLabのリポジトリに登録する必要があります。
Javaのソースファイルと.gitlab-ci.ymlを作成していきます。
ソースファイルの作成
作業端末の作業用ディレクトリにローカルリポジトリを作成します。
$ git clone https://<GitLabのFQDN>/runners/projectjava.gitCloning into 'projectjava'...warning: You appear to have cloned an empty repository.
プロジェクト名でディレクトリが作成されているので移動します。
$ cd projectjava
projectjava配下にsrcディレクトリを作成し、src配下にHello.javaファイルを以下の内容で作成します。
import java.lang.*;
public class Hello { public static void main(String[] args) { try { System.out.println("Hello, world."); } catch(Exception e) {} }}
.gitlab-ci.ymlの作成
projectjava配下に.gitlab-ci.ymlファイルを以下の内容で作成します。
# ジョブ名job01: # 利用するDockerイメージを記述 image: <GitLabのFQDN>:5050/runners/projectjava/openjdk:11 # 実行したい処理を記述 script: # ビルドしたクラスファイルを格納するディレクトリを作成 - mkdir -p build # Javaのサンプルソースファイルをビルド - javac -d build src/Hello.java # ビルドしたクラスファイルの格納ディレクトリに移動 - cd build # ビルドしたクラスファイルを実行 - java Hello # Shared Runnerのタグを指定 tags: - <Shared Runnerのタグ>
<Shared Runnerのタグ>は前回のGitLab Runnerの登録で登録した値です。
リポジトリへの登録
Javaのソースファイルと.gitlab-ci.ymlをGitLabのリポジトリに登録します。
.gitlab-ci.ymlがリポジトリに登録されると、パイプラインが自動で実行されるようになります。
$ git add .gitlab-ci.yml src/Hello.java$ git commit -m "初回登録"$ git push
リポジトリにJavaのソースファイルと.gitlab-ci.ymlが登録されていることを確認します。
- プロジェクト画面で左ペインの「プロジェクトの概要」->「詳細」を選択
パイプライン実行結果の確認
リポジトリの変更によってパイプラインが実行されたかどうか確認します。
- プロジェクト画面で左ペインの「CI/CD」->「パイプライン」を選択
パイプライン画面を確認すると、パイプラインのステータスに実行結果が表示されています。
パイプラインの詳細を確認します。
- ステータスの「成功」を選択
job01は.gitlab-ci.ymlで設定したジョブ名です。
ジョブの詳細を確認します。
- ジョブ名「job01」を選択
ジョブの詳細画面では.gitlab-ci.ymlのscript:で記述したコマンドの結果等が確認できます。
script:で記述したコマンドの結果は21-25行目です。コンパイルして実行した結果「Hello, world.」が表示されていることが確認できます。
これで次回以降も、リポジトリを変更すると.gitlab-ci.ymlで構成されたパイプラインが自動で実行されます。
パイプラインの書き方
設定パラメータ
.gitlab-ci.ymlの記述方法について、Javaのソースファイルをビルドするサンプルで説明します。
stages: - Stage01job01: stage: Stage01 image: <GitLabのFQDN>:5050/runners/projectjava/openjdk:11 script: - mkdir -p build - javac -d build src/Hello.java tags: - <Shared Runnerのタグ>
キーワード | 説明 | |
---|---|---|
stages | ジョブ内でのstageで記載する任意の文字列を記載 記載しない場合、デフォルトでbuild、test、deployがステージ名として利用可能 | |
job01 | ジョブ名を任意に記載 | |
stage | stagesで記載したステージ名を記載 記載しない場合、デフォルトでtestステージとなる | |
image | コンテナで使用するDockerイメージを記載 記載しない場合、Shared RunnerのデフォルトのDockerイメージが利用される | |
script | コンテナ内で実行するコマンドを記載 配列で複数のコマンドを記述することが可能 | |
tags | GitLab Runnerの登録時に入力したShared Runnerのタグを記載 |
詳しくはGitLab CI/CD パイプライン設定リファレンス ⧉を参照してください。
ステージとジョブ
以下の.gitlab-ci.ymlを実行してジョブとステージの関係をみてみます。
3つのステージを定義して、それぞれのステージに2つ、1つ、3つのジョブを設定しています。
image: <GitLabのFQDN>:5050/runners/projectjava/openjdk:11stages: - Stage01 - Stage02 - Stage03job01: stage: Stage01 script: - echo hello tags: - <Shared Runnerのタグ>job02: stage: Stage01 script: - echo hello tags: - <Shared Runnerのタグ>job03: stage: Stage02 script: - echo hello tags: - <Shared Runnerのタグ>job04: stage: Stage03 script: - echo hello tags: - <Shared Runnerのタグ>job05: stage: Stage03 script: - echo hello tags: - <Shared Runnerのタグ>job06: stage: Stage03 script: - echo hello tags: - <Shared Runnerのタグ>
実行したパイプラインは以下の通りです。
列がステージになり、行に各ステージのジョブが配置されます。
ジョブの実行は左のステージから右のステージの順番になり、各ステージのジョブは上から処理されます。
同時実行数が3の場合(※)は、まず「job01」と「job02」が並列に処理され、両方が完了した後に「job03」が実行され、「job03」完了後に「job04」と「job05」と「job06」が並列に処理されます。
※同時実行数はGitLab Runnerサーバの/etc/gitlab-runner/config.tomlファイルのconcurrentの値で変更可能
CI/CDで定義済みの環境変数
.gitlab-ci.ymlで利用できる環境変数の一部を紹介します。
環境変数 | 説明 | 例 |
---|---|---|
CI_PROJECT_DIR | プロジェクトの起点となるディレクトリパス | /builds/runners/projectjava |
CI_PIPELINE_ID | 現在のパイプラインのユニークID | 38 |
CI_JOB_ID | 現在のジョブのユニークID | 128 |
CI_REGISTRY_IMAGE | プロジェクトのContainer Registryパス | <GitLabのFQDN>:5050/runners/projectjava |
詳しくはGitLab CI/CD 定義済みの変数 ⧉を参照してください。
静的解析ツールの利用手順
Javaの静的解析ツール「Checkstyle」「PMD」「SpotBugs」を含むDockerイメージを作成し、利用する方法について説明します。
まず、下記のDockerfileでDockerイメージ<GitLabのFQDN>:5050/runners/projectjava/analysis-tool-java:latestを作成し、GitLab Container Registryに登録します。
Dockerイメージ作成に必要なファイルは以下の公式ページからダウンロードします。
FROM openjdk:11COPY checkstyle-10.1-all.jar /COPY google_checks.xml /COPY pmd-bin-6.44.0.zip /COPY spotbugs-4.6.0.zip /RUN mkdir /usr/lib/spotbugs \ && mkdir /usr/lib/pmd \ && mkdir /usr/lib/checkstyle \ && mkdir /usr/lib/checkstyle/checkstyle-10.1 \ && unzip spotbugs-4.6.0.zip -d /usr/lib/spotbugs/ \ && unzip pmd-bin-6.44.0.zip -d /usr/lib/pmd/ \ && mv checkstyle-10.1-all.jar /usr/lib/checkstyle/checkstyle-10.1/ \ && mv google_checks.xml /usr/lib/checkstyle/checkstyle-10.1/ \ && chmod +x /usr/lib/spotbugs/spotbugs-4.6.0/bin/spotbugs \ && chmod +x /usr/lib/pmd/pmd-bin-6.44.0/bin/run.sh \ && echo "if [ \$? -eq 4 ]; then">> /usr/lib/pmd/pmd-bin-6.44.0/bin/run.sh \ && echo " exit 0">> /usr/lib/pmd/pmd-bin-6.44.0/bin/run.sh \ && echo "fi">> /usr/lib/pmd/pmd-bin-6.44.0/bin/run.sh \ && rm spotbugs-4.6.0.zip \ && rm pmd-bin-6.44.0.zipENV SPOTBUGS_HOME /usr/lib/spotbugs/spotbugs-4.6.0ENV PATH $PATH:/usr/lib/spotbugs/spotbugs-4.6.0/binENV PATH $PATH:/usr/lib/pmd/pmd-bin-6.44.0/binENV PATH $PATH:/usr/lib/checkstyle/checkstyle-10.1
コンテナ内で実行したコマンドやスクリプトの返却値が0でない場合、ジョブは異常終了します。
/usr/lib/pmd/pmd-bin-6.44.0/bin/run.shは返却値が4になるため、返却値が0になるように追記しています。
それでは、Javaのソースファイルを各ツールで解析してみます。
Checkstyle
Checkstyleは、ソースコードがコーディング規約に則しているかを確認するツールです。
詳しくはStandard Checks ⧉を参照してください。
Checkstyleを利用する場合の.gitlab-ci.ymlの記述は以下の通りです。
job01: image: $CI_REGISTRY_IMAGE/analysis-tool-java:latest script: - cd /usr/lib/checkstyle/checkstyle-10.1 - java -Duser.language=ja -jar checkstyle-10.1-all.jar -c google_checks.xml -o $CI_PROJECT_DIR/result-checkstyle.txt $CI_PROJECT_DIR/src/ artifacts: paths: - result-checkstyle.txt tags: - <Shared Runnerのタグ>
キーワード | 説明 | |
---|---|---|
job01 | ジョブ名を任意に記載 | |
image | $CI_REGISTRY_IMAGE/analysis-tool-java:latestを記載 | |
script | Checkstyleを実行するためのコマンドを記載 | |
artifacts | ジョブ内で作成したデータをGitLabに格納しダウンロードが可能 pathsにはGitLabに格納するファイル、ディレクトリを記載 記載したファイル、ディレクトリはartifacts.zipとして格納される | |
tags | GitLab Runnerの登録時に入力したShared Runnerのタグを記載 |
Checkstyle実行のコマンド・ライン・オプションの説明は以下の通りです。詳しくはCommand Line Usage ⧉を参照してください。
java -Duser.language=ja -jar checkstyle-10.1-all.jar -c google_checks.xml -o <出力ファイルのパス> <ソースファイルのパス>
オプション | 説明 |
---|---|
-Duser.language=ja | 解析結果を日本語で表示 |
-c | チェックに使用するコーティング規約のファイルパスを記載 今回はGoogleのJavaコーディング規約でチェックする |
-o | 解析結果を指定されたファイルに出力 |
パイプラインを実行すると、result-checkstyle.txtには以下の解析結果が出力されます。
監査を開始しています...[WARN] /builds/runners/projectjava/src/Hello.java:1:17: '.*' 形式のインポートの使用は避けるべきです - java.lang.*。 [AvoidStarImport][WARN] /builds/runners/projectjava/src/Hello.java:3:1: Javadoc コメントがありません。 [MissingJavadocType][WARN] /builds/runners/projectjava/src/Hello.java:4:3: Javadoc コメントがありません。 [MissingJavadocMethod][WARN] /builds/runners/projectjava/src/Hello.java:7:7: WhitespaceAround: 'catch' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3) [WhitespaceAround][WARN] /builds/runners/projectjava/src/Hello.java:7:26: WhitespaceAround: '{' is not followed by whitespace. Empty blocks may only be represented as {} when not part of a multi-block statement (4.1.3) [WhitespaceAround][WARN] /builds/runners/projectjava/src/Hello.java:7:26: 空の catch ブロックです。 [EmptyCatchBlock][WARN] /builds/runners/projectjava/src/Hello.java:7:27: WhitespaceAround: '}' is not preceded with whitespace. [WhitespaceAround]監査が完了しました。
PMD
PMDは、Javaのソースコードを解析し、未使用の変数、空のcatchブロック、不要なオブジェクトの作成などの潜在的な問題を検知するツールです。
詳しくはPMD 6.44.0 ⧉を参照してください。
PMDを利用する場合の.gitlab-ci.ymlの記述は以下の通りです。
job01: image: $CI_REGISTRY_IMAGE/analysis-tool-java:latest script: - run.sh pmd -d $CI_PROJECT_DIR/src/ -R rulesets/java/quickstart.xml -f html -r $CI_PROJECT_DIR/result-pmd.html artifacts: paths: - result-pmd.html tags: - <Shared Runnerのタグ>
キーワード | 説明 | |
---|---|---|
job01 | ジョブ名を任意に記載 | |
image | $CI_REGISTRY_IMAGE/analysis-tool-java:latestを記載 | |
script | PMDを実行するためのコマンドを記載 | |
artifacts | ジョブ内で作成したデータをGitLabに格納しダウンロードが可能 pathsにはGitLabに格納するファイル、ディレクトリを記載 記載したファイル、ディレクトリはartifacts.zipとして格納される | |
tags | GitLab Runnerの登録時に入力したShared Runnerのタグを記載 |
PMD実行のコマンド・ライン・オプションの説明は以下の通りです。詳しくはPMD CLI reference ⧉を参照してください。
run.sh pmd -d <ソースファイルのパス> -R rulesets/java/quickstart.xml -f html -r <出力ファイルのパス>
オプション | 説明 |
---|---|
-d | ソースファイルのパスを記載 |
-R | ルールセットファイルを記載 |
-f | 解析結果の出力形式を記載 |
-r | 解析結果を指定されたファイルに出力 |
パイプラインを実行すると、result-pmd.htmlには以下の解析結果が出力されます。
SpotBugs
SpotBugsは、Javaプログラムの中のエラーとなる可能性の高いソースコード(バグパターン)をみつけるツールです。
詳しくは検知可能なバグの詳細 ⧉を参照してください。
SpotBugsを利用する場合の.gitlab-ci.ymlの記述は以下の通りです。
stages: - stage01 - stage02cache: paths: - build/job01: stage: stage01 image: $CI_REGISTRY_IMAGE/openjdk:11 script: - mkdir -p build - javac -d build src/Hello.java tags: - <Shared Runnerのタグ>job02: stage: stage02 image: $CI_REGISTRY_IMAGE/analysis-tool-java:latest script: - spotbugs -textui -html:fancy-hist.xsl -output $CI_PROJECT_DIR/result-spotbugs.html -sourcepath $CI_PROJECT_DIR/src/ -longBugCodes $CI_PROJECT_DIR/build/ artifacts: paths: - result-spotbugs.html tags: - <Shared Runnerのタグ>
SpotBugsはバイナリコードを解析しますので、クラスファイルが対象となります。
ビルドを行いクラスファイルが生成されるのを待ってから、静的解析ツールを実行したいため、ステージを指定してジョブを構成しています。
キーワード | 説明 | |
---|---|---|
stages | ジョブ内でのstageで記載する任意の文字列を記載 | |
cache | ジョブ間でファイル・ディレクトリを共有するための記載 | |
paths | 今回はbuildディレクトリを共有するためbuild/を記載 job01で作成したbuildディレクトリがjob02でアクセス可能になる | |
job01 | ジョブ名を任意に記載 | |
stage | stagesで記載したステージ名を記載 | |
image | $CI_REGISTRY_IMAGE/openjdk:11を記載 | |
script | Javaのソースコートをビルドするためのコマンドを記載 | |
tags | GitLab Runnerの登録時に入力したShared Runnerのタグを記載 | |
job02 | ジョブ名を任意に記載 | |
stage | stagesで記載したステージ名を記載 | |
image | $CI_REGISTRY_IMAGE/analysis-tool-java:latestを記載 | |
script | SpotBugsを実行するためのコマンドを記載 | |
artifacts | ジョブ内で作成したデータをGitLabに格納しダウンロードが可能 pathsにはGitLabに格納するファイル、ディレクトリを記載 記載したファイル、ディレクトリはartifacts.zipとして格納される | |
tags | GitLab Runnerの登録時に入力したShared Runnerのタグを記載 |
SpotBugs実行のコマンド・ライン・オプションの説明は以下の通りです。詳しくはSpotBugsの実行 ⧉を参照してください。
spotbugs -textui -html:fancy-hist.xsl -output <出力ファイルのパス> -sourcepath <ソースファイルのパス> -longBugCodes <クラスファイルのパス>
オプション | 説明 |
---|---|
-textui | コマンドラインユーザインタフェースの実行 |
-html:fancy-hist.xsl | 解析結果をHTMLとして出力 スタイルシートとして以下が指定できる plain.xsl/fancy.xsl/fancy-hist.xsl |
-output | 解析結果を指定されたファイルに出力 |
-sourcepath | 解析対象クラスのソースファイルが保管されているパスを記載 |
-longBugCodes | すべてのバグを報告 |
パイプラインを実行すると、result-spotbugs.htmlには以下の解析結果が出力されます。
おわりに
GitLab Runnerの利用について、Javaのソースファイルをビルドする、静的解析ツールを実行するという方法を紹介しましたが、いかがだったでしょうか。
皆さんには、単体テストを自動実行させたり、開発環境へデプロイを行ったりなど、この記事では触れなかったものも踏まえて、よりよいパイプラインの構成を検討して頂ければと思います。
この記事が皆さんのCI/CD導入のお役に立てば幸いです。