gitlab.com で いますぐCI してみよう

　QiitaでもMicrosoftによるGitHub買収でいろいろと盛り上がっていますが，よほどのアンチMSでもなければ，特にGitHubからGitLabへ移行することも無く「ふーん」で終わってしまうでしょう．

　しかし，GitLabにはGitHubには無い魅力も満載です！
　（わかりやすいところでは，プライベートリポジトリが無限に作れるところとか．GitHubもMicrosoftに買収されてやってくる気もしますが）
　~~見方によっては本番DBを吹き飛ばしかけたところも，とてもお茶目でかわいらしいですね~~

# GitLabの目玉機能 CI/CD Pipeline

　今回はその魅力の一つ， CI / CD機能のご紹介です． **もちろん無料です** （が， [1ユーザ1ヶ月あたり2,000分の制限があります](https://about.gitlab.com/pricing/#gitlab-com) ）
　GitHubの場合，別途 Travis や CircleCI，Drone.ioといった外部のCIサービスと，CIのベースとするDockerのコンテナレジストリサービスと連携して行うことがほとんどだと思いますが，GitLabはいずれも自己完結することができます．
　しかし，無料だからといって仮想通貨のマイニングとかすると他のユーザにもGitLabにも迷惑なのでしないでくださいネ
　なお，今回のサンプルはAndroidアプリをベースとしています．

# 第三者評価でも高評価を得たCI機能

2017/9に，GitLab CIは Forrester Wave社の第三者評価で高い評価を得ています．
https://about.gitlab.com/2017/09/27/gitlab-leader-continuous-integration-forrester-wave/
https://reprints.forrester.com/#/assets/2/921/RES137261/reports

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51949/212a4aca-1120-46d3-0821-6b898f323829.png)

右上に行くほど戦闘力高い

# CIしてみる

　では早速CIしてみましょう．
　今回使用したサンプルプロジェクトはこちらで公開しています
　https://gitlab.com/tetsukay/qiita-gitlab-ci-sample

## プロジェクトをpushする

まずは，GitLab上でプロジェクトをつくり，Android Studioで作ったAndroidプロジェクトを，そのままGitLab上にpushします．
GitLabのページを更新して，ファイルがアップロードされていることを確認します．

## `.gitlab-ci.yml` を作る

次に，GitLab CI のCI/CDの設定ファイルである `.gitlab-ci.yml` を作ります．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51949/6513e35f-85e8-808d-a15a-1ea7e16c20c9.png)

プロジェクトトップ，またはリポジトリのファイル一覧のページから，New Fileを選択します．
WebIDEを使っても良いのですが，New Fileからだと `.gitlab-ci.yml` がテンプレート化されているので，こちらのほうがラクです．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51949/6454efa5-03a0-29d1-2658-48590448df14.png)
New File の画面に遷移したあとは，テンプレートから `.gitlab-ci.yml` を選び，さらに Android のテンプレートを読み込みます．

```yaml:.gitlab-ci.yml
# This file is a template, and might need editing before it works on your project.
# Read more about this script on this blog post https://about.gitlab.com/2018/10/24/setting-up-gitlab-ci-for-android-projects/, by Jason Lenny
# If you are interested in using Android with FastLane for publishing take a look at the Android-Fastlane template.

image: openjdk:8-jdk

variables:
  ANDROID_COMPILE_SDK: "28"
  ANDROID_BUILD_TOOLS: "28.0.3"
  ANDROID_SDK_TOOLS:   "4333796"

before_script:
  - apt-get --quiet update --yes
  - apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1
  - wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_TOOLS}.zip
  - unzip -d android-sdk-linux android-sdk.zip
  - echo y | android-sdk-linux/tools/bin/sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" >/dev/null
  - echo y | android-sdk-linux/tools/bin/sdkmanager "platform-tools" >/dev/null
  - echo y | android-sdk-linux/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" >/dev/null
  - export ANDROID_HOME=$PWD/android-sdk-linux
  - export PATH=$PATH:$PWD/android-sdk-linux/platform-tools/
  - chmod +x ./gradlew
  # temporarily disable checking for EPIPE error and use yes to accept all licenses
  - set +o pipefail
  - yes | android-sdk-linux/tools/bin/sdkmanager --licenses
  - set -o pipefail

stages:
  - build
  - test

lintDebug:
  stage: build
  script:
    - ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint

assembleDebug:
  stage: build
  script:
    - ./gradlew assembleDebug
  artifacts:
    paths:
    - app/build/outputs/

debugTests:
  stage: test
  script:
    - ./gradlew -Pci --console=plain :app:testDebug

```

