僕のお手伝いしている、とある会社ではdeployをSlack botから行っていましたが、ある日そのbotが動かなくなっていました。Twitterでも少し話題になったので覚えていらっしゃる方もいると思います。
Rubotyで動いてた煉獄さんがSlack RTM周りの変更で動かなくなってしまったためGitHub Actionsに載せ替えました。通知の責務に関しては、炭治郎が受け継ぎました pic.twitter.com/nM4hvc5oTL
— 黒曜@Leaner Technologies (@kokuyouwind) December 7, 2021
このとき何が起こっていたのか。前述したとある会社では、Slack bot frameworkとしてRubotyを、Slackとの通信にはruboty-slack_rtm gemを使っていました。
ではまず、こちらのSlack APIのChangelogをご覧ください。
If you still use
rtm.connect
orrtm.start
to connect to Slack, you’ll notice that all WebSocket URLs now begin withwss://wss-primary.slack.com
.https://api.slack.com/changelog#changelogdate2021-11
以前はどのようなURLだったのかというのはわかりませんが、これに関連して、ruboty-slack_rtm gem側で以下のissueに記載のあるような問題が発生するようになりました。
OpenSSL::SSL::SSLError: SSLwrite at Heroku · Issue #46 · rosylilly/ruboty-slackrtm
どうやらSlackがWebSocketに使用するURLにて、TLS証明書にSNIが導入されたようです。そして、ruboty-slack_rtm gemがWebSocketでの通信のために使用しているwebsocket-client-simple gemがSNIを考慮できていないため、WebSocketでの通信が行えなくなってしまっている、ということのようでした。
一旦はslack-ruby-client gemを使うことで凌ぐことができましたが、websocket-client-simple gemにSNI対応が入ってくれると助かります。
さて、そのようなPull requrstは複数作成されていましたが、ownerであるところのshokaiさんの反応はありませんでした。
そこで思い切って聞いてみました。
@shokai 突然すみません、このpatchが取り込まれてほしいのですが、これをmergeするのに何か障害になっていることはあるのでしょうか?https://t.co/LPxcKEHizh
— うなすけ (@yu_suke1994) December 24, 2021
すると、移管について前向きに検討していただけるとのことだったので、同様にRubotyを使っているruby-jp slackのGitHub organization下で管理するということになりました。
他の人が管理してくれるなら全部移管したいです
— Sho Hashimoto (@shokai) December 24, 2021
それについて、ruby-jpで行った会話の流れ1が以下になります。
さて、そんなこんなでruby-jp以下に shokai/websocket-client-simple
をforkし、gemをpublishする権限をいただいてから行ったことを以下にまとめました。
https://github.com/ruby-jp/websocket-client-simple
まずは既存のrepositoryのREADMEを更新します。websocket-client-simple gemは歴史のあるrepositoryですから、 shokai/websocket-client-simple
であるという共通認識があることでしょう。
そのため、「開発は ruby-jp/websocket-client-simple
に移動したよ」ということをREADMEの上部、すぐ目に入る部分に記載するべきでしょう。(これは元々の shokai/websocket-client-simple
に出す必要があります)
Update README (repo moved notice) by unasuke · Pull Request #42 · shokai/websocket-client-simple
merge後、既存のissue及びpull requestに対して「まだこの変更が必用なら ruby-jp/websocket-client-simple
側にお願いします」とコメントしました。
次に、CIが長期間実行されていないので、テストが通るかどうかを確認する必要があります。テストはGitHub Actionsで実行することにしました。
GitHub Actions by unasuke · Pull Request #1 · ruby-jp/websocket-client-simple
そして、CIが定期的に実行されるように設定しておきます。これにより、依存している別のgemの破壊的変更にすばやく気づくことができるようになります。
CIは整備しましたが、ここまでロジックは変更していません。最低限必要とするRubyのバージョンも変更していません。この状態で「開発は ruby-jp/websocket-client-simple
に移動したよ」というメッセージをgemのinstall時に出すような変更を行い patch releaseを行いました。
Update gem metadata by unasuke · Pull Request #2 · ruby-jp/websocket-client-simple
このメッセージはそろそろ消そうかなと思います。homepage_url
と source_code_url
で事足りるためです。
このリリースまでが、いわゆるmigration pathとしてのリリースです。リリース時点でメンテナンスされている、EOLになっていないRuby versionを下限とする制限を行ったリリースをしました。
さて本題のSNI対応です。これは元々のrepositoryにpull requestを出している方が2人いらっしゃいました。その変更を見て僕がコードを編集して出すということもできますが、それはお二人にリスペクトがないと感じたため、その二人からpull requestが来るのを待つことにしました。
そしたらそのうちの一人であるfuyutonさんからpull reqを頂いたので、これを無事mergeしてリリースを行いました。やった!!!
Added to use SNI by fuyuton · Pull Request #6 · ruby-jp/websocket-client-simple
このあたりの変更を大晦日から年明けにかけてやっていました。いい年越しでした。
ここでめでたしめでたし……とはいかず、ruboty-slack_rtm gem側が要求しているwebsocket-client-simpleが低いままなので問題は解決していません。
そのため、ruboty-slack_rtm側でSNI対応を行ったバージョンである0.5.0以上に依存するように変更を行ない、これをmergeしていただきました。
これにて職場でのSlack botもmonkey patchなしで動くようになり、chatopsが無事にできるようになりました。めでたしめでたし。
さてこの度、Twitterでコミュニケーションしてgemの権限を頂くということを行いました。ところで、このような「owner権限のリクエスト」という機能がrubygems.orgに入っています。この機能では、作者がownerを引き受けてくれる人の募集、もしくはあるgemに対してのowner権限のリクエスト(こっちはgemのdownload数などに制限がある)を行うことができます。
ただ、まだリリースアナウンスはされていないようです。
shokaiさんの視点からの記事が出ているのでリンクを貼ります。
websocket-client-simpleをruby-jpに移管した - 橋本商会
Rubygems Adopationsについて公式の発表があったので更新しました。
発言の掲載については許可を得ています ↩