10分で理解: GitLab CI/CD の設定


# CI/CD とは

- Continuous Integration: ソースコードが変更されるたびに、テスト等の定型処理を自動実行。
- Continuous Deployment: 公開サーバーへのコードの配置を自動実行。（テストを通った、などの条件を満たした場合）

# 例題

ここでは、以下のような CI/CD を GitLab 上で構築することをゴールとして、概念から実際の設定までを説明していく。

- Merge Request が作られるたびにテストを自動実行する。このテストが成功しない限りは Merge ボタンを押せない。
- release branch に対する Merge Request が承認され（Merge ボタンが押され）release branch に commit が為されたときには、release branch の内容を GitLab Pages に自動公開する。

# 概念

## Stage, Job, Pipeline

- **Job**: CI/CD の中で実行される実際の動作の単位。（例）build-job, test-job-1, release-job
- **Stage**: Job をどのような順番で実行するのかを制御する。（例）Build stage, Test stage
- **Pipeline**: commit などのきっかけで起動される Job 集合。
- 各 job はいずれかの stage に属する。
- stage 間には順番があり、前段 stage に全部の job が成功しない限り、後段の job は実行されない。

GitLab の UI 表現で表すと、たとえば Pipeline は下図のようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1861827/3c9f1861-1893-3c86-454b-51fbef2be157.png)

## Job の中身

- Job は　GitLab サーバー上で Container としてそれぞれ独立して実行される。
- Container の Image を選ぶことで多様な処理が可能。たとえば Apline Linux Image を用いて shell script を実行することができる。

## Rule

Job が起動される条件は Rule によって制御できる。例えば、今回の例題の場合は、以下のようになる。

| 条件 | build-job | test-job | release-job | 
|:-:|:-:|:-:|:-:|
| MR作成  | 実行  | 実行  |   |  
| release branch への commit  | 実行  |   | 実行  |  

## Artifact

- Job はそれぞれが独立した Container として実行されるため、Job 間での情報の受け渡しが必要な場合は明示的な指示が必要。
- **Artifact**: ある Container 上での Job 実行が終了した後で、後段の Job 群に伝えたい Container 内部のファイル群。たとえば、build-job はビルド結果を含むフォルダー以下を artifact とする。

# 実例

## Pipeline の記述

GitLab 上の各 repo のルートディレクトリの `.gitlab-ci.yml` という設定ファイルが、その repo に関する Pipeline を記述する。今回の例題の場合は以下のようになる。

```yml:.gitlab-ci.yml
stages:                 # stages を定義
    - build
    - test
    - deploy

build-job:
    rules:
        - if: $CI_MERGE_REQUEST_IID             # Merge Request 生成時
        - if: $CI_COMMIT_BRANCH == "release"　  # release branch への commit 時
    stage: build          # build ステージで実行
    image: node:latest    # node.js の docker image を用いた container 上で実行
    script:
        - yarn install
        - yarn build.     # react アプリを想定した例
    artifacts:
        paths:
            - build/      # ビルド成果物の入った "build" フォルダーを後段の job で利用できるように保存

test-job:
    rules:
        - if: $CI_MERGE_REQUEST_IID
    stage: test
    image: node:latest
    script:
        - yarn install
        - yarn test

pages:                    # この pages という job 名は特別で、この job の artifact が静的 Web サイトになる
    rules:
        - if: $CI_COMMIT_BRANCH == "release"
    stage: deploy         # build ステージの job (build-job) が成功した後で、deploy ステージで実行
    image: alpine:latest  # Alpine linux の docker image を用いた container 上で実行
    variables:
        GIT_STRATEGY: none  # git repo は clone しない
    script:
        - mv build public   # build-job から引き継いだ "build" フォルダーを "public" にリネーム
    artifacts:
        paths:
            - public        # pages job の出力として "public" フォルダーを保存。このフォルダー以下が静的 Web サイトとなる
```

## GitLab 上での操作

### .gitlab-ci.yml の編集

普通に repo をチェックアウトして `.gitlab-ci.yml` を編集することもできるが、下図のように GitLab UI 上で直接編集することも可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1861827/79958489-7c24-6c9d-1ba4-d5a92db82468.png)

## Pipeline の状態確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1861827/f6abd46e-98b3-99dd-8738-d1c89ed3b65a.png)

## GitLab Pages の確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1861827/12e53715-23a5-9ebe-4ba7-5fad64ffcad2.png)

# 詳細情報

- [GitLab CI/CD | GitLab](https://docs.gitlab.com/ee/ci/) CI/CD 情報のトップページ
- [The .gitlab-ci.yml file | GitLab](https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html) Pipeline 設定ファイルの記法
- [Predefined variables reference | GitLab](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) .gitlab-ci.yml ファイルの中で参照できる変数群
- [GitLab CI/CD Examples | GitLab](https://docs.gitlab.com/ee/ci/examples/) CI/CD 設定のサンプル集
- [GitLab Pages | GitLab](https://docs.gitlab.com/ee/user/project/pages/) GitLab Pages（静的 Web サーバー）の説明