.gitlab-ci.yml をローカルのMacで動かしたい


## TL;DR

- `git`と`docker`が入っていればこんな感じで動作確認できます。

```
$ sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
$ sudo chmod +x /usr/local/bin/gitlab-runner
$ git clone https://github.com/y-amadatsu/hello-gitlab-runner.git
$ cd hello-gitlab-runner
$ gitlab-runner exec docker rspec
(snip)
Finished in 0.31912 seconds (files took 1.23 seconds to load)
27 examples, 0 failures, 13 pending

Skipping cache archiving due to empty cache key
Job succeeded
```

- `gitlab-ci-multi-runner` は `gitlab-runner` に名前が変わりました。
    - https://docs.gitlab.com/runner/install/old.html


## 🔰超重要🔰

この記事はあくまでローカルでお手軽に動かすための手順で、本来の`gitlab-runner`の使い方を説明したものではありません。詳細は公式サイト👇を参考にしてください！

https://docs.gitlab.com/runner/commands/#gitlab-runner-exec

## こんなエラーが出るんですよ😢って方へ（2020/6/29更新）

どうやら `.gitlab-ci.yml` 上の `default:` がgitlab-runnerでは利用できないみたいです（ざっと探してみたのだけど見つからなかった）
しょうがないので手元の `.gitlab-ci.yml` をYAMLのアンカー使って書き換えて実行しました。

```
$ gitlab-runner exec docker rubocop
Runtime platform                                    arch=amd64 os=darwin pid=38954 revision=6214287e version=13.1.0
Running with gitlab-runner 13.1.0 (6214287e)
Preparing the "docker" executor
ERROR: Failed to remove network for build
ERROR: Preparation failed: no Docker image specified to run the build in
Will be retried in 3s ...
ERROR: Failed to remove network for build
ERROR: Preparation failed: no Docker image specified to run the build in
Will be retried in 3s ...
ERROR: Failed to remove network for build
ERROR: Preparation failed: no Docker image specified to run the build in
Will be retried in 3s ...
ERROR: Job failed (system failure): no Docker image specified to run the build in
FATAL: no Docker image specified to run the build in
```

## 発端…

.gitlab-ci.ymlを作成したけど、動作確認のときに一々サーバにPushしてたんじゃがめんどいなー、なんとかならないかなーってgitlabの公式サイト漁っていたらでてきましたよ、救世主 `gitlab-runner` が。

## 事前準備

先に進む前に、dockerが必要です🐳
インストールは省略致しますのでQiitaで探して下さい 🙇

## `gitlab-runner` のインストール

ここを参考にインストールします。
https://docs.gitlab.com/runner/install/osx.html#installation

### インストールの手順

