humangas's blog

自分用のメモなので雑です。

Travis CI で、GitHubへpushしたらドキュメントを自動で作り、さらに結果をSlackへ通知する

ググれば色々でてくるが、手順が多く、多分細かい所を忘れるので未来の自分用に手順などをメモしておく。

やりたいこと

最終的にやりたいことは、"GitHubのあるリポジトリ用のドキュメントページを公開したい、んで、そのページは自動で生成したい。" になる。

出来たものがコレ(中身は随時更新される): https://humangas.github.io/dotfiles/

(これは、自分のmacOSを全自動でセットアップするオレオレプロジェクト:humagas/dotfiles のドキュメントサイト。前は同じようなことを Ansible で頑張ってやってたけど、何度も走らせるので、その遅さにうんざりしたのと、途中でPlaybook書くのが面倒くさくなってきて止めた(サーバー構築する時は Ansible 使うけど)。結局、初めから入ってる bash でやるのが一番手軽かつココはこうしたいなどの自分要望がすぐに反映できて応用が効かせられてやりやすかったので作り直した(随時更新中)。ちなみに、Ansible でやってた版はコレ: humangas/mac-setup だが、今は部品しか動かない。参考用として残している)

ドキュメントを公開したい

"GitHubのあるリポジトリ用のドキュメントページを公開したい" だけならすぐ出来る。GitHub Pages を使う。

  • master: /docs 配下に静的ファイル(HTML, CSS, JS など)を格納してリポジトリにpushしておく
  • 対象のリポジトリ > Settings > Options > GitHub Pages
  • Source: master branch /docs folder を選択して Save
    • ただし、/docs がすでに無いとエラー出る(たしか)

以前は、リポジトリ単位のドキュメントを公開する時は、gh-pages という別のbranch を作ってそこで公開するという方法しかなかったが、今は上記が出来るようになった(参考:gh-pages でやってた時の感じ:https://github.com/humangas/mkdocsex/tree/gh-pages)。その他ドキュメント公開する方法として、手軽に GitHub/Wiki を使うという手もあるし、Read the Docs や、GitBook など、外部のサービスと連携するという手もある。

ページは自動で生成したい

つまり、/docs ディレクトリ配下の静的ファイル(HTML, CSS, JS など)を自動生成できればいいということ。

で、今回手順を残したいのはコレ。方法は色々あると思うが、Travis CI にやってもらうことにした。

まず、やりたいこと整理:

  1. GitHub へ push したらそれをトリガーにドキュメントを生成したい
  2. そのドキュメントを同じリポジトリ/docs ディレクトリへ Pushしたい
  3. その結果を Slack に通知したい

これらを勝手にやってほしい訳だ。ということで、おなじみ Travis CI 登場。

(この方法を使う前は、ローカルでコミットしたら、.git/hooks/post-commit を走らせてドキュメントを自動生成させていたが、更新を頻繁にかけているリポジトリなので、コミット毎に走られてるとウザくて方式移行した。ライトにやるなら、それで良いと思うし、今後もどっかで使うかもしれないので、忘れないようにその方法も末尾に載せておく(オマケ2: .git/hooks/post-commit でドキュメント自動生成))

よし、Travis CI にぜんぶやってもらおう

ということで、やって頂く。やりたいことは、全て .travis.yml に書けばいい。それをリポジトリ直下に配置する。

かなり色んなことが出来る。細かい話はググったほうが早いが、今回やりたかったやつの説明を記載しておく(本当はもうちょい追加でやってるが、タイトルに即した処理だけ抜粋している)。

language: python
python:
  - 3.6
install:
  - pip install -r requirements.txt
script:
  - make docs
after_success:
  - openssl aes-256-cbc -K $encrypted_xxx_key -iv $encrypted_xxx_iv -in travis.enc -out ~/.ssh/id_rsa -d
  - chmod 600 ~/.ssh/id_rsa
  - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
  - git config --global user.name "humangas"
  - git config --global user.email "humangas.net@gmail.com"
  - git remote set-url origin git@github.com:humangas/dotfiles.git
  - git checkout master
  - git add docs
  - git commit -m "Updated docs by Travis CI (BUILD $TRAVIS_BUILD_NUMBER:$TRAVIS_BUILD_ID) [skip ci]"
  - git push origin master
notifications:
  slack:
    secure: xxx...

source: https://github.com/humangas/dotfiles/blob/master/.travis.yml

Travis 氏 にお願いしていることは大雑把に以下のお仕事:

Python 3.6 で、このリポジトリに置いてある requirements.txt のモジュールをインストールしてください。

その後、 make docs してください。で、うまく行ったら以下もお願いします。

  • master に push するための gitの設定をお願いします
  • このリポジトリの master に checkout してください
  • make docs で 作成した docs に更新あればコミットしてください
  • このリポジトリの master に push しといてください。

結果のお知らせは、Slack にお願いします。

次項から前述のやりたきことを一つずつ説明していく。

と、その前に、Travis CI と自分のGitHub アカウント が連携できてないと当然動かないので、まずその辺の環境設定をする。

Travis CI と GitHub リポジトリ を連携ONにする

  1. Sign up は、Travis CI サイトにて、GitHub アカウントでやる
  2. ユーザー名 > Accounts で 自分のリポジトリ一覧が出て来るので、対象のリポジトリとの連携ONにする

これで、.travis.yml を push すれば、それに書いた通り動いてくれる。

GitHubへpushしたらそれをトリガーにドキュメントを生成したい

前述 .travis.yml のこの部分

language: python
python:
  - 3.6
install:
  - pip install -r requirements.txt
script:
  - make docs

...

ドキュメント生成は、最終的に HTML が出来ればいいだけなので何でやっても構わない。

今回はPython製静的サイトジェネレーターの MkDocs(テーマは mkdocs-material)を選択した。選択理由は、MkDocs はシンプルなので好きなのと、このテーマだとデフォルトで日本語検索に対応しているため(ちょいとした設定は必要)。ここではMkDocs の話しかないので、記事タイトルとは関係ない。

pip install -r requiremts.txt のところは今のところpip install mkdocs-material しかないので、それを直接記載してもいいが、後の拡張性を考慮してこのスタイルにしている。このファイルはリポジトリ直下に配置している。mkdocs-material>=2.0.3 としているのは、日本語対応したバージョン以降をインストールしたいから(See aslo: mkdocs-material-2.0.3)。

make docs のところは自作のMakeコマンド。MkDocs でドキュメント生成するだけならmkdocs build コマンドだけで良いが、色んなディレクトリに配置してあるREADME.md を持ってきてリネームしたり、INDEXページを自動生成するなど色々やっているので色々やるドキュメント生成自作スクリプトをコールしている。で、こういう自作系コマンド群は Makefile にまとめている(というのが最近の自分スタイルのため)。

docs:
    @bash scripts/docs.sh
    
...

ドキュメント生成スクリプト(scripts/docs.sh): https://github.com/humangas/dotfiles/blob/master/scripts/docs.sh

また、最終的に docs というディレクトリ配下に静的ファイルを生成したいので、mkdocs.yml を以下のようにして出力先を変更している。デフォルトは、docs: *.md ファイルの置き場所、site: mkdocs build後に静的ファイルの出力先のため。

docs_dir: '_docs'
site_dir: 'docs'

...

mkdocs.yml: https://github.com/humangas/dotfiles/blob/master/mkdocs.yml

まとめると、以下のことをやっている。

  1. mkdocs-material インストール(依存しているMkDocs も同時にインストールされる)
  2. 自作ドキュメント生成スクリプトをコールし、_docs 配下に *.md ファイル群を生成
  3. mkdocs build して静的ファイルをdocs 配下に生成

そのドキュメントを同じリポジトリ/docs ディレクトリへ Pushしたい

前述 .travis.yml のこの部分

after_success:
  - openssl aes-256-cbc -K $encrypted_xxx_key -iv $encrypted_xxx_iv -in travis.enc -out ~/.ssh/id_rsa -d
  - chmod 600 ~/.ssh/id_rsa
  - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
  - git config --global user.name "humangas"
  - git config --global user.email "humangas.net@gmail.com"
  - git remote set-url origin git@github.com:humangas/dotfiles.git
  - git checkout master
  - git add docs
  - git commit -m "Updated docs by Travis CI (BUILD $TRAVIS_BUILD_NUMBER:$TRAVIS_BUILD_ID) [skip ci]"
  - git push origin master
  
...

after_success は、script ステージが成功した時に動く処理を書くステージ。ちなみに、script は必須ステージなので、何か書く必要がある。でないとそもそもエラーになるので、after_success も動かない。また、after_success 自体の内容は成功しても失敗してもTravis CI の通知結果に影響しない。script ステージが成功していれば、Travis CI の結果はグリーンになる。そのため、after_success の全ての処理がうまくいったか確認したければログを確認するしかない。

この定義は長いので、処理ごとに見ていく。

SSH 設定

この部分。git push するためのSSH設定をしている。

  - openssl aes-256-cbc -K $encrypted_xxx_key -iv $encrypted_xxx_iv -in travis.enc -out ~/.ssh/id_rsa -d
  - chmod 600 ~/.ssh/id_rsa
  - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config

...

openssl aes-256-cbc -K $encrypted_xxx_key -iv $encrypted_xxx_iv -in travis.enc -out ~/.ssh/id_rsa -d

で、同じリポジトリにある travis.enc という鍵ファイルを ssh秘密鍵~/.ssh/id_rsa)に複合している。

