はじめに
最近、OSS(hasura/graphql-engine)にコントリビュートしました。
本記事は、業務で遭遇したOSSのバグに遭遇してから、IssueとPull requestでのバグ報告・修正するまでの経緯を簡単にまとめています。
今まで自分は、OSSへのコントリビュートは難易度が高いと思っていました。しかし、いざやってみると思ったより敷居が低く、経験値も多く得ることができました。
OSSコントリビュートしてみたいけど、今一歩踏み出すことができない
といった方の参考になればという考えのもと、記事にしました。拙い文章ではありますが、参考になれば幸いです。
対象読者
・OSS活動をしてみたいが、どうやってやればいいかわからない方
・Hasuraにコントリビュートしてみたい方
コントリビュート内容
立てたIssue・Pull Requestは以下です。
業務で、HasuraというGraphQLサーバーに付属するCLI(Go製)のバージョンアップをしたところ、ある特定コマンドのオプションが動かなくなってしまいました。
具体的には、HasuraのWebコンソールを起動するコマンド
hasura console --address XXX
の、マイグレーション用のAPIエンドポイントを指定する--address
オプションが、hasura v2.1.0で新しく追加された--api-host
というベータ版のオプション追加により、動かなくなってしまっていた、というものです。
コントリビュートするまでの道のり
問題発生〜Issue 作成まで
web検索で記事・Issue漁り
今回遭遇したバグは、エラーメッセージを吐き出していました。なので、まずはエラーメッセージをコピペして記事・Issueに該当するものがないかWeb検索しました。
エラーメッセージは、
Hasura console is not able to reach your Hasura CLI instance...
(Hasura CLIインスタンスと接続できませんでした)というものだったのですが、該当する情報は1つもヒットしませんでした。
ある程度規模が大きいOSSで、エラーが1つもヒットしないことは稀です。
問題発生時、バージョンをアップグレードしたばかりだったので、おそらく最新バージョンで発生したのだろうという仮説を立てました。検証のために一つ前のバージョンに戻したところ、問題なく正常に動作したため、最新バージョンのみの挙動であることがわかりました。
メモ:
・ある程度の規模のOSS(Github Star数25k~)で、具体的な内容のメッセージを吐くエラーについてのIssueや記事が見つからないことは稀。
・ヒットしないときは、最新バージョン特有の問題か、自分のググり力を疑う。
再現する条件の調査
ある程度調査して、解決策が見つからないので、HasuraにIssueを立てることを考えます。Issueでバグ報告する際は、再現条件を記述することが必須なため、どのような条件で問題が発生するのかを調査しました。
問題発生時、コマンドには下記の様に複数のオプションを渡して実行していました。
hasura console --console-port XXX --api-port XXX --address XXX --no-browser --admin-secret XXX
この内の、どれがバグを引き起こしたのかを調査するために、
- 1つずつオプションを渡して実行
- 複数のオプションを組み合わせて実行
をしらみつぶしにやっていくと、--address
オプションが効いていないことが判明します。
メモ:
・問題の再現方法が記載されていないバグ報告をしてもOSSのメンテ側は困るので、なるべく再現できる状態を調べてからIssueを立てる。
・再現方法を調べる際は、まずシンプルな仮説から試し、徐々に組み合わせを試していく。
Issue 作成〜Pull Request 作成まで
Issue作成
問題の再現ができたので、HasuraにIssueを投稿する準備をしていきます。
HasuraのIssueには、バグ報告用のテンプレートがあるので、それに沿ってIssueを書いていきます。
Hasuraの例だと、以下の様な記述項目があります(一例)。
- Version Information:バージョン情報
- What is the expected behaviour?:期待する振る舞いはなんですか?
- What is the current behaviour?:どの様な振る舞いをしていますか?
- Any possible solutions?:回避策はありますか?
バグの原因となったソースコードを読む
Issueテンプレートには、
Can you identify the location in the source code where the problem exists?(ソースコードのどこで問題が発生しているかわかりますか?※分かれば)
という記述項目がありました。
ソースコード上のどこに問題があるかを特定しなくてもIssueは立てられます。ただ、今回問題が発生したHasuraのCLIは自分が普段使っているGoで書かれていたので、**「普段Goで書いているから読めるだろう」**という考えのもと、ソースコードを読んでみることにしました。
ただ、何の手がかりもなく読み進めることはできません。(へっぽこエンジニアなので...)そこで、以下の方法でコードリーディングを進めることにしました。
- 最新バージョンのみで発生した問題だったため、最新バージョンへの変更差分を調べて、関係がありそうなファイルを見つける
- 問題が発生した
--address
オプションに関わるコードを中心に、バグの原因を調べていく
原因を突き止める
そんなこんなで読んでいくと、バグの原因らしきコードが特定でき、
-
--address
オプション指定時の挙動が、新しく追加されたオプション引数によって変更されている
という仮説を立てます。修正したコードでビルド&テストしてみると、問題なく動作し、自分の仮説が合っていたことを確信します。
メモ:
・Issueのテンプレートがある場合は、そのOSSのテンプレートに沿ってIssueを立てる。
・読んだこともないソースコードを一から理解するのは骨が折れるので、ファイル名・リリースバージョンの差分などから当たりをつけ、読む範囲を狭めていく。
Pull Request 作成〜Merge まで
修正方針の決定
ソースコード中の問題箇所が特定できたので、Pull Requestを作っていきます。
今回の問題の修正をするためには、デグレを引き起こした新オプションと、今まで動いていたオプションの両方が指定された場合の挙動を決定する必要がありました。
そのため、修正はIssue上でメンテナに方針を聞いてから着手しています。
コントリビューション作法の調査
リポジトリをforkしてブランチ切って...といったOSSコントリビューションの流れは、他の方の記事を読みながら進めていきました。
OSSによっては、コミットメッセージやブランチ名のスタイルガイドが決まっているものもあるので、適宜作法を合わせていきます。また、修正対象のHasura CLIはE2Eテストに合格していることが必須なので、手元で自動テストに合格したことを確認して、Pull Requestを送ります。
Merge
pushした後は、メンテナにレビューされるのを待ちます。緊急度によってレビューされるまでの時間に差異がありますが、今回は半日ほどでした。
その後、メンテナと数回細かなコードやPull Request名の修正のやりとりが行われ、mergeされました。
Hasuraの場合、mergeされるとミニオンが踊ってくれます
これにて、一連のバグ報告〜修正が終了しました。
おそらく、次バージョンで取り込まれた修正がリリースされる予定です。
振り返り
ソースコードの変更分はたったの数行程度ですが、バグ発見から修正まではなかなか大変でした。
つまづいた点を以下にまとめています。
・最初、関係のないWeb記事やStackOverFlow、Issueに引っ張られて調査が混乱した
・DeepLで翻訳するにしても、ちゃんとした日本語(主語・述語をはっきりするなど)にしないと伝わらない
・英語力のなさ
・英語力のなさ
とはいえ、反省点以上に、たくさんの良い経験が得られました。
・OSSのソースコードは意外に読める
・次回以降のOSS活動のハードルがグンと下がる
・英語が下手でも、ソースコードの正しさとパッションがあればなんとかなる
・感謝される
おわりに
書いてみると、体験談をつらつら述べただけの記事になってしまいました。
自分は、**「OSS活動なんて、すごいエンジニアしかできないもの」**と思っていたのですが、今回の経験を通してOSSがグッと身近なものになりました。
自分の様にどんなに小さなことでも、OSS活動する人が増えれば増えるほどソフトウェア業界全体にとってプラスになると思います。
今までやったことがない方でも、機会があれば是非やってみてはいかがでしょうか。