GitLab CIを使って仕事で楽をする

初めまして。Qiitaにはいわゆる初投稿というやつです。今後も(あれば)よろしく。

### 軽い自己紹介
大学生やってます。後輩のコードレビューをする際に品質を下げずに楽をしたかったので、CIを用いることにしました。

この記事はJenkins等のCI環境を経験したことをなかった僕が手探りでやった内容になりますので、おかしい点があったら指摘してもらえるとありがたいです。

# GitLabとGitLab CI
## ちょっとしたお話
GitLab CIはバージョン7までは設定したら使える、GitLab本体とは別の機能でした。
ですが、8にてGitLab本体と完全に統合された結果、特に設定しなくても有効になり、またUI面でも細かい部分が変化しています。既にあるブログの資料などが、若干runnerの扱いが異なったりするのはそのためです。

## 使う計算機資源
GitLab(Ver:8.4.2)用のサーバーが一台
CI Runnerとして使えるものが最低1台

## 環境構築の流れ
* GitLabのインストール
* GitLab CI Runnerのインストールと登録
* プロジェクトの作成とCIの準備

# 環境構築
## GitLabのインストール
Omnibus Packageを使うなり、各自好きな方法でインストールしたら良いと思います。割愛します

## GitLab CI Runnerのインストールと登録
Gitlabに取り込まれたのはGitLab CI Serverという機能ですが、これは実際にテストを走らせる環境ではありません。
サーバーからのテスト実行要求を受けて実際にビルドをするのはRunnerで、Serverは各Runnerにビルド実行要求を出し、その結果を管理する役目になります。

### CI Runnerについて
GitLab CI用のAPIが公開されているので、様々な非公式のRunnerがありますが、ここでは[公式のもの](https://gitlab.com/gitlab-org/gitlab-ci-multi-runner)を使います。
また公式のRunnerでも{gitlab-ci-multi-runner}と{gitlab-ci-runner}がありますが、後者は前者に取って代わられたのでmulti-runnerの方を使って下さい。

(元々multi runnerはshared runnner(複数プロジェクトで利用可能なrunnner)として、ci-runnerの方は特定のプロジェクトの為のrunnerとして使うためのものでしたが、CI Server側の仕様変更によりこの関係が崩れました。)

### インストール
インストールはリポジトリのREADMEにあるリンクから、OSに合わせて行って下さい。下記の例はUbuntu/Debianでやっています。作業内容としてはREADMEほぼそのままです

```bash
$ curl -sSL https://get.docker.com/ | sh
$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash
$ sudo apt-get install gitlab-ci-multi-runner
```
### ServerへRunnerを登録
GitLab CI ServerにRunnerを登録します。

```bash
ubuntu@gitlab-ci-runner:~$ sudo gitlab-ci-multi-runner register
Running in system-mode.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/ci):
https://git.example.com/ci
Please enter the gitlab-ci token for this runner:
ThisIsRegToken
Please enter the gitlab-ci description for this runner:
[gitlab-ci-runner]: regtestrunner
Please enter the gitlab-ci tags for this runner (comma separated):
shell-executor,chef-recipe
Registering runner... succeeded                     runner=hogehoge
Please enter the executor: parallels, docker, docker-ssh, virtualbox, ssh, shell:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
```

この登録は対話形式で行われるので、順番に情報を入力するだけですが、各項目について簡単に解説しておきます
#### RunnerのRegister時の入力項目

| 項目名 | 説明 |
|----|----|
| coordinator URL | GitLab CIのURLです。かつての名残で末尾に/ciが付きます |
| gitlab-ci token | CI Runner登録用のTokenです。Admin AreaのRunnersにあります。わからない場合は[ここ](https://qiita-image-store.s3.amazonaws.com/0/112269/fc8d714c-a6f6-5e19-5ead-cc0bb36475f1.png) |
| description | runnerにつけられる説明です 変更可能です |
| tags | runnerにつけるtagです 特定のtagがついたrunnerでのみbuildを走らせる、などのrunnerの選択に使います |
| executor | buildを実行する方法です |

executorについてですが、以下のようになります
* parallels,docker,docker-ssh,virtualboxはそれぞれで仮想マシン(コンテナ)を作成し、jobを実行
* sshは特定サーバーへssh接続をし、そこでjobを実行
* shellはrunnner本体で、その名の通りshellでjobを実行

executorはコンテナを軽量に作成できる、環境も綺麗なままで保ちやすいdockerがおすすめですが、テストコード自体でDockerを利用したい場合(Docker containerを起動し、そこにserverspec等を実行するなどDocker外部からコンテナに対しアクセスする場合など)はshellを使う事になると思います。

とりあえず、これでRunnerが登録されました。
後はプロジェクトを作り、プッシュするだけです


## CIしてみる
プロジェクトがあり、コードが作成済みになったとします。
テストが実行可能になった際、repository root直下に.gitlab-ci.ymlを作成します

```yaml:.gitlab-ci.yml
stages:
  - test

test_job:
  type: test
  script:
    - ./test_script.sh
  tags:
    - docker
```

このような形になります。詳しい記法などに関しては[公式ドキュメント](http://doc.gitlab.com/ce/ci/yaml/README.html)を参照下さい。
後はこのファイルをgit add,commitしてpushすると、runnerにてtest_script.shが実行され、その実行結果によってbuild successやfailed等結果が記録されます。

## 仕事を楽にするのに活かす
### Merge Accept予約
GitLabのそれなりに新しいバージョンから、Merge Requestに対してテストが成功した場合自動でマージするボタンというものが増えました。用法を守って使えば非常に便利です。CIの統合など、GitLabのCIに対する気合が垣間見える更新だと思います。

### 自動デプロイ
例えば、Git Flowにて開発を行っている場合、master branchへのコミットに対してはテスト成功時に自動でデプロイする、と言った自動化をしたい場合があるかもしれません(テストケースが万全な場合に限られるかもしれないですが…)
この場合、deploy用に、shell executorなrunnerを用意し、以下のようにします(あくまで一例です)

```yaml:.gitlab-ci.yml
stages:
  - test
  - deploy

test_job:
  type: test
  script:
    - ./test_script.sh
  tags:
    - docker

deploy_job:
  type: deploy
  script:
    - sudo /etc/deploy_scripts/deploy_hoge.sh
  tags:
    - deploy
  only:
    - master
```

```bash:/etc/deploy_scripts/deploy_hoge.sh
ssh administrator@appserver.example.com
cd /var/www/some_application && git pull && ./restart.sh
```
appserver.example.comにはrootの公開鍵を登録しておく

```text:/etc/sudoers
gitlab-runner ALL=(ALL) NOPASSWD: /etc/deploy_scripts/deploy_hoge.sh
# もちろんvisudoコマンドで編集して下さい
```

このようにすると、master branchへのコミットでtest_jobが実行され成功した場合にのみdeployのscriptが実行されデプロイ処理が行われます。
ユーザーがgitlab-runnerになってますが、記事公開時の公式Runnerを導入した際にはこのユーザー名になりますが環境によっては違うかもしれないので注意して下さい。

## 最後に
buildの失敗をslackで通知すると便利

以上で、GitLabCIをどうやって使うのかという内容に関しては触れられたと思います。今度は実際にDjangoのアプリかchefのレシピをテストしてみる、という内容で具体的な部分に触れられたらなと思います。