SSHの仕様的に秘密鍵パーミッションは600(400でもいい)でないとダメなので、chmod 600 ~/.ssh/id_rsa で変更する。

接続する時に、未接続ホストの場合、本当にココに接続するの? というプロンプトが出て止まってしまうため、その問いかけを無視するために、~/.ssh/config に github.com への接続の場合はホスト接続チェックを無視するように設定追記する。

echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/configは、以下になる。

Host github.com
    StrictHostKeyChecking no

travis.enc は、ローカルでtravis コマンドで予め作成し、リポジトリにPushしておく。以下のように作る。

まず、インストールとログイン。--auto とやると、travis が keychain やら何やらログインできそうな情報を勝手に探してきてログインしてくれるというもの(らしい)。 当然、前述のGitHubとの連携は事前に必要。

$ gem install travis
$ travis login --auto
Successfully logged in as humangas!

で、普通に秘密鍵を作成する。鍵の名前はなんでも良い。ただ、自分は作り直しの目安になるので作成日を付けることが多い。あと、拡張子を.pem にしている。これは探しやすくしたり、.gitignore に定義しやすいため(後述)。なので拡張子はなんでも良いけど、AWSで鍵作ったら、*.pem というファイルが落っこちてくるので合わせただけ。

その秘密鍵travis.enc にした後は使わないので必要ないが、再生成などする場合に使うので一応どこかに保管しておく。自分は他の鍵同様、~/ssh 配下で管理している。でもどこでもいいし、最悪無くしたらもう一回作り直せばいいだけなので、正直どうでもいい。

