OSS コントリビューションや GitHub 上のアクティビティのまとめレポート投稿を自動化する
月ごとに、 OSS コントリビューションや GitHub 上での活動をまとめたレポートの当ブログへの投稿を自動化しました。
なかなかブログも書けないので、これから GitHub の月報を投稿していくことにしました。
[Monthly report] 2017-04 my activity this month on GitHub
目次
流れ
やっていることは単純ですが大まかな流れとしては、
- GitHub API から User event を取得して該当月のイベントから記事を作成する
- GitHub へ push
- API で Pull request を作成し、 CI がパス次第 API で Merge
- CircleCI などで上述の script を実行
- cron などで月末に定期ビルドさせる
前提として、 GitHub 上で投稿までのサイクルが回るようになっています。
React と Redux なブログ運用をソフトウェア開発する話し
List events performed by a user
User event は GET /users/:username/events
エンドポイントから取得します。パブリックなイベントのみでいいはずなのでアクセストークンは必要ないです。
ただ API の仕様で、過去 90 日以内でかつ上限 300 件しか取得できないので、活動が多かった月は漏れがあるかもです。週ごと程度定期で取得してストックしておくなどの対応が必要かもですね。
ref: https://developer.github.com/v3/activity/events/#list-events-performed-by-a-user
$ curl "https://api.github.com/users/sugarshin/events"
[
{
"id": "5823717083",
"type": "PushEvent",
"actor": {
"id": 2001452,
"login": "sugarshin",
"display_login": "sugarshin",
"gravatar_id": "",
"url": "https://api.github.com/users/sugarshin",
"avatar_url": "https://avatars.githubusercontent.com/u/2001452?"
},
"repo": {
"id": 58251000,
"name": "sugarshin/blog.sugarshin.net",
"url": "https://api.github.com/repos/sugarshin/blog.sugarshin.net"
},
"payload": {
"push_id": 1723998566,
"size": 1,
"distinct_size": 1,
"ref": "refs/heads/gh-pages",
"head": "2944a811f7f2c9f58b994ad46da1a7d67f1a5de8",
"before": "21e6e15b34bad569fb2b2a6f233354ea38fdd69f",
"commits": [
{
"sha": "2944a811f7f2c9f58b994ad46da1a7d67f1a5de8",
"author": {
"email": "[email protected]",
"name": "Travis CI"
},
"message": "Updates",
"distinct": true,
"url": "https://api.github.com/repos/sugarshin/blog.sugarshin.net/commits/2944a811f7f2c9f58b994ad46da1a7d67f1a5de8"
}
]
},
"public": true,
"created_at": "2017-05-07T04:57:51Z"
},
...
]
記事作成
記事作成は取得したイベントデータを元にパース、フォーマットして Markdown ファイルとして書き出します。
blog.sugarshin.net/scripts/create-monthly-report/index.js
対象のイベントは現状、下記に絞ってあります。
CreateEvent
PullRequestEvent
PublicEvent
WatchEvent
IssuesEvent
イベントタイプはドキュメントにまとまっています。
ここから Markdown として出力するのに少しフィルタリングしています。
ビルド
ビルドは CircleCI 上で行います。
ブログのリポジトリだけで完結させられるかと思いましたが、ごちゃごちゃしそうだったので別環境を用意しています。
https://github.com/sugarshin/build.blog.sugarshin.net
現状、 Pull request のマージは、ステータスが mergeable
かつ mergeable_state === 'clean'
になるまでポーリングしています。ステータス変更をトリガーできればいいですね。
CircleCI の API からビルドを実行します。
ref: Recent Builds For a Project Branch - CircleCI API v1.1 Reference - CircleCI
$ curl -XPOST "https://circleci.com/api/v1/project/sugarshin/build.blog.sugarshin.net/tree/monthly-report?circle-token=$TOKEN"
定期実行
月末に定期実行させるために、 cron などで上述 CircleCI の API を叩きます。
今回は既存の自分のプライベート Hubot 内で起動させてあります。
# Description:
# monthly report to blog
{ CronJob } = require 'cron'
fetch = require 'node-fetch'
{ HUBOT_BLOG_BUILDER_CIRCLE_TOKEN: TOKEN } = process.env
module.exports = () ->
executeMonthlyReport = ->
fetch(
"https://circleci.com/api/v1/project/sugarshin/build.blog.sugarshin.net/tree/monthly-report?circle-token=#{TOKEN}"
method: 'POST'
)
new CronJob('0 01 00 01 * *', executeMonthlyReport).start()
月の末日をとるのが難しかったので、月初の 0 時 1 分とし、そこからビルド時間を考慮した分をマイナスして計算するようにしてあります。
GitHub の API でとれるデータを元に、エンジニアのパフォーマンス計測や作業量などの算出に利用して、エンジニアの働き方やワークライフバランス改善の 1 つの指針に利用できたりしないかなと考えてみたりしています。