Jenkins + GitBook で GitHub のドキュメント(PDF)のパブリッシュを自動化しよう

  • 10
    いいね
  • 0
    コメント

はじめに

「AWS で CI 環境を構築」シリーズの第二弾です。

今回は Jenkins で GitHub のドキュメントを GitBook で PDF 化して、GitHub のリリースにアップロードすることで、ドキュメントのパブリッシュを自動化します。

準備

GitHub - Jenkins 連携

以下で、GitHub のイベントをトリガーに、Jenkins サーバにソースが展開されるようにしておきます。

「Jenkins で GitHub のイベントを受けてゴニョゴニョする準備」
http://qiita.com/exabugs/items/cc2c6f59da98cd81a06f

API トークン 作成

リリースの作成と成果物のアップロードで GitHub API を使用します。

そのため、Settings - Personal access tokens で API トークン を作成します。
screencapture-github-settings-tokens-1483809559363.png

scopes (権限) は repo をチェック
スクリーンショット_2017-01-08_2_24_46.png

作成したら、token をメモしておいて下さい
スクリーンショット_2017-01-08_2_25_33.png

インストール

Node.js

yum では、まだ 0.10 です。古いです。
ここは LTS の 6系 が望ましいです。

Node.js は環境の管理をしたいので nvm を使います。
https://github.com/creationix/nvm

以下で nvm をインストール。
NVM_DIR でインストール ディレクトリを指定できます。(指定しない場合は ~/.nvm にインストールされる)
全ユーザで使えるように、/usr/local/nvm にインストールします。

# curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | NVM_DIR=/usr/local/nvm bash

インストール後、以下が ~/.bashrc に追記されます。しかし、このままではインストールしたユーザでしか使えない。
そのため、この部分を /etc/profile.d/nvm.sh (新規) に移動して、全ユーザで読み込まれるようにします。

/etc/profile.d/nvm.sh
export NVM_DIR="/usr/local/nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm

再ログインで、上記 nvm が使用可能になります。

# nvm ls-remote

         v6.9.0   (LTS: Boron)
         v6.9.1   (LTS: Boron)
         v6.9.2   (LTS: Boron)
         v6.9.3   (LTS: Boron)
         v6.9.4   (Latest LTS: Boron)

最新の v6.9.4 をインストールしましょうか。

# nvm install v6.9.4
# nvm use v6.9.4
# nvm alias default v6.9.4

以下になれば Node.js はインストール完了です。

# node -v
v6.9.4

GitBook

GitBook は以下でインストールできます

# sudo npm install gitbook-cli -g
# gitbook install

また、PDF出力のために、Calibre が必要です
https://calibre-ebook.com/download_linux

# sudo -v && wget -nv -O- https://download.calibre-ebook.com/linux-installer.py | sudo python -c "import sys; main=lambda:sys.stderr.write('Download failed\n'); exec(sys.stdin.read()); main()"

OS のライブラリも、不足があるようなのでインストールします

# yum install mesa-libGL

以下で、動作確認しておきましょうか。
(README.md と SUMMARY.md が必須)

# gitbook pdf

設定

Jenkins

GitBook で PDF を生成し、リリースにアップロードします。
上記を実行するタイミングとしては、リポジトリにSUMMARY.md が存在し、かつ tag が Push された時だけとします。

スクリーンショット 2017-01-08 3.03.09.png
スクリーンショット 2017-01-08 3.03.56.png

#!/bin/bash

export PATH=/usr/bin:/usr/local/bin:$PATH
. /etc/profile.d/nvm.sh

param() {
  echo $payload | jq -r $1
}

OWNER=`param '.repository.owner.name'`
BRANCH=`param '.ref' | sed "s:^refs/heads:remotes/origin:"`
NAME=`param '.repository.name'`
URL=`param '.repository.ssh_url'`
ID=`param '.after'`

echo $URL
echo $BRANCH

if [ ! -d $NAME ]; then
  git clone $URL
fi

cd $NAME

git fetch origin
git reset --hard ${BRANCH}