ただし、Push してしまうのだけは絶対ダメ!! 暗号化の意味なしなのと、後述するリポジトリ設定をしてしまった後はそのリポジトリのPushを鍵盗んだ人には出来るようになってしまうため。とはいえ、この為だけに鍵を作るのであれば、最悪このリポジトリだけの被害で済む。なので、リスクを最小化するためにも絶対に既存の使い回しは避け、新規作成すること。

$ ssh-keygen -t rsa -f travis_2017-12-14.pem
$ mv travis_2017-12-13.pem* ~/.ssh

※ 参考: 暗号強度は上げても良いと思う(確認は、$ ssh-keygen -l -f xxx.pub で)。 See also: お前らのSSH Keysの作り方は間違っている

ということで、誤ってPushしない設定だけは、.gitignore に直ぐに入れておく。

自分の場合は以下を含むオレオレ.gitignore をどんなリポジトリでも初めに作るようにしている。

ちなみに、.envrcdirenv の設定ファイルだが、クレデンシャル情報を記載する場合があるため追加している。

# Key files
#---------------------------
*.pem
*.pem.pub
id_rsa
id_rsa.pub
.envrc

...

※ 参考: .gitignore は、gibo を使えば簡単に作成できる。上記のオレオレ.gitignore もgiboで作成できるように設定している(.gitignore-boilerplates/humangas.gitignore)。

作成したSSH秘密鍵Travis CI 用に暗号化した秘密鍵に変換する。

$ travis encrypt-file travis_2017-12-14.pem travis.enc
Detected repository as humangas/dotfiles, is this correct? |yes| yes
encrypting travis_2017-12-14.pem for humangas/dotfiles
storing result as travis.enc
storing secure env variables for decryption

Please add the following to your build script (before_install stage in your .travis.yml, for instance):

    openssl aes-256-cbc -K $encrypted_xxx_key -iv $encrypted_xxx_iv -in travis.enc -out travis_2017-12-14.pem -d

Pro Tip: You can add it automatically by running with --add.

Make sure to add travis.enc to the git repository.
Make sure not to add travis_2017-12-14.pem to the git repository.
Commit all changes to your .travis.yml.

before_install ステージに書けと書いてあるが、別にインストール時に使う訳ではないのでafter_success の処理前に書いている。この中のコレが秘密鍵復号コマンド。実際に使うときは鍵の指定を省略できるように、-out 部を ~/.ssh/id_rsa に書き換えている。

openssl aes-256-cbc -K $encrypted_xxx_key -iv $encrypted_xxx_iv -in travis.enc -out travis_2017-12-14.pem -d

ココで気になることがあると思う。

GitHub 上に置いている travis.enc ファイルと .travis.yml に記載している上記のコマンドで秘密鍵ってすぐに複合できてしまうのでは?

もちろん、そんな事はない。鍵を作成したリポジトリTravis CI 上で実行されないと複合することは出来ない。実際にローカルとTravis CI上の別のリポジトリで試してみたが、たしかに複合できず、空のid_rsa ファイルが出来るだけだった。

関連する質問をIssueでも見つけた: decrypting encrypted file #437 これに中の人が以下のように回答している。

BanzaiMan commented on Oct 11, 2016 You cannot decrypt the file outside of Travis CI. (We store the private key that encrypted the file in our database, and it is not accessible from the outside.)

Git Push 設定

この部分。git push するためのGit設定をしている。

  - git config --global user.name "humangas"
  - git config --global user.email "humangas.net@gmail.com"
  - git remote set-url origin git@github.com:humangas/dotfiles.git

...

git clone するだけなら、特に設定は必要ないが、push する場合は最低限 user.name と user.emal が必要になるので設定している。また、SSH で push するために remote url を変更している。Travis CI が走る時は https で clone されるため。

Git commit & push 処理

この部分。script ステージで作成済みの docs を commit & push している。

  - git checkout master
  - git add docs
  - git commit -m "Updated docs by Travis CI (BUILD $TRAVIS_BUILD_NUMBER:$TRAVIS_BUILD_ID) [skip ci]"
  - git push origin master
  
...

git checkout master は、Travis CI が走る時に以下のようにコミットにcheckoutしているため、再度 master に戻しているということ。

$ git clone --depth=50 --branch=master https://github.com/humangas/dotfiles.git humangas/dotfiles
Cloning into 'humangas/dotfiles'...
$ cd humangas/dotfiles
$ git checkout -qf b08536d8f79963aa72318cec18d39edb3bd02808

git add docs は、script ステージで作成済みの docs ディレクトリ のみ Add しているということ。

git commit -m "Updated docs by Travis CI (BUILD $TRAVIS_BUILD_NUMBER:$TRAVIS_BUILD_ID) [skip ci]"Travis CI が Update したという旨のメッセージを入れているが、$TRAVS_ で始まる環境変数に色々と値が入っているのでコレを使っている。他の環境変数を知りたいなら、travis.yml に env | grep TRAVIS_ と書いて実行し、ログを実際に見てみるといい。ちなみに、この設定で出力されるコミットメッセージは、"Updated docs by Travis CI (BUILD 15:317245285)" という感じになる。

最後に [skip ci] と書いてあるのは、このコミットは無視(スキップ)してくれという特殊な命令を Travis CI に出している。これを書かないと、docs に更新があった場合に、その push で再度 Travis CI が反応してしまい、余計な動きが1回走ってしまうため。コミットメッセージ中のどこかにあれば良いらしい。詳細はマニュアル参照:Travis CI/Skipping a build。 ちなみに、この記法は他の有名CIでも実装されているらしい。

ちなみに、以前は git clcoe し直して再度 make docs していた。

language: python
python:
  - 3.6
install:
  - pip install -r requirements.txt
