intra-mart実践入門の作成記録 #005 続・VSTSでCI

# [VSTS](https://www.visualstudio.com/ja/team-services/)での設定
## 参考情報
　[前回の記事](https://qiita.com/drafts/dc1b57f89c1faf125554)でおおよその方向性が決まったので次は[VSTS](https://www.visualstudio.com/ja/team-services/)での設定を行っていきます。今回、参考にさせてもらうのはkkamegawaさんの「[Visual Studio Team ServicesでRe:VIEWのCIを実施する](http://kkamegawa.hatenablog.jp/entry/2017/08/20/213622#%E6%88%90%E6%9E%9C%E7%89%A9%E3%81%AE%E5%8E%9F%E7%A8%BF%E3%82%92%E4%BB%96%E4%BA%BA%E3%81%A8%E5%85%B1%E6%9C%89%E3%81%99%E3%82%8B%E8%BF%BD%E5%8A%A0)」です。kkamegawaさんはDockerコンテナを使っていますが、ここではもう一段階レベルを下げてシェルスクリプトの実行で成果物を作っていきます。

## [Git](https://git-scm.com/)リポジトリの作成
　[VSTS](https://www.visualstudio.com/ja/team-services/)で[チームプロジェクトを作成](https://docs.microsoft.com/en-us/vsts/user-guide/sign-up-invite-teammates)するとチームプロジェクト名と同じリポジトリが作成されます。そのリポジトリをそのまま使うのもいいですが、今回は書籍の原稿用に新しくリポジトリを作成しました。何故かというと、この後[intra-mart](https://www.intra-mart.jp/)の環境を作成したり、その中でアプリケーションを作ったりする場合に、それ専用のリポジトリが必要になることが明白だからです。また、チームプロジェクト名のリポジトリには主にプロジェクト管理系の情報を集めておきたい(前職での癖)という事情もあります。

　特に捻りもなく「manuscript」という名のリポジトリを新しく追加しました。このリポジトリに```review-init```コマンドで作成したファイル一式をコミットして、初回のプッシュを行います。これで[ビルド定義](https://docs.microsoft.com/en-us/vsts/build-release/actions/ci-cd-part-1)を作成する準備は終わりです。

## [Microsoft/vsts-agent](https://github.com/Microsoft/vsts-agent/blob/master/docs/start/envlinux.md)のセットアップ
　[Re:VIEW](http://reviewml.org)をセットアップした環境に[Git](https://git-scm.com/)をインストールします。残念ながら[CentOS](https://www.centos.org/)のyumリポジトリにあるGitはバージョンが少し古いので[ソースコードからインストール](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)しました。その後、[Microsoft/vsts-agent](https://github.com/Microsoft/vsts-agent)のセットアップのために[.Net Core 2.x](https://github.com/dotnet/core)を用意します。[Microsoft/vsts-agent](https://github.com/Microsoft/vsts-agent)の中にセットアップのために必要なスクリプトも含まれているため、下記の手順で[Git](https://git-scm.com/)、[.Net Core 2.x](https://github.com/dotnet/core)、[Microsoft/vsts-agent](https://github.com/Microsoft/vsts-agent)のセットアップまで可能です。

```bash:vsts-agent.sh
# Git インストール
yum -y install wget gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker autoconf
mkdir /tmp/git
wget  -qO- https://www.kernel.org/pub/software/scm/git/git-2.15.1.tar.gz | tar zxv -C /tmp/git --strip-components=1
cd /tmp/git
make configure
./configure --prefix=/usr
make all
make install
cd ~
rm -rf /tmp/git

# ユーザーの作成
USER_NAME="your_name"
USER_DESCRIPTION="vsts-agent用のユーザー"
useradd ${USER_NAME} -g wheel -c "${USER_DESCRIPTION}"

# wheelグループにパスワードなしのsudoの許可
sed -i -e "$ a %wheel ALL=NOPASSWD: ALL"  /etc/sudoers
# ${USER_NAME}にttyなしのsudoを許可
sed -i -e "$ a Defaults:${USER_NAME} \!requiretty"  /etc/sudoers
# ユーザー変更
su ${USER_NAME} -l

# vsts-agentのセットアップ
mkdir myagent && cd myagent
wget -qO- https://vstsagentpackage.azureedge.net/agent/2.126.0/vsts-agent-linux-x64-2.126.0.tar.gz | tar zxv -C ./ --strip-components=1
sudo ./bin/installdependencies.sh
./config.sh
################################################################################
# 手動の入力が必要
# 1.ライセンスの同意確認
# 2.サーバーURL
# 3.認証の種類
# 4.Personal Access Token
# 5.エージェントプール
# 6.エージェント名
# 7.作業フォルダー
################################################################################
./run.sh
```

## [VSTS](https://www.visualstudio.com/ja/team-services/)の[ビルド定義](https://docs.microsoft.com/en-us/vsts/build-release/actions/ci-cd-part-1)作成
　次に[VSTS](https://www.visualstudio.com/ja/team-services/)側に戻って、設定を行います。kkamegawaさんの解説で充分とは思いますが、異なるところもあるため画面キャプチャを交えながら説明していきます。

### 1. 「Build and Release」のメニューを選択する
![キャプチャ01.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/cf9fe8a5-4eed-de77-6e4c-24532a27e0df.png)

### 2. 「New」ボタンを押下する
![キャプチャ02.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/4ca7b9bc-ee87-93a2-c2ad-a4ffdc542418.png)

### 3. 「Empty Process」を選択する
![キャプチャ03.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/2d30027f-79c4-640b-b067-40dc8d82dff9.png)

### 4. 「Process」の設定
　注意点は「Agent queue」に先ほどローカル環境に作成した。[Microsoft/vsts-agent](https://github.com/Microsoft/vsts-agent)を使用するように設定することです。
![キャプチャ04.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/691a1171-12c2-1a43-d154-4d90fbca3f24.png)

### 5. 「Get sources」の設定
　注意点は「Clean」に「true」を選択し、全てのディレクトリを対象にすることです。これは[Re:VIEW](http://reviewml.org)がソースディレクトリの中に成果物を出力するため、次回ビルド時に持ち越されないようにするためです。
![キャプチャ05.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/c9ae8221-f850-7892-63c2-4e829f025d5b.png)

### 6. 「Phase 1」にタスクを追加
　「Phase 1」の右側にある「＋」ボタンを押下すると、右側のペインに追加可能なタスクの一覧が表示されます。「Utility」の中にある「Shell Script」を選択して「Add」ボタンを押下します。
![キャプチャ06.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/f100497a-1c79-2646-9fbe-b9effdc344aa.png)
　追加された「Shell Script」タスクを選択して設定を行います。ポイントは「Version」で「3.*(preview)」を選択することです。これまではソースの中に含まれているシェルスクリプトのパスを指定していましたが、コマンドを直接実行できるようになりました[^1]。実行したいのは```rake pdf```という簡単なコマンドですので、そのためだけにシェルスクリプトをバージョン管理せずに済むのはありがたいです。同様にして、EPUBを作成するタスクも作成しておきましょう。タスクをクローンして、コマンドを```rake epub```に変更すると楽に作成できます。
![キャプチャ07.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/d093d7d1-17f7-0efd-0490-9c1df03c2194.png)
　成果物を取得するためにビルド環境にアクセスするのも面倒ですので、作成したPDFやEPUBを[VSTS](https://www.visualstudio.com/ja/team-services/)に保存してダウンロードできるようにしておきます。先ほどと同様に「Phase 1」の右側の「＋」ボタンを押下し、「Utility」から「Copy and Publish Build Artifacts」を選択、「Add」ボタンを押下します。
![キャプチャ08.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/0951bab5-6d73-fad9-cd07-6dea1b876bbd.png)
　ソースディレクトリの中にあるPDFファイルをdropというディレクトリにコピーする設定にしました。「Artifact Type」は[VSTS](https://www.visualstudio.com/ja/team-services/)に保存するのでServerのままで問題ありません[^2]。同様にしてEPUBのコピーのタスクも作っておきましょう。タスクをクローンして「Contents」を``` *.epub```に変更すると楽に作成できます。
![キャプチャ09.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/1fa694f0-d4de-89bb-3041-2326ae4908db.png)

### 7. トリガーの設定
　メニューから「Triger」を選択して、「Enable continuous integration」にチェックをつけます。今回はmasterブランチしか存在しないため、masterを対象にしていますがブランチを切って執筆する場合はそちらのブランチを指定します。
![キャプチャ10.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/9dd8944c-17a1-7d09-a299-e1f2020deac0.png)

### 8. ビルド定義保存とテスト実行
　画面右上の「Save & queue」ボタンを押下するとダイアログが表示されます。
![キャプチャ11.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/40225845-39c2-8670-9512-7d8bebf1bb42.png)
　保存時のコメント等を入力して「Save & queue」ボタンを押下するとビルド定義がキューに設定されます。ビルド結果の「Artifacts」から作成された成果物を取得することができます。
![キャプチャ12.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/0dd68d4c-320a-6995-547d-c77fa360b324.png)
![キャプチャ13.PNG](https://qiita-image-store.s3.amazonaws.com/0/228081/597478b6-3338-a6c6-6cac-1cb49a9444ce.png)


# まとめ
　CI環境の構築の流れをシェルスクリプト風[^3]にまとめておきます。rootから実行する前提です。

```bash:CI_setup.sh
#!/bin/bash
# セキュリティアップデート
yum -y update

# Gitのインストール
yum -y install wget gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker autoconf
mkdir /tmp/git
wget  -qO- https://www.kernel.org/pub/software/scm/git/git-2.15.1.tar.gz | tar zxv -C /tmp/git --strip-components=1
cd /tmp/git
make configure
./configure --prefix=/usr
make all
make install
cd ~
rm -rf /tmp/git

# TeX Live 2017のインストール
yum -y install wget perl-Digest-MD5
mkdir /tmp/texlive
wget -qO- http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz | tar zxv -C /tmp/texlive --strip-components=1
echo "selected_scheme scheme-basic" > /tmp/texlive/texlive.profile
echo "option_doc 0" >> /tmp/texlive/texlive.profile
echo "option_src 0" >> /tmp/texlive/texlive.profile
perl /tmp/texlive/install-tl --profile=/tmp/texlive/texlive.profile
sed -i -e '$ a export INFOPATH=/usr/local/texlive/2017/texmf-dist/doc/info:$INFOPATH' /etc/profile
sed -i -e '$ a export MANPATH=/usr/local/texlive/2017/texmf-dist/doc/man:$MANPATH' /etc/profile
sed -i -e '$ a export PATH=/usr/local/texlive/2017/bin/x86_64-linux:$PATH' /etc/profile
source /etc/profile
rm -rf /tmp/texlive

# TeX Liveの更新
tlmgr install collection-latexrecommended 
tlmgr install collection-latexextra
tlmgr install collection-fontsrecommended
tlmgr install collection-langjapanese
tlmgr install latexmk
tlmgr install xetex
tlmgr update --self
tlmgr update --all


# ユーザーの作成
USER_NAME="your_name"
USER_DESCRIPTION="vsts-agent用のユーザー"
useradd ${USER_NAME} -g wheel -c "${USER_DESCRIPTION}"
# wheelグループにパスワードなしのsudoの許可
sed -i -e "$ a %wheel ALL=NOPASSWD: ALL"  /etc/sudoers
# ${USER_NAME}にttyなしのsudoを許可
sed -i -e "$ a Defaults:${USER_NAME} \!requiretty"  /etc/sudoers

# ユーザー変更
su ${USER_NAME} -l

# rubyインストール
sudo yum -y install wget bzip2 gcc openssl-devel readline-devel zlib-devel
mkdir /tmp/ruby
wget  -qO- https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.tar.gz | tar zxv -C /tmp/ruby --strip-components=1
cd /tmp/ruby
./configure --prefix=/usr/local/ruby
make
sudo make install
echo 'export PATH="/usr/local/ruby/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
cd ~
rm -rf /tmp/ruby

# Re:VIEWのインストール
echo 'export GEM_HOME="$HOME/.gem"' >> ~/.bash_profile
echo 'export PATH="$GEM_HOME/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
gem install review

# vsts-agentのセットアップ
mkdir ~/myagent && cd ~/myagent
wget -qO- https://vstsagentpackage.azureedge.net/agent/2.126.0/vsts-agent-linux-x64-2.126.0.tar.gz | tar zxv -C ./ --strip-components=1
sudo ./bin/installdependencies.sh
./config.sh
################################################################################
# 手動の入力が必要
# 1.ライセンスの同意確認
# 2.サーバーURL
# 3.認証の種類
# 4.Personal Access Token
# 5.エージェントプール
# 6.エージェント名
# 7.作業フォルダー
################################################################################
./run.sh
```



[^1]: ただし、preview機能のため、リリースされるタイミングによって使えるまでに時間がかかる場合もあります。
[^2]: ファイルサーバー立てている人ならFile shareから設定してください。
[^3]: 例によって手動操作が混じるのでシェルスクリプトではありません。