LoginSignup
3
0

More than 3 years have passed since last update.

Natural Language APIとGitHub Actionsでコードレビューを機械的にレビューする👮‍♀️

Last updated at Posted at 2020-11-30

アドベントカレンダー1日目を頂きました。
@yuta-ron です🐧

成果物

プルリクエスト or Issueについたコメントの内容が不穏だった場合、こんな感じで指摘してくれるGitHub Actionsワークフローを作りました。

Image from Gyazo

ソース
yuta-ron/reviewpolice - GitHub

デモ🚨

コメントしてみると実際に動くので、どんな動きをするか試せます🙌
https://github.com/yuta-ron/reviewpolice/issues/1

採用した経緯

最近、この記事がトレンドに乗ったということもあり、皆さんのコードレビューに対する関心が高いのだと感じました。
偶然にも、コードレビューのレビューツールを開発していたところなので、1日目のテーマに採用しました🎉

コードレビューのコミュニケーションを良くして効率をあげましょう!
https://qiita.com/buddhikapallewela/items/cba0d0093383f435c6e4

なんで作ったのか

仕事の立場上、レビュアーになることが増えてきたのですが、そこでいろんな悩みを抱えました。
それを解決する糸口になればと思い開発しました。

僕がコードレビューで意識していることは下記の通りです。

  • 自分の感情を切り離して考える。(超大事)
  • 相手が萎縮しないようなレビューをする。(超大事)
  • 誰が見ても100%伝わるようなレビューコメントを書く。
  • レビューイの学習意欲を刺激し、以後同じレビューが繰り返されないようにする。

プルリクエストのコードレビューというのは、レビュアーとレビューイ2つの立場がありますが、どうしてもレビューイの立場が弱くなりがちです。
その最中、レビュアーが高圧的な態度をとってしまうと、レビューイは萎縮してしまい、人によってはコードに手がつかなくなります。
結果、どんどん雰囲気が悪くなり、何を指摘されているのかも分からず誰にも聞けないという負の循環に陥ります。

とはいえ、レビュアーが感情に流されずレビューをすることはそれなりの経験と人間の器が試されるところだと思います。
レビュアーも自分の仕事を抱え、いろんな要因で心の余裕がなくなっていることが往々にしてあるのではないでしょうか。

また、レビュアーの気が立っているところにわざわざメンションをつけてクールダウンしてくれる勇気のある人は少ないと思います。
ここを機械に代替させて、人の手を介入させずにクールダウンさせることができればみんな幸せじゃない?と考えました。

余談で、マサカリ文化というものがありますが、あれは両者の心理的安全性が存在する状態でのみ成立する文化と考えており、
僕個人としては、常にその文化を引き合いに出すべきではないと考えています。

導入想定

結成後間もない or 心理的安全性が確保されていないチーム

早くなんでも言い合える雰囲気になって、このようなツールは1日も早く廃止されることが望ましいです。😇

採用技術

アーキテクチャと呼ぶほど大したものではありませんが、下図のように実装しました。

スクリーンショット 2020-11-30 22.14.25.png

感情分析にはGCPのNatural Language APIを使いました。

ネガポジ判定のコードは、

Natural LanguageのAPIを叩いてスコアを見て判定
->  問題ありそうだったらHTMLを作って返す

という単純なことしかしていません。ほぼチュートリアルにあったコードを拝借しています。
いろんな言語のSDKが公開されているのですが、最近仕事でGoを触っているのでGoで実装しました。

アルゴリズム

文章全体、文節ごとのスコアリングをしてくれます。
文章全体がいい雰囲気でも、一部辛辣な表現があるとそれで台無しなのでその部分だけ考慮しました。

とりあえず、下記いずれかを満たす場合に指摘をするようにしました。

  • 文章全体のスコアが0.2を下回った場合
  • 文節の表現に0を下回るものがあった場合

かいつまんで実装メモ

Natural Language APIのセットアップ方法

公式ドキュメントが詳しいので説明はそちらに譲ります

