GitLabCI入門 ~ 環境変数を使う ~ 

今回はGitLabCIの環境変数について整理します。

### 環境変数とは何か

実行中のジョブに渡すことができる変数です。
環境変数を使うと、ymlファイルに値をベタ書きせずに済むので便利です。


### 事前定義された環境変数

GitLabCIにはデフォルトで定義されている環境変数があります。
ブランチやタグ名・コミットSHA等を準備なしで参照することができます。

数があまりにも多いため(110個あります)、よく使いそうなものだけピックアップして整理します。

- CI_COMMIT_REF_NAME
  - ジョブが実行されているブランチまたはタグ名を参照する。
- CI_COMMIT_REF_SLUG
  - CI_COMMIT_REF_NAMEを小文字化して63byteに圧縮したもの。
- CI_COMMIT_SHA
  - コミットのリビジョン番号を参照する。
- CI_COMMIT_BRANCH
  - コミットされたブランチ名を指す。
- CI_COMMIT_TAG
  - コミットされたタグ名を指す。
- CI_DEFAULT_BRANCH
  - デフォルトブランチ名を指す。
- CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
  - マージリクエストのソースブランチ名を指す。
- CI_MERGE_REQUEST_TARGET_BRANCH_NAME
  - マージリクエストのターゲットブランチ名を指す。
- CI_PIPELINE_SOURCE
  - パイプラインがどのように起動するかを示す。

このうち、``` CI_PIPELINE_SOURCE ``` は他の変数と比較して複雑なので詳しく見ていきましょう。

#### CI_PIPELINE_SOURCEの使い方


以下のようにrules句のifで ``` $CI_PIPELINE_SOURCE == "設定値" ``` のようにしてジョブやパイプラインが起動する条件を規定します。

```yml

# マージリクエストを作成した時に起動する
job:
 script: echo "にゃーん"
 rules:
   - if:  $CI_PIPELINE_SOURCE == "merge_request_event"
```


|設定値|概要|
|-----|----|
|api|pipelines APIでトリガーする|
|chat|GitLab ChatOpsコマンドで起動する|
|external|GitLab以外のCIツールから実行される|
|external_pull_request_event|GitHubのプルリクエストが作成・更新された時に実行する|
|merge_request_event|マージリクエストが作成・更新された時に実行する。|
|parent_pipeline|親パイプラインから実行される。|
|pipeline|triggerキーワードまたはCI_JOB_TOKENありのAPIから実行される|
|push|pushしたときに実行される|
|schedule|定期実行する|
|trigger|トリガートークンによって起動される|
|web|GitLabの画面から実行する|
|webide|WebIDEにより実行する|


### カスタム環境変数

定義済み環境変数に加えてカスタム環境変数(独自の環境変数)を指定することもできます。


#### .gitlab-ci.ymlで定義する

``` variables ``` 句で独自の変数を定義します。
グローバルに変数を定義すると全てのジョブから参照する事が出来ます。

```yml

variables:
  API_SERVER: https://hogehoge.com/api/v1/users/

job1:
  script: curl $API_SERVER

job2:
  script: curl -X POST -H "Content-Type: application/json" -d "{"name": "ちいかわ"}" $API_SERVER
```

ジョブレベルで変数を定義するとそのジョブ内でのみ参照することができます。

```yml

job1:
  variables:
    TMP_DIR: ./tmp
  script: ls $TMP_DIR  
    
# 参照不可能
job2:
  script: cat $TMP_DIR/hoge.txt
```

また、変数から別の変数を展開することも可能です。

```yml

job:
  variables:
    HOGE: "aaaa"
    FUGA: $HOGE.txt
  # ルートディレクトリにaaa.txtというファイルが作成される。
  script: touch $FUGA

```

#### 設定画面で定義する

1. リポジトリのSetting > CI/CDで変数定義用のセクションを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/b959752d-3490-5ee1-ac70-9c9309064b6c.png)

2. Add Variableボタンを押して変数を入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/598747/63c78c7f-70e5-d31e-875f-ff3061bdb496.png)


- Key: 変数名を入力します。文字・数字・```_``` のみ利用可能です。
- Value: 変数の値を入力します。
- Type: FileまたはVariableです。後者を使うことが多いでしょう。
- Environment scope: 変数の有効範囲を指定します。基本的にはデフォルトのままで良いです。
- Flags
  - Protect variable: 保護されたブランチやタグからしか変数を参照できないようにします。
  - Mask variable: ログに変数の値がマスクされて出力されるようにします。APIトークン等機密性の高い情報についてはONにしましょう。

画面で定義した環境変数は全てのジョブから参照することができます。

### 環境変数の優先順位

変数は定義される場所によって優先順位が変わります。
しかし、名前が重複しないように変数を定義すればこの順序を気にしなくても済みます。


1. トリガー変数・スケジュールされたパイプライン変数・手動パイプライン実行変数
2. リポジトリ単位の変数またはプロテクトされた変数
3. グループ単位の変数またはプロテクトされた変数
4. 継承された環境変数
5. .gitlab-ci.ymlで定義されたジョブ単位の変数
6. .gitlab-ci.ymlで定義されたグローバルな変数
7. 事前定義された環境変数

### 環境変数の評価式

パイプラインで実行されるジョブを制御するために評価式を利用することができます。

#### 文字列による等式マッチング

以下の例ではmainブランチにコミットされた時のみjobがパイプラインに追加されます。

```yml
# シングルクォート・ダブルクォートのどちらでも可
job:
  script: echo "にゃーん"
  rules:
    if: $CI_COMMIT_BRANCH == "main"
```

逆に、以下の例ではmain以外のブランチにコミットされた時にjobがパイプラインに追加されます。
(mainブランチにコミットされた時は追加されません。)

```yml
# シングルクォート・ダブルクォートのどちらでも可
job:
  script: echo "にゃーん"
  rules:
    if: $CI_COMMIT_BRANCH != "main"
```

#### 未定義チェック

``` null ``` と比較すると変数が定義されているかを調べる事が出来ます。
使用頻度はあまり高くないでしょう。

#### 空文字列との比較

``` $VARIABLE == "" ``` や ``` $VARIABLE == '' ``` のように定義済み変数が空文字列かどうかを
調べることもできます。

#### 2つの変数の比較

``` $VAR1 == $VAR2 ``` や ``` $VAR3 != $VAR4 ``` で2つの変数の値を比較することができます。
この時、参照先ではなく値が比較されます。

#### パターンマッチ

正規表現によるパターンマッチを利用可能です。

- ``` =~ ```： パターンにマッチした場合に真になる。
- ``` !~ ```： パターンにマッチしない場合に真になる。

### 参考情報

[GitLab日本語ドキュメント](https://gitlab-docs.creationline.com/ee/ci/variables/README.html)