[参考サイト](https://docs.gitlab.com/runner/install/osx.html#installation)のままですが、以下でダウンロードして下さい。

```
sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
```

んで、実行権限をつけて…

```
sudo chmod +x /usr/local/bin/gitlab-runner
```

これで終わりです🎉マヂで簡単。

## 動かしてみる

枠だけのRails環境をgithub上に用意しました。

https://github.com/y-amadatsu/hello-gitlab-runner

`.gitlab-ci.yml`の中身は👇な感じです。

```

stages:
  - test

.base_job_template: &base_job_definition
  image: amd2/rails-gitlab-runner
  tags:
    - docker
  cache:
    untracked: true
    key: "$CI_BUILD_NAME"
    paths:
      - vendor

.test_job_template: &test_job_template
  <<: *base_job_definition
  services:
    - postgres:10.1-alpine
  variables:
    DATABASE_HOST: postgres
    DATABASE_USERNAME: postgres
    DATABASE_PASSWORD: ""
    RAILS_MAX_THREADS: "5"
    RAILS_ENV: test
  before_script:
    - ruby -v
    - bundle install --jobs $(nproc) --path vendor/bundle

rubocop:
  <<: *test_job_template
  stage: test
  script: bundle exec rubocop
  allow_failure: true

rspec:
  <<: *test_job_template
  stage: test
  script:
    - rails db:setup
    - SIMPLECOV=1 bundle exec rspec
```


なお、👆で使っているdocker-image（[amd2/rails-gitlab-runner](https://hub.docker.com/r/amd2/rails-gitlab-runner/)）はDocker Hub公式のものではないので、潔癖症の方はご注意を。ちなみに私の作ったrailsテスト用のimageで、恐らく危なくはないと思います（心配性）



ってことで、実際に動かしてみましょう！

```
$ git clone https://github.com/y-amadatsu/hello-gitlab-runner.git
$ cd hello-gitlab-runner
$ gitlab-runner exec docker rspec
(snip)
 9) UsersController PUT #update with invalid params returns a success response (i.e. to display the 'edit' template)
    # Add a hash of attributes valid for your model
    # ./spec/controllers/users_controller_spec.rb:118

 10) UsersController DELETE #destroy destroys the requested user
    # Add a hash of attributes valid for your model
    # ./spec/controllers/users_controller_spec.rb:127

 11) UsersController DELETE #destroy redirects to the users list
    # Add a hash of attributes valid for your model
    # ./spec/controllers/users_controller_spec.rb:134

 12) UsersHelper add some examples to (or delete) /builds/project-0/spec/helpers/users_helper_spec.rb
    # Not yet implemented
    # ./spec/helpers/users_helper_spec.rb:14

 13) User add some examples to (or delete) /builds/project-0/spec/models/user_spec.rb
    # Not yet implemented
    # ./spec/models/user_spec.rb:4

Finished in 0.31912 seconds (files took 1.23 seconds to load)
27 examples, 0 failures, 13 pending

Skipping cache archiving due to empty cache key
Job succeeded
```

あっけなく、Job成功です🎉🎉🎉

## 注意点とかとか…

### ❗️git管理されているリソースだけがgitlab-runner側に転送されます

Gitlab-CIの用途を考えると当然ですが、ローカルで動かすときは見落としがちなので注意です！

### ❗️GitLab-CIのすべての機能が使えるわけではない

> With current implementation of exec some of the features of GitLab CI will not work or may work partially.

https://docs.gitlab.com/runner/commands/#limitations-of-gitlab-runner-exec

とのことです。

@daichifukui さまから情報いただきましたように、例えば extends は利用できません。結構痛い。。。

> https://gitlab.com/gitlab-org/gitlab-runner/-/issues/3794
> ↑でも議論されていますが、gitlab-runnerは.gitlab-ci.ymlを全てをサポートしているわけでは無くて、例えばextendsに対応していないようですね。

ということで、私の場合は.gitlab-ci.ymlを新規で作る際の、単純なjobの動作確認や不具合検証で使っています。

### ❗️`gitlab-runner exec docker ***` で渡せるのはjobだけ

ステージとか渡せないっす。

```
$ gitlab-runner exec docker test
FATAL: no job named "test"
——
```

### 😎`.gitlab-ci.yml` の環境変数に値をセットしたい

こんな感じでOKです。

```
gitlab-runner exec docker deploy \
--env "HTTP_PROXY=$HTTP_PROXY" \
--env "HTTPS_PROXY=$HTTPS_PROXY"
```
### 🙅しかし…めちゃ遅いです

実行する度にgemのインストールが走ります。。。なんとかならんか。。。

```
$ gitlab-runner exec docker rspec
(snip)
$ bundle install --jobs $(nproc) --path vendor/bundle
Fetching gem metadata from https://rubygems.org/.............
Fetching rake 12.3.1
Fetching concurrent-ruby 1.0.5
Fetching minitest 5.11.3
Installing rake 12.3.1
Installing minitest 5.11.3
Installing concurrent-ruby 1.0.5
Fetching thread_safe 0.3.6
Fetching builder 3.2.3
Fetching erubi 1.7.1
Installing builder 3.2.3
Installing thread_safe 0.3.6
Fetching mini_portile2 2.3.0
(snip)
```

### 🙋最後に

Gitlab-CI も dokcer も最近触ったばかりなのでよくわからないことでいっぱいです😨
もっとよい方法や間違いなどありましたらコメントで教えていただければ幸いです🤣