VuePressでGitHub Pagesにリッチなドキュメントを作る

# 概要

GitHubでソースコード、ドキュメント両方を管理し、自動的にデプロイする仕組みを作ります。
ドキュメントの作成にはVuePressを、CIサービスとしてTravis CIを用います。

**背景**

自作ライブラリやアプリケーションをGitHubで公開しても、なかなかその使い方や仕様のドキュメントまで手が回らなかったりします。そもそも書かなかったり、最初のうちは書いていたけど徐々に書かなくなって情報が古くなったり・・・。どうにか楽して両方をメンテしたい！

**実現したいこと**

masterブランチに、ソースコードとドキュメントの両方を配置し、ドキュメントがソースコードに追従するようにします。
masterブランチに変更を加えると、Travis CIが自動的にビルドし、バイナリをGitHubのReleasesページに、ドキュメントをGitHub Pagesにアップロードします。

![deploy_model.png](https://qiita-image-store.s3.amazonaws.com/0/39261/618cb845-3806-e953-29f3-4f8b0a0a3142.png)

**記事の流れ**

実際に適当なコマンド(`hello`)を作り、Travis CIを使ってGitHub Pagesにドキュメントを公開します。

# helloコマンド開発

例として`hello`というコマンドを作りました。
非常にシンプルで、実行するとhelloと出力するだけのプログラムです。

この部分は皆さん好きな言語で好きなプログラムを書くと思いますので、詳細は省略します。

適当にプログラム書いて

https://github.com/uphy/vuepress-example/commit/6967311a6648766cd4738c04dfde934843138b40

ビルドスクリプト書いて

https://github.com/uphy/vuepress-example/commit/d06aa7c4bd0950bdeb2ab8a8c3e4312338e2f01c

Travis CIで自動ビルド、リリースするように設定します。

https://github.com/uphy/vuepress-example/commit/b554d33e3b290e3a6a466031bd2110f6a86badc8

こんな感じになりました。

https://github.com/uphy/vuepress-example/tree/b554d33e3b290e3a6a466031bd2110f6a86badc8

Travis CIで本リポジトリを追加し、Travis CIのリポジトリ設定にEnvironment VariableとしてGITHUB_TOKENを追加します。GitHubトークンの取得は[こちら](https://github.com/settings/tokens)から。

設定後、タグを追加し

```console
$ git tag -a -m "1.0.0 Relase" 1.0.0
$ git push --tags
```

Travis CIがビルドしてくれて、[GitHub Releases](https://github.com/uphy/vuepress-example/releases)にバイナリが追加されたことを確認しました。

# VuePressによるドキュメント作成

上で作りました`hello`コマンドの使い方をまとめたドキュメントを作成します。

プロジェクト直下にdocsディレクトリを作成し、そこでドキュメントを作成します。

```console
$ mkdir docs
$ cd docs
$ yarn init
yarn init v1.9.4
question name (docs):
question version (1.0.0):
question description:
question entry point (index.js):
question repository url:
question author:
question license (MIT):
question private:
success Saved package.json
✨  Done in 20.09s.
$ yarn add -D vuepress
...
✨  Done in 28.37s.
```


作成したディレクトリに、VuePressの設定、favicon、各種Markdownファイルを作成します。

作り方は[公式ページ](https://vuepress.vuejs.org/)がとても丁寧に説明してくれてますし、[公式ページのソース](https://github.com/vuejs/vuepress/tree/master/docs)が参考になるので省略します。

こんな感じに作りました。

![Kapture 2018-09-09 at 14.48.03.gif](https://qiita-image-store.s3.amazonaws.com/0/39261/a2a39f99-2404-028f-b44d-6371b8d1212b.gif)

ソース: 
https://github.com/uphy/vuepress-example/commit/4b9e1e86ede18c225d7bca7f4553bcebe358a006

# Travis CIによるGitHub Pages更新

Travis CIでVuePressで書いたドキュメントをビルドし、できたhtml/css/js等をGitHub Pages(gh-pages)ブランチにpushするように設定します。

`language`を`go`として作成しているので、VuePressのビルドに必要な`yarn`や`npm`はインストールされていません。
インストールするのも面倒なのでDockerでさくっとビルドするようにしました。
差分で示します。


```diff:.travis.yml
+sudo: required
...
+services:
+  - docker
...
+  cache:
+    directories:
+      - docs/node_modules
...
script:
+   - docker run --rm -v "$(pwd)/docs:/docs" node:8 bash -c "cd /docs && yarn && yarn build" |
```

Dockerを有効にするには`sudo: required`を付加する必要があります。
VuePressのビルドは、`node:8`イメージを使って、コンテナ内にdocsをマウントして、yarnでビルドしています。

続いてGitHub Pagesへのデプロイに関する設定を追記します。

```diff:.travis.yml
deploy:
+  - provider: pages
+    github-token: $GITHUB_TOKEN
+    local-dir: docs/.vuepress/dist
+    target-branch: gh-pages
+    skip_cleanup: true
+    on:
+      branch: master
```

まとめるとこんな感じです。

https://github.com/uphy/vuepress-example/commit/76006ccbf7fe565e343b134106398385eb903484

これでgit pushするだけでソースコードのビルドに加えてドキュメントがアップロードされるようになりました。

# 機能追加

お試しで`hello`コマンドに機能を追加して、ドキュメントも合わせて更新してみます。

hello/main.go

```diff
-import "fmt"
+import (
+ "fmt"
+ "os"
+)

 func main() {
-   fmt.Println("Hello")
+ var name string
+ if len(os.Args) > 1 {
+         name = os.Args[1]
+ }
+ fmt.Printf("Hello %s\n", name)
 }
```

docs/getting-started.md

```diff
+You can also specify your name with the first argument.
+
+```console
+$ hello uphy
+Hello uphy
+```
```

これならメンテできる！かも