Azure DevOps ビルドパイプラインで Pandoc を使って Markdown ファイルから Word ファイルを作る

例えばシナリオとして、「ドキュメントは Markdown 形式のテキストファイル（.md）で編集し、最終的な成果物として Word ファイルを作成する」というような場合、私は Pandoc を使用します。

![概要 Markdown → Repos → Pipeline → Word ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474869/0fb5a9d2-c9b2-544d-7518-5ce2454c7edc.png)


ローカル環境なら、Pandoc をインストールして、Visual Studio Code の拡張機能も入れて・・・ これはこれで書式などを細かく調整するときには小回りが利いていいのですが、ドキュメントを書くメンバー全員がこれをやる必要はないなと感じてしまいます。

もしビルドパイプラインで Pandoc が使えるなら「Git リポジトリを更新すると、最新の Word ファイルが誰でもダウンロードできるようになっている！」ということが実現できます。

## パイプラインに必要な手順
- リポジトリに Markdown テキストファイルと書式の Word ファイルを用意する（パスを確認しておく）
- vmImage を MacOS に設定
- brew install pandoc で Pandoc をインストールする
- pandoc で Word ファイルを作成する
- 作成したファイルをビルド結果に保存する（or 共有する）

## パイプラインの設定（YAML）

```YAML
pool:
  vmImage: 'macOS-10.15'

steps:
- script: |
    brew install pandoc
  displayName: 'Pandoc Install'

- script: |
    pandoc --version
  displayName: 'Pandoc Version'

- script: |
    pandoc ./SampleFolder/Sample.md --reference-doc=./SampleFolder/reference.docx  --table-of-contents --output=$(Build.ArtifactStagingDirectory)/Sample.docx
  displayName: 'Execute Pandoc (Create Word file)'

- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact: drop'
```

この例ではリポジトリの SampleFolder に Sample.md  と reference.docx  を保存しています。

次にビルドマシンに Pandoc をインストールする方法を考えます。Pandoc のインストール手順 [Installing pandoc](https://pandoc.org/installing.html) を見ると、様々なインストール方法に対応していることがわかります。

例えば Windows ならインストーラ（msi）をダウンロードするか、choco を使用するか。インストーラでのインストールは、Azure DevOps の標準のビルドマシンでは使用できません。choco は Azure DevOps の拡張機能 [Chocolatey](https://marketplace.visualstudio.com/items?itemName=gep13.chocolatey-azuredevops) をインストールすると使用することができます。この方法でもよさそうです。ただ、私が確認したときには、この方法では、pandoc のインストールに 1分以上の時間がかかっていました。そこで今回は別の方法を使用します。

MacOS では ```brew install pandoc``` でインストールできるようようなので、パイプラインを実行する仮想マシンの設定 vmImage を変更して、MacOS で動作するようにします。この方法を私が確認したときには、12秒でインストールが完了していました。

参考：[Use a Microsoft-hosted agent](https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/hosted?view=azure-devops#use-a-microsoft-hosted-agent)

インストールの次のタスクで ```pandoc --version``` を実行して、 Pandoc がちゃんとインストールできていることを確認します。

その次のタスクがいよいよ今回の目的のタスク。pandoc コマンドに Markdown ファイルと、書式の Word ファイルを指定して、ファイルを作成します。必要に応じて、対象のファイルを全て指定するように変更します。

ここでのポイントは出力先のフォルダを ```$(Build.ArtifactStagingDirectory)``` に指定することです。この変数（マクロ）は、次の PublishBuildArtifacts タスクで使用される、ビルド結果に成果物として保存されるファイルの保存場所を表すパスです。PublishBuildArtifacts タスクはこのフォルダの内容を読み取って、タスクの実行結果にファイルを保存してくれます。

ビルドパイプラインが成功すると結果の Related に「1 published」と表示されるのでクリックすると・・・

![ビルド結果に保存された Word ファイル](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474869/f9d0e4c5-302a-e595-bace-9d23a53c6ee6.png)

作成した Word ファイルをダウンロードすることができます。

もちろん必要に応じて、もっとよい共有場所へ保存するようにできます。例えば Word ファイルを受け取る人が参照できる場所に直接配置できるのであれば、そのようにタスクを構成するとよいでしょう。

## パイプラインの設定（Classic）
YAML パイプラインと同様の設定を、クラシックのパイプラインでも設定できます。画面に従って設定すれば、わかりにくい箇所は無いと思います。```- script:``` は Command Line タスクに置き換えてください。

## ドキュメントは「インクリメント」として扱いたい
アジャイルのスクラムでは、ステークホルダーとプロダクトオーナーのレビューを受ける成果物は「インクリメント」といって、スプリントの期間で完成させるものという意識で扱います。最初から最後までそれを完成させて、みんなで見るという意識があります。

対して、アジャイルではないプロセスでは、成果物が「契約書に納品物として記載されているかどうか？」で扱いを柔軟に変えようとすることが多いように思います。特に「ドキュメントは納品物でないから、そこまで重視されない」ようなことが、プロジェクトの開始時には言われることが多いです。しかし、顧客とのコミュニケーションがうまくいかずドキュメントが結局重視されることになったり、あまりにもコストをかけなかったためにドキュメントの出来が悪くて結果としてドキュメントを最重要と考えるようになったり。こういった場合に、ドキュメントの作成コストが膨大になることが多い様に思います。

どちらにしても、ドキュメントを読む人がちゃんと存在する場合には、最初から最後まで、契約にどう書かれているかに関わらず、ソースコードをビルドするとアプリやサービスが出来上がり、Markdown をビルドすると必要なドキュメントが出来上がる。そういうCI・CDを最初に組んでしまうのが、コストがかからなくて満足の得られるものになるように思います。