はじめに
TFS2017本をRe:VIEWを使って書いているのですが、ローカルビルドでやっていました。ビルド環境が安定しないのと、Windows Subsystem for Linuxでpdf生成までやろうとすると、ディスク食うのでやってみたかったDockerとの連携をすることにしてみました。
VSTSビルドエージェントを作る
最初はVSTSのLinux Hosted Agentを使おうとしたのですが、残念ながらLinux Hosted AgentにGit-LFSが入っていないようで、原稿のpullができませんでした(報告済み)。
(8/25追記)今日最新のHosted Agentが更新されたようで、Git LFSも入っています。試したらちゃんとHosted Agentでビルドできました。したがって、この手順は不要です。ビルド時にLinux Hosted Agentを選択してください。
そこで、Azure(じゃなくてもいいんだけど)にUbuntu 16.04 LTSを立てて、ビルドエージェントを作ります。VSTSビルドエージェントのdockerイメージが提供されているので、素直に使います。
https://store.docker.com/community/images/microsoft/vsts-agent
こんな感じのシェルスクリプトを作って起動させます。
docker run -d --hostname ubuntsu001 \ -e VSTS_ACCOUNT={vsts account} \ -e VSTS_TOKEN={PAT} \ -e VSTS_WORK='/var/vsts/$VSTS_AGENT' \ -v /var/vsts:/var/vsts \ -v /var/run/docker.sock:/var/run/docker.sock \ -it microsoft/vsts-agent
PAT(Personal Access Token)は最長一年なので、気を付けてください。期限切れの通知もありません。Sprint 136の新機能でPATの有効期限切れが通知されるようになりました。
VSTSエージェントをdockerで実行します。/var/run/docker.sock をマウントさせるのはほんとはまずいらしいのですが、VSTSエージェントはsshなどでログインさせる必要がないので、大丈夫のはずです。
Dockerレジストリへの接続設定
最初にDocker拡張機能を追加します。
拡張機能を追加すると、dockerビルドタスクが使えるようになります。コンテナイメージを都度pullする場合、管理ページからdocker.comへの接続を作ります。
DockerIDとパスワードを指定します。
Re:VIEW文書をビルドする
本のPDF/epubごとにビルドタスクを作ります。
- DisplayName:タスクの表示名です。好きな名前でどうぞ
- Container Registry Type: Azureコンテナレジストリか、それ以外か
- Docker Registry Connection:上で作成したdocker.comへの接続を選択します
- Action:pullしたイメージを実行するので、"Run an image"
- Image Name:vvakameさんが提供してくれてる、vvakame/reviewを指定します。
- Volumes: マウントするボリュームを選択します。$(Agent.BuildDirectory)配下にTeXフォントキャッシュ(?)を指定します。ビルドで使用する$(Build.SourcesDirectory)をマウントしておきます。
- Command: ビルドに指定するコマンドを指定します。
/bin/sh -c "cd $(Build.SourcesDirectory)/1_setup && review-pdfmaker config.yml"
ソースリポジトリからpullしたソースが$(Build.SourcesDirectory)にあるので、その下/1_setupでPDFを作ります。
この記事中に出てくる$()で囲まれている文字列は、VSTS内で定義されている値です。どんな値が定義されているかはこちらに載っています。
例えば、Gitのコミットハッシュやブランチ名などを使うのもいいでしょう。
$(Build.SourcesDirectory)などのこの記事中の値はすべてVSTSでデフォルト定義されているものしか使っていませんが、例えばデータベースへのパスワードなどはvariablesハブで定義した独自の値を使うこともできます。
実際データベースのパスワードのような機密性の高い値はvariableへの直書きではなく、variable groupsに定義して、さらにAzure KeyVaultに保存しましょう。
ビルドのvariablesはビルド内しか使えませんが、variable groupsに登録しておけば、ビルドとリリースの両方で使えます(今回はリリースを使っていませんが)。
成果物にする
Re:VIEWでは特に指定しなければ、ソースフォルダ直下に作成します。このままではすぐに消えてしまうので、どこかに取っておきます。ここではVSTSの中に保持しておきます(これもデフォルトでは一定期間で削除されます)。
まず、成果物として、VSTS内に保存したいファイルだけをソースファイルからステージングフォルダへコピーします。次で説明するPublish to Artifactタスクがフォルダ丸ごとのコピーしかできないためです。
- Source Folder:$(Build.SourcesDirectory)を指定します。
- Contents:コピーしたいファイルを選択します。minmatchパターンが使えます。
- Target Folder:$(Build.ArtifactStagingDirectory)を指定します。
Publish ArtifactタスクでVSTS内に保存します。
- Path to Publish:先ほどコピーした$(Build.ArtifactStagingDirectory)を指定します。
- Artifact Name:成果物の名前です。dropを慣例的につけてます。
- Artifact Type:Serverを指定すると、VSTSに保存します。File Shareを指定すると、UNCのファイル共有になります。実際はAzure Storageのファイル共有になるでしょう。
ビルドが成功すれば、このようにartifactsに格納されます。
成果物の原稿を他人と共有する(追加)
VSTSは無料で5人まで無制限のGitリポジトリとしてアクセスできます。ただ、epub/pdfだけアクセスできればいいという場合、ライセンスを使うのももったいない話です。
そういう場合、ビルドタスクで各種クラウドストレージやGitHubに送るという方法が考えられます。
例えば、ビルド成果物をGitHub Releaseに送る拡張機能。
AWSのS3などに送るための拡張機能。
標準機能でもあるのですが、ビルドできたことをSlackへ通知するための拡張機能(VSTSへのアクセス権がある人はメール通知もできます)。
#MS Teamsは現時点では残念ながらAzure ADで運用しているVSTSじゃないと使えません。
最初はMS FlowやLogic Appを使って通知および、ファイルコピーしようと思ったのですが、VSTSのコネクタにはビルド成果物へのアクセスがないので、REST APIを使うしかないようです。
個人的にはAzureのBlobストレージへのコピーをやろうとしているのですが、Azure CLI 2.0のコマンドがよく理解できなくて止まってます…。Windows上のエージェントだったらPowerShellやAzCopyを使ったコピーが楽にできるのですが。
#.NET CoreベースのAzCopyにはまだ公式Dockerイメージがないようなので。自分で作るしかないか…。
終わりに
dockerをあまり理解しておらずやってたので、結構試行錯誤しました。これでCIができました。VSTSのhosted agent使えばビルド時にdockerイメージをpullすることもできるはずです。
Git LFSが入っていないことに気づくまで、何回かHosted Agentでやったのですが、vvakame/reviewイメージのダウンロードは大体30秒かからないようです。でも、毎回だとちょっときついですね。