上記のようなテンプレートがテキストエリアに読み込まれます．
`variables` で設定されている ANDROID_COMPILE_SDK と ANDROID_BUILD_TOOLS のバージョンを適切に合わせます．
今回は `ANDROID_COMPILE_SDK` は `28` , `ANDROID_BUILD_TOOLS` は `28.0.3` に設定しました．
`ANDROID_SDK_TOOLS` はダウンロードするSDK zipのバージョンですので，そのままでも構いません
（CI中のSDKアップデートで必要なSDKバージョンを取得します）

## パイプライン

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51949/6bae2ee5-a116-8caf-980f-d3dc362a91c6.png)

CI / CIメニューのパイプラインのページヘ移動すると， `.gitlab-ci.yml` が追加されたことでCIが走ります．
さらに，上記の `running` のアイコンをクリックすると

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51949/422fa216-777f-2895-bca3-f510bed27250.png)

パイプライン構成を見ることができます．上の例では， build と unitTests がシーケンシャルで実施されることがわかります．
build が正常に終わると

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51949/63311393-eb03-cf6c-83ef-c0ae908ac6cd.png)

と，変化して，unitTestsに遷移します．
build や unitTests をクリックすると，ビルドコンソールの詳細に遷移できます．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51949/f123b3cb-0283-0956-db31-9dcc6967b35e.png)

## Artifacts

`.gitlab-ci.yml` に書かれた `artifacts` で指定されているファイルは成果物として保存されます．
パイプラインページ右のダウンロードボタンをクリックすると，buildステージで作られたapkをダウンロードできます．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51949/65e22e3f-8f06-31d1-4866-687e465d37d0.png)

# まとめ

　GitHubにはない魅力の一つとして，GitLab CIを紹介させていただきました．
　単純にAndroidプロジェクトをビルドするだけならこのように数ステップだけで出来てしまいます．簡単ですね！

　ただ，デフォルトで用意されているCIランナーのスペックはショボいです．無料で開放しているので致し方ないところですが，少し大きいAndroidプロジェクトになると辛くなってきます．
　でもGitLab CIは，自分のPCや余っているPCにCIランナーをインストールすることで， **自分専用のGitLab.com のランナーとして追加することもできます！**
　こういう柔軟なところもGitLabの魅力です！

# 参考情報

- Microsoft アレルギー患者に贈る GitLab のススメ
    - GitLab全体の解説記事
    - https://qiita.com/msh5/items/653c2b61ed8389e07bf4
- GitLab CIでテスト・ビルド・デプロイを自動化する
    - CI / CDのもっと詳細な情報
    - https://qiita.com/bremen/items/f47f383b9931a840a25c
- GitLab CI ユーザーのための YAML 入門
    - https://qiita.com/masakura/items/e1ad161690c6275259fa
- GitlaberのためのAndroid Dockerベース CI
    - GitLabはコンテナレジストリ機能も内包するので，Android SDKはDockerイメージにしておくと時間短縮になります
    - https://qiita.com/tetsukay/items/ee6661d1801ce35a532f
- GitLab CIとAWS Spot Instanceでお手頃価格のスケーリングCIを実現する
    - AWSスポットインスタンスを使う方法も
    - https://qiita.com/tetsukay/items/cd9c3a6c432191dff25f