19
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Jenkinsを使わずにGitLabとSonarQubeを連携してみた

Last updated at Posted at 2020-01-10

背景

ソースコードをcommit/pushした際の自動レビューと、コード品質の可視化のためにSonarQubeを導入することになった。
既にソースコードはGitLabで管理しており、GitLab-CIを使ってビルドやテスト、デプロイの自動化まで実装済み。

今さら感はあるが、GitLabとSonarQubeの連携方法について調べてみた。

Jenkinsは必要か?

調べていくと、どの事例もJenkinsを間に挟んでGitLabとSonarQubeを連携させている。
図にするとこんな感じ。

mermaid-diagram-20200110143300.png

正確には、SonarQube側にはsonar-scannerという登場人物もいて、実際の解析を行っているのは彼ですが、ココでは細かいことは割愛。

もともとJenkinsを導入済みのプロジェクトであれば、この構成でも良いと思うが、未導入の場合は無駄な構成のように感じた。
実際、私のプロジェクトもJenkinsは導入していなかった。
SonarQubeに加えてJenkinsが必要なため構築に2倍の労力がかかるし、SonarQubeのためだけにJenkinsを動かしておくのも経済的とは思えない。

一方で、Jenkinsを導入したほうが良いケースもありそう。
Jenkinsのジョブのトリガは、きめ細かに設定することができるので、「日次や週次で定期的に実行させたい」といったケースなどであれば、Jenkinsの導入が有効かもしれない。

ただ、私のプロジェクトでは、GitLabへのコードのPushやマージリクエストのタイミングで実行できれば十分だったので、やはり私のプロジェクトではJenkinsはいらないという結論に至った。

ということで、次の図のような、よりシンプルな構成で導入を試みることにした。

mermaid-diagram-20200110143242.png

環境

  • CentOS 7.5.1804
  • GitLab CE 11.11.3
  • gitlab-runner v12.6.0
  • SonarQube Community Edition Version 7.6 (build 21501)

SonarQubeのインストール

公式が提供しているDockerイメージを使用する。
今回は、簡単に構築するために、公式のdocker-composeサンプルを活用する。

公式のdocker-composeサンプルをダウンロード

mkdir SonarQube
cd ./SonarQube
curl https://raw.githubusercontent.com/SonarSource/docker-sonarqube/master/recipes/docker-compose-postgres-example.yml -o docker-compose.yml

docker-compose.ymlをカスタマイズ

以下のように、docker-compose.ymlをカスタマイズする。

docker-compose.yml
version: "2"

services:
  sonarqube:
    # コンテナ名を明示的に指定(必須)
    container_name: sonarqube-core
    # SonarQubeのバージョンを"7.6-community"に指定(必須)
    image: sonarqube:7.6-community
    ports:
      - "9000:9000"
    networks:
      - sonarnet
    environment:
      - sonar.jdbc.url=jdbc:postgresql://db:5432/sonar
    volumes:
      - sonarqube_conf:/opt/sonarqube/conf
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
    # マシンやdockerデーモンの再起動でコンテナが立ち上がるように(お好みで)
    restart: always

  db:
    # コンテナ名を明示的に指定(推奨)
    container_name: sonarqube-postgres
    # postgresのバージョンも固定化(お好みで)
    image: postgres:12.1
    networks:
      - sonarnet
    environment:
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonar
    volumes:
      - postgresql:/var/lib/postgresql
      # This needs explicit mapping due to https://github.com/docker-library/postgres/blob/4e48e3228a30763913ece952c611e5e9b95c8759/Dockerfile.template#L52
      - postgresql_data:/var/lib/postgresql/data
    # マシンやdockerデーモンの再起動でコンテナが立ち上がるように(お好みで)
    restart: always

networks:
  sonarnet:
    driver: bridge

volumes:
  sonarqube_conf:
  sonarqube_data:
  sonarqube_extensions:
  postgresql:
  postgresql_data:

SonarQubeを起動

# 仮想メモリの上限値を変更(省略するとSonarQubeが無限に再起動を繰り返す)
sudo sysctl -w vm.max_map_count=262144

# 起動
docker-compose up

SonarQubeのダッシュボードにアクセス

ブラウザで下記のURLにアクセス。
ユーザ名とパスワードはadminでログインできる。

http://{your_IP_address}:9000/

SonarQubeへのプラグインのインストール

sonar-gitlab-plugin

GitLabと連携するためのプラグイン。

ネット情報では、SonarQubeのGUI上から検索してインストールできるようだったが、私の環境では検索してもヒットせず。
このため、手作業でインストールを実施。