クイックスタート: 自然言語を設定する
https://cloud.google.com/natural-language/docs/setup?hl=ja

文節ごとに区切ってくれるのがうれしい

たとえば、 

なんでこんなIssue立てたんですか?ナメてるんですか?

という文字列をNatural Languageに投げた場合このように返ってきます。

{
    "document_sentiment": {
        "magnitude": 0.9,
        "score": -0.4
    },
    "language": "ja",
    "sentences": [
        {
            "text": {
                "content": "なんでこんなIssue立てたんですか?"
            },
            "sentiment": {
                "magnitude": 0.7,
                "score": -0.7
            }
        },
        {
            "text": {
                "content": "ナメてるんですか?",
                "begin_offset": 47
            },
            "sentiment": {
                "magnitude": 0.2,
                "score": -0.2
            }
        }
    ]
}

当初、「文節ごとに区切る処理が必要になるなー」と思ってたのですが、文節ごと/文全体のネガポジを出してくれてかなり優秀です🎉

絵文字まで判定してくれるのが嬉しい

😁の場合(途中省略)

...
            "text": {
                "content": "😁",
            },
            "sentiment": {
                "magnitude": 0.3,
                "score": 0.3
            }
...

😭の場合(途中省略)

{
...
            "text": {
                "content": "😭",
            },
            "sentiment": {
                "magnitude": 0.1,
                "score": 0.1
            }
...
}

多言語に対応してる

「いいね!」を食わせた場合 (途中省略)

{
...
    "language": "ja",
...
}

「LGTM👍」を食わせた場合 (途中省略)

{
...
    "language": "en",
...
}

GitHub Actionsでイベントをキャッチするところで戸惑った

Issue/PullRequestに投稿されたコメントは、GitHub Actionsでイベントを拾ってワークフロー を実行しているのですが、
Issue/PullRequest共に同じイベントの名前で飛んでくるため、Workflow内でそれぞれの処理を分岐する必要があるようです。

PRでも、Issueでも、issue_comment のイベントが飛んできます


name: ISSUE_OR_PR_COMMENT_POSTED

on: 
  issue_comment: 
    types: [created]

こんな感じでPRの処理、Issueの処理を分岐させてあげる必要があります。
(WebHookで飛んでくるイベントオブジェクトの中身が違うため、コメントを取る処理を別々にする必要がある。)

if: contains(github.event.comment.html_url, '/pull/')

参考URL

Pull RequestのコメントからGitHub Actionsを実行する
https://akaimo.hatenablog.jp/entry/2020/05/16/101251

GitHub AcionsからGCPの認証を通す方法

当社インフラエンジニアの @j_matsumoto が書いた記事が参考になりました🎉

GitHub Actionsの使い方 https://www.jhhk-family.net/?p=859

Todo

一般公開して、Workflowに気軽に組み込めるようにしたいですね。

GitHub Marketplaceでのアクションの公開
https://docs.github.com/ja/free-pro-team@latest/actions/creating-actions/publishing-actions-in-github-marketplace

まとめ

確かに、コードレビューは時と場合によって厳しい表現が必要になります。
全て優しい表現にすると、レビュアーの真意が100%通じなくなることが懸念されるためです。

しかし、チームビルディングが甘い状態で厳しい表現をみだりに使うと、相手が不信感を持つ原因にも繋がり、
どんどん悪い方向に向かっていきます。

最初はポジティブな表現で相手との距離を縮め、お互いになんでも言えるような関係になってから徐々に厳しい指摘を交えていくのがベター進め方なのかなと思いました。

明日は、 @y-nakazawa-adven です!お楽しみに🙌

おまけ

スカイチケットを開発する株式会社アドベンチャーはエンジニア採用を強化中です👍
常時カジュアル面談実施してますので、お気軽にご連絡ください!

フロントエンド
- https://jobs.qiita.com/employers/255/postings/1167

バックエンド
- https://jobs.qiita.com/employers/255/postings/1169

インフラ
- https://jobs.qiita.com/employers/255/postings/1413

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0