クリアコードに入社してから早くも7ヶ月が経ちました。児玉です。本記事では、私がクリアコードに入社した経緯や、働く中で感じたことについてお話しします。 とくにクリアコードが理念としている「フリーソフトウェアとビジネスの両立」やクリアコードの開発スタイルである「問題を見つけたらupstreamで直す」に関して実体験を添えながらお話しします。
現在、クリアコードでは、一緒に働く仲間を募集しています。少しでもクリアコードの仕事に興味を持っていただけたら幸いです!
フリーソフトウェアへの憧れとエンジニアへの道
私はもともと、g0vやSafecastといったフリーソフトウェアを活用したオープンコラボレーションの活動に強く憧れを抱いていました。 大学卒業後、「憧れているだけではなく、自分も実際に手を動かしてみたい」と思い立ち、ソフトウェアエンジニアになるためにプログラミングの勉強を始めました。 その結果、Webアプリケーションを開発する会社に入社しました。
前職では、お客様の視点に立ち、チームで良いWebアプリケーションを作ることを目指し、毎日楽しく開発に取り組んでいました。 仕事にも慣れ始めた頃、以前から興味を持っていたフリーソフトウェアの活動にも参加してみようと考え、実際に参加を始めました。 具体的には、Red Data ToolsやOSS Gateといったコミュニティになります。これらのコミュニティは、現状の技術力に関係なく、継続的に活動しながら少しずつフリーソフトウェアを良くしていこうという考えに基づいていたので、思い切って飛び込むことができました。
フリーソフトウェアの活動を通じて、普段業務で利用しているミドルウェアやライブラリのコードに触れたり、開発者の方々とやり取りする機会が増えていきました。 その中で、より低レイヤーの技術領域に興味を持つようになりました。具体的には、Webアプリケーションの背後で動いているミドルウェアの仕組みや、それがどのような思想を持っているのか、といったことです。
クリアコードとの出会い
そんなときに出会ったのが、クリアコードでした。クリアコードでは、フリーソフトウェアとして実装されたミドルウェアやライブラリの開発からメンテナンスまで幅広く業務で扱っており、私が関心を持っていた領域とも一致していたので興味を惹かれました。一番心惹かれたのは、ホームページの理念と開発スタイルでした。実際にそれぞれの考え方を読んでいく中で心が踊っていったのを今でも覚えています。
- 理念: フリーソフトウェアとビジネスの両立
- 開発スタイル: 問題を見つけたらupstreamで直す
そこに書かれていた理念や開発スタイルは、私がこれまで感じてきたフリーソフトウェアへの思いや、技術への探求心と深く結びついていました。 実際に会社説明会に参加したり、社員の方々とお話しする中で、フリーソフトウェアの考え方や開発スタイルに共感し、ここで働きたいなと思うようになりました。 それから縁があって今はクリアコードで働いています。そんな心が踊った理念と開発スタイルを私の実体験も含めて、それぞれ紹介させてください。
フリーソフトウェアとビジネスの両立
「フリーソフトウェアとビジネスの両立」は、クリアコードの理念になっています。詳しくはこちらのクリアコードとフリーソフトウェアとビジネスをご覧ください。ここでは私の言葉で実体験も含めて、この理念を紹介します。
フリーソフトウェアとビジネスの両立とは、フリーソフトウェアの活動を持続的に続けていくための環境をビジネスを通じて構築することだと今の私は理解しています。
なぜ、フリーソフトウェアとビジネスの両立を意識する必要があるのかというと、フリーソフトウェアの推進だけを意識していても収益を上げなければ、会社としてその活動を続けていけないからです。継続できない活動は、改善やメンテナンスがされないソフトウェアを生み出していってしまいます。一度はソフトウェアやライブラリを利用しようとした際に、メンテナンスがされておらず使えないという場面に直面された方もいらっしゃるのではないでしょうか?そのような状況を回避するためにも、ビジネスを通じて継続して活動できる環境を作り出していくことが重要になります。
では、具体的にどのようにビジネスを行っているのか紹介します。クリアコードでは主に以下の方法で収益を得ています。
- 導入支援:フリーソフトウェアのインストールや設定の支援
- カスタマイズ:フリーソフトウェアの設定変更やプラグインの開発
- サポート:運用中のフリーソフトウェアの問題解決や技術的な支援
- 受託開発:お客様が求めるソフトウェアの開発
これらのビジネス活動を通じて収益を上げると同時に、お客様の課題解決とフリーソフトウェアの推進を両立しています。
たとえば、導入支援やカスタマイズでは、得られた知見や開発したツールをフリーソフトウェアとして公開し、コミュニティ全体の発展に寄与しています。 また、サポート業務では、問題を報告・修正し、フリーソフトウェアの品質向上に貢献しています。
そうはいっても、具体的にどのように活動しているのか気になる人もいると思います。 なので、本記事ではサポート業務の具体的な例として私の実体験を紹介します。
Knowledgebaseプラグインの代替となるWiki Articleプラグインの公開について
RedmineのKnowledgebaseプラグインを利用しているお客様から、Rubyのバージョンを上げたところプラグインが動作せず、Redmineが起動できなくなって困っているというご相談をサポート業務の一環として受けました。
この問題は、Knowledgebaseプラグインのメンテナンスが滞っており、新しいRubyやRedmineのバージョンに対応していないために発生していました。 その結果、お客様はRubyやRedmineのアップデートを行うことができず、最新のセキュリティパッチや機能改善を享受できない状態にありました。さらに、長期的な視点で見るとセキュリティリスクの増大の懸念がありました。
お客様と相談の上、Knowledgebaseプラグインを引き継ぎメンテナンスすることも選択肢の1つでしたが、以下の理由から新たにWiki Articleプラグインを開発・公開することで、この課題を解決する方針を取りました。
- メンテナンスの負担: Knowledgebaseプラグインは独自のテーブルを追加するなど、複雑な構造を持っており、メンテナンスコストが高そうであること
- 必要な機能の見直し: お客様の使用用途を詳しく伺うと、Redmineの標準機能であるWikiに少し機能を追加すれば十分であるとわかったこと
- データ移行の容易さ: Wikiにデータを移行するためのツールを提供することで、お客様がこれまで蓄積してきた情報を引き続き活用できること
この方針には、お客様とフリーソフトウェアコミュニティの双方にメリットがあります。それぞれのメリットを紹介します。
お客様の視点では、以下のメリットがあります。
- 課題の解決: 現在抱えている問題を解決し、最新のRubyやRedmineでも従来の蓄積した情報を利用できること
- 将来のアップデートへの対応: 新しいプラグインは必要最小限の機能のみを提供し、拡張が容易なシンプルな作りにもしているため、メンテナンスコストが低く、今後のRedmineのアップデートにも対応しやすいこと
- ベンダーロックインの回避: フリーソフトウェアとして公開することで、クリアコード以外からのサポートを受ける選択肢が持てるため、ベンダーロックインを避けることができること
フリーソフトウェアの推進という点では、以下のメリットがあります。
- 同じ課題を持つユーザーの支援: 同様の問題に直面している他のRedmineユーザーも、このプラグインを利用することで問題を解決できること
- コミュニティでの協力開発: フリーソフトウェアとして公開することで、コミュニティ全体での改善や機能追加が可能になること
ここで重要なのは、お客様から開発費用をご負担いただくことで、具体的な課題を迅速に解決できるという点です。 フリーソフトウェアなので、お金を出していただかなくても、コミュニティに問題を報告していただければ、解決が試みられる可能性があります。しかし、その場合は解決までに時間がかかったり、必ずしも望む形で解決されるとは限りません。クリアコードにご依頼いただき、開発費用をご負担いただくことで、お客様のニーズに合わせた解決策をより早く提供できます。
このように、クリアコードではサポート業務を通じて、お客様の課題解決とフリーソフトウェアの推進に貢献しています。 本記事では、サポート業務を紹介しましたが他の業務に関しては、先述したクリアコードとフリーソフトウェアとビジネスをご覧ください。
次は、クリアコードの開発スタイルについて紹介します。
問題を見つけたらupstreamで直す
クリアコードでは、「問題を見つけたらupstreamで直す」という開発スタイルを採用しています。詳しくは、こちらの開発スタイルをご覧ください。ここでは私の言葉で実体験も含めてこの開発スタイルを紹介します。
「問題を見つけたらupstreamで直す」とは、ソフトウェアを開発している中で既存のツールやライブラリの問題を発見した場合に、その問題を自社内または手元で回避するのではなく、開発元(upstream)にフィードバックし可能であれば修正パッチを提供し直すという開発スタイルです。
この開発スタイルを採用することのメリットを3つ紹介します。
1つ目は、問題を根本から解決することで、同じ問題に直面する他の開発者やユーザーの助けになります。 実際に修正プルリクエストを送ると同じ問題を抱えていた人からコメントやリアクションをもらえたりするので、報告してよかったなという気持ちになります。
2つ目は、個別に問題を回避するためのモンキーパッチを維持する必要がなくなり、長期的な保守コストが減少します。 たとえば、実際に当てていたモンキーパッチがライブラリのバージョンアップにあたって動かなくなったので修正を余儀なくされた経験をお持ちの方もいらっしゃるのではないでしょうか?そんな状況を回避できます。
3つ目は、ソースコードを深く理解し、コミュニティと協働することで、エンジニア個人のスキルアップにも繋がります。 実際に遭遇した問題を解決するためにupstreamに報告するとメンテナーの方がより良いコードの書き方をオススメしてくださったり、修正方法の提案などもしてくださり知見が広がるという恩恵も得られます。
このような取り組みは、フリーソフトウェアの精神とも深く結びついています。単にソフトウェアを利用するだけでなく、その発展に寄与することで、より良いエコシステムを築いていくことにもつながっていきます。
そうはいっても、具体的にどのように活動しているのか気になる人もいると思います。そこで、私の実体験を紹介します。
Ruby OpenURIにリダイレクト時のヘッダーを制御できる仕組みを導入した
背景
業務でGitHub Actionsのアーティファクトをダウンロードする必要があり、その際にRubyのOpenURIライブラリを使用していました。 その中で、OpenURIライブラリのリダイレクト時のヘッダーの扱いに関して気になる点があり、upstreamに報告することを決めました。 具体的な内容を紹介します。より詳しく知りたい人は、こちらのPRをご確認ください。
遭遇した課題を紹介する前に簡単にGitHub Actionsのアーティファクトをダウンロードする仕組みに関して紹介します。 アーティファクトをダウンロードする流れは次のような流れになります。
- 認証リクエスト:Authorizationヘッダーを使用して、GitHub APIにダウンロードリクエストを送信します。
- リダイレクト:GitHub APIから、アーティファクトが保存されている実際のダウンロードURL(Shared Access Signature付きのURL)へリダイレクトされます。
- アーティファクトのダウンロード:リダイレクト先のURLからアーティファクトをダウンロードします。
遭遇した課題
次に、実際に課題に遭遇したコードを紹介します。 こちらのコードは、OpenURIライブラリを利用し、GitHub Actionsのアーティファクトをダウンロードするコードになります。
require 'open-uri'
uri = ENV['ARTIFACT_URL']
access_token = ENV['GITHUB_ACCESS_TOKEN']
URI.open(uri, "Authorization" => "token #{access_token}")
実行してみると、次のようにリダイレクト先でAuthorizationヘッダーが不正な形で解釈され、403エラーが発生します。
$ ruby download_artifact.rb
/home/otegami/.rbenv/versions/3.3.5/lib/ruby/3.3.0/open-uri.rb:376:in `open_http': 403 Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature. (OpenURI::HTTPError)
課題の詳細
エラーの原因は、リダイレクト先のホストに対してAuthorizationヘッダーがそのまま送信されてしまう点にあります。リダイレクト先では、URLに含まれるShared Access Signature(SAS)を使用して認可を行う必要がありますが、Authorizationヘッダーが存在する場合は、その値を利用して認可を行うようです。しかし、Authorizationヘッダーに含まれるGitHubのアクセストークンは、SASとは形式が異なるため、認可に失敗し403エラーが発生しています。(ただ、もちろん形式が同じだったとしても必要とする値とは異なるため認可には失敗するでしょう。)
Upstreamへの報告と提案
この問題は、リダイレクト時にAuthorizationヘッダーを送らないことで問題は解決できます。 しかし、ここで気になるのは意図しないホストに認証情報であるAuthorizationヘッダーを渡してしまっていることです。 これは意図しないホストに対して認証情報を漏洩するリスクがあるのではないかと思い、upstreamに報告することを決めました。
そこで、リダイレクト時にAuthorizationヘッダーを単純に削除する実装をしたパッチと一緒にupstreamへ報告をしました。 なぜなら、CurlやFetch APIの仕様では、別のホストにリダイレクトする際にAuthorizationヘッダーを取り除く仕様が推奨されたり、そのような実装になっていたためです。
メンテナーとの協議と最終的な解決策
報告後に、RubyのOpenURIライブラリのメンテナーの方と相談させていただく中で、メンテナーの方から、より柔軟にヘッダーを制御できる仕組みを導入するのはどうだろうかという提案をいただきました。確かに、Authorizationヘッダーに留まらず、今後同様の問題が生じたときに1つ1つ対応していくのは大変です。さらに、ユーザー視点でもヘッダーを柔軟にコントロールできるほうが嬉しいはずです。これらの点からも最初に報告した案よりもより良い案になっていました。こういったアドバイスをいただけるのもupstreamに報告することで得られる嬉しいポイントです。
そして、実際にリダイレクト時のヘッダーを動的に制御できる仕組みを導入しました。具体的には、request_specific_fields
という新しいオプションを追加し、各リクエストごとにヘッダーを柔軟に指定できるようにしました。このオプションでは、初回のリクエストのみに特定のヘッダーを設定したり、リダイレクト先のURIに応じてヘッダーを動的に変更することもできます。
たとえば、初回のリクエストのみにAuthorizationヘッダーを設定する場合には次のように書くことで、リダイレクト時にAuthorizationヘッダーは利用しません。このコードでもちろんアーティファクトも無事にダウンロードできます。
URI.open(uri, request_specific_fields: {"Authorization" => "token #{access_token}"})
この変更により、セキュリティリスクを軽減しつつ、開発者がリクエスト時に必要なヘッダーを適切に管理できるようになりました。 この改善はRuby本体にすでにマージされているので、クリスマス(12/25)にリリース予定のRuby 3.4から利用可能になります。 今回の変更により、今後同じ問題に直面する開発者の数を減らすことができたと考えています。
この経験を通じて、「問題を見つけたらupstreamで直す」というクリアコードの開発スタイルが持つ意義を改めて実感しました。単に自分たちの問題を解決するだけでなく、コミュニティ全体の改善につながる取り組みができたことに大きな達成感を感じています。これからも積極的にフリーソフトウェアの発展に貢献し、より良いエコシステムを築いていきたいと思います。
まとめ
今回の記事では、私がクリアコードで働く中で感じた「フリーソフトウェアとビジネスの両立」や「問題を見つけたらupstreamで直す」という理念と開発スタイルの魅力を、具体的な事例とともに紹介しました。これらの取り組みを通じて、技術者としての成長だけでなく、フリーソフトウェアの推進や持続可能なエコシステムの構築に寄与できることを実感しています。
もし、フリーソフトウェアの精神に共感し、私たちと一緒に技術を深めながらフリーソフトウェアに貢献していきたいと考えている方がいらっしゃいましたら、ぜひ一緒に働く仲間を募集のページからご連絡ください。共にフリーソフトウェアの未来に貢献していきましょう。
クリアコードの入社エントリー
クリアコードの他のメンバーの入社エントリーもぜひご覧ください。それぞれの入社エントリーでは、クリアコードを選んだ理由や、そこでの働き方、フリーソフトウェアへの思いなどが語られています。ぜひ、他のメンバーのエントリーもご覧いただき、クリアコードの考え方に触れてみてください。