なお、sonar-gitlab-pluginがサポートするSonarQubeのバージョンは7.6まで。
docker-compose.ymlでバージョンを指定したのはこのため。

# GitHubからパッケージをダウンロード
curl https://github.com/gabrie-allaigre/sonar-gitlab-plugin/releases/download/4.1.0-SNAPSHOT/sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar -o sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar

# パッケージをsonarqube-coreコンテナにコピー
# ※あらかじめdocker-compose.ymlでコンテナ名をつけているので、コンテナの指定が楽にできる
docker cp sonar-gitlab-plugin-4.1.0-SNAPSHOT.jar sonarqube-core:/opt/sonarqube/extensions/plugins

SonarQubeのダッシュボードにログインし、Administration > System > Restart Serverで、SonarQubeを再起動する。

再起動後、Administration > Marketplace > Installedで、GitLabが表示されていればOK。

その他のプラグイン

主要な言語用のプラグインなどは、プリインストールされている。
インストール済みのプラグインの確認は、Administration > Marketplace > Installedで確認可能。

もし不足している場合はAllタブで検索して追加する。
SonarQube上で検索してヒットしない場合は、GoogleやGitHubなどで検索し、sonar-gitlab-pluginと同様の手順で手動インストールする。

私のプロジェクトの場合、JavaScriptの静的解析のプロファイルにESLintを使用したかったので、sonar-eslint-pluginを追加でインストール。
こちらも、SonarQubeのGUI上ではインストールできなかったので、手動でインストールした。

SonarQubeの設定

Administration > Configuration > General Settings > GitLab

最低限、以下の項目を設定する。
その他は、必要であれば、個別の環境に合わせて設定する。

項目 設定値 備考
GitLab url {your_GitLab_URL}
GitLab User Token {your_GitLab_User_Token} 後述の手順で取得したトークン

Quality Profiles

各言語の静的解析に使用するプロファイルを選択する。
標準ではSonar wayという、SonarQube推奨のプロファイルが選択されている。

特にこだわりがない場合や、プロジェクトで決まっているものがなければ、デフォルトのままでも問題ない。
もし、ルールを変更する場合は、使いたいプロファイル横の歯車アイコンからSet as Defaultをクリック。

私の場合は、前述の通りJavaScriptのDefaultプロファイルをESLintに変更した。

Projects

右上のアイコンから、新規プロジェクトを作成し、以下の情報を設定。

項目 設定値 備考
Project key {your_repository_name}
Display name {your_repository_name}

Analyze your project画面に遷移するので、Generateをクリック。
表示されるトークンをメモしておく。

さらに、作成されたプロジェクトを開き、Administration > General Settings > GitLab > GitLab Project idに、GitLab上の解析対象プロジェクトのIDを登録しておく。

GitLabの設定

gitlab-runnerのインストール

GitLab-CIを実行するためのgitlab-runnerをインストールする。
既にDocker executorのgitlab-runnerが存在する場合、この手順は省略可。

# docker版の`gitlab-runner`を起動
docker run -d \
    --name gitlab-runner-docker \
    --restart always \
    -v /srv/gitlab-runner-docker/config:/etc/gitlab-runner \
    -v /var/run/docker.sock:/var/run/docker.sock \
    gitlab/gitlab-runner:v12.6.0

# GitLabにrunnerを登録
docker exec gitlab-runner-docker gitlab-runner register \
    --non-interactive \
    --url {your_gitlab_url} \
    --registration-token {your_gitlab_runner_token} \
    --name "gitlab-runner-docker" \
    --tag-list "autotest-server,docker" \
    --executor "docker" \
    --docker-image "alpine:latest"

SonarQubeが使用するBOTアカウントを設定

SonarQubeが、静的解析結果をコミットやマージリクエストに対してコメントするためのアカウントを作成する。

BOTアカウントを作成

項目 設定値 備考
Name SonarQube 他の名前でも可。投稿に表示されるので、SonarQubeからの投稿であることが分かりやすいように命名する。
Username SonarQube 他の名前でも可。
Email 任意のメールアドレス
Avatar SonarQubeのアイコンなどを設定するとわかりやすい

BOTアカウントに権限を付与

作成したBOTアカウントに、対象プロジェクトへのDeveloper権限を付与する。

BOTアカウントのトークンを取得

作成したBOTアカウントでログインし、Settings > Access Tokensで新規のアクセストークンを発行する。

項目 設定値 備考
Name SonarQube 任意の名前で可。
Expires at (空欄)
Scopes api

発行したトークンは、SonarQubeの Administration > Configuration > General Settings > GitLab > GitLab User Tokenに登録する。

SonarQubeのトークンをgitlab-runner用の環境変数に登録

