プライベートリポジトリも見れる GitHub Warp で今年を振り返る
「クソアプリ Advent Calendar 2021 その2」の16日目の記事です。
ちなみに、とくに振り返ってはません。
GitHub Wrap
GitHub が GitHub Wrap というのをツイートしてました:
どうやら、2021年のパブリックなコントリビュートをいい感じなカードっぽい画像で出力してくれるそうです:
さて、OSS活動を主な仕事にしてる方なら、この結果イコール今年の活動になると思いますが、職業プログラマーであればプライベートリポジトリが主な活動拠点な方もいると思います。僕もそうです。できればプライベートリポジトリのコントリビュートも出したいです。
ということで
作りました。
残念ながら僕には「いい感じなカードっぽい画像で出力」する能力はないので、CLI です。ただし、流行り(?)に乗って GitHub CLI の Extension にしました:
$ gh extension install matsubara0507/gh-wrap
...
$ gh wrap
{
"GitHub CLI Wrap 🚀": "matsubara0507's 2021 GitHub ALL Stats",
"Commits": 2653,
"PullRequests": 420,
"Issues": 112,
"NewRepos": 19
}
(NewRepos
が減ってるのは、フォークを弾いたからです)
中身
どうやって各種総数を取ってくるかですが、GitHub GraphQL API でささっと取ってこれるもんだと思いますよね?
ドキュメントを漁ると、確かに viewer
クエリ(user
クエリ)の結果に ContributionsCollection
オブジェクトなるものがあります:
$ gh api graphql -f query='query{ viewer{ login, contributionsCollection(from:"2021-01-01T00:00:00"){ totalCommitContributions, totalIssueContributions, totalPullRequestContributions } } }'
{
"data": {
"viewer": {
"login": "matsubara0507",
"contributionsCollection": {
"totalCommitContributions": 456,
"totalIssueContributions": 9,
"totalPullRequestContributions": 61
}
}
}
}
しかし、どうやらこれはパブリックなコントリビューションのみみたいです。目を皿にしてドキュメントを漁り、あの手この手で試しましたが、User
オブジェクトからプライベート込みの各種総数を取得することは無理そうでした。。。(あったら教えてください)
ちなみに、本家 GitHub Wrap は ContributionsCollection
を使っていそうです(ソースコードは探したけど見つからなかった)。
search
クエリ
便利な search
クエリというのを使います。これは、GitHub の Web UI の左上の検索っぽいやつをそのまま API にしたようなやつです。例えば、自身がオープンした PR の総数を取得するにはこうします:
$ gh api graphql -f query='query{ search(query: "type:pr author:matsubara0507 created:2021-01-01..2021-12-31", type: ISSUE) { issueCount } }'
{
"data": {
"search": {
"issueCount": 420
}
}
}
これの欠点は、PR 数や Reposiotry 数などをそれぞれ別のクエリで取得する必要がある点です(バイバイ GraphQL の旨味)。なので、gh wrap
はめっちゃ遅いです。
それと、GitHub の検索ではコミットも検索できるのですが、GraphQL では(なぜか)対応していません。なので、コミット数はふつーの REST API を使いました:
$ gh api -X GET search/commits -f q='author:matsubara0507 author-date:2021-01-01..2021-12-31' -f per_page=1 --jq .total_count
2653
あとはこれをそれっぽい JSON にして表示してるだけです。
おまけ:GitHub Actions
GitHub Actions で gh
拡張の動作確認がしたいですよね。ということで足しました:
name: Run Extension Command
on:
pull_request: null
push:
branches:
- main
jobs:
run:
runs-on: ubuntu-18.04
env:
GH_TOKEN: ${{ secrets.GH_PAT }}
steps:
- uses: actions/checkout@v2
- name: Install extension
run: gh extension install .
- name: Run extension
id: gh
run: |
result=$(gh wrap)
result=${result//$'\n'/\\n}
result=${result//$'"'/\\\"}
echo "::set-output name=wrap::${result}"
- name: Comment result
uses: actions/github-script@v5
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: "Run `gh wrap` at workflow:\n```\n${{ steps.gh.outputs.wrap }}\n```\n"
})
実際に gh
コマンドを実行して、その結果を PR へコメントするだけです。コメントには actions/github-script
を利用しています。
ちなみに、いくつか罠がありまして。まず、GitHub Actions 組み込みの GITHUB_SECRET
では動きません。以下のようなエラーが出ます:
gh: Resource not accessible by integration (HTTP 403)
GitHub Actions 組み込みの GITHUB_SECRET
は、そのリポジトリに特化した権限しか持っていないため、うまく実行できなそうです。
仕方がないので、パブリックリポジトリへの権限だけを持った個人トークンを利用することにしました。
また、actions/github-script
へのエスケープ処理が厄介でした。
GitHub Actions の ${{ ... }}
は、変数の中身をそのままそこに貼り付けるので、body
の文字列へ埋め込むには、"
や改行をエスケープする必要がありました。
おしまい
ちなみに、引数に「年」を渡すと2021年以外も出してくれます:
$ gh wrap 2021
{
"GitHub CLI Wrap 🚀": "matsubara0507's 2021 GitHub ALL Stats",
"Commits": 2653,
"PullRequests": 420,
"Issues": 112,
"NewRepos": 19
}
$ gh wrap 2020
{
"GitHub CLI Wrap 🚀": "matsubara0507's 2020 GitHub ALL Stats",
"Commits": 3447,
"PullRequests": 587,
"Issues": 155,
"NewRepos": 30
}
$ gh wrap 2019
{
"GitHub CLI Wrap 🚀": "matsubara0507's 2019 GitHub ALL Stats",
"Commits": 3332,
"PullRequests": 590,
"Issues": 140,
"NewRepos": 51
}
あれ。。。今年だけまぁまぁコントリビュートが少ない。。??
Discussion