この記事は「Azure DevOps Advent Calendar 2019 - Qiita」の13日目の記事です。
Azure DevOps の Pipelines では WebApps をはじめ、主にWeb環境向けのデプロイ機能が標準で用意されています。
一方で、アプリパッケージという形で手っ取り早く共有したいときには、ファイル共有サービスにデプロイしたくなりますが、残念ながら、Google Drive や OneDrive へのデプロイ機能は用意されていません(2019/12/13時点)。
ここでは、利用者も多く、プランによっては無制限で使える Google Drive へ、Azure DevOps の Pipelines でデプロイする方法を説明します。
Google Drive 側の準備
サービスアカウントを作成する
今回、デプロイには、コマンドラインで Google Drive にアクセスできる、rclone を使います。このツールでは、対話型のログイン機能を使うこともできますが、自動でデプロイを行うために、サービスアカウントでログインするようにします。
まず、Google API Console に入り、Google Drive APIを使用可能にします。
初めてGoole APIを作る場合には、プロジェクトを作成する必要があるので、「プロジェクトの選択」から新しいプロジェクトを作成します。

プロジェクトを作成・選択したら、「ライブラリ」に入り、Google Drive を検索して、有効化します。

有効にしたら、API Console に戻り、「認証情報」から、「認証情報を作成」→「サービスアカウントキー」を選択します。
「新しいサービスアカウント」を選択して、任意のサービスアカウント名を入力します。役割は選択不要です。また、キーのタイプは「JSON」になっていることを確認して、「作成」します。

作成すると JSON ファイルが作成されます。このファイルは後ほど使用しますが、秘密鍵が含まれていますので、取り扱いに注意してください。
サービスアカウントキーが作成されたら、「サービスアカウントの管理」をクリックし、サービスアカウントの管理画面に入ります。先ほど作成したサービスアカウントのメールアドレスが確認できるので、これを記録しておきます。

Google Drive でデプロイ先を作成する
サービスアカウントが作成出来たら、Google Drive に入り、デプロイ先のディレクトリを作成します。ここでは、「azure-devops」というディレクトリ名にしています。
ディレクトリを作成したら、「共有」から先ほど作成したサービスアカウントのメールアドレスを追加します。この時、編集可能な設定にしてください。

Pipelines を作成する
Release pipeline の作成
Azure DevOps に入り、Release pipeline を作成します。ここでは、既にビルドパイプラインは作成済みの前提で進めますので、もし、まだであれば、先に作成をしておいてください。
まずは、Release Pipeline を作成します。テンプレートは「Empty job」を選択してください。 Release Pipeline を作成したら、Artifact に対象のビルドパイプラインを設定します。 この時、Source alias が設定されますので、この値を記録しておきます。

Agent job の設定
「Tasks」→「Stage 1」を選択して、job を設定していきます。
Google Drive へのアップロードに使用するツールの Rclone は、各OSに対応していますが、今回はDocker イメージを使用します。このため、実行環境は ubuntu を使用します。
「Agent job」を選択して、Agent Specification を「ubuntu-18.04」に切り替えます。

切り替えたら、下記の3つの Task を追加します。 (Bash は2つ追加します)
- Archive files
- Bash(設定ファイルの生成)
- Bash(Google Drive へのアップロード)

Archive files の設定
デプロイを zip ファイルにまとめます。
Release Pipeline では、設定したビルドパイプラインの成果物を自動的に下記のパスに展開してくれます(Source aliasの部分は先ほど Artifact で設定した文字列が入ります)。
$(System.DefaultWorkingDirectory)/{Source alias}/
このパスを「Root folder or file to archive」に設定します。
また、「Archive file to create」に保存先を設定します。ここでは、ブランチ名のディレクトリ配下に、ビルド番号を名前としたファイルを生成するように、下記の値を入れています。
$(System.DefaultWorkingDirectory)/data/$(Build.SourceBranchName)/$(Build.BuildNumber).zip

Bash(設定ファイルの生成)
Rclone では、接続先サービスなどの設定が必要になります。このステップでは、動作に必要な最小限の設定ファイルを作成します(単に文字列を書き込んでいるだけです)。
Type を「Inline」に切り替え、Script に下記のコマンドを設定します。
mkdir -p $(System.DefaultWorkingDirectory)/config/rclone/
echo -e "[gdrive]\ntype = drive\nscope = drive\n" > $(System.DefaultWorkingDirectory)/config/rclone/rclone.conf

なお、ファイルで残らないように、ここではログイン情報を書き込まず、アップロード時に環境変数で渡すようにしています。
Bash(Google Drive へのアップロード)
最後に Rclone(Docker イメージ) を使って、アップロードします。
先ほどと同じく、Type を「Inline」に、Script に下記コマンドを設定します。
(Google Drive のディレクトリ名を変えている場合は、コマンド最後の「azure-devops」をディレクトリ名に変えてください)
docker run --rm \
--volume $(System.DefaultWorkingDirectory)/config/rclone:/config/rclone \
--volume $(System.DefaultWorkingDirectory)/data:/data \
--env RCLONE_DRIVE_SERVICE_ACCOUNT_CREDENTIALS="$DRIVE_SERVICE_ACCOUNT_CREDENTIALS" \
rclone/rclone \
copy --drive-shared-with-me -v /data gdrive:azure-devops
さらに、Environment Variables に下記項目を追加します。
- Name : DRIVE_SERVICE_ACCOUNT_CREDENTIALS
- Value : $(DriveServiceAccountCredentials)

Docker コマンドでは、最初に作成した zip ファイルが入ったディレクトリを data ディレクトリに、
作成した設定ファイルの入ったディレクトリを config ディレクトリにマウントしています。
また、サービスアカウントの認証情報をパイプライン自体の環境変数から Docker 内の環境変数に設定して渡しています。
Variables の設定
サービスアカウントの認証情報をパイプラインの環境変数に設定します。
Variables を選択し、Pipeline variables に下記を追加します。
- Name : DriveServiceAccountCredentials
- Value : サービスアカウントで取得した JSON ファイルの中身をそのまま入れます
- 鍵マーク : 【重要】クリックして秘密情報に設定します

ここまで、設定が終わったら、「Save」ボタンを押して保存します。
デプロイを実行する
設定が完了したら、「Create release」ボタンを押して、デプロイを開始します。
正常に完了すれば、Google Drive の共有ディレクトリにファイルがアップロードされたのが確認できます。

おわりに
この記事では省略していますが、ビルドパイプラインの成功などをトリガーに設定すれば、CI/CD 環境を作ることができます。
HoloLens などのアプリケーションで手っ取り早く CD を始めたい場合に、Google Drive は有効だと思いますので、(公式で用意されるまでは)ぜひ活用していただければと思います。
良い CI/CD ライフを。