2017年9月16日

GitLab CIを使ってWebAPIのPDFドキュメント生成を自動化する

前回は Web APIに組み込んだSwaggerが生成する swagger.json ファイルからコマンドラインでPDF形式のドキュメントを生成するところまで出来ました。

今回はこの一連の処理をGitLab CIを使って自動化してみようと思います。

大まかな流れは次のようになります。


  1. GitLabにプロジェクトを作成する
  2. 「.gitlab-ci.yml」ファイルを作成する
  3. GitLabにプッシュしてCIが動作することを確認する
  4. Web APIをAzure App Servicesに自動デプロイする
  5. CIでPDFドキュメントを自動生成する
  6. 生成されたPDFドキュメントをダウンロードする



1. GitLabにプロジェクトを作成する


CIサービスと言えば、Circle CIやTravis CI、Werkerなどたくさんありますが、今回は GitLab CI を使うことにしました。

まだ gitlab.com にアカウントが無い場合はユーザー登録しましょう。
ログイン後、「New Project」ボタンを押して新規プロジェクトを作成します。GitHubに既にプロジェクトがある場合はそちらからそっくりインポートする事も可能です。


2. 「.gitlab-ci.yml」ファイルを作成する

ソリューションの直下に .gitlab-ci.yml と言う名前のファイルを作成します。

Visual Studioを使っている場合はソリューションを右クリックして「追加」をすればSolution Itemsの下に表示されます。


ファイルの内容はとりあえずこんな感じにしておきます。




Dockerのベースイメージとして、Ubuntu 14.04 を使っています。

before_script の部分で apt-get コマンドを使ってJavaとRubyのインストールを行ない、script の部分で動作確認のためにJavaとRubyのバージョンを出力しています。

.gitlab-ci.ymlファイルの仕様は下のページに載っています。
https://docs.gitlab.com/ce/ci/yaml/README.html#gitlab-ci-yml




3. GitLabにプッシュしてCIが動作することを確認する


この状態でGitLabにプッシュして見ます。Pipelinesというメニューをクリックすると自動的にPipelineが作成されている事が分かります。


Jobsというサブメニューを開いて実行されたJobをクリックして詳細を表示すると、黒い画面でコンソール出力の結果を確認する事が出来ます。JavaとRubyのインストールが正常に行われて、最後にバージョン情報が表示されていれば成功です。



リポジトリへのPushを検知してGitLab側で自動的にDockerコンテナを起動して指定のコマンドを実行してくれているわけですね。

Circle CIなど他のサービスを使わずに、しかも無料でこれが出来るというのがGitLabの良い所だと思います。

ちなみに「CI Runner」というものを自前のサーバーにインストールしておけば、Dockerコンテナをそのサーバー上で起動させる様にする事も可能なようです。(むしろ元々は自前で用意するのが基本だったようです。)



4. Web APIをAzure App Servicesに自動デプロイする



Web APIのデプロイ先はAWSやGoogle Cloudなどどこでも構わないのですが、今回はAzure App Servicesを使います。

Azure App Servicesに自動デプロイするにはいくつかの方法がありますが、ここではTravis CIが作成している dpl コマンドを使ってみます。

GitLab CIのジョブでdplコマンドを実行するための設定は次のようになります。



Ubuntu 14.04を起動した後 Rubyをインストールし、さらに gem install dpl で dpl コマンドをインストールしています。

その後、dpl --provider=AzureWebApps で実行します。


ちなみに、
only:
    - /^release-.*$/
の部分は、「release-」で始まるタグ付きでプッシュされた時だけこのジョブが起動されるようにするための設定です。この2行を削除するとプッシュするたびに毎回起動されます。


さて、上の設定ファイルではデプロイ先のURLやデプロイ用の認証情報などを一切指定していません。それらはGitLab内のプロジェクト毎の設定画面に「Secret variables」として登録しておきます。





dplコマンドは

  • AZURE_WA_SITE
  • AZURE_WA_USERNAME
  • AZURE_WA_PASSWORD

の3つの設定を自動的に読み込んで処理してくれます。

この状態で実際にGitLabにプッシュして見るとAzure App ServicesにWeb APIが自動デプロイされます。下はデプロイ成功時のジョブのログを表示したところです。



念のためAzure側のURLを開いてみると確かにWebAPIとSwagger UIが動いています。







5. CIでPDFドキュメントを自動生成する


さて、次はいよいよWeb APIのPDFドキュメントを自動生成します。設定ファイルにpdfというジョブを追加しました。




stages:
  - deploy
  - pdf
となっているので、「deployというステージが終わってからpdfというステージを実行する」という意味になります。ひとつのステージには複数のジョブを含める事が出来ますが、その場合はステージ内の各ジョブが並列実行されます。今回の設定ではそれぞれのステージに同名のジョブを一つずつ含んでいるだけという形になっています。

それぞれのジョブは別個のDockerコンテナとして起動されるので、pdfジョブの方でも再度Rubyのインストールが必要になります。こちらのジョブではJavaのインストールも必要なのでdeployジョブよりも少し時間がかかります。

cd ./MySampleWebApi.Doc && chmod +x *.sh && ./build.sh $SWAGGER_JSON_URL

MySampleWebApi.DocフォルダにあらかじめダウンロードしておいたJavaのコマンド(swagger2markup-cli-1.3.1.jar)やスクリプトを格納してあるので、そのフォルダに移動して build.sh を実行しています。

これで前回に実行したのと同じ一連の処理が動いて ./MySampleWebApi.Doc/pdf フォルダにPDFファイルが作成されます。

この時にSecret Variablesの設定から $SWAGGER_JSON_URL の値を読み込んでスクリプトに渡しています。

こうしておけばAzure側のデプロイ先が変わっても柔軟に対応出来るので便利ですね。



6. 生成されたPDFドキュメントをダウンロードする


最新の成果物へは下の形式のURLでアクセス可能になっています。

https://gitlab.com/(ユーザー名またはグループ名)/(プロジェクト名)/-/jobs/artifacts/master/browse?job=(ジョブ名)

このURLへはGitLabにログインした状態でかつ権限があるユーザーでないとアクセス出来ないので、実運用では .gitlab-ci.yml にさらにジョブを追加してAWSやAzureなどのストレージにアップロードするような処理を追加することになると思います。


あと、この設定のままだとジョブが起動される度に素のUbuntuに対してJavaやRubyのインストールから行っているので、終了するまでにかなり(数分程度)時間がかかってしまいます。

出来ればJava/Rubyが既に入った状態のイメージを探してくるか自分で作成するかして、それをベースイメージに指定した方が良いと思います。



今回作成したサンプルプロジェクトの全ソースコードは下記で参照可能になっています。

https://gitlab.com/mikehibm/AspNetCoreWebApiSwagger