今更感
github-pagesに直接何か生成して置くのもCircleCIを使うのも始めてでNode.jsを真面目に使うこともなかった人間がいきなりこれをやったらどうなるかの覚書
GitBookがクラウドサービスに注力してCLIの開発は基本的にやめるよとか言ってるタイミングで自力でやるとか何考えてるんだ?
まあGitBookでなくとも(例えばmdBookでも)基本は変わらないわけだし。mdBookはとっとと多言語サポート入れてくれ。docsifyとかは開発活発なのかな?
ところで、以下のやり方だと実質1コミットしかない短命なgh-pages
ブランチが作られては上書きされて消えていく。初めはMarkdownがあるからHTMLやPDFは欲しい人が適宜作れるから気にしなくていいやと思っていたが、開発が止まって生成用のツールが入手できなくなる可能性を考えると、今後もどんどんバージョンを変えていってドキュメントも更新していくであろうプロジェクトではmaster/docs
に生成したHTMLを入れてそれも一緒に更新していく方が良さそうな気がするなあ。
したいこと
GitBookを使ってMarkdownからリファレンス的なウェブサイトを生成し、それをGitHub pagesに置いて表示したいが、ローカルで毎回buildするのはたるいからCIサービスを使いたい
具体的には、以下をやる
Markdownでドキュメントを書く
頑張って書く。
GitBookを使うなら、gitbook init
するとREADME.md
とSUMMARY.md
ができる。README.md
は最初のページになる。SUMMARY.md
は基本的にリストがあるだけで、ここには目次を書いていく。これが最終的に左側にメニューバーとして出現し、またページをめくっていくときの順番にもなる。
だいたいこんな感じ↓
# Summary * [Introduction](README.md) * [Usage](Usage.md) * [Reference](Reference.md)
GitBookでHTMLを生成する
基本的にこれはお手軽だ。ただ、少しばかり用意するべきものがある。book.jsonに使うパッケージやその設定を書く必要がある。例えば、
{ "root": "book/", "plugins": [ "hints", "anchors", "fontsettings", "search", "back-to-top-button" ] }
root
はドキュメントのルートディレクトリだ。先のREADME
やSUMMARY
を入れる場所。このjson
ファイルがレポジトリのトップにあるなら、book/
ディレクトリ以下に全てを置くことになる。これらの他にも使ってみているプラグインはあるが、面倒なのでスルー。気が向いたら書くかも知れない。
HTMLファイルを生成する前に、これらのプラグインをインストールする。
$ gitbook install # プラグインをインストール $ gitbook build # HTML生成
buildするとしばらくして_book/
ディレクトリにindex.html
その他が出力される。これをgh-pages
にぶち込めばよいわけだ。
GitHub pagesに置く
GitHub pagesでは、以下の3通りの場所にindex.html
を置くことができる。
master
ブランチのルートmaster
ブランチのdocs/
gh-pages
ブランチのルート
gh-pages
のdocs
というのは駄目だ。
さて、_book/
以下にあるものを改めてルートにしてgh-pages
に置く必要がある。ウェブページに必要のないソースコードなどはディレクトリに含めたくない。どうするか。
_book/
内でgit init
を実行し、_book
の内容しか持っていないレポジトリを作ってしまえばよい。そうするとソースコードは含まれなくなる。そこからおもむろにgh-pages
ブランチを作り、元レポジトリのgh-pages
ブランチに全てを無視してpushすればよい。
# 生成されたHTMLが入っているディレクトリに移動 $ cd _book/ # そのディレクトリをルートとしてgit init _book$ git init # 仮のmasterに1コミット(虚無) _book$ git commit --allow-empty '[ci skip] init docs' # そこから分岐してgh-pagesを作る _book$ git checkout -b gh-pages # そこに_book以下全てを入れる _book$ git add . # _book以下全てをルートに持っている状態にしてgh-pagesにコミット _book$ git commit -am "[ci skip] update docs" # USER/REPOのgh-pagesに無理やりpush _book$ git push --force git@github.com:USER/REPO.git gh-pages
力技だが、これでなんとかなる。
だが結構アレなことをするし、いちいちこれを手元でやりたくない。そもそもgit add .
とかして、ローカルにある変なファイル(秘密鍵とか中学二年生の頃に書いた日記のtxtファイルとか)を含めてしまったらどうするんだ(心配性)。全世界に公開されるんだぞ。いや絶対そんなもん自分のレポジトリ下にコピーして来ないが、CIサービスでやればそもそも毎回まっさらな仮想環境が構築されるので絶対に大丈夫だという安心感がある。
というわけで後は、これをCircleCIで自動でやる。
CircleCIからgh-pagesにpush
というわけで最低限必要なものを示す。
version: 2.1 executors: default: docker: - image: circleci/node:8.11.4 jobs: deploy: executor: name: default steps: - add_ssh_keys: fingerprints: - "<fingerprint of your ssh-key for deployment>" - checkout - run: name: install dependencies command: | npm install gitbook-cli git config --global user.name "Your Name" git config --global user.email "Your Email Address" ./node_modules/gitbook-cli/bin/gitbook.js install ./node_modules/gitbook-cli/bin/gitbook.js build cd _book/ git init git commit --allow-empty -m '[ci skip] update docs' git checkout -b gh-pages git add . git commit -am '[ci skip] update docs' git push --force git@github.com:USER/REPO.git gh-pages workflows: setup_and_deploy: jobs: - deploy: name: update docs filters: branches: only: master
どこで何をしているかある程度言わないと不親切だが、私は何もわからない。俺達は雰囲気でCIサービスを使っている。
まあ、なんかCircleCI(2.1)はexecutor
として何かの言語のdocker
イメージを使うらしく、これを先に設定しておくことで後々似たような設定を何度も書かなくて済むとのことらしい。npmを使いたいのでnode
を指定する。
続いて、jobs
というのとworkflows
というのがあり、workflows
ではjobs
に登録されているものの依存関係やどういう順序で流すかなどを指定できるらしい。つまり、テストして、それが完了していたらそこで作ったバイナリをサーバーに置くとか、そういうことができる。まあ今回は使わないんですけど。
なので今回はworkflowにはdeploy
しか置いていない。で、deploy
というjob
をjobs
の中に入れる。まず、そこで使うexecutor
を指定。これはexecutors
で指定した名前(今回はdefault
)で指定する。で、steps
のところに実際何をしていくかを書いていくようだ。
まず、add_ssh_keys
でfingerprints
を設定する必要がある。というのも、CircleCIのデフォルトのdeploy keyはRead onlyなので、gh-pages
にgit push --force
などとてもできないのだ。なのでこちらで新しくそのためだけのssh鍵を作り、登録してやる必要がある。
GitHubのレポジトリの設定から「Deploy keys」みたいなとこに飛び、「Add key」で鍵の公開鍵を書く。ここで小さなチェックボックスがあり、チェックすると書き込み権限を与えられるようになっている。厳重だ。忘れかねないので注意だ。
今度はCircleCIの「jobs」から目的のレポジトリのjobに飛び、歯車アイコンをクリックして同様にSSH鍵を登録する。CircleCIがこの鍵を使ってGitHubにpushするので、秘密鍵をコピペする必要がある。なので面倒だからと自分が普段使っている鍵を流用しようとしないように。
で、何故かこれだけだとCircleCIは足してあげたSSH鍵を使おうとしない。なので、明示的にadd_ssh_keys
で足した鍵のfingerprint
を指定する必要がある。忘れたら or 確認したかったらGitHubなりCircleCIで登録されてる鍵のfingerprintを見ればよい。
それをしておいたら、checkout
によってレポジトリのコードをcheckoutしてきて、それから実行するコマンドを羅列する。command:
のところに書くと良い。基本的に上の感じで大丈夫だが、npm
のためにpackage.json
を書いたりgh-pages
なるパッケージをnpm
で入れたりするとこの辺の操作が短くなるらしい。初心者なのでそれらが何をしているか知らずなんとなく気持ち悪いので全部手で書いた。
上手くいったらGitHub pagesにGitBookで生成した内容が表示される。確認した後、レポジトリのURL欄にでも貼ると良い。
ちなみにこれを実行するとgh-pages
ブランチが突然現れた虚無のmaster
からにゅっと生えたブランチということになり、GitHubのNetworkで見ると不連続になっている。ちょっとおもしろい。
ちなみに中学の頃の私は日記を書けるほどマメではなかったので中2の頃の日記のtxtファイルというものはない。