解析対象のプロジェクトの、Settings > CI / CD > VariablesにSonarQubeのトークンを追加する。

項目 設定値 備考
Type Variable
Key SONARQUBE_TOKEN
Value {your_sonarqube_token} 前述の手順で取得したトークン

sonar-project.propertiesの作成

解析対象のプロジェクト直下に、下記のファイルを作成する。
設定値は、各環境に合わせて変更が必要。

sonar-project.properties
# プロジェクト情報(SonarQubeで設定した内容)
sonar.projectKey={your_repository_name}
sonar.projectName={your_repository_name}

# プロジェクトのバージョン(SonarQubeのGUI上で解析結果をバージョンごとに管理可能)
sonar.projectVersion=1.0

# ソースコードのパス
sonar.sources=src
# ソースコードから除外する条件
sonar.exclusions=**/*.spec.js

# テストコードのパス
sonar.tests=src,config
# テストコードに加える条件
sonar.test.inclusions=**/*.spec.js

# 言語を指定しない場合、自動で言語認識をしてくれる。
# 自動認識の場合は、複数言語の認識にも対応。(Javascript + CSSなど)
# sonar.language=js

# カバレッジレポートのパス
sonar.javascript.lcov.reportPaths=coverage/lcov.info

# エンコーディング
sonar.sourceEncoding=UTF-8

.gitlab-ci.ymlの作成

GitLab-CIが実行する処理を定義する。
sonar-scannerという、SonarQubeの解析処理を実行するプログラムが実施されるように定義していく。

なお、sonar-scannerについては公式のDockerイメージを使用する。
インストールして使うこともできるが、不用意に環境を汚したくないし、導入が簡単なDocker版を採用。
公式のDockerイメージは、2020/01/10時点で未だにBeta版だが、今回の用途では何ら問題なく使用することができた。

.gitlab-ci.yml
stages:
  - analysis
analysis:
  stage: analysis
  image:
    name: sonarsource/sonar-scanner-cli:4.2
    entrypoint: [""]
  allow_failure: true
  variables:
    SONAR_HOST_URL: http://{your_SonarQube_IP}:9000
    SONAR_TOKEN: ${SONARQUBE_TOKEN}
    SONAR_PROJECT_BASE_DIR: ${CI_PROJECT_DIR}
  script:
    - |-
      sonar-scanner \
        -Dsonar.gitlab.project_id=$CI_PROJECT_ID \
        -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME \
        -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA
  tags:
    - docker

公式のDockerイメージは、docker runコマンドで使用されることを前提に作成されており、渡せる環境変数やオプションが限られている。
今回は、GitLabのプロジェクトID、ブランチ名、コミットハッシュを渡したかったため、entrypointを上書きしてコンテナ内でsonar-scannerを直接実行するようにしている。

いよいよ実行

ここまで設定した状態で、GitLabにコードの変更がPushされると、gitlab-runnersonar-scannerが実行され、静的解析の結果がSonarQubeに登録されるとともに、GitLabのコミットやマージリクエストに対するコメントとしても投稿される。

各登場人物の仕事を図に表すと、こんな感じ。

mermaid-diagram-20200110143146.png

もし、静的解析の結果をSonarQubeのダッシュボードに登録したくない場合は、-Dsonar.analysis.mode=previewというオプションを追加すると良い。

その他のTips

SonarQubeBOTの投稿コメントに、SonarQubeダッシュボードへのリンクを追加する

SonarQube標準の設定では、GitLabに投稿されるコメントにSonarQubeダッシュボードへのリンクは含まれない。
しかし、静的解析結果を読んだら、グラフィカルなダッシュボードで詳細を見たくなるはず。

以下の設定をすることで、SonarQubeダッシュボードへのリンクを追加することができる。

Administration > Configuration > General Settings > GitLab > Global template

You can check the details on the [SonarQube dashboard](${sonarUrl}). (Login username and password is `admin`.)  
The summary of the analysis results is as follows.

---

<!-- ここに、以下のURLからコピーしたマークダウンを貼り付ける -->
<!-- https://github.com/gabrie-allaigre/sonar-gitlab-plugin/blob/master/templates/global/default.md -->

Administration > Configuration > General Settings > GitLab > Inline template

You can check the details on the [SonarQube dashboard](${sonarUrl}). (Login username and password is `admin`.)  
The summary of the analysis results is as follows.

---

<!-- ここに、以下のURLからコピーしたマークダウンを貼り付ける -->
<!-- https://github.com/gabrie-allaigre/sonar-gitlab-plugin/blob/master/templates/inline/default.md -->
19
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?