script:
  - make dotfiles
  - make docs
after_success:
  - openssl aes-256-cbc -K $encrypted_xxx_key -iv $encrypted_xxx_iv -in travis.enc -out ~/.ssh/id_rsa -d
  - chmod 600 ~/.ssh/id_rsa
  - echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
  - git config --global user.name "humangas"
  - git config --global user.email "humangas.net@gmail.com"
  - git clone git@github.com:humangas/dotfiles.git _dotfiles
  - cd _dotfiles
  - make docs
  - git add -A
  - git commit -m "Updated docs by Travis CI (BUILD NUMBER:$TRAVIS_BUILD_NUMBER, ID:$TRAVIS_BUILD_ID)"
  - git push origin master
notifications:
  slack:
    secure: xxx...

source: https://github.com/humangas/dotfiles/blob/f8cb1ee6dc83073749b9eb4425e52e356e874e3e/.travis.yml

別にこの方法でも最終的にやりたいことは満たせるので何ら問題はない。ただ、もう一度同じ make docs コマンドを発行してとか、リポジトリ直下にリポジトリと同じ名称のディレクトリを配置しているために clone 時にリネームしたりなど、無駄が多いので、シンプルに整理して今の形になった。ちなみに、コッチの場合はgit clone git@github.com:humangas/dotfiles.git _dotfiles しているので、remote url の値はすでにgit@github.com:humangas/dotfiles.git になっている。そのため、git remote set-url origin git@github.com:humangas/dotfiles.git をする必要はない。

GitHubリポジトリに Deploy Key を登録

前述までで、Travis 側の Git Push 設定は完了している。後は、そのPush を受け付けるための公開鍵設定をリポジトリ側に設定する。

  1. 対象リポジトリ > Settings > Deploy keys
  2. Add deploy key 押下
  3. Title: travisci_2017-12-14(任意の名前) 、Key: travis_2017-12-14.pem.pub の値(前述で作成した秘密鍵に対する公開鍵)を入力 、Allow write access にチェック し、 Add key 押下

その結果を Slack に通知したい

前述までで基本的にやりたいことの設定は完了しているが、最後に処理結果をSlackに通知したい。

前述 .travis.yml のこの部分

notifications:
  slack:
    secure: xxx...

...

secure のキーを作るだけ。キーは以下で作成できる。

  1. Slack > 歯車アイコン > Add an app
  2. Travis CI を検索して選択
  3. Add Configuration 押下
  4. Post to Channel で チャンネル選択し、Add Travis CI Integration 押下
  5. Encrypting your credentials の下段コマンドをコピー

下段のほうだと、GitHubアカウント名/リポジトリ まで限定できる。そのため、このコマンドで生成されるキーを別のアカウントやリポジトリで使用しても動かない。

travis encrypt "humangas:xxx" --add notifications.slack -r humangas/dotfiles

このコマンドを実行すると、自動で travis.yml に追記される( —add notifications.slack とあるため)。

これで全て完了したので、travis.yml をpushすれば、Travis CI が動くはず。

オマケ1: travis バッジをリポジトリに貼る

オマケといいつつ自分には大事。昔は誰かのリポジトリを見て、コレどうやってつけるんだろう、付けたいななどと思っていた。Travis に興味をもったスタートも実はこのバッジだったし。

Travis CI のテスト画面で、右上にバッジが表示されているので、それをクリックする。Markdown を選択すると以下のようにMarkdown 記述が出て来るので、それをREADMEなどにそのまま転記すればいい。そうすれば最新のテスト結果に応じて自動で結果が反映される。

