Windows10下のVisualStuioプロジェクトをgitlab-ciでビルドする

# はじめに
本記事では、Windows10環境下にてVisualStudioのプロジェクトを`gitlab-ci`でビルドする手順をまとめる。
gitlab-ciに関しては、Docker環境下での情報が大半であり、かつ、これまでのWindows環境下の情報にないつまづきポイントがあったため、本記事を書くに至る。

# 筆者の環境
- Windows10 professional
- VisualStudio2017

# gitlab-ci導入手順
では、順を追ってgitlab-ciの導入手順を見ていこう

## インストール
[gitlabの公式リファレンス](https://docs.gitlab.com/runner/install/windows.html)より、バイナリファイル(.exe)をダウンロードする。
ダウンロードしたバイナリをPATHの通っているファイルにコピーする。
名前が長いので、`gitlab-runner.exe`とリネームする。これ以降は、この名前にバイナリファイルをリネームしたとして進める。
コマンドプロンプトを管理者で実行し、以下のコマンドをたたく。

```console
$ gitlab-runner install
```

## リポジトリ登録
gitlabのリポジトリとgitlab-runnerを紐づける。
CIを導入したいgitlabプロジェクトの`Settings` → `CD/CI` →　`Runners`を`expand`する。
上記の操作をすれば、`Set up a specific Runner manually`と出る。そこに記されているURLとトークンを以降の手順で使用する。
コマンドプロンプトに戻り、以下のコマンドをたたく。

```console
$ gitlab-runner　register
```
すると対話モードになるので、以下のように順に入力していく。

```
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
# URLを記述し、Enter

Please enter the gitlab-ci token for this runner:
# Tokenを記述し、Enter

Please enter the gitlab-ci description for this runner:
# runnerに任意の名前をつける。

Please enter the gitlab-ci tags for this runner (comma separated):
# runnerに任意のtagをつける。

Please enter the executor: shell, docker+machine, virtualbox, docker-ssh+machine, kubernetes, docker, docker-ssh, parallels, ssh: 
# 実行する環境を指定する。今回はwindows上でビルドするので、shellと入力する。
```

## Config.tomlの編集(つまづきポイント)
gitlab-runnerの設定は、`C:\Windows\System32\config.toml`に記述される。
現在の状態ではおそらくこのような中身であろう。

```config:C\Windows\System32\config.toml
concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "windows10"
  url = "gitlabのURL"
  token = "トークン"
  executor = "shell"
  shell = "powershell"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
```
このままでは、CIのジョブはpowershell上で動くため、コマンドプロンプトに変更するには、`shell = "cmd"`に書き換える。
また、**デフォルトの設定では、`git clone`するディレクトリは`C:/Windows/System32/builds`下となる。このままでは`msbuild`コマンドは失敗してしまう。**
そのため、`git clone`するディレクトリを変更してやる必要がある。
`config.toml`に `builds_dir = "任意のgitlab-ciがgit cloneするディレクトリ"`と追記する。なお、ディレクトリパスは**バックスラッシュではなく、フォワードスラッシュで記述する。**
上記の変更を加えると`config.toml`は以下のようになる。

```config:C\Windows\System32\config.toml
concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "windows10"
  url = "gitlabのURL"
  token = "トークン"
  executor = "shell"
  shell = "cmd"
  builds_dir = "任意のgitlab-ciがgit cloneするディレクトリ"
  [runners.custom_build_dir]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]
```

## gitlab-runner起動
コマンドプロンプトで以下のコマンドをたたく。

```console
$ gitlab-runner start
```

gitlab側で以下の画面のように、緑色の丸になっていれば、起動完了だ。
![gitlab-runner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267287/02cd7b3f-1ae9-0b21-8337-5133a7914a47.png)
鉛筆マークから、gitlab-runnerの設定画面に入れる。
`git tag`がついていないコミットでもジョブを走らせたい場合は`Run untagged jobs`にチェックを入れておこう。(下図)
![gitlab-ci_settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267287/6ab44828-68e7-2c1e-0d1b-efb5d5babf9a.png)

## ジョブの記述(.gitlab-ci.yml)
さて、いよいよCIが実行するジョブを記述し、VisualStudioのプロジェクトを`git push`時にビルドするようにする。
gitlab-ciにジョブを与えるには、リポジトリのルート下に`.gitlab-ci.yml`を加え、そこにスクリプトを記述する。
より詳しい説明は[公式リファレンス](https://docs.gitlab.com/ce/ci/yaml/README.html)を参照していただきたい。
今回は、`.gitlab-ci.yml`に以下のように記述する。

```yaml:.gitlab-ci.yml
before_script:
  - chcp 65001
  - 'call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\Tools\VsDevCmd.bat"'
stages:
  - build
debug_duild:
  stage: build
  script:
    - msbuild
  artifacts:
    paths:
      - プロジェクトの名前\bin\Debug
```
順に説明していこう。
コマンドプロンプトの文字コードはSHIFT-JISであるため、文字化けしてしまう。そのため、`chcp 65001`でutf-8な環境にする。
`VsDevCmd.bat`はVisualStudioに付属する、コマンドラインでビルドするためのファイル群のPATHをよろしく設定してくれるバッチファイルだ。
後は、`msbuild`コマンドを実行し、ビルド成果物を`artifacts`に指定すればよい。
`artifacts`に指定したビルド成果物は、gitlab上からダウンロードすることができる。

# 参考
[(公式)config.tomlについて](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section)

# おわりに
本記事では、ビルドについて触れたが、同様にMStestによるユニットテストを動かすこともできる。