はじめてのGitLab-CI


とりあえずGitLab-CIを使ってみたくて、簡単なジョブを実行させてみたお話。

GitLab-CIを始める前の設定は[こちらの記事](http://qiita.com/yurano/items/30de57c163f6edbb42de)を参照してください。

## ビルドジョブの概要

以前よりドキュメントをmarkdownで記述し、S3の静的ウェブサイトホスティング機能を使ってドキュメントを公開していました。

ドキュメントはgitでバージョン管理して、[MkDocs](http://www.mkdocs.org)を使ってhtml化し、S3にアップロードしています。

今回は、この作業をGitLab-CIを使って行います。

## 実行環境

* GitLab 8.7.5
* GitLab-CI Multi Runner 1.4.1

## GitLab-CIの設定ファイル`.gitlab-ci.yml`作成

GitLab-CIによるビルドを行うときは、gitリポジトリのルートに`.gitlab-ci.yml`を置いてビルド手順を記述します。

`.gitlab-ci.yml`の書き方について詳しく知りたい方は、
[GitLabの公式ドキュメント](http://docs.gitlab.com/ce/ci/yaml/README.html)をご一読ください。

本記事では、とりあえずGitLab-CIでジョブを実行できるようになることが目的のため、今回記述した`.gitlab-ci.yml`に範囲を絞って説明します。

以下が今回記述した`.gitlab-ci.yml`です。


```yaml:.gitlab-ci.yml
image: python:2.7

stages:
  - build
  - test
  - deploy

before_script:
    - pip install --upgrade pip

build_job1:
  stage: build
  script:
    - pip install --upgrade mkdocs
    - mkdocs build
  artifacts:
    paths:
      - site/

test_job1:
  stage: test
  variables:
    AWS_ACCESS_KEY_ID: "your-aws-access-key-id"
    AWS_SECRET_ACCESS_KEY: "your-aws-secret-access-key"
  script:
    - pip install --upgrade awscli
    - aws s3 sync --dryrun --delete ${CI_PROJECT_DIR}/site s3://your-bucket-name/

deploy_job1:
  stage: deploy
  variables:
    AWS_ACCESS_KEY_ID: "your-aws-access-key-id"
    AWS_SECRET_ACCESS_KEY: "your-aws-secret-access-key"
  script:
    - pip install --upgrade awscli
    - aws s3 sync --delete ${CI_PROJECT_DIR}/site s3://your-bucket-name/
  only:
    - master
```

順に説明していきます。

### image

```yaml:
image: python:2.7
```

ビルドジョブを実行する環境となるDockerイメージを指定します。

ビルドジョブは、markdown形式のドキュメントをHTMLに変換するMkDocsと、変換したドキュメントをS3にアップロードするAWS CLIに依存します。

いずれもpython製であるため、今回はpythonのDockerイメージを利用します。

ビルド環境の雛形となるDockerイメージは、[Docker Hub](https://hub.docker.com)で探すことができます。


### stages

```yaml:
stages:
  - build
  - test
  - deploy
```

ビルドは、ステージごとに逐次実行されます。
各ステージは複数のジョブを設定することができます。
同じステージの各ジョブは並列実行されます。

ここでは、ビルドの工程として`build`,`test`,`deploy`と3つのステージがあり、各ステージをこの順番で実行することを指定しています。

### before_script

```yaml:
before_script:
    - pip install --upgrade pip
```

`before_script:`には、すべてのジョブの前に必ず実行されるスクリプトを記述できます。

今回はpipのupgradeを行っています。

このほか、`after_script:`でジョブの最後に実行されるスクリプトを記述することもできます。

### stage, script, artifacts


```yaml:
build_job1:
  stage: build
  script:
    - pip install --upgrade mkdocs
    - mkdocs build
  artifacts:
    paths:
      - site/
```

`build_job1:`以下で、ジョブの内容を記述しています。
ジョブの名前は任意に設定できます。

`stage:`では、先ほど`stages:`で宣言したステージのうち、どのステージのジョブかを指定します。

`script:`では、ジョブの内容を記述していきます。

`artifacts:`は、ジョブの実行結果を他のジョブで使うための指定です。

ここでは、`mkdocs build`でmarkdownをhtmlに変換していますが、この時、`site/`ディレクトリにhtmlが出力されます。
この後のジョブで、出力されたhtmlをS3にアップロードしたいので、`site/`を
artifactsとして指定しています。

### variables, only

```yaml:
deploy_job1:
  stage: deploy
  variables:
    AWS_ACCESS_KEY_ID: "your-aws-access-key-id"
    AWS_SECRET_ACCESS_KEY: "your-aws-secret-access-key"
  script:
    - pip install --upgrade awscli
    - aws s3 sync --delete ${CI_PROJECT_DIR}/site s3://your-bucket-name/
  only:
    - master
```

deployステージのジョブで、`variables:`と`only:`について説明します。

deployステージでは、S3にビルドされたhtmlをアップロードしていますが、このジョブはmasterブランチのビルド結果でしか実行したくありません。

このような場合に`only:`を指定します。

ここでは`only:`にmasterブランチを指定しているので、このジョブはmasterブランチに対するビルドでしか実行されません。

`only:`の反対、すなわち特定のブランチ以外で実行する、といった指定をすることもできます。この場合は`except:`を使います。

`only:`や`except:`では、ブランチ名だけでなく、以下のようにタグ名や、正規表現を指定することもできます。

```yaml:
only:
  - v1.0.0
except:
  - /^feature.*$/
```

deployステージでは、AWS CLIを使ってS3にhtmlをアップロードしています。

AWS CLIでは、認証の際に`AWS_ACCESS_KEY_ID`と`AWS_SECRET_ACCESS_KEY`を環境変数として設定しておくと、その環境変数の値を使って認証を行います。

ジョブで環境変数を設定する場合は、`variables:`を使用します。
`環境変数名: 値`の形式でジョブ実行時の環境変数を指定することができます。

## 所感

GitLab-CIはGitLabに統合されているため、GitLabでソース管理をしている場合は[とても簡単に使い始める](http://qiita.com/yurano/items/30de57c163f6edbb42de)ことができます。

それまではWebHookでJenkinsを使ったCIを行っていましたが、GitLabとの連携の設定が複雑でした。

GitLab-CIは一旦設定すれば、`.gitlab-ci.yml`をリポジトリに追加するだけで簡単にCIを行うことができます。
また、今回は簡単なタスクの説明でしたが、頑張ればもっと複雑なタスクも実行できるので、GitLabを使っているチームにはオススメできると思います。