drone.ioを使ってgithub-pagesの更新情報をtwitterに自動投稿する

2013-09-17  /  CI/CDGitHub自動化

github pages に新規投稿をプッシュした際、自動的にTwitterに更新情報を投稿できるようにしてみた。

最新記事があるか判別する

  1. gitの履歴から追加・更新されたものを取得する。
  2. published:true か判断する

という処理にした。
記事のpublishedのチェックが必要かどうかは、運用の仕方による。

jekyllの標準では

として使用される前提のようなので、それに従っている場合は必要ないと思う。
ただ、自分の場合は、_drafts を使ってない。_posts に追加 = 投稿&公開 とは限らないので、チェックを入れている。

コードは以下のような感じ

{% highlight ruby %}
def shared_target_post
git_am_files = git -c core.quotepath=false diff-tree --no-commit-id --name-only --diff-filter=AM -r HEAD _posts.split(/\n/)

git_am_files.each do |file|
post = get_post(file)
if post.published?
return post
end
end

nil
end
{% endhighlight %}

get_postでファイル名からJekyll::Postを取得できるようにしているので、投稿のステータスは簡単に取得できる。

git で追加・更新されたファイルを取得する方法については、前に書いた。
Gitで直前のコミットで追加されたファイルを確認する

これ今気づいたけど、公開済みのモノを修正したファイルも対象になってしまうので、もうちょっと修正が必要っぽい。更新の場合は前回と比較して、publishedが変更されたかどうかを判断しないとマズい。

Twitterに投稿する

twitter というGemがあったのでそれを使用している。

以下の環境変数が設定されていれば、コード内ではtokenの設定がいらない。

TWITTER_CONSUMER_KEY
TWITTER_CONSUMER_SECRET
TWITTER_OAUTH_TOKEN
TWITTER_OAUTH_TOKEN_SECRET

token はさすがにハードコードできないのと、drone.ioとの連携では環境変数を使いたいので、ちょうど良い。

tokenが設定できていれば投稿は簡単にできる。1行だけ。

{% highlight ruby %}
Twitter.update message
{% endhighlight %}

rake タスクを作っておく

ここまでの内容をrake から呼び出しできるようにしておく。

{% highlight ruby %}
require ‘cgi’
require ’twitter'

def get_site
options = Jekyll.configuration({:safe => true})
site = Jekyll::Site.new(options)
end

def get_post(file)
site = get_site
post = Jekyll::Post.new(site, site.source, “”, File.basename(file))
end

def shared_target_post
git_am_files = git diff-tree --no-commit-id --name-only --diff-filter=AM -r HEAD _posts.split(/\n/)

git_am_files.each do |file|
post = get_post(file)
if post.published?
return post
end
end

nil
end

namespace :share do

desc ‘Check shared post’
task :check do
post = shared_target_post
if post.nil?
puts “no files updated”
next
end

puts post.name

end

desc ‘Share new post to Twitter’
task :twitter do

post = shared_target_post
if post.nil?
  puts "no files updated"
  next
end

title = post.title
url = "http://kawaken.github.io#{post.url}"

message = %Q(書きました "#{title}" #{url})
Twitter.update message

end
end
{% endhighlight %}

rake share:check

で、更新があるかチェックできるようにした。

rake share:twitter

で投稿できる。

日本語を使ってるせいでURLがすごく長くなるんだけど、その辺はTwitter側で良い感じにやってくれてるらしい。

github pages と drone.io の連携

drone.io からは github pages のリポジトリを対象としたプロジェクトを作って、github からはwebhookでdrone.ioのプロジェクトを起動するように設定しておく。

この辺は前に書いた。drone.ioでjekyllのビルドテストを実行する

drone.io の設定

↑で書いたように、Twitterに投稿するために環境変数が必要なので、プロジェクトの設定画面で、Twitter用の環境変数を設定する。Environment Variables って箇所に設定する。

ビルドスクリプトも修正して、rakeタスクを呼び出すようにしておく。

{% highlight sh %}
bundle install –binstubs
bin/jekyll build –safe –trace
rake share:twitter
{% endhighlight %}

おしまい。後は記事をプッシュしたらOK。

その他

###ページの反映
github pages はリアルタイムで更新されるわけではないらしいので、Twitterに投稿したけど記事がない!ということになる可能性はある。今んとこ、タイムラグは気になったことないけど。

投稿前にページがあるかチェックした方が良いかもしれない。けどそうなると、ページが出来るまで待つのか、次回のビルドに持ち越すのかとか、考え出すとメンドクサイ。

Jekyll::Post

最初は、sedとか呼び出してたけど、drone.ioの環境だと上手く動作しなくなったので、悪戦苦闘しながら何とか取得ができるようになった。ここが一番大変だった。

git と日本語ファイル名

git でファイル名を取得する際に、"-c core.quotepath=false" を入れないと日本語で取得できない。自分の環境では~/.gitconfigとかで設定しているが、drone.io ではその辺りはデフォルト設定になるっぽいので、注意が必要。

この辺の設定がわかんなくて、drone.ioの環境変数とかgit config取得したくて、色々と試してたら、drone.ioでbuildが出来なくなった…。のでサポートにメールしたらしばらくしてビルド出来るようになった。

twitter gem

9月12日頃にドキュメントが更新されていたらしく、tokenを指定するところの環境変数が変わっていた。なので、改めて試してみると全然動かなかった…。

4.8.1

TWITTER_OAUTH_TOKEN
TWITTER_OAUTH_TOKEN_SECRET

5.0.0rc1

TWITTER_ACCESS_TOKEN
TWITTER_ACCESS_TOKEN_SECRET

通常bundleでインストールされるのは4.8.1の方なので、環境変数にはOAUTHの方を使うようにしておかないと上手く動かない。