[![Build Status](https://travis-ci.org/humangas/dotfiles.svg?branch=master)](https://travis-ci.org/humangas/dotfiles)

ちなみに、README には他にも LICENCE や OS 種別のバッジを貼っているが、これは https://shields.io/ というサイトで作成している。画面下部にある "Your Badge" から好きなように作成することが出来る。

See also: https://github.com/humangas/dotfiles/blob/master/README.md

オマケ2: .git/hooks/post-commit でドキュメント自動生成

ここに書いてある Travis CI にドキュメント自動生成をやってもらう前は、githooks を使いコミットした後にドキュメント自動生成スクリプトを走らせてやっていた。この方法であればローカルで手軽に出来るので気軽にやるにはこれでも良いと思う。

githooks は、コミット時以外にも色んなタイミングで任意の処理を走らせることが出来る。ググれば出るので、詳細は書かないが、そん時にやっていた方法だけメモしておく。

githooks/post-commit スクリプト: https://github.com/humangas/dotfiles/blob/20171214/githooks/post-commit

これを Make でインストール(実行権限を付けるところは忘れないように)。

install:
    ...
    @cp -f githooks/post-commit .git/hooks/
    @chmod +x .git/hooks/post-commit

source: https://github.com/humangas/dotfiles/blob/c07baab186efbfa76ffadc82f2b08f7f33f6b7a4/Makefile#L30

こんな書く気は無かったが、忘れないように一個ずつ気になったところの説明を書いてたらすごい長くなってしまった。

広告を非表示にする

githubのリポジトリをコマンドで作成する(hubコマンドで)

タイトル通り。hub (https://github.com/github/hub) コマンドを使う。

だいぶ前から存在は知っていたけど、特に必要なかったので使わなかった。リポジトリもそんな頻繁に作成しないので、素直にWebからやっていた。ただ、テストリポジトリとかを頻繁に作る必要があってそれも面倒くさくなったので、使ってみたメモ(結論:便利なのでちょいちょい使うと思う)。

インストール (macOS)

$ brew install hub

リポジトリ作る

$ mkdir test; cd $_
$ git init
$ hub create
github.com username: humangas
github.com password for humangas (never stored):
two-factor authentication code: ******
Updating origin
created repository: humangas/test

これだけで出来てる。

$ hub browse

で、ブラウザで該当のページが表示される。

最初、パスワードではなくてssh鍵を登録できるんだろうと思い、色々さがしたけどなかった。

普通にパスワード入れて、2段階認証してればそれを聞いてくる。つまり、Webログインの方法と同じだった。まぁ、そっか。。

あと、終わった後に、https://github.com/settings/tokens にアクセスすると access tokens が追加されているはず。

広告を非表示にする

はてなブログにSNSアイコンでプロフィールをつくる

タイトル分かりにくいけど、要はこういうこと。サイドバーをなるべくシンプルにしたかったため。

f:id:Humangas:20170909081542p:plain

やりかたの流れ

  1. SNSsvgファイルを手に入れる
  2. それをどっかのサイトに置く(Publicアクセスできる場所)
  3. サイドバーでHTMLを編集して終わり

SNSsvgファイルを手に入れる

適当に画像検索なりすると出て来る。公式に配られている場合もある。

それをどっかのサイトに置く

Cloudupが便利かも

使い方は超簡単で、アカウント作成 -> D&DでファイルをUPするだけ

画像以外のファイルも何でも良い。https://cloudup.com の動画を見てみると利用イメージがよく分かる。

UPしたファイルを選択し右上の MORE > DIRECT URL をクリックすると 直リンクURLが得られるので、それを使う

サイドバーでHTMLを編集して終わり

  1. 自分のはてなブログの管理画面で、デザイン > カスタマイズ を選択
  2. サイドバー > モジュール追加 してHTMLを選択
  3. タイトルは未入力にして以下を貼って終わり
<p style="margin:0px 0px; text-align:left">

<a href="https://github.com/humangas" target="_blank"><img  src="https://cldup.com/XXX.svg" width="35" height="35" alt="GitHub"></a>

<span style="margin-right: 5px;"></span>

<a href="https://gist.github.com/humangas" target="_blank"><img  src="https://cldup.com/XXX.svg" width="35" height="35" alt="Gist"></a>

<span style="margin-right: 5px;"></span>

<a href="https://twitter.com/humangas_" target="_blank"><img  src="https://cldup.com/XXX.svg" width="35" height="35" alt="Twitter"></a>

</p>

XXXX.svg のところがさっき手に入れた直リンク

見た目の修正は適当にCSSやらで調整すればいい

(※上のmarginは意味ないが後で調整するかもしれないので、そのままmargin: 0px 0px で置いてあるだけ)

広告を非表示にする

go+html,css,jsをライブリロードするのは、mattn/goemonが一番良かった

TL;DR

goで、webアプリとか作ってる時に、ファイル保存→ WEBライブリロードが出来ないと、苦痛でしょうがない。 それを解決するツールで最適だったのが、mattn/goemonだったという話(私にとっては)。使い方も超簡単。感謝。

使い方

簡単なので、以下をサッとみればわかる。

ポイントを記載しておく

Installation

$ go get github.com/mattn/goemon/cmd/goemon

五右衛門の設定ファイルを出力

$ goemon -g > goemon.yml
$ vim goemon.yml
# watch対象のパスを変えたりする

リロード対象のHTMLには以下を突っ込んでおく

<head>
    ...
    <script src="http://localhost:35730/livereload.js"></script>
    ...
</head>

See also: https://github.com/mattn/goemon#livereload

このポート番号は、goemon.ymlの以下と一致させておく

livereload: :35730

goemon 起動

$ goemon go run main.go

あとは、ひたすら開発しとけばいい。あぁ、楽だ。

オマケ

go専用ツールというわけではないので、markdownファイルだけということもできるもよう

$ goemon -g md > goemon.yml
$ goemon --

その場合は、mdファイルだけ監視しておいて、保存したら、任意のコマンドを流してHTMLにする、で、livereload: とかしとけばいい。

コレ見ればわかる。

jsをmin化したいなら、↓を入れといて、js保存時の処理で流せばいい。

$ npm install -g minifyjs

試行錯誤メモ

goemonに辿り着く前に、色々やってみたりしたので、そんときのメモ

まず、このライブリロードをやりたければ、選択肢は無数にあると思う。以下など。

  1. fswatchをmakeとか自作スリクプと組み合わせる
  2. go製の他のライブリロード系ツールをつかう
  3. gulpで、goもbuildしてしまう

fswatch + make

色々試したりしてみてみたが、ドンピシャがなくて、goemonに出会う前までのしばらくはこれでやっていた。
要は、こういう感じにする。

GO_FILES = $(wildcard *.go)
serve:
    @make restart
    @fswatch -o . | xargs -n1 -I{}  make restart || make kill

※ fswatchでなくても、ファイル監視できるツールならなんでもいいけど。

参考にしたサイト:

あとは、自作スクリプトなりを組み合わせて、別にこれでもそれなりには出来ていたけど、以下ができてなくてめんどくさいなと思ってた。
本質的でないところに時間とられたくもないし。。

気に入ってないところ

  • いちいち、セキュリティ警告がでる:そのアプリの証明書をつくればいけるがめんどくさい
  • ビルドできるのはいいけど、画面描画は手動でやってる。browser-sync的にやりたい。

go製の他のライブリロード

go自体のファイルを監視、ビルドするツールは色々あり、それはそれで使えるツール達だったが、今回の静的ファイル(HTMLとか)との組み合わせだとサッとはできなかった。

  • gin(WebフレームワークのGinとは違うやつ)
  • fresh
  • ReRun

See also: http://www.spidersoft.com.au/2014/live-code-reload-in-golang/

gulpでやる

フロント系リソース(HTML, CSS, JS)の開発だけなら、別にこれでいいと思う。
これは、gulpるで書いた。

ここに、goファイルを保存したらリロードも入れたいわけだ。

プラグインは一杯あるし、var exec = require('child_process').exec; とか使えば、OSコマンドは叩けるのでなんでもできそうだし。

でも、いちいちgulpfileを組むのがめんどくさいし、goの開発したいのに、gulpでつうのも何か気持ち悪い。なので、途中でやめた。

じゃあ、go製のタスクランナーは?

godo という go版gulp的なものがあった。 goで、gulpfileみたいなやつを書く感じ。
正直なんでもできそうな感じはしたけど、それだとmake+fswatchでもいい気がするし、いちいち覚えるまでモチベーションも上がらなかったのでやめた。

まとめ

結局、goemonでサクッとできた。とても気持ちいい。

ところで、goでなんか調べていると、このmattnさんの記事がすごく出て来て勝手にお世話になっている。 で、人追いしてたら、memoとりツールも作られていて、それが自分が欲しかった要件を満たしていて、すごく感激した。

mattn/memo

カスタムも出来るようになっているし、zsh completionと組み合わせると便利すぎた。
これから使っていくと思うけど、自分のMUSTツールになりそう。

広告を非表示にする

gulpる

gulpをさっと試す。HTMLいじったら自動でリロードしてもらうところでま記載。

なぜ、gulpりたいのか?

サクッと、WebUIを持つツール等を作りたい時がある。 そんな時に、サクサクサクッとやりたいわけだ。 フロントには慣れてないが、そういう時によく聞くgulpを使おうとなった。

先に書いておくと、↓がドンピシャだった。感謝!

結論:思いのほか簡単で、すぐにやりたいことが出来、気持ちよかった。

セットアップ

node.jsを入れて、gulpを入れる。 gulpは、nodeのパッケージなので。

$ brew install node
$ npm install gulp -g

-g は、グローバルにインストールという意味。
gulpとか、どこでも使うコマンドは、グローバルに入れておくのが楽。

package.json をつくる。 このファイルには、nodeのパッケージとか記載する。 これがあれば、別環境とかで、npm install とするだけで、環境が復元できる。

pythonで言う、requiretemnts.txtみたいなもんと思えばいいだろう。

$ npm init

勢い系(全部Enter)でOK

ブラウザリロードするために必要なパッケージと、gulp本体を突っ込む

$ npm install gulp --save-dev
$ npm install browser-sync --save-dev 

--save-dev をつけてインスコすることで、さっきのpackage.jsonに記載される。
pip freeze > requiretemnts.txt みたいなことだと思えばいいだろう。

いよいよgulpファイルを書く

gulpは、タスクランナー。gulpfile.jsというファイル名で、自動でやらせたいこととか書いて、gulpコマンドを打てば、それで終わり。
make(= gulp) と、Makefile(gulpfile.js) というざっくり理解でいいだろう。

gulpfile.js

var gulp = require('gulp');
var browserSync = require('browser-sync').create();

gulp.task('browser-sync', function() {
    browserSync.init({
        server: {
            baseDir: "src",
            index: "index.html"
        }
    });
});

gulp.task('bs-reload', function () {
    browserSync.reload();
});

gulp.task('default', ['browser-sync'], function () {
    gulp.watch("src/*.html", ['bs-reload']);
    gulp.watch("src/*.js", ['bs-reload']);
    gulp.watch("src/*.css", ['bs-reload']);
});

これは、src配下のhtml, js, css を監視しておき、ファイルが更新されたら、reloadして。と書いてある。

gulpる

$ gulp

これだけで、監視が始まり、ブラウザが自動で起動する。

あとは、src配下のhtmlなどをゴリゴリ書いては、更新をすれば、見た目をガンガン確かめながら開発を進められる。気持ちよす。

オマケ

npm install やると、node_modules というフォルダが出来て、そこにブツが入ってくる。 開発中は必要だが、コレ自体をgit管理する必要はないので、.gitignoreとかに書いとけばよいだろう。

広告を非表示にする

Material Design Lite(MDL)はさくっとWeb画面つくるのに最適(かも)

何?

サクッとWebツールを作りたい時がある。 画面は、生HTMLでもいい。 そんぐらいの要件。
とはいえ、それだとあまりにダサいので、ちょちょっと気軽に、シンプルなCSSフレームワークは無いかと見ていたところ、これがあった。

Google製である。

https://getmdl.io/

Setup

CDNでやるが楽。ローカルに何もいらない。

<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>

gulpでオートリロードと組み合わせると、開発楽なので、npmで入れるのもいいだろう。

npm install material-design-lite --save

See also: https://getmdl.io/started/index.html

マニュアルがシンプル

あとは、COMPONENTS を見て、HTMLを記載するのみ。

見れば、わかる。

まとめ

Liteというだけあって、軽いし、その分、やれる種類も少ない。
でも、重厚なもんはいらない。サッと装飾したいだけ、みたいな感じの要件のときには、かなり最適なのではと思った。

で、gulpと組み合わせると、より楽できるのである。 その辺はココに書いてある。

最近、なんでもGoで組むことが多いが、ちょいとしたWebアプリつくる際に、先に紙芝居をさっとこれでつくっておいて、あとで、go側実装して、html/templateを画面に組み合わせてアプリ化する。というフローがそれなりにスピーディーにやれるようになってきた。

参考になるサイト

もうちょい細かくは、他でググったほうが、コンポーネントの説明など書いてくれてる以下のようなサイトをざっと眺めるのが早い。お世話になりました。

広告を非表示にする

Terraformで、Digital Oceanする

何したい?

terraformで、手軽に検証サーバを作りたい。Digital Oceanが楽そうだという話

ちょいとしたサーバをテストしたい時、AWSよりもっと気軽に安く試せる環境はないかと思っていたところ「Degital Ocean」を思い出した。

最近、terraformで、vSphere, AWSなどを構築しだしたので、対応してるかなぁと調べると、ドンピシャ対応してたので、やってみることにした。

結論:使えそう。特に、Ansible開発をペペッとやりたいと思っていたので、ちょうど良いかもしれない。

Digital Oceanのアカウント作成

  1. https://www.digitalocean.com/ にアクセス
  2. サインアップしたら、以下をやっておく
  3. Paypal登録($5のプランでいいだろう)※1
  4. 二段階認証設定(少しでも安全を)※2
  5. API > Token > Generate New Token から Tokenを作成する ※3
  6. あとは、terraformでやるので特に設定なし

注釈

  • ※1: はじめに支払って$5使い切るまでストックされてる感じぽい。あと、$10のサービスもついてきた ※2017/03/02現在
  • ※2: Google Authenticator とかでいい
  • ※3: (terraformで構築する時のアカウント認証に必要)

ローカルで秘密鍵を作成する

sshで鍵認証でログインするために、つくっておく(パスフレーズなし)

$ cd ~/.ssh
$ ssh-keygen -t rsa -f digitalocean_2017-03-02.pem

セキュリティ情報を環境変数にして外出しておく

$ cat ~/.zsh.d/digitalocean.sh

export TF_VAR_digitalocean_token='***'
export TF_VAR_ssh_fingerprint=$(ssh-keygen -l -E md5 -f ~/.ssh/digitalocean_2017-03-02.pem | awk '{print $2}' | sed -e 's/^MD5://')

注釈

  • ここで設定するtokenは、先に作成したToken
  • TF_VAR_xxという環境変数にしておくと、terraformから、variable “xxx” {} と設定しているところに勝手に設定してくれる。(設定されてない場合は、実行時に聞かれる)
  • ハマりポイント!: fingerprintは、MD5にしとかないとterraform planする時に怒られた。(もしかすると、鍵を作る前に実行したから?。。今度しらべておく)
  • 鍵関係で構築に成功したり、失敗したりしたので、もしや、鍵作られる前にサーバ実行しに行ってる? と思い、後で依存関係を足した(depends_on = ["digitalocean_ssh_key.default"])。それなのか、↑のMD5なのか、今となっては前後関係がわからん。

ちなみに

↑のファイルは、zsh環境変数の一つとしてロードするが、~..zshrcの最後に↓でロードしているから。 完全にオレオレ仕様なので、適宜読み替えてください。

# Source ~/.zsh.d/*.sh
setopt nonomatch
if ls ~/.zsh.d/*.sh > /dev/null 2>&1; then
  for file in ~/.zsh.d/*.sh ; do
    [[ -r $file ]] && source "$file"
  done
fi
setopt nomatch

早速、実行

ソースは、ここにあるので、git cloneするなりして入手 - https://github.com/humangas/provision-examples/tree/master/examples/example-03/terraform

$ cd /Users/humangas/src/github.com/humangas/provision-examples/examples/example-03/terraform
$ terraform apply

SSHでログイン

applyの最後に、IPが出力されるので、それがサーバのIP

$ ssh root@サーバのIP

後片付け

検証とかテストが終わったら、以下で削除しておく(Digital Oceanは停止してても課金されるので注意)

$ terraform destroy

# 次で、yes を入力

オマケ:imageのIDが分からないんですけど?

Webで、お目当てのサーバとかを選択した時のURL欄を見れば、パラメータに表示されているので、その文字列を使えばよい。

広告を非表示にする

はてなブログでFlickerの画像をつかう(とか、Flickerでリアル名を表示しない、アップロードした画像を削除する方法)

追記:

結論、はてなの写真投稿機能で良かった(リアルタイムプレビューも効くし)。
途中まで書いたのでとりあえず、投稿しておく。


最近またはてなでブログを書き出した(主に自分用のメモ)。
(いつまで続くかは不明。またすぐ止めそうな気はするが…)

で、こんなかんじで記事を書くわけだが、画像を楽に貼り付けたいな。 と改めて思っていたところで、適当にブログのメニューバーを見てると、Flickerを使えることを発見した。

これまでは、はてなの画像投稿からやってたけど、なんか遅いので、写真だけ気軽にブチ込んでおいて、あとで振り返りやすい場所としても使えるかなとFlickerでやってみることにした。

(が、後で改めてはてなの写真を投稿を使ってみたら、そっちのほうがやっぱ手軽で良かったので、せっかくFlickerアカ作ったけど、結局使わないかもしれない)

アカウント作成

なんか米国Yahooのアカウントが必要らしく、それなりにめんどくさそうだが、実際作るのは、Sign up ボタンからウィザードに従って適当に入れれば良い。

その後、確認用のコードを登録したメルアド宛に送付するボタンを押下する。

なんかすんなり届かなかったので、2回ほど押した記憶がある。

で、メールに届いた4,5桁のコードを入力してVerify完了。

これで一応使えるようになる。

使ってみる

簡単で、見たまま

  1. 右上のアップロードできそうな雲のマークを押す
  2. 画像をD&Dするか、普通に選択していってアップロード
  3. 右上のUpload N Photoをクリック

f:id:Humangas:20170826010841p:plain

パッと見、アップロードボタンが分かりづらかった。

あとは、下図のように差し込めば良いだけで、ユーザーで自分を検索すると、Publicな画像が見えるから選択すれば良い。

f:id:Humangas:20170826010812p:plain

オマケ:アップロードした画像を削除する

これもパッと見、わかりにくい。

  1. You > Photostream > 消したい写真を選択
  2. 下図の通りEditボタンをクリック
  3. Delete クリック

f:id:Humangas:20170826011236p:plain

ちなみに、同じくEditから写真を編集する機能もついているようだ。 また、写真毎に公開範囲も変えれるみたい。

リアル名を表示しない

デフォルトだと、アカウント作成時に入力した名前が表示されてしまうので嫌

変更前:(リアル名が表示) f:id:Humangas:20170826011111p:plain

変更後:(ニックネームだけ表示) f:id:Humangas:20170826011648p:plain

  1. 一番右上の自分のアイコン(デフォルトはカメラの画像)選択
  2. Settings 選択
  3. Your profile > edit who can see what リンク選択 f:id:Humangas:20170826011700p:plain
  4. 一番つようそうな下図の権限に変更 f:id:Humangas:20170826011710p:plain
広告を非表示にする

GitBookでMyナレッジベースを作ってみる

最終型はこんな感じ

f:id:Humangas:20170826002847p:plain

コンテンツは、まだ全然ないけど、ここにひたらすら貯めていけば、それなりに使えるブツになるかも。

前に、軽く GitBookを使ってみる で、ローカルでのGitBookの使い方を書いた。

GitBookには、複数のテンプレがあるが、その中のKNOWLEDGE BASEを使うと、個人的なナレッジベースが作れそうだなと思ったんでやってみた。

やりかた

  1. GitBookでアカウント作成
  2. New > KNOWLEDGE BASE 作成
  3. Settings > 自分のGitHubリポジトリを選択(空のやつ)
  4. Syncを押下(エラーが出たら、強制的に同期つーのがあるので、GitBook側で上書き)
  5. Git Cloneして、ローカルとかで適当にいじる -> push

これだけでいい

ちなみに、KNOWLEDGE BASEは、 book.jsonに以下を書くだけでできるので、別に上記手順じゃなくてもいい

"plugins": [
    "theme-faq",
]

また、Git Cloneしなくても、オンラインエディタで直接いじるでももちろんいい。

広告を非表示にする

GitBookをローカルで使う方法メモ

なぜ GitBook ?

見た目が良さげ&epub、PDFなどにも出力できるようなので、使ってみることにした。
どっかで、ちゃんとしたドキュメントを納品しないといけないとかいう場合に使えるかもということで(Wordなんか使いたくない)。

インストール

今回はローカルで使ってみたいので、そのセットアップ手順

$ npm install gitbook-cli -g
$ gitbook --version
CLI version: 2.3.0
GitBook version: 3.2.2

–vesrionを打つと、GitBook本体もインストールされたっぽい。

calibreインストール

pdf, ebupなどに変換する場合に必要なので、インストールしておく。

$ brew install Caskroom/cask/calibre

セットアップ

$ mkdir -p ~/src/work/test-gitbook
$ cd $_
$ gitbook init
warn: no summary file in this book
info: create README.md
info: create SUMMARY.md
info: initialization is finished
$ ls -l
total 8
-rw-r--r-- 1 humangas staff 16  2 27 20:44 README.md
-rw-r--r-- 1 humangas staff 40  2 27 20:44 SUMMARY.md

なるほど、init すると、READMEとSUMMARYが出来る。 適当に、Markdownファイルを足して、SUMMARYに結びつけておけばよし。

ビルド

$ gitbook build
$ gitbook pdf
$ gitbook epub

Serve

$ gitbook serve

他のテーマを使ってみる

GitBookのサイトでCreateしようとすると、デフォルトのBOOK&MANUAL以外にも利用できる模様。 ローカルでやる時には以下のようにやれば良いみたい。

book.jsonを作成する

README.mdとかと同じ階層にbook.jsonを作成する

$ cat book.json
{
    "plugins": [ "theme-faq" ]
}

プラグインをインストールする

book.jsonを読み取ってくれて、勝手にインストールしてくれる。

$ gitbook install
info: installing 1 plugins using npm@3.9.2
info:
info: installing plugin "theme-faq"
info: install plugin "theme-faq" (*) from NPM with version 1.2.1
/Users/humangas/src/work/test-gitbook
└── gitbook-plugin-theme-faq@1.2.1

info: >> plugin "theme-faq" installed with success

あとは、gitbook serve とかで起動してやると、たしかに見た目が変わった。 同じ要領でやれば、他にも拡張できるのだろう。

日本語検索対応

昔は、日本語検索が全然だめだったみたいだが、デフォルトでも引っかかるようになっていた。 とはいえ、中途半端。。

そこで、検索してみると、プラグインがあったので、追加でインスコしてみると、精度がぐっと良くなった。使えるレベルだと思う。 上記のfaqテーマに加えて、日本語検索対応を追加してみる。

$ cat book.json
{
    "plugins": [
        "theme-faq",
        "-lunr",
        "search-languages"
    ],
    "pluginsConfig": {
        "searchLanguages": {
            "lang": "jp"
        }
    }
}

$ gitbook install

GUI

brew search gitbook したら、2つ出てきた。 どちらもインスコしてみたが、以下で良いみたい(公式ぽい)。 もう一つも公式ぽいが、View用なのかな? よくわからん。

$ brew install Caskroom/cask/gitbook-editor

使い方は、見ればわかるという感じだったのでメモなし。

広告を非表示にする