GitLabCI/CD入門 ~とりあえず動かす

### 前提知識

- CI/CDそのものについての理解
- GitLabの基本的な使い方(アカウント開設・リポジトリ作成等)
- Gitの基礎知識


### GitLab CI/CDとは

GitLabに組み込まれたCI/CDツールです。
サードパーティ製のツールやライブラリを導入しなくても利用できるのがメリットです。

- Saasでもオンプレミスでも利用可能
- パイプライン処理をymlファイルで定義できるため、可読性が高い
- 実行環境としてコンテナを利用可能である

等の特徴があります。

### 他のCIツールとの比較

※ 金銭的なコストは利用状況によるのでここでは触れません。

|ツール|導入コスト|ジョブの定義方法|
|-----|----------|--------------|
|Jenkins|高<br>(Jenkinsを実行するサーバを用意する必要があるため)|Jenkinsfile(独自のUDL)|
|CircleCI|中<br>(サーバは不要だがGithubと連携する必要あり)|yml|
|GithubActions|低<br>|yml|
|GitLabCI/CD|低<br>|yml|

導入コストはJenkins > CircleCI > GithubActions=GitLabCI/CDになるかと思います。
また、Jenkinsは他のツールと異なりパイプライン処理を独自の記法で定義するので習得コストがやや高めです。

導入コストと習得コストを加味すると2022年現在JenkinsをCIツールとして採用する理由はあまり無さそうです。
また、CircleCIはGithubやGibLabと連携する手間がかかります。
(いずれも初期コストだけなので許容できる範疇かもしれませんが...)

とするとCIツールとしてはGitHubActionsとGitLabCI/CDが有力と思われます。
Githubを利用している場合は前者を、GitLabを利用している場合は後者を使うことになるでしょう。
(両社を軽く触ったところ、あまり違いはありませんでした。「GitLabCI/CDの方が優れているからGitHubからGitLabに乗り換える」というようなことは
検討する必要は無さそうです。(逆もしかり))

### GitLab Runner

パイプライン処理を実行するにはGitLab Runnerと呼ばれる実行環境が必要です。

自前のサーバにRunnerをインストールことも可能ですが、今回はGitLabが用意してくれている
環境を使います。設定変更等は特にしなくても問題ありません。

### .gitlab-ci.yml

リポジトリのルートディレクトリに ```.gitlab-ci.yml``` という名前のファイルを作成し、ジョブを定義します。
ルートディレクトリ以外に作成すると読み込まれません。

また、.gitlab-ci.ymlは1つのリポジトリに1つしか作成できないため肥大化しやすい点に注意が必要です。
(解決策については別途ご紹介します。)


### 実際に動かす(最小構成)

それでは実際にジョブを作成していきます。

#### pushしたらジョブを実行

デフォルトではpushした時にジョブが実行されます。


```yml:.gitlab-ci.yml

# ジョブの名前
build-job:
　# ジョブのステージ
  stage: build
  # 実行する処理をscript句に配列形式で定義
  script:
    - echo "Hello, $GITLAB_USER_LOGIN!"

test-job1:
  stage: test
  script:
    - echo "This job tests something"

test-job2:
  stage: test
  # 複数行の処理を定義することも可能
  script:
    - echo "This job tests something, but takes more time than test-job1."
    - echo "After the echo commands complete, it runs the sleep command for 20 seconds"
    - echo "which simulates a test that runs 20 seconds longer than test-job1"
    - sleep 20
```

ジョブを定義してリモートリポジトリにpushしてみます。

GitLabのCI/CD > Piplinesからパイプラインの実行結果を確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/8afff5e1-5366-617f-542f-a7352298e64a.png)


無事に成功していますね。

#### マージリクエストを出したらジョブを実行

続いてpushしたときに加えてマージリクエスト(Githubで言うプルリクエスト)を作成した時にもジョブを実行するように変更します。
実行対象は何でもいいので今回はtest-job1を変更します。

```yml:.gitlab-ci.yml

# 変更箇所のみ記載
test-job1:
  stage: test
  script:
    - echo "This job tests something"
  rules:
    - if: $CI_PIPELINE_SOURCE ==  'merge_request_event'
```

rulesという構文を使うとジョブを実行する条件を定義する事が出来ます。
今回はマージリクエストが作成された時に実行されるようにしています。

#### マージしたらジョブを実行

最後にmainブランチに変更がマージされた時にジョブが実行されるようにします。

```yml:.gitlab-ci.yml

test-job2:
  stage: test
  script:
    - echo "This job tests something, but takes more time than test-job1."
    - echo "After the echo commands complete, it runs the sleep command for 20 seconds"
    - echo "which simulates a test that runs 20 seconds longer than test-job1"
    - sleep 20
  # mainブランチにコミットされた時にジョブを実行する
  rules:
    - if: $CI_COMMIT_BRANCH == 'main'
```

変更をpushしてマージリクエスト作成⇒マージします。
test-job2が実行されていることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/90d198dc-3cd6-d870-94a9-9656ec265f91.png)


とりあえずパイプラインを動作させることはできました。
次回以降構文や発展的なジョブ作成の手順を整理します。

### 参考文献

[Circle CI](https://circleci.com/ja/product/)
[GitLabのCI/CDで超重要なrulesの全てを理解する](https://dev.classmethod.jp/articles/sample-to-understand-rules/)
[GitLab Documentaion](https://docs.gitlab.com/)