gRPC開発におけるドキュメントを自動生成する
gRPCのドキュメントを自動生成するための備忘録です。
GitHub Actionsで実行した場合はこちらを参照
なぜやるか
gRPCの開発におけるメリットの一つにスキーマ駆動の開発になることがあると思います。protoファイルが全てなのでrpcについて知りたければprotoファイル見ればいいじゃん勢でしたが、「このField何?」とか「このrpcはどういうエラー吐くの?」とか聞かれたときに全然protoファイル見てもわかんないなとなり、別途手動でドキュメント管理するのはやりたくなかったので何かいい方法ないかなと調べたときにprotoc-gen-docの存在を知りました。protoファイルは絶対書くことになるのでprotoファイルの情報量をコメントで増やし、そこからドキュメントを自動生成すれば実装者の負担も減るし、使う側も最新の情報を取得できるしwin-winだなと思い導入。もし、チーム内で採用するのであればprotoファイルに書き込むコメントのルールを事前に決めておくことで実際にprotoファイルを作成するときに悩まないと思います。
protocbufのインストール
brew update
brew upgrade
brew install protobuf
brew upgrade protobuf
protoc --version
> libprotoc 3.19.4
protoc-gen-docのインストール
go version
> go version go1.18.3 darwin/arm64
go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@latest
下記コマンドでドキュメントを生成します。
(./docフォルダは事前に作成しておく必要があります。)
protoc \
--doc_out=./doc \
--doc_opt=markdown,index.md \
./**/*.proto
問題なければ./doc/index.mdが生成されているかと思います。
push時にドキュメントを自動生成する
今回はGitLabのCI/CDを使用しますがGitHub Actionsなどでも同じ感じでできると思います。
以下のようなgitlab-ci.ymlを作成。ドキュメントを作成した後にコミットし直す必要があるのでssh, gitのインストールと設定も必要。あと、mainブランチのprotoファイルが変更あった時に条件絞ってます。
# protoc-gen-docのインストールにGoを使うのでGoのdockerイメージを使用
image: golang:latest
stages:
- build
protoc-gen-doc:
stage: build
script:
- apt-get update && apt-get install -y unzip sudo openssh-server git
# protocolbufのインストール
- curl -OL https://github.com/google/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip
- unzip protoc-3.19.4-linux-x86_64.zip -d protoc3
- sudo mv protoc3/bin/* /usr/local/bin/
- sudo mv protoc3/include/* /usr/local/include/
# protoc-gen-docのインストール
- go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@latest
# sshのセットアップ
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan -H "$CI_SERVER_HOST" >> ~/.ssh/known_hosts
- eval "$(ssh-agent -s)"
- echo "$SSH_PRIVATE_KEY" | ssh-add - > /dev/null
# gitのセットアップ
- git config user.name $GITLAB_USER_NAME
- git config user.email $GITLAB_USER_EMAIL
- git remote set-url --push origin git@$CI_SERVER_HOST:$CI_PROJECT_PATH.git
- git checkout $CI_COMMIT_REF_NAME
# スクリプト実行
- ./generate-document.sh
artifacts:
paths:
- doc/
rules:
- changes:
- "**/*.proto"
if: '$CI_COMMIT_REF_NAME == "main"'
when: on_success
#!/bin/bash
# docディレクトリがなければ作る
if [ ! -d ./doc ]; then
mkdir ./doc
fi
# ドキュメント作成(markdownとhtmlの2種類を生成)
protoc \
--doc_out=./doc \
--doc_opt=html,index.html \
./**/*.proto
protoc \
--doc_out=./doc \
--doc_opt=markdown,index.md \
./**/*.proto
# ごみ削除
if [ -d ./protoc3 ]; then
rm -r protoc3
fi
if [ -e protoc-3.19.4-linux-x86_64.zip ]; then
rm protoc-3.19.4-linux-x86_64.zip
fi
# 差分があればコミットし直す
if [ `git status -s | wc -l` -gt 0 ]; then
git add ./doc
git commit -m 'update document'
git push --push-option=ci.skip origin $CI_COMMIT_REF_NAME
echo "Success commit"
else
echo "Exit due to no difference"
fi
protoファイルに変更がある状態でpushをし、GitLabのjobが成功していてドキュメントが生成されていれば成功。こんな感じ
おまけ(GitLab pagesで公開する)
html形式でも出力をしていたのでGitLab pagesにて公開してみる。gitlab-ci.ymlを以下のように修正。
image: golang:latest
stages:
- build
+ - deploy
protoc-gen-doc:
stage: build
script:
- apt-get update && apt-get install -y unzip sudo openssh-server git
# protocolbufのインストール
- curl -OL https://github.com/google/protobuf/releases/download/v3.19.4/protoc-3.19.4-linux-x86_64.zip
- unzip protoc-3.19.4-linux-x86_64.zip -d protoc3
- sudo mv protoc3/bin/* /usr/local/bin/
- sudo mv protoc3/include/* /usr/local/include/
# protoc-gen-docのインストール
- go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@latest
# sshのセットアップ
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan -H "$CI_SERVER_HOST" >> ~/.ssh/known_hosts
- eval "$(ssh-agent -s)"
- echo "$SSH_PRIVATE_KEY" | ssh-add - > /dev/null
# gitのセットアップ
- git config user.name $GITLAB_USER_NAME
- git config user.email $GITLAB_USER_EMAIL
- git remote set-url --push origin git@$CI_SERVER_HOST:$CI_PROJECT_PATH.git
- git checkout $CI_COMMIT_REF_NAME
# スクリプト実行
- ./generate-document.sh
artifacts:
paths:
- doc/
rules:
- changes:
- "**/*.proto"
if: '$CI_COMMIT_REF_NAME == "main"'
when: on_success
+pages:
+ stage: deploy
+ dependencies:
+ - protoc-gen-doc
+ script:
+ - mv doc/ public/
+ artifacts:
+ paths:
+ - public
+ rules:
+ - if: '$CI_COMMIT_REF_NAME == "main"'
+ when: on_success
+ - when: never
アクセス可能ユーザーも設定できて、GitLabへのアクセス権があるユーザーのみに公開もできるのでチーム内のみに公開とかもできるし、逆に誰でも見れるように公開もできる。参考までに作成したものはこちらです。
以上!
Discussion