#GitBook
if [[  $BRANCH = refs/tags/*  ]]; then

  if [ -f SUMMARY.md ]; then
    gitbook pdf
    github_asset_upload.sh $OWNER $NAME ${BRANCH:10}
  fi

fi

Jenkins から呼び出しているスクリプト (github_asset_upload.sh) が以下になります。
gitbook コマンドで生成した book.pdf を、GitHub のリリースにアップロードする処理になります。
book.pdf が既に存在するなら、削除してアップロード (更新) になります。

github_asset_upload.sh
#!/bin/bash

TOKEN=<ここにトークンを記載>

OWNER=$1
REPO=$2
TAG=$3

FILE=book.pdf
TYPE=application/pdf

URL_API=https://api.github.com/repos/${OWNER}/${REPO}/releases
URL_UPLOAD=https://uploads.github.com/repos/${OWNER}/${REPO}/releases
CURL=(curl -s -H "Authorization: token ${TOKEN}")


# タグのリリースがあるか?
#  なければ、作成
#  あれば、何もしない
ID_RELEASE=`"${CURL[@]}" -X GET $URL_API | jq ".[] | select(.tag_name == \"$TAG\") | .id"`
if [ -z $ID_RELEASE ] ; then
  echo Release $TAG create.
  ID_RELEASE=`"${CURL[@]}" -X POST $URL_API -d "{\"tag_name\":\"$TAG\"}" | jq ".id"`
else
  echo Release $TAG exists.
fi
echo Release : $ID_RELEASE


# タグのリリースで、指定したファイル名のassetsがあるか?
#  なければ、何もしない
#  あれば、削除
ID_ASSET=`"${CURL[@]}" -X GET $URL_API/$ID_RELEASE/assets | jq ".[] | select(.name == \"$FILE\") | .id"`
if [ -z $ID_ASSET ] ; then
  echo Asset $FILE not exists.
else
  echo Asset $FILE exists : $ID_ASSET. so delete.
  "${CURL[@]}" -X DELETE $URL_API/assets/$ID_ASSET -d "{\"tag_name\":\"$TAG\"}"
fi


# ファイルのアップロード
echo Asset $FILE upload.
ID_ASSET=`"${CURL[@]}" -X POST -H "Content-type: $TYPE" -F file=@$FILE $URL_UPLOAD/$ID_RELEASE/assets?name=$FILE | jq ".id"`
echo Asset : $ID_ASSET

動作確認

タグを打ってPushしてみます。

$ git tag -a v1.9.0
$ get push origin v1.9.0

Release v1.9.0 が作成され、その中に book.pdf が追加されました。
スクリーンショット_2017-01-08_2_33_03.png

日本語対応

日本語に対応するためには、フォントが必要です。

以下のサイトを参考に「Adobe/Google謹製の源ノ角ゴシック(Noto Sans CJK / Source Han Sans)」をインストールしました。(ありがとうございます)
http://backport.net/blog/2016/09/06/pdf_embedded_japanese_font/

フォントは、book.json で "GenShinGothic" を指定します。

book.json
{
  "pdf": {
    "fontFamily": "GenShinGothic"
  }
}

さすが源ノ角!日本語がキレイにPDF化されました!
スクリーンショット 2017-01-12 10.06.38.png

カスタマイズ

PDF の見栄えをカスタマイズできるようです。
https://toolchain.gitbook.com/config.html

book.json
{
    "pluginsConfig": {
        "fontSettings": {
            "size": 2
        }
    },
    "pdf": {
        "fontFamily": "GenShinGothic",
        "fontSize": 12,
    }
}

リポジトリの小技

ドキュメント(マークダウン)は、ソースコードと同じツリーに入れる派と、いや、リポジトリも分けたいんだよ、という派があると思います。

ドキュメントの編集が頻繁にある場合、ソースと同じブランチだとコミットログが荒れてくるので、今回はドキュメント用のリポジトリを分離したいと思います。

その際、Git の オーファン(ルートなし) ブランチが便利です。
(コミット履歴やタグ等、master ブランチとは完全に切り離されたブランチになります。)

以下で、ルートなしの documents ブランチを作成し、そこに ドキュメント(マークダウン) をコミットしていきます。

$ git checkout --orphan documents

おわりに

  • これで、「ドキュメントはマークダウンで」活動が、一歩進みました。
  • GitHub の操作は、Jenkins の Git プラグインを上手く使えば、もっと簡単にできるかもしれないです。
  • HTML 形式で出力して、GitHub-Pages でパブリッシュしようか、とも思いましたが、Private リポジトリでも GitHub-Pages は Public になるのですね。危ない、危ない。