はじめに
この記事はVisual Studio Team Services Advent Calendar 3日目の記事です。
VSTSではContinuous Integrationを担当するBuildとContinuous Delivery(Deployment)を担当するReleaseが別々に用意されています。
なんで分割されているかといえば、責務の分散でしょうかね。Releaseのほうがあとから追加というか、Release Managementという製品があって、その会社を買収したので統合した、という感じなんですが。大きくなるとビルド定義にデプロイ書いてもあまりいいことないですしね。
ビルドの成果物
成果物というのはビルド結果にある"Artifacts"をクリックして表示されるファイル群です。
直接ダウンロード、一覧探索が可能です。
JavaScript, PHP, Rubyといったスクリプト系言語ではsass使ってCSS生成したり、スクリプトの難読化くらいかなと思いますが、.NETやJava,ネイティブコードではソースから実行形式のバイナリを生成して、ターゲット環境に配備ということが必要になります。
じゃあ、ソースから生成されたもの(このカレンダーでは一貫して成果物と呼びます)を対象環境に配備するにはどうすればいいのでしょう?
それがビルド定義の中にある、Copy FilesタスクとPublish Artifactsタスクです(.NET CoreではPublishコマンド実行時直接出力先に指定しています)。
Copy Filesタスクでリリース定義に受け渡したいファイルを選別して、$(build.artifactstagingdirectory)フォルダに一度コピーします。
次に、Publish Artifactsタスクで$(build.artifactstagingdirectory)の中身を丸ごとartifacts(成果物)としてVSTSに登録します。
Releaseは以前はこのArtifactsがあることを前提にして動作していましたが、今はリポジトリを直接対象とすることもできるようになりました。
Releaseの作成
Create release definitionをクリックすると、リリース定義の作成が開始されます。
既存のテンプレートから作成するか、Emptyを選択して、一から作成しても問題ありません。結構いろいろあります(AzureやWindows環境前提が多いですが)。
Environment (リリース先)
VSTSではEnvironment単位にリリース先を設定します。Environmentはどんなくくりでも構わないのですが、大体こんな感じでしょうか。
- 検証環境と本番環境(検証でテストしてOKなら本番へ)
- 複数の本番環境へ段階的にデプロイ
- データベースとWebサーバー
- 異なるリージョンへ並列して展開する
Environmentで何をどこに展開するのか、わかりやすい名前をつけましょう。
ここではこんな風にProduction(本番)とつけます。ほかのパターンは後日紹介します。
Tasks (リリース作業)
実際のリリースはTasksに登録するリリースタスクで実施します。Releaseで使用するタスクとBuildで使用するタスクは基本的に共通です。どちらかでしか使えないタスクというのはそうありません。
今回は.NET CoreアプリケーションをAzure Web Appsに展開します。まず、Buildと同様に、Environment共通で使用するパラメータを登録します。
リリースで使用するアプリケーションタイプを指定します。App Servicesで使用可能なアプリケーションタイプ(Logic App, Functionsなど)が指定できます。
Buildと同様にエージェントを指定します。ひとつ面白い点として、BuildとReleaseで異なるエージェントプールを指定しても問題ありません。
例えば、Web関係のツールはLinuxエージェントのほうが間違いなく整っています。なので、ビルドはLinuxエージェントを使って、デプロイ先がWindows(およびSQL Databaseなど)であれば、Windowsのエージェントを使ったほうが間違いなく問題が少ないので、Hosted VS2017を使う、ということが可能です。
私も原稿を書くときre:viewはLinuxじゃないと動かないので、Linuxのエージェントを使いますが、Azureのストレージにバックアップするとき、AzCopyがLinuxのエージェントに入っていないので、ReleaseでWindowsのエージェントを使ってazcopyを呼び出しています。
Artifacts(成果物)の設定
ArtifactsのAdd(赤枠)をクリックして、成果物を指定します。
ビルド定義をSource Typeに指定した場合、成果物にしたいビルド定義を選択します。
前にも書いたように、Releaseはビルド定義で生成されたArtifactsを対象にしていました。しかし、JavaScriptやスクリプト言語、静的なコンテンツのように必ずしもビルドが必要のないものもあります。
そういう場合、いちいちレポジトリ全体をPublish Artifactsタスクで登録するのは無駄だということで、Release定義から直接レポジトリやDockerHubを参照できるようになりました。
ビルド定義の成果物を参照するときはこのようなパラメータが指定できますが、ソースごとに違います。
詳細はドキュメントを参照してください。
一つ注意点として、ビルド時に生成されたSource artifactsは通常ビルド定義の名前が使われます。これをリリース定義内で参照する場合、スクリプトによっては誤動作することがあります。
具体的にはマルチバイトのビルド定義を使っていると、シェルスクリプトが期待通り動かないというパターンです。なので、ここでANKのみで表現される別名を使うことを推奨します。
artifactsは一つだけとは限りません。複数追加して、ある特定の成果物が生成されたときにリリースを実行するということもできます。
継続的デプロイの設定
Artifactsの右上にあるアイコンをクリックすると、Continuous Deployment triggerがあり、そこをEnabledにすると、いわゆる継続的デリバリーが設定できます。入力元のブランチを指定できるので、何でもかんでも成果物が生成されたらリリースが動く、ということはありません。
基本的にはリリース用のブランチかmasterブランチのみを指定することをお勧めします。
どの環境にリリースするか、という設定はEnvronment毎に設定します。
リリース前処理
Environmentの左側にある上の雷のようなアイコンをクリックすると、成果物のフィルタリングやリリースの設定ができるようになります。複数の環境にリリースしたいけど、この環境にはこのソースのみ適用したい、Environmentへのリリースタイミングを制御したい場合便利です。
リリーストリガー
Environementへのリリースをどのタイミングで行うか、という設定です。
- After Release : リリースが作成されたとき
- Manual : 手動
Artifacts Filterで複数の成果物か特定の成果物のみが生成されたときというフィルタリングができます。
スケジュール
ScheduleをEnableにすると、リリース生成後、特定の時間でデプロイできます。特定のキャンペーンなどで、時間指定が必要なコンテンツの場合便利です。もちろん、展開には時間がかかるので、本当に有効にするにはそのあとプログラム側で制御が必要です。
リリース実行
説明が長くなりましたが、ようやくリリースです。今回は手動でリリースを実行してみましょう。
Releaseから今回はDraft Releaseを選択します。Draftを選択すると、リリースの内容が表示されます。
リリース内容が確認できます。Startをクリックすると、リリース前確認画面が表示されます。
リリース用のartifactを選択して、Startをクリックすると、リリースが開始されます。
リリース状況はLogsから確認できます。
まとめ
リリース機能はビルドと被っているように見えますが、それぞれ個別の役割がちゃんとあります。まずはビルドはビルド、リリースはリリースということで分割して考えてみてはどうでしょうか。