こんにちは! タイミーでデータアナリストをしているtakahideです。 突然ですが、「この事業を成功させるにはどうすれば?」といった、ふんわりと大きなテーマを渡されて、「さて、どこから手をつけようか...」 と悩んだ経験はありませんか? タイミーでも、今後より会社の重要課題に関わる分析プロジェクトが増える中で、こうした上流の課題を見つけ、精度の高い仮説を立てる力、いわゆる「課題発見・仮説思考力」の重要性が高まると考えています。 本記事では、「仮説向上プロジェクト」での取り組みを元に、複雑な課題を構造化し、具体的なアクションに繋げるための思考整理術をご紹介します。 この記事が、同じように課題発見に悩む方々の助けに少しでもなれば幸いです。 「知っている」と「できる」の壁 思考のプロセスを可視化する「仮説向上プロジェクト」 思考整理の「3つのステップ」 1. 「問い」から「5W1H」への整理 2. 「5W1H」から「Flywheel」への落とし込み 3. 「Flywheel」から「定義」の再整理へ 今後の展望:思考プロセスをAIを用いてスケールさせる We’re Hiring! 「知っている」と「できる」の壁 これまでもデータアナリティクス部では、事業部のメンバー向けに仮説構築の勉強会を開いてきました。1回目は仮説のタネから仮説の木を育てる「仮説構築」の全体像を、2回目では論理を整理するための「便利な道具 (フレームワーク)」について行いました。 おかげで、チーム内で「仮説」という言葉の目線は一定揃ったのかな、と思っています。一方、知識として「知っている」ことと、実践で「使いこなせる」ことの間には、思った以上に大きな隔たりがありました(当たり前ではありますが、、)。 思考のプロセスを可視化する「仮説向上プロジェクト」 そこで、この壁を乗り越えるために、実験的な「仮説向上プロジェクト」を立ち上げました。 このプロジェクトの目的は、とてもシンプルです。 「問いを立てる力を引き上げること」。 分析の精度は、最初の「問い」の質でそのほとんどが決まってしまいます。MECE (モレなく、ダブりなく) やロジックツリーといったフレームワークといった調理器具を使う前に、「そもそもどの食材をどう料理するべきか?」 という「見立てる力 (素材の目利き)」を鍛えることにフォーカスしてみました。 具体的には、会社としての重要テーマを題材に、メンバーと1on1形式でディスカッションを重ねました。この抽象的なお題を、どう整理し、具体的な分析テーマに落とし込んでいくか。その思考プロセスを繰り返しました。 思考整理の「3つのステップ」 この実験的な取り組みを数回繰り返す中で、手応えのある思考整理のプロセスが見えてきました。 1. 「問い」から「5W1H」への整理 すべては、一つの大きな「問い」から始まります。特に会社の重要課題につながるような抽象的な問いの場合、そのままでは、どこから手をつければ良いか判断がしづらいです。 そこで、まずは問いを具体的な要素に分解することで、その後のプロセスがスムーズに進むことが分かりました。 特に、5W1Hは問いを具体化する初期段階において、シンプルですが便利なフレームでした。 Who (誰が) まず、「誰にとっての成功なのか?」を定義します。特に私たちのようなプラットフォーム事業では、関わるプレイヤーが複数存在します。例えば、「ワーカー」と「事業者」です。 What (何を) 次に、この新しい事業が「具体的に何を価値として提供するのか」を、それぞれのプレイヤーの目線で定義します。 Why (なぜ) そして、それぞれのプレイヤーが「なぜ、提供された価値に関心を持って、関わりうるか?」という動機を深掘りします。提供者が抱える「不安定さへの不満」や、利用者が感じる「既存サービスへのコストや品質面の課題」など。 一つの問いを様々な視点から分解していくことで、漠然としていたテーマの輪郭が見えてきます。チーム全員の目線を合わせ、分析のブレをなくすための最も重要な土台作りと考えています。 2. 「5W1H」から「Flywheel」への落とし込み 5W1Hで事業の構成要素を洗い出したら、次に行うのがFlywheel (はずみ車)への落とし込みです。 Flywheelとは、事業を「一度回れば自律的に成長していくサイクル」として捉えるための思考ツールです。「何がどう作用して、次のどんな結果に繋がるのか?」 という一連の因果関係のループとして可視化することで、事業成長のエンジンがどこにあるのかを特定しやすくなります。 私たちのようなプラットフォーム事業を例に考えてみます。 1. まず、事業の成長を促すためのアクションがあります。例えば、マーケティング施策や営業活動によって、ワーカーの集客を強化したとします。 2. プラットフォーム上のワーカーが増えると、人材を探している事業者にとっての魅力が増し、「ここなら良い人が見つかりそうだ」と事業者の利用が増加します。 3. 事業者の利用が増えれば、仕事の募集件数も増えます。 4. 仕事が増えることで、ワーカーはより多くの就業機会を得ることができ、満足度が高まります。 5. 満足したワーカーがリピートすると、事業者の満足度にも繋がります。満足した事業者は継続的に利用し、さらに多くの仕事を募集してくれます。 このように、「ワーカーの増加 → 事業者の増加 → 仕事の増加 → ワーカーの満足度向上 → 事業者の満足度向上 → さらなるワーカーと事業者の増加...」 というように、片方の満足がもう片方の満足を呼び、雪だるま式に事業が成長していく好循環が生まれます。 この図を描いて共通認識を得ることで、「このサイクルのどこにエネルギーを注げば、最も効率的に全体を加速させられるのか?」 という、事業戦略の勘所が見えてきます。 3. 「Flywheel」から「定義」の再整理へ 最後のステップは、Flywheelで事業全体のサイクルを俯瞰しながら、もう一度最初の問いに立ち返る、「定義の再整理」です。 5W1Hで各要素を分解し(点の理解)、Flywheelでそれらの因果関係を繋ぎ合わせる(線の理解) ことで、事業を一つの動的なシステムとして捉えられるようになります。この視点を持つと、当初ぼんやりと設定していた言葉の定義が、より解像度の高い、具体的なものに変化していることに気づきます。 特に、求められている「成功」が「Flywheelのどの部分を、どのように回すことなのか?」という問いに変わります。 「短期的な売上」を成功とすれば、新規獲得やマッチング率といった回転数を上げるための分析に集中します。 一方、「長期的な成長」が成功であれば、リピート率や評価といった質を高め、遠心力を強めるための分析に注力します。 このように、抽象的な言葉が、具体的な指標やアクションと結びつきやすくなります。 このステップを行うことで、分析が向かうべきゴールが明確になり、その精度が高まると思います。 今後の展望:思考プロセスをAIを用いてスケールさせる 今後は、本プロジェクトで得られた知見を基に、AIとの対話を通じて同様のワークが誰でも実現できる仕組みを作りたいと考えています(例えば以下のようなものを想定しています)。 1. 分析したい「問い」をAIに入力する 2. AIが対話形式で分析テーマをサポートする 3. 仮説を選択・編集する 4. 最終的な分析プランが提案される 私たちの挑戦はまだ始まったばかりです。データから価値を生み出すために、これからもアナリスト自身の「考える力」を磨き続けていきたいと思います。 We’re Hiring! タイミーのデータアナリティクス部では、ともに働くメンバーを募集しています!! カジュアル面談 も行っていますので、少しでも興味がありましたら、気軽にご連絡ください。
はじめに タイミーでAndroidエンジニアをしているふなちです。 本記事は、 「DroidKaigi 2025 参加レポート〜Part 1〜」 の記事の続きになります! まだPart 1を読んでないよ!と言う方は、ぜひPart 1も読んでいただけると嬉しいです。 本記事(Part 2)では、Part 1から続いてエンジニアメンバーによるセッションレポートと、タイミーのブース出展の様子をお届けします 📣 エンジニアによるセッションレポート nakagawa 紹介するセッション: Gemini エージェントで Android Studio 開発を高速化 タイミーではdroidkaigiでブースを出しており、多く方に足を止めていただくことができました。 ブースに立っている中で初日にどこか見覚えのある方がいらっしゃり、「お会いしたことありましたっけ?」と聞いてみたら、特に面識はないとのこと… 翌日に聴講したセッションでその方が登壇しており、その時に気づきました。 「あの人、YouTubeのGeminiでE2Eテストの動画に出てた人だ!!」 www.youtube.com セッションではYouTubeで見て未来に思いを馳せていたGeminiが自然言語で記述されたテストを実行するJourneyのライブデモを見ることができ、ちょうど当日にAndroid Studio Canaryでリリースされたばかりとのことでした。 デモでは日本語で記述して実行結果のスクリーンショットとその結果とその根拠をテキストで出力しており、メンテナンスコストが低いE2Eテストの実装ができそうだと感じました。 後にAsk the speakerに質問をしにいき、見覚えがあった理由の話もしたのですが、「彼はYouTube Famousだからね」と一緒に登壇されていたMandaさんも笑っていました。 「CIで動くようになるのはいつですか?」と伺ったところ、絶賛開発中とのことでした、期待です。 DroidKaigiから帰ってさっそくタイミーのプロジェクトで試してみましたが、まだ動かなそう…?Build Logic使っているせいか、まだうまく読めてないような気がしていますが、まだしっかりとは見れていません。安定的に使えるようになったら実際の運用で使えるか試してみたいと思いました。 murata( @murata ) 紹介するセッション: Cache Me If You Can RyuNen344さんによる「Cache Me If You Can」は、多くのAndroid開発者が"何となく"で使ってしまいがちな Gradleのキャッシュ機構 に深く迫るセッションでした。 私自身、Gradleはブラックボックス同然で、ビルドエラーが起きるたびにStack Overflowを彷徨う…そんな場当たり的な対応を繰り返していました。このセッションは、そんな私のGradleに対する苦手意識を打ち破る、まさに目から鱗の内容でした! セッションで得た知識を元にさっそくプロジェクトのGradle設定を見直したところ、ビルドパフォーマンスにつながる以下の改善を実現できました。 Configuration Cacheと並列実行の有効化 ( org.gradle.configuration-cache.parallel=true ) 環境変数を参照していた System.env() を Provider API に置き換え 通常のビルドでは不要なタスクを提供するプラグインの適用方法を最適化 これまではConfiguration Cacheが効かずに頭を悩ませることも多々ありましたが、今ではこのセッションで学んだ知識を武器に、自信を持って原因を調査できる気がしています👍 「Gradleのビルド遅いな…でもよくらからないから後回し!」となっている、そこのあなた! ぜひ本セッションのアーカイブ動画を視聴して、一緒にGradleの世界を切り拓いてみませんか?😊 スポンサーブースも大盛況でした🎉 DevRelのみーた( @earlgrayMK )です。 今回タイミーではゴールドスポンサーとしてブースを出展しました。 多くの方にお立ち寄りいただき、ありがとうございます! スキマバイトとしてアンケートのお仕事をみなさんにお願いし、たくさんの回答をいただいたのでご紹介します。 みなさんのご投票の結果、Android開発において最も困難だと感じられているのは、「既存コードベースの保守・改善」と「OSバージョン・デバイスの多様性」であることが明らかになりました。 この根深い課題に対して、タイミーのAndroidエンジニアがどのように向き合っているのか、具体的な取り組みをまとめました。 1. OSバージョン・デバイスの多様性への対応 自動テストの活用 テスト自動化ツール「MagicPod」を導入し、サポート対象OSの上下限バージョンで毎日テストを実行。広範囲の環境を効率的にカバーしています。 多様な物理デバイスでの検証 外部のQAチームや、クラウド型検証サービス「RemoteTestKit」を活用。さらに、社内Slackで特定端末を持つメンバーに協力を仰ぐなど、物理デバイスでの実機検証を徹底しています。個人的に折りたたみスマホを購入し、検証に活かす開発者もいます。 2. 既存コードベースの保守・改善 進捗の「見える化」と「仕組み化」 リファクタリングの進捗をLinterのwarning数やモジュールの分割状況などで定量的に可視化し、チーム全体で課題意識を共有する仕組みを重視しています。デザインシステムの構築やEdge-to-Edge対応もその一環です。 プロダクトオーナー(PO)との共通理解 技術的負債の解消がプロダクトの価値向上に不可欠であるという点をPOと共有。これにより、計画的なリファクタリングを実現しています。 適切なエンジニアリソースの確保 リソース不足が負債の蓄積と開発の悪循環を招かないよう、Androidエンジニアの適切なリソース確保に努めています。 バランスの取れた技術選定 新技術の導入時は、必ずその妥当性をチームで議論し、合意形成を図ります。これにより、将来の負債化を防ぎ、技術的なバランスを保っています。(この領域では、特にエンジニアの村田が重要な役割を担っています。) 高いサービスレベル目標(SLO)の維持 プロダクトの品質目標を高く設定し、それを維持する文化が、コードベースの健全性を保つ動機付けにもなっています。 両課題に共通する、タイミーの強み 厚いチーム体制 チームメンバーが多いため、新規のプロダクト開発と並行しながら、検証やリファクタリングといった改善活動を分担して進められる体制が強みです。 「地道な努力」の文化 メンバー全員が「地道に改善を続けるしかない」という共通認識を持っており、日々の継続的な取り組みを大切にしています。 Day2「開発している中でAIをどのように活用していますか?」 Day2では様々なご回答をいただいたので、特に多かったものや面白いと思ったものをまとめました。 おわりに DroidKaigi 2025では、各セッションや参加者の方々との交流から、日々の開発の参考になる知見を得ることができました。ここで得た学びは、今後のプロダクト開発につなげていきたいと思います💪 また、10月21日(火)にココナラ社、アンドパッド社、令和トラベル社、そしてタイミーの4社共催で「 After iOSDC & DroidKaigi 2025 」を開催します。 当日は弊社からAndroidエンジニアの tick-taku が登壇します 🎉 ハイブリッド開催 となっておりますので、ご興味のある方はぜひ気軽にご参加ください 🙌 reiwatravel.connpass.com 最後に、本カンファレンスを支えた運営・登壇者のみなさん、ならびにタイミーブースにお越しいただいた方々、ありがとうございました!
はじめに タイミーでAndroidエンジニアをしているみかみです。 2025年9月10日から12日にかけて、Androidの技術カンファレンスである「 DroidKaigi 2025 」が開催されました。タイミーからはAndroidチームをはじめとする複数のメンバーが現地に参加し、今年も昨年に続いてゴールドスポンサーとしてブースを出展しました。 セッションでは最新の知見に触れる機会が多く、日々の業務にもつながる具体的な学びを得ることができました。また、会期を通しては立ち話や展示をきっかけに参加者同士が議論を深める場面も多くあり、交流の広がりも強く感じました。そのような様子は会場にとどまらず、XなどのSNSを通じて、オンラインでも盛り上がりをみせていたのが印象的です。 Part1、Part2の2記事に渡り、エンジニアメンバーによるセッションレポートと、ブース出展の様子をお届けします。 本記事(Part 1)では、エンジニアメンバーによるセッションレポートをご紹介します! エンジニアによるセッションレポート まずは、DroidKaigiに参加したエンジニアメンバーによるセッションレポートを紹介します。 Hunachi( @_hunachi ) 紹介するセッション: Androidライブラリアンの手引き:堅牢なライブラリとSDKの構築 私はライブラリを公開した経験はないのですが、このセッションはライブラリ開発者だけでなく、マルチモジュール構成で開発している人、そしてライブラリを利用する人にも多くの学びがある、非常に有益な内容でした。 このセッションで特に印象的だった、新しく学べた点をいくつかご紹介します。 公開範囲の制御の重要性について internal を正しく使うことはもちろん、 Explicit API mode を有効にすることで、意図せずパブリックAPIが公開されてしまうのを防げると知りました。これによって、モジュールの責任範囲が明確になり、APIの健全性を保つことができます。 親切なAPIの非推奨化ついて クラスや関数を非推奨(Deprecated)にする際、 @Deprecated アノテーションの message や replaceWith 引数に具体的な説明を記述することで、利用者がスムーズに新しい実装に移行できる配慮が大切だと学びました。 破壊的変更の自動検知について パブリックAPIを変更、特に削除する際には、 binary-compatibility-validator を導入して自動的にチェックをかける手法が紹介されていました。うっかり互換性を壊してしまうミスを防ぐための仕組みは、特にライブラリのメンテナンスにおいて非常に重要だと感じました。ライブラリを作成する機会があったら利用するようにしたいです。 また、ライブラリとそれを利用するプロジェクト間でリソース名が衝突するという問題についても話がありました。マルチモジュールでの問題においては弊社でも対応は済んでいるものの、ライブラリ使用者として予期せぬ挙動に悩まされた経験が何度かあるので自分がライブラリを作る側になった時は気をつけようと思いました。 ライブラリの裏側で何が起きているのかを知ることで、利用者としてもより賢く付き合っていくことができると再認識しました。今後、マルチモジュールでの開発やライブラリを利用する際に、今回学んだ知識を活かしていきたいです。 tick-taku 紹介するセッション: EncryptedSharedPreferences が deprecated になっちゃった!どうしよう! タイトルの通りで、なぜ deprecated になったかなどの背景を含め紹介し覚悟を決めさせてくれる素晴らしいセッションでした。 タイミーでは KeyStore + Cipher + DataStore を利用していましたが、別のブログで Tink を利用するといい感じに wrap されて、複雑な暗号化周りをライブラリに任せつつ実行速度が速くなると知りました。特定端末でのみクラッシュしてそうな気配を Crashlytics から観測しており、「もしや自前の実装が悪く Tink であれば Google 提供だしその辺も対処してくれているのでは…?」と思い移行しようとちょうど DroidKaigi 直前に Issue を作成して検討していたところ、このセッションの存在を知りました。 結論からですがやめた方がいいとのことです 😇 どうやら観測していたクラッシュは OEM デバイスの KeyStore のバグでどうしようもないとバッサリでした。これは security-crypto が deprecated になった要因の1つらしく、Tink に移行したところで解決せず、むしろアプリ側でのハンドリングが難しくなるそうです。こうなったらどうしようもないのでデータは捨てましょうと割り切るしかないとのことでした… また、クラッシュの要因としてもう1つバックアップ設定の話がありました。 allowBackup=false に設定しているため大丈夫と考えていたのですが、Android 12 からメーカーによっては device-transfer によるバックアップは allowBackup の設定を無視するようになっているそうです。おかげでデータは移行されるのに key が異なるので復号に失敗するというものでした。 本当にちゃんと作ってくれメーカー… また EncryptedSharedPreference が存在してしまうが故に我々はなんでもかんでもデバイスのストレージに保存してしまうという思想のもと deprecated にした背景もあるらしく、「そもそもそのデータをデバイスに保存する必要があるのか?」は設計時に常に意識したい事項だと感じました。 紹介するセッション: OAuthを正しく実装する:Androidアプリのためのセキュアな認証 OAuth を導入するための基礎知識や歴史が理解できる内容でした。 一度実装したり触れたりしたことがある人はそうだよねとなる内容も多く OAuth の入門として非常に勉強になると思います。 気になった点としては、多くのアプリでは access token をデバイス上に保存していると思いますが、その際は変に暗号化せずにシンプルに SharedPreference を使ってデバイスを信頼しましょうといった趣旨の内容が話されていて、Android は root 化したら引き抜けると思ったのですが大丈夫なんでしょうか… また、 PKCE がベストプラクティスらしいですが、そこまで実装しているアプリはどれだけあるのか気になります。 haru 紹介するセッション: スマホ新法って何?12月施行?アプリビジネスに影響あるの? DroidKaigi初の公正取引委員会の人による発表で、主にこれから施行される新しい法律に関する話でした。 対象になるのは基本的にAppleやGoogleなどのプラットフォーム事業者で、In App Biilingなどの機能に対して影響があるようでした。 とはいえ、一般デベロッパーに開放していない機能を開放して欲しいなどのリクエストを送ることもできるようになるらしいので、今後どうなっていくか目が離せない法律の1つでもありますね。 みかみ 紹介するセッション: Be a Business-Driven Android Engineer DroidKaigi 2025に参加して、特に印象に残ったセッションの1つが、ohzonoさんの「 Be a Business-Driven Android Engineer 」です。Androidエンジニアがどのようにビジネスの成長に貢献できるのかを解きほぐした内容で、今の自分が所属するストリームアラインドチーム(価値提供チーム)の状況とも重なり、とても心に残りました。 特に共感したのは「越境」という考え方です。現在所属するチームは少人数のため、エンジニアがデータ分析を担ったり、専門外の実装に挑戦したりと、役割の垣根を越えた働き方が自然に行われています。そのため、「越境」という言葉はもともとチーム内でもキーワードになっていました。今回のセッションは、そうした取り組みを価値あるものとして肯定してくれる内容であり、大きな励みになりました。AIの進化によって専門外の領域に踏み込みやすくなっている今、「越境」はこれからますます重要になると感じます。 また、開発チームが売上を直接的なKPIとして持つという話も新鮮でした。私はこれまで、パフォーマンス改善やエラー率の低減、ユーザー行動に基づく指標といったプロダクト内部の成果に注目することが多かったのですが、このセッションではそれに加えて、自分たちのアウトプットを事業全体の成果と結びつけて考える視点が提示されました。自分の仕事がどうビジネスインパクトにつながるのかを意識することで、エンジニアとしてもっと広い視野で取り組んでいきたいと感じました。 さらに、この考え方を技術面から支える手段として、Kotlin Multiplatform (KMP) の存在感も改めて実感しました。副業や別プロジェクトでKMPを利用してきた経験からも、その有効性を強く感じています。もちろん、ビルド速度やKMPそのものの複雑さ、iOSとAndroidエンジニア間の連携といった課題はまだあります。ドメインレイヤーの共通化によるメリットは大きく、KMPはAndroidエンジニアがiOS開発へと「越境」する後押しとなり、チーム全体の生産性を高める現実的な選択肢だと思います。今後も注目していきたい技術です。 syam 紹介するセッション: KotlinでのAI活用による開発 JetBrains の Sebastian Aigner さんと Márton Braun さんによる「 KotlinでのAI活用による開発 」というセッションが気になったので聴講しました! Kotlin と AI の関わり方を「コード補完のような軽い支援」から「エージェントに任せる自動実装」まで段階的に紹介しており、JetBrains の AI エージェント Junie を使ったデモでは、新しい画面追加や UI の改良を自動で行っていて、既存コードのパターンも踏まえた修正が印象的でした。 また、Kotlin 製のフレームワーク Koog も紹介され、マルチプラットフォームで AI エージェントを組み込める仕組みとして活用できるとのことでした。 nshiba( @nshiba310 ) 紹介するセッション: ユーザーも開発者も悩ませない TV アプリ開発 - Compose の内部実装から学ぶフォーカス制御 AndroidTVアプリを Compose を使って実装方法を紹介するセッションでした。 Compose 以前の時代に存在していた leanback library という Google 製のライブラリがありましたが、これは Compose には対応していません。 Compose で AndroidTV を実装しようと思ったら、どういったライブラリを使ったら良いかと行った基礎的なことから始まり、leanback library ではデフォルトでライブラリが対応してくれていた、フォーカス周りの制御やいまどのUIにフォーカスがあったているかがわかりやすくなるUIの制御などを Compose では自前で実装する必要がありどういった対応が必要かについても詳しく解説されていました。 また AndroidTV アプリでは、スクロールの制御についても通常のモバイルアプリとは異なる実装方法が必要になり、これについても詳しく解説されていました。 セッションタイトルの通りどのセクションでも Compose の内部実装までちゃんと処理を追って説明されていてとてもわかりやすく、これから Compose で AndroidTV アプリを作成する方にとって必見の内容がつまっていました! 続きはPart 2の記事で! 引き続き、Part 2の記事にて他のエンジニアメンバーによるセッションレポートと、ブース出展の様子をお届けします。 ぜひ読んでください! tech.timee.co.jp
こんにちは、タイミーでエンジニアをしている徳富です。 今回は、 EKS上にGitHub Actions Self-hosted Runner基盤を構築した話 をお届けします。 背景:GitHub Actionsへの移行と、新たに見えてきた課題 2024年10月に公開した CI基盤をGitHub Actionsへ移行した記事 で紹介したとおり、 CircleCIからGitHub Actionsへの移行によって、私たちのCI体験は大きく改善しました。 しかし、開発者やテストケースが増え、時間が経つにつれて 新たな課題 も見えてきました。 実行回数の急増によるコスト高騰 2025年2月頃からDevinをはじめとしたAIエージェントの利用が進み、PRやpushの回数が一気に増加 開発者数の増加も重なり、ワークフロー実行回数が比例して伸びていった GitHub-hosted Runnerは料金や安定性の面である程度最適化されているため、Self-hostedに切り替えれば必ずしもコスト削減につながるとは限らない。 しかし、割引オプションが少なく、コストコントロールが難しい という課題もある 一方AWSならSavings PlansやSpotインスタンスなどの仕組みを活用でき、柔軟に最適化が可能。開発者やエージェントの利用増加で実行回数が急増するタイミーのユースケースにおいては、この「柔軟に最適化できる」という点が大きなメリットであることがわかってきました テスト時間のじわじわとした増加 テストケース数の増加により、全体の実行時間も長くなってきている apt install などのセットアップ処理にも時間がかかっている 「ランナーイメージに事前インストールしておけばもっと速くできるのでは?」という声も出始めた 「コストをコントロールしながら、テストももっと速くしたい」 そんな思いから、私たちは Self-hosted Runner基盤の構築 を検討し始めました。 最初のアプローチ:ECS + Lambda構成 当初は ECS + Lambda + API Gateway を組み合わせて、ランナー基盤を構築しようとしました。 しかし実際に検証してみると、すぐにいくつかの課題に直面しました。 レートリミットの考慮 1回のCI実行で最大35並列のランナーを起動してます。 日中は多いときで 1時間に60回以上 実行されることもあり、GitHub API の レートリミット を意識した設計が必要になります。 → これを Lambda 側で考慮して実装するのはかなり複雑。 ランナーは30秒以内に立ち上がってほしい という要件がある。 Lambda のコードを継続的にメンテナンスするコスト も無視できない。 「長期的に運用するには、この構成は少し複雑すぎるかもしれない」 そう判断し、よりシンプルに運用できる別のアプローチを探すことにしました。 選んだのは EKS(auto mode) × Actions Runner Controller そこで目をつけたのが、GitHub公式が提供する **Actions Runner Controller (ARC)**。 ARCはGitHub ActionsとKubernetesをつなぎ、必要なときだけランナーPodを動的に起動してくれます。 さらにクラスタ基盤には EKS Auto Mode を採用しました。 ノード管理やスケーリング設定をほとんど自前で持たずに済むため、運用の手間を大幅に減らせるのが魅力です。 「EKS Auto Mode × ARC であれば、管理コストを抑えつつ柔軟なSelf-hosted Runnerが作れるのでは?」 そう考え、この構成で進めることにしました。 アーキテクチャ概要 ざっくりとした構成はこんなイメージです。 アーキテクチャー図 ARC : GitHub APIと連携し、ランナーPodを自動的に作成・削除 EKS Auto Mode : クラスタ管理を最小限に抑えつつ、柔軟なスケーリングが可能 Karpenter : Auto Modeの裏側で働くプロビジョナー。従来のCluster Autoscalerよりnode起動が速い 特にCIのように時間帯によって必要リソースが大きく変動するワークロードでは、 Auto Mode+Karpenterの組み合わせが非常に相性が良く、メンテナンス性・柔軟性の両立 ができました。 導入時に直面した課題と解決策 ここからが本番です。 実際に導入を進めていくと、次々と問題が発生しました。 1. Spotインスタンスの安定性問題 当初はコスト削減を狙って、停止率の低いインスタンスタイプの Spotインスタンス を採用していました。 しかし、弊社のCIは 35並列で高頻度に実行 されるため、必要なインスタンス数が多くなり、停止確率が低いタイプでも 1日あたり5〜10回ほどノードが落ちる ことがありました。 その結果、CIが途中で失敗するケースが頻発し、 開発者体験を大きく損ねる要因 となってしまいました。 対策 そこで思い切って オンデマンドインスタンスに切り替え 、必要に応じて Savings Plans を適用する方針にしました。 オンデマンドにしたことで、ランナーが突然落ちるリスクがなくなり、安定してCIを回せるようになった 安定性が向上したことで、CIだけでなく デプロイなど他のワークフローもSelf-hosted Runnerに寄せる ことが可能に これによりEC2のアイドル時間を減らし、稼働率を高めることでコスト効率も改善できました 2. スケールインでランナーPodが強制終了する問題 次に直面したのは「EC2のスケールインによって、ランナーPodがCI実行中に突然落ちる」という問題です。 原因は、Karpenterの設定でした。 デフォルトでは disruption.consolidationPolicy が WhenEmptyOrUnderutilized になっており、 ノードのリソース使用率が低いと、 Podが稼働中でも容赦なくノードを落としてしまう のです。 (参考: https://karpenter.sh/docs/concepts/disruption/) 対策 consolidationPolicy を WhenEmpty に変更 Podがないノードのみスケールイン対象とするよう設定 spec : disruption : consolidationPolicy : WhenEmpty これでランナーPodが実行中に消える問題は解消しました。 3. ノードが全然スケールインしない問題 しかし、ここで別の問題が発生します。 「一度スケールアウトすると、ノードがほとんど減らない」という現象です。 原因は Kubernetes のスケジューリング。 Kubernetes のスケジューラには、Pod をできるだけ均等に配置しようとする仕組みがあります。 そのため Pod が複数のノードに分散して配置されやすく、 ノード上の Pod が 0 になるケースが少ない ため、スケールインがなかなか進まなくなります。 対策 Pod Affinity を利用し、ランナーPodはなるべく同じノードに詰めるよう設定 Pod配置の断片化を防ぎ、スケールインしやすくしました affinity : podAffinity : preferredDuringSchedulingIgnoredDuringExecution : - weight : 100 podAffinityTerm : labelSelector : matchLabels : actions.github.com/scale-set-namespace : arc-runners topologyKey : kubernetes.io/hostname これによりリソース効率が大きく改善されました。 4. 夜間にリソースを最適化する作戦 リソース効率をさらに高めるため、 日中は安定性を優先し、夜間だけ段階的にノードを整理する仕組み を導入しました。 具体的には、 disruption.consolidationPolicy を WhenEmptyOrUnderutilized に設定したうえで、夜間に 一定間隔で15分だけpodが存在するノードのスケールインを許可 → その後は再び禁止 というサイクルを繰り返します。 これにより、ノード上にPodが残っていても一気に消されることはなく、 「急にPodが落ちてCIが止まる」といったリスクを避けながら、少しずつリソースを最適化 できるようになります。 spec : disruption : consolidationPolicy : WhenEmptyOrUnderutilized consolidateAfter : 5m budgets : - nodes : "0" reasons : - Underutilized schedule : "0 0 * * *" # 0:00〜11:45 UTC 禁止 (JST 9:00〜20:45) duration : "11h45m" - nodes : "0" reasons : - Underutilized schedule : "0 12 * * *" # 12:00〜15:00 UTC 禁止 (JST 21:00〜翌0:15) duration : "3h15m" - nodes : "0" reasons : - Underutilized schedule : "30 15 * * *" # 15:30〜17:00 UTC 禁止 (JST 翌0:30〜翌2:15) duration : "1h45m" - nodes : "0" reasons : - Underutilized schedule : "30 17 * * *" # 17:30〜20:00 UTC 禁止 (JST 翌2:30〜翌5:15) duration : "2h45m" - nodes : "0" reasons : - Underutilized schedule : "30 20 * * *" # 20:30〜24:00 UTC 禁止 (JST 翌5:30〜翌9:00) duration : "3h30m" この仕組みによって、 日中は安定してCIを回しつつ、夜間は少しずつノードを整理してリソースを効率的に活用 できるようになりました。 5. コールドスタート問題をランナープールで解消 弊社では 35並列 のランナーを利用しています。 そのため、完全なオンデマンド起動では間に合わず、 ランナー起動待ちが発生してしまうこともありました。 そこで、ARCの minRunners 設定を活用し、 ランナープールを作成 。 あらかじめ一定数のランナーを起動しておくことで、 要求があればすぐに割り当てられるようになり、 GitHub-hosted runnerと同じ快適な使い心地を実現しました。 5 Runner PodでDockerを使う工夫 最後のハードルは「ランナーPodでDockerをどう使うか」です。 私たちのCIではMySQLやRedisなどの service container を多用しているため、RunnerコンテナからDockerを操作できる仕組みが必要でした。 選んだ方法 RunnerでDockerを扱う方法は大きく分けて DooD (Docker outside of Docker) と DinD (Docker in Docker) の2種類があります。(参考: GitHub Actions の self-hosted runner で Docker を使う際のパターン整理 )。 今回は DinD を採用しましたが、その中でもさらに実現方法が2パターン存在します。 Runnerコンテナ内で直接Dockerデーモンを起動する方式 Runnerコンテナ自身が dockerd を立ち上げ、 docker build や docker run を自己完結的に実行する。 シンプルですが、Runnerコンテナに 特権モードや大量の権限 を付与する必要があるため、セキュリティ面での懸念が残ります。 また、RunnerコンテナとDockerデーモンが同居することでリソース管理が複雑化しやすく、トラブルシュートもしづらいという課題があります。 Dockerデーモンをサイドカーとして起動する方式 Pod内で Runner と dockerd を分離し、 emptyDir などを介して ソケット通信 させる。 Dockerの実行環境はサイドカーに閉じるため、Runnerコンテナは通常権限で動かせる。 CIジョブ終了とともにPodごと削除されるため、イメージやボリュームなどの作業痕が自動的に掃除される点もメリットです。 私たちは Runnerコンテナに強い権限を持たせないことを重視 し、後者の DinDサイドカー方式 を選択しました。 まとめと次回予告 今回、 EKS × ARC を使ってGitHub Actions Self-hosted Runner基盤を構築し、 コスト・パフォーマンス・柔軟性のいいバランスで実現できました。 ただ、これで終わりではありません。 次回は、この基盤の上で テスト実行時間をさらに短縮するために行ったチューニング について詳しく紹介する予定です。 「GitHub-hosted runnerで限界を感じている」 「EKSでSelf-hosted Runnerを検討している」 そんな方の参考になればうれしいです。
こんにちは!
タイミーでBackendEngineerをしている志賀( @akitoshiga )です!
2025年9月6(土)に開催された「ながらRuby会議01」に行ってきましたので、その様子を振り返りたいと思います! ながらRuby会議には、「Kaigi Pass」という社内制度を利用して参加しました。
「Kaigi Pass」とは、世界中で開催されているすべての技術カンファレンスに無制限で参加できる制度です。 productpr.timee.co.jp 会場の様子 当日は長良川沿いにある「 長良うかいミュージアム 」というとても素敵な場所で開催されました。 会場内にはスポンサーノベルティや展示などもありました。 セッションの様子 refinementsのメソッド定義を4000倍速くした話 alpaca-tc さん Ruby3.2以降、refinementsにおけるメソッド定義は約1万倍低速化していました。 社内サービスの開発でこの事態に直面した際に、原因の究明からRubyへのコントリビュートまでを行った過程をお話しされていました。 refinementsとはRuby2.0から導入された安全にRubyを拡張する仕組みのことで、モンキーパッチを当てたクラスのスコープを限定させることが可能です。 きっかけは、社内サービスのRubyのアップデートの際にRuby on Railsのアプリケーションの起動に数十秒かかるようになってしまったことでした。 Vernier とMiddlewareを利用して計測を行ったところ、ボトルネックとなっている処理が判明しました。 そこにrefinementsのメソッド Module#refine が存在していました。 Ruby3.3では、 Module#refine を呼び出した際にrefineのcallcacheがクリアされる処理が追加されます。 このcallcacheが削除されたことが低速化の原因でした。 これを Ruby Issue Tracking System で報告したところアドバイスをもらいました。 しかし、alpaca-tcさんはRubyの実装であるC言語には馴染みがありませんでした。 この問題に対してはChat-GPTや ko1/rubyhackchallenge を活用したりコミュニティでアドバイスを得ることで解決していきました。 最終的にプルリクエストを作成してRuby本体へのマージが実現したそうです。 技術的なギャップを埋めるためにAIを活用したのは素晴らしい解決方法ですし、粘り強く取り組みRubyへのコントリビュートを実現する姿は素晴らしいと思いました! 知っているようで知らないrails newの世界 luccafortさん speakerdeck.com Ruby on Railsではプロジェクトの初期化の際に rails new というコマンドを実行します。 しかし、このコマンドの裏側でどのような処理が行われているかは多くは知られていません。 そこで、コマンドはどのような実行フローを行っているか、また使われている技術がどのような設計の組み合わせによって実現しているかについて深掘りしてお話しされていました。 luccafortさんの今回の発表の動機の一つには、オーガナイザーを務められた「 関西Ruby会議08 」での体験から、個人開発以外の成長の選択肢を模索したかったという想いがあったそうです。 rails new で実行される処理は以下の流れになっています。 コマンド解析 ジェネレータ初期化 オプション処理 ディレクトリ作成 ファイル生成 bundle install これだけでも長大な処理なので、本発表ではコマンドの解析からジェネレータの初期化まで中心に説明していました。 rails new を実行すると Rails::Command によってargの解析やエラーチェックが行われます。 その後、 Rails::Command.invoke によって入力したコマンドの内容から Rails::Command の適切なサブクラスが呼び出されます。 今回の場合は Rails::Command::ApplicationCommand が読み込まれます。 Rails::Command::ApplicationCommand#perform によって無効なコマンドチェックなどが行われた後、 Rails::Generators::AppGenerator.start で定義された各種ファイルの生成タスクが実行されます。 その後、 Rails::Generators::AppGenerator#bundle_command によって bundle install が実行され最終的にコールバックが呼び出されます。 rails new に関する説明は以上です。 この取り組みを通してluccafortさんは仕組みを理解する重要性について気づきがあったそうです。 仕組みを理解していなくてもRuby on Railsは使えるものの、深く理解することで新しい発想や新たな気づきのきっかけになるとお話しされていました。 Ruby × iOSアプリ開発:共に歩んだエコシステムの物語 Tomoki Kobayashi さん speakerdeck.com Kobayashiさんは普段は主にモバイルエンジニアとして活動されています。 RubyはiOS開発の歴史において過去大きな役割を担っており、またiOS開発コミュニティもRubyに大きく貢献しています。 iOS開発とRubyが今までどう関わってきたかの歴史をお話しされていました。 2010年ごろのiOSアプリ開発はObjective-Cが使用されていましたが、サードパーティのライブラリのインストールが大変だったそうです。 ライブラリによってインストールの仕方が異なっており、Xcodeのビルド設定を行う際にもAppleの非公開の独自仕様のために保守性が非常に低いものでした。 この問題を解決するために CocoaPods というパッケージマネージャーが登場しました。 これによりライブラリの依存性解決・ダウンロード・Xcodeへのプロジェクト統合まで自動できるようになりました。 CocoaPodsはRubyでライブラリ管理に使用されるRubyGemsとBundlerを参考に作成されており、本体の実装もRubyで書かれています。 その他も nomad-cli や fastlane といったRubyを参考にしたツールが登場してきました。 この背景はツールの作成者が元々RubyやRuby on Railsのエンジニアが多かったことにあるそうです。 そして、CocoaPodsの依存関係リゾルバーである Molinillo(モリニージョ) はBundler1.9, RubyGems2.9に搭載されるようになりました。 しかしながら、iOS開発とRubyの関わりは薄れつつあるそうです。 2014年のSwiftの登場を機にSwiftが公式のパッケージマネージャーを発表したりBundler2.4でMolinilloが引退しています。 Ruby Mini Language作成記 〜ハンズオンで学ぶインタプリタの世界〜 haruguchi さん Rubyを用いてインタプリタを作成した経験をもとに、字句解析、構文解析、評価とった処理の実装方法や設計上の注意点についてお話しされていました。 インタプリタを作ろうと思ったのはharuguchiさんがRubyKaigi2025に参加したことがきっかけだそうで、RubyKaigiでよく発表される言語処理の話の理解を深めたいと思った時にインタプリタの実装を思いついたそうです。 haruguchiさんが参加されている勉強会でこの話を持ち込み、他のメンバーと実装していくことになりました。 インタプリタはFizzBuzzが動くものをゴールとして、単純な2項演算の実装からはじめることにしました。 最初は単純なパーサーのみで実装することとし、インタプリタの機能を追加していくにつれてレキサーを実装したり構文解析方法を工夫したりと実装を進めていきました。 自身で実装することを面白くするポイントとしてif文の条件式の区切りを < > にしたりとオリジナルの要素を追加していったそうです。 5ヶ月ほどでFizz Buzzの実装まで完了して、途中デモで実践していました。 会場のみんなでモブプロしてるの良すぎる #nagara01 pic.twitter.com/PX9v0mA3k2 — しが あきとし (@akitoshiga) 2025年9月6日 当初のゴールとしては達成したのですが、ここから配列やハッシュといったデータ構造も行ってみたいとのことでした。 言語処理の話題はRubyではよく出てくるのですが、その理解のためにインタプリタを自前で実践するところに尊敬しました。また、自分も挑戦してみたいと思いました。 💡Ruby(ひかるびー) 川辺で灯すPicoRubyからの光 bash さん speakerdeck.com PicoRubyという組み込み向けの軽量なRubyを使ってLEDを点灯させるところから、音声や加速度といったセンサーを追加して様々なことに挑戦することでRubyで組み込み開発をする楽しさについてお話しされていました。 最初の機材は「 ATOM Matrix 」という開発ボードで、内蔵のLEDを点灯させるところから始まりました。 また、基本的なアーキテクチャは「Super Loop Architecture」というものを用いていました。 Super Loop Architectureとは、初期化の後に発生させた無限ループの中でLEDに対しての操作を行うものです。 LEDの点灯に成功させたあとは、ランダムに点灯させたり自分の動きに合わせて点灯させたりといった試みを行っていきました。 最終的には棒状のLEDやMIDIシンセサイザーといった他の機材と連携させる試みを行っていました。 ライトセイバーを振り回すbashさん #nagara01 pic.twitter.com/SSv6g6SMAE — すぎうり (@uproad3) 2025年9月6日 365日のOSS開発を続ける舞台裏 Koichi ITO(Koic) さん speakerdeck.com RuboCopのコミッターであり、365日OSSにコントリビュートを行っているITOさんの普段の開発環境やOSSに対する心構えについてお話しされていました。 開発環境は業務のコードとOSSのコードを透過的に扱えるようにすることをテーマとしていました。 そのためのツールとして ghq や gem-src の使用を推奨されていました。 OSS活動をするとローカルリポジトリが大量に増えるのですが、その点については peco や fzf を用いた対策を紹介されていました。 印象的だったのは、gitコマンドの扱い方でコミット権のないリポジトリとリポジトリでの振る舞いを合わせるためにFork先のリポジトリをoriginとして、upstreamをForkした方のリポジトリとすることを推奨されていた点です。 これによってどの環境にプッシュする際も git push upstream head と同一のコマンドにできる利点について強調されていました。 心構えについては、コードの内容だけではなく発言やレビューについても恥ずかしくない振る舞いをしようという「ソーシャルコーディング」という考え方や、OSSを地球全体での非同期開発と捉えて自己完結したコードのみのPRを出さずにコンテキストを文章化して伝えることの重要性にも触れられていました。 アフターイベント 懇親会の後にはアフターイベントとして鵜飼漁の観覧がありました! 鵜呑みです。 #nagara01 pic.twitter.com/EPTU5bsiJ3 — どみにをん525 (@Dominion525) 2025年9月6日 残念ながら自分は参加できなかったのですが、大変盛り上がったみたいです。 まとめ スポンサーLTも含めてどのセッションも大変面白かったです。 発表者の「これがやりたいからやる!」といった気持ちに基づいた発表が多かったのですが、その姿勢をとても尊敬しました。 また小規模の開催だったこともあり、アットホームで参加者間でのコミュニケーションもとりやすくたくさんの方と交流できました。 また、自身は今回初めて岐阜に行ったのですが、自然と人々の生活が調和したとても素晴らしい場所でした。 大変心に残る素晴らしい会だったので、次回開催される際はまたぜひ伺いたいなと思いました!
はじめに こんにちは。タイミーでデータエンジニアをしている chanyou です。 先日、おそらく関西圏で初めてのデータエンジニアリング・アナリティクスエンジニアリングをテーマとしたイベント、 関西データエンジニア/アナリティクスエンジニアMeetup に参加してきました! https://monotaro.connpass.com/event/360460/ monotaro.connpass.com このミートアップは、株式会社MonotaRO主催のもと、「関西に住みながらデータ関連の仕事をしたい」「関西で同じ職種の仲間と繋がりたい」という想いを持つデータ専門職向けに開催されました。 当日は株式会社10X、株式会社MonotaRO、ダイハツ工業株式会社、そして当社タイミーの4社の発表と、最後にパネルディスカッションがありました。 非常に熱量あるイベントでしたので、内容をまとめてお伝えします。 会社にデータエンジニアがいることでできるようになること まずは株式会社10X 吉田さんの発表です。 speakerdeck.com マネージドサービスが普及し、誰でもある程度のデータ基盤を構築できるようになった現代において、改めて「なぜデータエンジニアが必要なのか」という問いに、具体的な事例で答えていく内容でした。 特に印象的だったのは、以下の2つの取り組みです。 アセスメントの実施とデータ品質の改善 DMBOKを拠り所にデータ品質を定義し、データセットごとに可視化する仕組みを構築されているとのこと。 正直データ品質の継続的なモニタリングまでされていて、見習っていかねばと思いました。 Data Contractによるデータソース仕様の確立 データの生産者とデータの消費者の橋渡し役として、連携のプロトコルを取り決めて運用されているとのこと。 これもまたマネージドサービスだけでは実現できない、人間に残された仕事のうちのひとつだなと思いました。 セッション全体を通して、「データエンジニアの本質とは何か?」という問いを突きつけられたような感覚で、身が引き締まる思いでした…!! 組織的データ活用をスケールさせる、アナリティクスエンジニアリングの実践 続いて株式会社MonotaRO 小谷さんの発表です。 アナリティクスエンジニアリングに特化した部署を立ち上げ、組織的なデータ活用をスケールさせている実践例が共有されました。 今回発表された小谷さんは、営業専門のアナリティクスエンジニアとして、営業組織にフルコミット。深く入り込んで課題の特定からソリューションの実装・運用までされているそうです。 印象的だったのは営業組織に本当に深く入り込んでいる点で、営業管理部署の定例に参加するのはもちろん、作業も同じ部屋で行うなど、徹底的に現場に寄り添っていました。これにより真の課題を特定して、成果につながったとのことでした。 さらに 縦に伸ばして横に広げる という、アナリティクスエンジニアが深さを探求して、データエンジニアがそれを横展開する思想が語られており、非常に共感できる考え方だなと思いました!! 具体的なソリューションについても、セマンティックレイヤーを整備したり、生成AIによる議事録作成の自動化をしたりと、踏み込んだデータ活用をされていて勉強になりました。 AnalyticsEngineeringがもたらした実インパクトと未来のロードマップ 当社 okodoon さんによる発表です。 speakerdeck.com タイミーにおけるアナリティクスエンジニアリングを「データ活用UXの改善」と定義し、これまで行ってきたデータモデリングやデータアプリケーション開発が、実際にどのようなインパクトをもたらしたかを紹介しました。具体的には以下の事例を紹介しました。 Looker整備によるアナリストの負荷軽減と指標統一 個人情報を含むデータのアウトプット申請フローのセルフサービス化 また、後半ではさらにデータ活用体験を向上させるために行っているヒアリング活動についても触れました。 データ利用者の業務理解には、ジョブ理論とユーザーストーリーマッピングを組み合わせた独自のフレームワークでヒアリングを実施。いざモデリングを行うとなった際にはアジャイルデータモデリングを実践しています。 またアナリティクスエンジニアリングの魅力に注目して語っていて、okodoonさんは 飽きないことも重要 と話していたのが同僚ながら面白かったです。 製造業におけるデジタル人材の活躍ポイント ダイハツ工業株式会社 太古さんによる発表です。写真NGのスライドでしたので文章のみでお伝えします! 自動車メーカーということで他の3社とは、データを取り巻く環境が全く異なっていました。AI、BI、アプリ開発の3軸で、トップダウンとボトムアップの両面で変革を推進しているとのことでした。 AI に関しては、スキルあるメンバーが現場に入り込み、たった2ヶ月でリリースして回っているとのことでした。スタートアップ顔負けなスピード感に驚きました…! BI に関しては、ちょっとダッシュボード作れるレベルの方を増やすのではなく、人に教えられるレベルの方を増やすことに注力した戦略を取られているとのことでした。 アプリ開発軸に関しては、手を挙げたキャリアチェンジしたい方などにプログラミング教育を実施して、元の部署や異動後の部署で現場の課題を解決する動きを取ってもらっているとのことでした。実際に人手で行っていた作業を自動化する内製アプリがポツポツと開発されていて、現場の課題をそのまますぐに解決できる環境が実現されているんだなと思いました…すごい。 パネルディスカッション セッション後は、登壇者全員によるパネルディスカッションが行われました。多岐にわたるテーマで議論が交わされ、特に印象に残った点をいくつかご紹介します。 Q. ジョブ理論の活用といった知識のインプットや、チームでの議論はどう進めている? okodoon(タイミー): 「プロダクト開発の知見を参考にしている。社内のプロダクトマネージャーが実践しているジョブ理論やユーザーストーリーマッピングの手法を、データ基盤の利用者ヒアリングに応用した。」 吉田さん(10X): 「X(旧Twitter)など外部からの情報収集に加え、ソフトウェアエンジニアリングの知見を参考にすることが多い。ただし、単に新しい技術を導入するのではなく、自分たちの組織のフェーズに合っているかが重要。経営陣にも年単位で繰り返し伝え続ける粘り強さも必要。」 Q. 大人数がデータを触る中でのガバナンスや管理体制はどのように担保してる? 太古さん(ダイハツ): 「まずはセキュリティを固めたセキュアな環境を構築し、その中で自由に使えるようにしている。新しい技術を試すためのSandbox環境を用意するなど、目的で使い分けている。」 Q. データ品質改善の副作用や、他部署への説得はどう乗り越えた? 吉田さん(10X): 「オペレーション部門などとの連携は課題になりやすい。まずは現状の定義がなぜ正しくないのかを紐解き、あるべき姿(to-be)を考える。元データの作りが良くないなら、データ基盤側で吸収するアプローチも取る。」 小谷さん(モノタロウ): 「営業組織などは特に指標が変わることに敏感だが、丁寧に説明することで理解を得やすい文化がある。」 Q. 何を作るかの意思決定、どこにベットする? okodoon(タイミー): 「投資しても腐らない領域にベットする。AEが担う指標の定義などは、やればやるだけ人間もAIも喜ぶ領域。」 吉田さん(10X): 「ビジネスプロセスをどう定義するか。枯れたフレームワークはLLMも解釈しやすい。」 Q. アナリティクスエンジニアというロールはどうやって生まれた? okodoon(タイミー): 「アナリストが闇堕ちして誕生した(笑)。『分析テーブルが汚い』といった憎しみを解決したいという想いが原動力。」 吉田さん(10X): 「ロールはなんでもよくて、執念をどこに捧げられるかの違い。」 おわりに 今回のミートアップを通じて、関西のデータコミュニティの熱量を肌で感じることができました。 各社の発表が刺激になったのはもちろん、パネルディスカッション後の懇親会では様々な領域の企業の方とお話できて、本当に西日本における盛り上がりを感じました…! このような素晴らしい場を設けてくださった運営・登壇者の皆様、そして当日お話しさせていただいた参加者の皆様、本当にありがとうございました! 今回得た学びを日々の業務に活かし、タイミーのデータ活用をさらに前進させていきたいと思います。
こんにちは、タイミーでバックエンドのテックリードをしている新谷 ( @euglena1215 ) です。 タイミーでは、開発効率を向上させるため、Devin や Claude Code Action といった AI ツールを活用してコードレビューの自動化を進めています。 Claude Code は「インラインコメントでレビューして」と伝えるとインラインでのレビューをしてくれるのですが、Devin は同じ指示をうまく解釈できずインラインでレビューしてくれません。 この能力の差は GitHub MCP が使えるかどうかの差ではあると思うのですが、Devin と Claude Code Action でのレビュー内容の精度を比較しようとした際に、レビューフォーマットが異なっていると純粋な性能比較が難しくなります。 そこで、今回は Devin でもインラインコメントによるレビューを実現するための方法を調べてみたので紹介したいと思います。 方法 方法は簡単で、以下の GitHub API を使ってインラインコメントを投稿する方法を記したドキュメントを Devin の knowledge として登録するだけです。 トリガー設定は登録時に Devin が提案してくるデフォルトの内容で問題なく動作しました。 How to post comments with code embedded: 1. Create JSON file for each comment you want to post. Example 1: { "body": "Security Issue: Hardcoded API key. Recommendation: Use environment variables", "commit_id": "954...12312", "path": "file.py", "line": 11, "side": "RIGHT" } Example 2: { "body": "Multiple issues found:\n1. Hardcoded API key should be in environment variables\n2. Inconsistent class naming (userAccount vs Product)\n3. Inconsistent parameter casing (Password vs username)\n4. Missing docstrings and type hints\n5. Inconsistent spacing around operators", "commit_id": "323......87686", "path": "code.py", "start_line": 11, "start_side": "RIGHT", "line": 25, "side": "RIGHT" } body: The text of the review comment. Include markdown code blocks for snippets commit_id: SHA of the commit you're reviewing. Not using the latest commit SHA may render your comment outdated if a subsequent commit modifies the line you specify as the position. path: Relative file path in repo line (integer): Specifies the exact line in the pull request’s diff view to which your comment should attach. Required unless using subject_type:file. The line of the blob in the pull request diff that the comment applies to. For a multi-line comment, the last line of the range that your comment applies to. side: In a split diff view, the side of the diff that the pull request's changes appear on. Can be LEFT or RIGHT. Use LEFT for deletions that appear in red. Use RIGHT for additions that appear in green or unchanged lines that appear in white and are shown for context. For a multi-line comment, side represents whether the last line of the comment range is a deletion or addition. subject_type: The level at which the comment is targeted. Either "line" or "file". Use "line" for inline comments. Use "file" for file-level comments. start_line (integer): Required when using multi-line comments unless using in_reply_to. The start_line is the first line in the pull request diff that your multi-line comment applies to. start_side: Required when using multi-line comments unless using in_reply_to. The start_side is the starting side of the diff that the comment applies to. Can be LEFT or RIGHT. A pull request diff may not match the original file's absolute line numbering. That is, if the PR contains additions or deletions before the line you’re commenting on, the line indices shown in the “Files changed” tab can shift from the original file’s line numbers. For example: In the pre-PR state, line 231 might refer to a completely different section of code than line 231 in the post-PR diff (because code added or removed above it shifts everything down or up). Therefore, you must use the line numbers as shown in the PR diff rather than the original file’s line numbers. If you have issues, visit the docs: https://docs.github.com/en/rest/pulls/comments?apiVersion=2022-11-28#create-a-review-comment-for-a-pull-request 2. Use gh api command. gh api \\ --method POST \\ -H "Accept: application/vnd.github+json" \\ /repos/owner/repo/pulls/4/comments \\ --input comment.json owner: the account owner of the repository. The name is not case sensitive. repo: The name of the repository without the .git extension. The name is not case sensitive. pull number: The number of the pull request. Key points: use "line" instead of "position", include code snippets in body using markdown, , set side="RIGHT" for additions この knowledge を登録することで Devin に「インラインコメントでレビューして」と一言伝えると、安定して正しくインラインコメントでレビューしてくれるようになりました! 🎉 実は、上記の knowledge の内容は Devin の開発元である Cognition 社の記事にそのまま掲載されています。 cognition.ai 公式ドキュメントを読みましょう、以上。の内容ではありますが、あまり日本語の文献が見つからなかったので記事にしてみました。 この記事が、同じように AI コードレビューに取り組む方々の助けになれば幸いです。
はい、亀井です。 インターネット上では、yykamei(わいわいかめい)という名前で活動しています。所属はタイミーです。 Kaigi Pass を利用して スクラムフェス仙台2025 に行ってきましたので、参加レポートという形でこちらに投稿しています。 まずは、スクラムフェス仙台の運営の皆さん、スポンサーの皆さん、会場提供をしてくださった enspace さん、そして、登壇者や参加者を始めとする関わってくださった皆さん、ありがとうございます。皆さんのおかげで終始楽しめました。 1日目はキーノートが行われます。今回は モンテディオ山形 の相田さんがキーノートスピーカーとして登壇されました。モンテディオ山形に入ってから相田さんが実施した取り組みを中心に、今後の展望についても話されていました。もともと楽天イーグルスやヴィッセル神戸などに関わっていたこともあり、クラブ運営についての知見などがあったと思うのですが「色々と変えてくれ」というオーダーを受けてモンテディオ山形にジョインされ、「色々」されたようです。たとえば、オフィスがあまりにも「オープン」すぎるがゆえに情報が筒抜けになっているので「これ、チームとしてまずいね」ということでオフィスの改善をしてセキュリティーレベルの向上をされたり、クラブも結局は売上が大事なので「試合をしていないときにどのようにして売上をあげていくか?」ということを考えてスタジアムの周辺の環境を整備されたりしたようです。印象的だったのは「地域にあってくれてよかった!」と言ってもらえること、そして、「このチームに入りたい!」と選手に思わせることを目指している、ということでした。スクラムフェスのように各地域で行われているスクラムフェスはそれぞれの地域で運営メンバーが異なりますし、同じスクラムフェスという名前を冠していても特色が異なります。そのような独自性をもつ地域スクラムフェスですが、みんな「地域に貢献したい」という思いがあるのではないかと私は思っています。そうした中で、スクラムフェス仙台で相田さんをキーノートにお招きしたのは何か感じるものがありますね。また、相田さんの話をよくよく聞いているとたくさんの 改善 をされたのですが、その 改善 の裏には丁寧な 観察 があったのではないかと推察します。というのも、先ほどのオフィスの話にしても現場に入ってよくよく見てみないと状況はわからないですからね。そのうえで対策を行うという話がまさにスクラムでいうというところの検査と適応なのだなと。 キーノートのあとにネットワーキングパーティーがありました。ここで写真を撮っておかなかったことを後悔していますが、とにかくわいわいやらせていただきました。特に印象に残っているのは、おーのAさんに「お、これは... 『かめり』さんですか?」といういじりですかね。ひらがなで「かめい」と書いたつもりなのですが、字が汚かったようで「い」が「り」に見えたようです。どうですかね?そんなに「り」ですか? 「かめり」?「かめい」? 2日目はいろいろと登壇セッションがありますね。初回は我らが ShinoP の登壇ということで聞いておりました。私はいわゆる「中の人」なので知っている内容ではあったのですが、あらためて聞いてみるとよくまとまっている話でしたね。さっそく 資料 もアップロードしていただいたみたいです。面白かったのはこれまでの行動を改めて言語化して、「共感性」「透明性」「一貫性」というものにまとめたところですね。誰かがその後質問をされていたのを盗み聞きしたところ、実際に行動を行っていた時はその言語化したことを意識してやっていたわけではない、とのことでした。改めてふりかえって言語化してみた結果、そうした概念にたどりついた、ということのようです。おもしろいですね。もちろん、内容自体の学びもあるのですが、登壇をきっかけに深いふりかえりによる内省が行われ自身の行動が明確化された、というところにも学びがありますね。別に登壇する機会がなくてもこういう内省自体には価値がありそうです。こういう気づきを与えてくれた盗み聞きの会話があるのもカンファレンスの醍醐味ですね。 続いて、りんさんの どうやら人って変われるらしい。一年半コーチングを受けて見つけたコンフォートゾーンの超え方。 という登壇を拝見しました。個人的に最近コーチングに興味があって学んでいる最中なのですが、クライアント視点でどう行動変容が行われたのか?という話は非常に学びがあります。コーチ視点だとクライアントの話を聞きながら適切なコーチングのスキルを活用していくことが求められるのではないかと思うのですが、そのコーチのあり方がクライアント側からはどう見えるのか?が垣間見えました。コーチングは共同関係だと思うのですが、まさにコーチだけではなくクライアントの努力があってこその行動変容なんだなと思いました。 お昼の時間帯は「はじめまして!」な方々とランチに行きました。厳密にはみんながみんな「はじめまして!」ではないのですが、まあいいでしょう。たまたま同じグループに地元の方がいらっしゃいましたので「いい感じの」ラーメン屋さんに行きました。おいしかったですね。その後、 鯛きち というおみせに行ってずんだ餅のたい焼きを食べました。 午後の時間帯はやはり登壇が行われるのですが、登壇と並行してコーチズクリニック、ワークショップ、フォトブース、OSTが行われます。なお、ワークショップは午前中からありました。本当はでたいワークショップがあったのですが、1日目の時点でほとんどのワークショップが定員に達してしまったので諦めました。私はほとんどOSTを行う部屋で過ごしていましたが、OSTとはいいつつもずっと誰かが話したいテーマを熱く語り合っていたり、たまにリーンコーヒーで構造的に話題を切り替えながら話をしていました。ここではかなりディープな内容を話していたのかなと思います。それこそ登壇では言えないような話とかがあるので、実は結構学びになる場だったかもな、と。 そういえば、スクラムフェス仙台が開催された会場である enspace さんについて話していませんでした。もともと最初のオーガナイザーだった天野さんが「スクラムフェス仙台やりたいなー」という構想段階で「じゃあうちでやりなよ!」と声をかけてくれたのが enspace さんだそうです。場所も日程も決まっていないし、なんならどういうコンセプトで何をやるのかすら決まっていない状態で声をかけてもらった感じみたいですね。 enspace さんはこのように初回からかなり協力的なのですが、実際のスクラムフェス仙台当日の動きについてもかなり協力的です。スクラムフェス仙台ではだいたい運営の方が紫色のTシャツをきていらっしゃるのですが、 enspace のスタッフの皆さんも同じ運営のTシャツをきています。つまり、 enspace のスタッフの方々もスクラムフェス仙台の運営として全面的に協力されていました。 enspace のスタッフさんお二人と話す機会がありました。一人目の方は大学4年生だとのことで、 enspace には大学1年生の頃からインターンとしてお仕事をされているとのことでした。「ここのお仕事はものすごく楽しい」と言っていたのが印象的です。来年からは新社会人として東京の会社に就職されるそうで enspace から離れるのを名残惜しそうに話しておりました。もう一人の方は大学3年生で enspace には大学2年生の頃から関わっているようです。こちらの方も「もうすごく楽しくてくるのが楽しみなんです」ということを言っていました。そして、スクラムフェス仙台が開催される日程が決まると、自分のシフトをそこに合わせるようにしたとのことでした。いわく、「スクラムフェスは楽しい」とのことです。会場を提供しているスタッフの方がこういう風に言ってくれるのは、ただの参加者である私にとってもとてもうれしいですよね。そして、そういう協力を惜しみなく提供する enspace のスタッフの皆さんにも本当に感謝したいです。 ここまでつらつらとスクラムフェス仙台の感想を書いてみました。もちろん、それぞれの登壇にも学びがありましたが、この場自体に存在することそれだけでも学びがありました。スクラムフェス仙台は今回が初めての参加でしたが、また来年も機会があれば行きたいですね。最後に、タイミーのメンバーで撮った写真をはっておわろうと思います。 タイミーからきた参加者の皆さん
8月6日、タイミー、UPSIDER、カケハシの3社共催による「 生成AI時代のPdM - 活用と未来戦略 」と題したイベントが開催されました。本イベントでは、プロダクトマネジメントにおける生成AIの活用と、それに伴うPdMの役割の変化に焦点が当てられました。本レポートでは、タイミーのプロダクトマネージャーである柿谷 樹の講演「AIで変わるPdMの役割 — 思考する力が武器になる」を書き起こし形式でお伝えします。 はい、株式会社タイミーの柿谷と申します。よろしくお願いします。 本日は『生成AI時代のPdM』というテーマで、『AIで変わるPdMの役割 — 思考する力が武器になる』という、少々仰々しいタイトルでお話しします。今回は『思考』をテーマにしたいと思います。 改めまして自己紹介をさせてください。株式会社タイミーでプロダクトマネージャーをしている柿谷です。バックグラウンドとしては、リクルートで新規事業開発を経験後、主にtoB領域のプロダクトマネジメントを5年ほど経験しました。昨年タイミーにジョインし、現在はバーティカルな市場での売上拡大を担当しています。タイミーは2-side-platformですが、toB担当・toC担当のように線を引かず、バリューストリーム(ユーザーに価値が届く一連の流れ)を単位に開発チームを組成しています。そのため、1人のPdMがプラットフォームの両面を横断して見ることが多いです。 それでは本題に入ります。このテーマを考えるにあたり、プロダクト開発の前提が大きく変わる中で、結局PdMに何が残るのかを突き詰めた結果、PdMの価値は『思考』へシフトするのではないかという結論に至りました。本日はその点について重点的にお話しできればと思います。 アジェンダは『思考する』『思考を止めない』『思考環境を整える』の3つです。 1. 思考する ── 文脈を設計し、出力を見極め、対話で共有する まず『思考する』についてです。『思考とは何か』という話ですが、デカルトの『我思う、故に我あり』といった話ではなく、私が読んだ本の中で非常に的確だと感じた説明を引用します。『思考とは、思考対象に対して何らかの意味を得るために、頭の中で情報・知識を加工すること』です。これは関数的な処理と捉えることができ、事象と知識というインプットからメッセージや意味合いというアウトプットを出すプロセスです。 この構造はAIの処理と似ていますが、本質的に異なる点があります。AIは不完全な入力に対しても、ハルシネーション(もっともらしい嘘)によってそれらしい出力を生成してしまいます。そのため、結局は人間による品質担保が不可欠です。ここに人間の価値が残ると考えており、プロダクトマネージャーには『コンテキスト設計能力』と『出力に対する審美眼』が求められるようになります。 この変化に伴い、ドキュメントの位置づけも変わってきます。アジャイル開発宣言では『ドキュメンテーションよりも対話』とされていましたが、AIに読み込ませるコンテキストが重要になる今、ドキュメントがAIへの重要なインプットとなり、PdMには『Why』を構造化するスキルが求められるようになります。これはPdMの役割が『コンテキストデザイナー』に変わることを意味します。ただ、これはドキュメント主義への回帰ではなく、コミュニケーションの重要性は普遍です。最終的にPdMには『思考の構造化』と『納得を生む対話力』が求められるようになると考えています。 2. 思考を止めない ── 継続的ディスカバリーが競争力の源泉に 次に『思考を止めない』についてです。これからの時代、継続的なディスカバリーこそが競争力の源泉になると考えています。一次情報が非常に重要になります。開発のデリバリー速度が爆発的に向上する中で、ディスカバリーも同じ速度で回す必要があります。そのためには、高速で一次情報に触れられる環境を構築し、そこから得た情報をもとに思考を常にアップデートし続ける仕組みが不可欠です。 では、何が大事かというと、これもAIとは直接関係ない部分もありますが、インタビューのリードタイムを極限まで短縮することです。明日インタビューしたいと思ったら、明日実行できるようなオペレーションを構築することが重要です。その上で、議事録の下書き作成などはAIに任せ、人間は考察に集中できる環境を作ります。そして『 オポチュニティ・ソリューション・ツリー(OST) 』のような思考フレームワークを活用し、論点を常にアップデートし続けることが重要です。 3. 思考環境を整える ── Bullshit Jobを減らし、意味ある仕事に集中する 最後に『思考環境を整える』についてです。PdMの仕事は『意味を作る仕事』へとシフトしていきます。AIの進化により、議事録作成や会議要約といった戦術的な労働から解放され、PdMは『意味の創造』という、より本質的な価値に時間を充てられるようになります。そのためには、いわゆる『ブルシット・ジョブ(無意味な仕事)』を減らし、思考しやすい環境を整えることが重要です。 チームや組織でAIを活用する方向性は、大きく2つに分けられると考えています。一つは、個人の成功事例を横展開し、チーム全体の生産性を底上げする試み。もう一つは、AI前提のオペレーションを抜本的に設計し直す試みです。まずは個人がアドホックにAIを活用し、そこで得たコンテキストや優れたプロンプトをチームで共有するなど、ボトムアップで進めていくのが現実的でしょう。 まとめ まとめになりますが、これからのPdMに求められることは、『思考する』『思考を止めない』『思考環境を整える』という3点です。 タイミーは積極採用中です。ご興味のある方は、カジュアル面談からでもぜひお声がけください。ありがとうございました。 hrmos.co 本講演のアーカイブはこちら 本講演の登壇資料はこちら speakerdeck.com
タイミーQAEnablingチームの松田( @yoshi_engineer_ )です。 先日、私の地元で開催されたスクフェス大阪に参加してきました! スクラムフェスに初めて参加したのは去年のスクラムフェス大阪24でして、その時の感動と熱が忘れられず、25年度も参加することに決めました。 www.scrumosaka.org 去年は個人で参加したのですが、今回は弊社のTED10というエンジニアの成長を支える制度を利用して参加させていただきました。 productpr.timee.co.jp 今年のスクラム大阪は去年とはまた違った取り組みも多く、参加者としてはとても満足しておりその取り組みも紹介できればと思います。 コーチーズクリニック ~経験豊富なコーチに相談してみよう~ 今回スクフェス大阪初の試みのコーチーズクリニック。 他のスクフェスでは何度か開催され、大変好評だったことから今回大阪でも採用されたとのことです。 そして今回はありがたいことにyoh nakamura( @yohhatu ) さんとのコーチーズクリニックを受けることができました。 以前から個人的に知っており、大変尊敬するお方でもあったので、とてつもなく緊張していたのですが、温かな笑顔で迎えてくださり、安心して対話し始めることができました。 私のスクラムに関する悩みを傾聴していただき、温かな空気の中、自分でも驚くほど話すことができました。 yohさんが寄り添いながら相槌を重ね、「どうして松田さんはそう思ったのかなー?」「松田さんの中でどうやったらもう少し良くできるだろう?」私が悩みを伝える中で、的確なタイミングで問いをいただきました。その答えも「あ,,,,じゃあ、こうしたら良いかも…!」と1人では気付けなかった(確信が持てなかった)仮説に自分から気づき言葉にすることができました。 ほとんど私の話だけで終えてしまったコーチングの時間でしたが、yohさんから「スクラムをする時、大事なのは、強い情熱持つことだよ。」と一言いただきました。 その言葉を聞いて、私はグーっと体の芯から力が湧き起こるような感覚になりました。 自分が困難な時、挫けそうになった時、yohさんからもらった言葉をお守りに頑張ろうと思います。 yohさん、有意義なお時間いただき本当にありがとうございました! 私の心を打ったsession アジャイル、諦めなかった10年 JTC,SIer,受託で挑んだリアル confengine.com JTC,SIer,受託会社の3社でアジャイル開発を推進を試みてきたOshikata( @oshikata200 )さん。この登壇はまさに理想と現実の中で泥臭く実践を行ってきたOshikataさんの10年間の軌跡を赤裸々に語っていただきました。 このセッションで話された内容は一言で言えば「組織改革への実践知」です。 「置かれた場所で咲く」よりも「咲ける場所を探す」べきなのか Oshikataさんはこれまで組織にアジャイルを導入すべく何度も奮闘してこられたのですが、組織の習慣や形態により導入するにあたって何度も壁にぶつかりました。 しかし、Oshikataさんの気づきはこうでした。 ソリューションやプラクティスを導入することを重視するのではなく、まずチーム、そして組織文化へのアプローチが必要。また、それは長い時間をかけて少しずつ行うことが重要。 失敗を恐れず、「増やす」から、「手放す」へ 企業の特性上、ドキュメントやルールが加速度的に増える現状があります。その背景には「過剰な失敗への回避」がそうせてる可能性があります。 しかし、そこで増えたドキュメントやルールは逆にメンバーやチームへの足枷になり速度と自立性を失わせます。 資産と思い積み重ねたものは、いつの間にか負債に変容。 現状を打破するためにも、形骸化されたルールやドキュメントを減らすことを推進されました。 負債を大きくするよりも、動きやすくするために手放すことを実践されました。 詰め込みすぎた制度,ルールがあるとそこから試行錯誤する姿勢が損なわれていきます。 “人を囲う”より,”みんなで空気を耕す” 「メンバーへの執着を手放す。そうではなく組織の空気を耕す」メンバーに執着することで自分のチームだけを囲うことは、長期的に見れば組織の衰退を助長します。 そうではなく、できる人材こそどんどん他の部署やチームに手放す。そしてまた新たなメンバーと対話し、組織の空気を耕していく。 それを体現するためにも、個人への信頼関係の構築が肝になる。 信頼関係の気付けた組織を耕し、メンバーがある範疇の制度の中でワークすることで工夫が行わられる。 「“強い個”を集めるのではなく、“みんな”で空気を耕す。 少しずつ、一歩一歩確実にみんなで進むことから風土が醸成されていく」 一朝一夕で組織は変わらないが、その一つ一つの積み重ねを愚直に行うことで芽が開く。とてつもなく大きい情熱を持って歩んでこられたOshikataさんのsessionは大きな学びと気づきを与えてくださいました。 困難な状態も、組織の実態もマイナスな要素をあげればキリがない状態であったとしても、少しずつ改善を重ね進まれていく姿が、今度は自分も頑張ろう!と心に火が灯るような感覚を覚えました。 おわりに 今回のスクラムフェスでも大変大きな気づきと学びを得ることができました。 この気づきと学びを活かして、より精進していきたいと思います! いつか私も聴講者としてではなく、登壇者としてスクラムフェスに寄与できればと思います!
こんにちは。データアナリストのtomitaです。 先日、社内のPdM(プロダクトマネージャー)とアナリストが中心となり、当社にとって重要な業界の一つである物流業界に関する勉強会を開催しました。 今回は、その内容と、そこで見えてきた当社の魅力についてご紹介したいと思います! 生成AIを駆使した『AI駆動勉強会』 今回の勉強会で最も特徴的だったのが、生成AIを活用した新しい学習スタイル『AI駆動勉強会』です。 これは、参加者各自がリサーチクエスチョンを設定し、それに対して生成AIを使って調査を行い、アウトプットと深掘りを行うスタイルです。 生成AIを使うことで、これまで何時間もかかっていた情報収集を短縮し、より本質的な議論に時間を割けるようにしました。 勉強会の様子 『AI駆動勉強会』の進め方 リサーチクエスチョンを立てる (5分):各自が知りたいテーマについて具体的な問いを立てます。 AIで調査する (15分):生成AIを使い、設定した問いについて効率的に情報を収集します。 アウトプット&質問深掘り (2分):調査結果を簡潔にまとめ、参加者と共有。疑問点やさらなる深掘りについて議論します。 このセッションを1.5〜2時間で2〜3回繰り返すことで、短時間で多くの学びを得ることができました。 参加者からの声 「リサーチクエスチョンを先に立てることで、集中して学習できた!」 「アウトプットと質問深掘りの時間で、学習内容がより深く定着した」 「AI活用の練度が上がり、効果的なプロンプトなどの知見が共有されたのが良かった」 「他の人のリサーチクエスチョン自体に学びがあり、視野が広がった」 部署を超えたメンバーとの交流 今回の勉強会には、アナリストだけでなく、PdMや元CSM(カスタマーサクセスマネージャー)で物流業界に詳しいメンバーまで、幅広い職種のメンバーが参加しました。 例えば、元CSMのメンバーからは、物流現場でのリアルな課題が共有され、AIによるリサーチだけでは得られない学びがありました。 多角的な視点からの議論は、私たちデータアナリストがデータから導き出したインサイトを、プロダクト改善やビジネス戦略に繋げる上で不可欠です。異なる専門性を持つメンバーと気軽に意見交換できる環境は、当社で働く大きな魅力の一つだと改めて感じました。 リモート参加も可能な柔軟な働き方 今回の勉強会では、多くのメンバーがオフィスに集まりました。私自身は家庭の事情でリモートでの参加でしたが、オフィスにいるメンバーと変わらず、活発な議論ができました。 当社のプロダクト組織では、働き方の柔軟性を担保する観点から、リモートワークOKとなっています。場所や時間にとらわれずに質の高いインプットとアウトプットができるのは、非常にありがたい環境です。 終わりに 今回の物流業界勉強会は、当社のPdMとアナリストが中心となり、生成AIを駆使した独自のスタイルで実施しました。AIで調査を進め、その結果をアウトプット・深掘りすることで効率的に物流業界への理解を深めることができました。 また、部署を超えて様々な職種のメンバーが参加することで、AIだけでは得られない物流現場でのリアルな課題が得られたり、多角的な視点からの議論ができたりしました。 We’re Hiring! 私たちは、ともに働くメンバーを募集しています!! カジュアル面談 も行っていますので、少しでも興味がありましたら、気軽にご連絡ください。
こんにちは、タイミーでPlatform Engineerをしている近藤です。 マージキュー上のエラー通知について GitHubのマージキューは、チームが効率的かつ安全にコードをリリースするために欠かせない仕組みです。特に、大規模なチームや頻繁にコードをデプロイするプロジェクトでは、マージキューがCI/CDプロセスの核となります。しかし、マージキュー上でエラーが発生した際、その通知を迅速に受け取ることが極めて重要です。通知が遅れたり、見落とされたりすると、次のような問題が生じる可能性があります。 リリースの遅延 エラーが発生すると、問題のある変更は差し戻されます。 その結果、後続のPRのベースが変更されるため、マージキュー上でのCI処理を再実行する必要が生じます。 これにより、本来スムーズに進むべきリリースサイクルが停滞し、開発スピードが著しく低下します。 開発者体験(DX)の低下 マージキューでのエラー通知が適切に行われないと、開発者が混乱したり、不要な手戻り作業を強いられたりします。これにより、開発者のモチベーションや生産性の低下を招くことにもなります。 以上の理由から、GitHubのマージキューでエラーが発生した際の通知を確実に行うことは、開発効率を保ち、迅速な問題解決を促すために不可欠です。通知の仕組みを整備し、チーム全体が即座に問題に対処できる環境を整えることが求められます。 エラー通知の課題 単にワークフロー中にエラー通知のジョブを入れるだけでは、先行してマージキューに積まれたPRにCIエラーが発生する内容が含まれている場合、後続の人にも不要なエラー通知が届いてしまいます。これを回避するために、GitHubのconcurrency機能を活用してCIを適切にキャンセルする仕組みを導入しました。 sequenceDiagram autonumber participant DevA as 開発者 A participant DevB as 開発者 B participant Queue as マージキュー participant CI as CI (GitHub Actions) participant Master as master ブランチ DevA->>Queue: PR A をキューに追加 DevB->>Queue: PR B をキューに追加 par Queue->>CI: PR A + master のテスト Queue->>CI: PR B + PR A + master のテスト end CI--x Queue: PR A + master でテストエラー Queue->>DevA: PR A がテストエラーになりました Queue->>DevB: PR B がテストエラーになりました Queue->>Queue: PR B + master の再エンキュー Queue->>CI: PR B + master のテスト CI-->>Queue: PR B のテスト合格 Queue->>Master: PR B を master にマージ PR AとPR Bがマージキューに積まれた状態で、先行するPR Aでエラーが発生すると、PR Bは自動的にPR Aの内容を除外した状態で再度マージキューに入れられます。 この際、マージキューの実行時に作成されるブランチ名は都度変化します。よって単純にブランチ名をキーとした以下の設定では、期待通りに動作しません。 concurrency : group : ${{ github.ref_name }} cancel-in-progress : true そこで、マージキュー上で作成されるブランチ名の規則性を利用します。ブランチ名にはPR番号が含まれているため、ワークフロー内でブランチ名からPR番号を抽出するジョブを追加しました。 最終的に採用したワークフローは以下の通りです。意外と知られていませんが、concurrencyキーワードはジョブレベルでも指定可能です。 name : ci on : push : branches : - '**' - '!master' - '!gh-readonly-queue/**' tags-ignore : - '*' merge_group : permissions : id-token : write contents : read pull-requests : write jobs : concurrency_key : runs-on : ubuntu-latest outputs : key : ${{ steps.extract_pr.outputs.key }} steps : - id : extract_pr name : Extract PR number from branch name shell : bash run : | if [[ $ {{ github.event_name }} == 'merge_group' ]] ; then full_ref="${{ github.ref_name }} " pr_number=$(basename " $full_ref" | cut -d- -f2) echo "key=$pr_number" >> "$GITHUB_OUTPUT" else echo "key=${{ github.ref }}" >> "$GITHUB_OUTPUT" fi ci : needs : concurrency_key concurrency : group : ${{ github.workflow }}-${{ needs.concurrency_key.outputs.key }} cancel-in-progress : true uses : ./.github/workflows/_ci.yml with : skip : ${{ github.event_name != 'merge_group' }} secrets : inherit merge_group_notify : needs : ci if : ${{ failure() && github.event_name == 'merge_group' }} uses : ./.github/workflows/_merge_group_notify.yml with : role_to_assume : arn:aws:iam::012345678901:role/example notification_type : failure secrets : inherit 上記の仕組みを導入することで、先行するPRでテストエラーが発生しても、その影響で後続PRに対して不要なエラー通知が送信されることを防げます。 sequenceDiagram autonumber participant DevA as 開発者 A participant DevB as 開発者 B participant Queue as マージキュー participant CI as CI (GitHub Actions) participant Master as master ブランチ DevA->>Queue: PR A をキューに追加 DevB->>Queue: PR B をキューに追加 par Queue->>CI: PR A + master のテスト Queue->>CI: PR B + PR A + master のテスト end CI--x Queue: PR A + master でテストエラー Queue->>DevA: PR A がテストエラーになりました Queue->>Queue: PR B + master の再エンキュー alt 失敗通知をキャンセル Queue -x DevB: PR B がテストエラーになりました (キャンセル) end Queue->>CI: PR B + master のテスト CI-->>Queue: PR B のテスト合格 Queue->>Master: PR B を master にマージ ただし、PR AとPR Bがほぼ同時にマージキューへ投入された場合など、極めて稀なタイミングによっては、キャンセル処理が間に合わず後続のPRに対して不要なエラー通知が送信されてしまうケースが残ってしまいます。 こうしたエッジケースまで完全に抑制しようとすると、ワークフロー全体の実装が大幅に複雑化し、運用・保守コストも増大してしまう懸念があります。 そのため、今回は「不要な通知の発生を現実的な範囲で最小化しつつ、実装のシンプルさを優先する」という方針を選択しました。 まとめ 本仕組みによって、マージキュー運用時の不要なエラー通知を大幅に削減しつつ、チーム全体の開発効率と安心感を両立できるようになりました。 今後も、より良い開発体験を目指して、現場の実情やフィードバックを取り入れながら、継続的な改善を進めていきます。
こんにちは、タイミーでバックエンドのテックリードをしている新谷 ( @euglena1215 ) です。 GitHubマージキューTIPSシリーズ、前回までに、マージメソッドの制約やCIの高速化といったTIPSを共有してきました。今回は、マージキューのポテンシャルを最大限に引き出すためのパラメータチューニングと、そのために不可欠なキューの状態の可視化について解説します。 デプロイ効率と安定性のトレードオフ マージキューには、その挙動をコントロールするためのいくつかのパラメータが存在します。 Build concurrency :マージキューのCIを同時に実行する並列数。 Minimum/Maximum pull requests to merge :一度のデプロイ(マージ)に含めるPRの最小数と最大数。 これらのパラメータは、効率性と安定性という、二つの相反する要素を調整するために使用します。 効率性(デプロイの速さ) :開発者の待ち時間を短縮するため、PRを迅速にマージすることが求められます。 安定性(変更の分離) :問題発生時の影響範囲を限定し、原因特定を容易にするため、一度にマージする変更は少なくすることが望ましいです。 例えば、 Maximum pull requests to merge を10に設定するとデプロイのスループットは向上しますが、障害発生時には10個のPRの中から原因を特定することが困難になります。逆に1に設定すると、原因特定は容易になりますが、PRが多数待機している場合に待ち時間が増加します。 キューの長さを計測する必要性 この関係を考慮してパラメータを調整するには、「現在のマージキューで待機しているPRがどの程度あるか」というデータが必要です。キューに待機しているPRがなければ設定を変更する必要はありませんが、常に多数のPRが待機している場合は、CIの並列数を増やすなどの対策を検討する必要があります。 しかし、キューの長さや待ち時間といった情報は、GitHubの標準機能では提供されていません。このため、キューの長さを計測し、可視化する仕組みを構築しました。 キューの長さを計測する方法 私たちのチームでは、GitHub Actionsを利用してキューの長さを計測し、Datadogへ送信しています。 その実装で利用している方法を紹介します。 gh コマンドによるキュー長の取得 GitHubマージキューの現在の長さは、GitHubのGraphQL APIを通じて取得できます。 gh コマンドを使えば、これを1行のコマンドで簡単に行えます。 使用するコマンドは以下の通りです。 QUEUE_COUNT=$(gh api graphql -f query=' query { repository(owner: "THIS_IS_ORG_NAME", name: "THIS_IS_REPO_NAME") { mergeQueue(branch: "DEFAULT_BRANCH_NAME") { totalCount: entries { totalCount } } } } ' --jq '.data.repository.mergeQueue.totalCount.totalCount') このコマンドは、GraphQLクエリで必要なデータ ( totalCount ) を指定し、 gh コマンドの --jq フラグでレスポンスから値を直接抽出しています。 このコマンドを、 on.merge_group (PRがマージキューに追加された時)をトリガーにしたGitHub Actionsで実行します。その結果をモニタリングツール(私たちの場合はDatadog)に送信することで、キューの長さを時系列グラフとして可視化できます。 マージキューに入っている Pull Request の数の時系列グラフ このダッシュボードによって「どの時間帯にマージが集中するのか」「現在のパラメータ設定でキューが効率的に処理されているか」といった状況を把握できるようになりました。 データに基づくパラメータ調整の実際 このダッシュボードを2週間運用した結果、私たちのチームでは同時にマージキューに積まれていたPRは最大でも 3件 であることが分かりました。 この実績データに基づき、安定性をさらに高めるため、パラメータを以下のように調整しました。 Maximum pull requests to merge : 変更前 5 → 変更後 3 Build concurrency : 変更前 10 → 変更後 6 一度にマージするPR数を実績値(3件)に合わせ、ビルドの並列数( Build concurrency )をその2倍に設定しました。これにより、リソースを効率的に使いつつ、より安定した運用を目指しました。 まとめ マージキューは導入するだけでも一定の効果がありますが、その効果を高めるには、開発の規模や状況に応じてパラメータを継続的に調整することが重要です。その調整は、勘や感覚ではなく、今回紹介したような可視化されたデータに基づいて行うことが推奨されます。 今回はキューの可視化とパラメータ調整について解説しました。次回以降も、マージキューをより効果的に活用するための情報をお届けします。
こんにちは、タイミーでバックエンドのテックリードをしている新谷 ( @euglena1215 ) です。 このシリーズでは 「モノリスRailsにマージキューを導入してデプロイフローを安定させる」 の続編として、導入時のTIPSを紹介しています。前回は 「GitHubマージキューTIPS:CIの実行を最適化し、障害対応を10分高速化する」 について解説しました。 本記事では、GitHubのマージキュー導入後に発生した、ブランチ保護機能(Ruleset)のbypass list機能との非互換性について解説します。 これまでのコードフリーズ運用 タイミーでは、主に年末年始やGWといった開発者が少ない期間にコードフリーズ期間を設けています。この運用を実現するため、我々はGitHubのRulesetsと、そのbypass list機能を活用していました。 これは非常に便利な機能で、以下のような運用を可能にしています。 通常時: 開発者は自由にマージできる。 コードフリーズ期間中: Rulesetを有効化し、原則マージを禁止する。 緊急時: ただし、bypass listに登録された開発者のみ、チェックボックス一つでこのルールを回避し、緊急の修正をマージできる。 この仕組みで、コードフリーズ期間中の安全性と、緊急時の柔軟な対応を両立していました。 マージキュー導入後に発覚した問題 マージキューを導入し、順調に運用が始まったかのように思えたある日、コードフリーズ期間直前に問題が発覚しました。 bypass listに登録されているにもかかわらず、ルールを回避してマージすることができなくなっていたのです。 コードフリーズ期間中にコードを変更することは基本ありませんが、例えば障害対応で緊急の修正が必要になった際に、これまでのように特定の担当者が即座にマージできなくなる、という影響が考えられます。これは、柔軟な対応を期待していた開発者にとっては意図しない仕様変更でした。 原因と対応 仕様上の非互換性 調査の結果、マージキューとRulesetのbypass機能は併用できないGitHubの仕様であることが分かりました。この件はGitHubの公式Discussionでも報告されています。 ref. https://github.com/orgs/community/discussions/45208 この仕様に対する直接的な解決策は見つからなかったため、bypass listを使用しない運用への変更が必要になりました。 新しい運用への変更 代替案として、以下の運用を構築しました。 コードフリーズ期間中、 常に失敗するCIジョブ をワークフローに追加する。 ただし、このCIジョブはブランチ保護ルールの 必須チェックには設定しない 。 これにより、開発者はCIの警告表示からコードフリーズ期間中であることを認識でき、意図しないマージの抑止につながります。 まとめ GitHubのマージキューは有用な機能ですが、Rulesetのような既存の機能と組み合わせる際には、意図しない動作をしないか注意が必要です。(この記事は2025年7月時点のGitHubの仕様に基づいています。) 私たちのケースでは、導入後にこの問題が判明し、コードフリーズ直前の対応が必要となりました。 マージキューの導入を検討する際は、通常のデプロイフローだけでなく、コードフリーズのような特定の運用条件下でも意図した通りに動作するか、事前に検証することを推奨します。 特に、ご自身のチームが以下の点に当てはまるか、一度確認してみてください。 ブランチ保護(Rulesets)で、特定の担当者やチームにマージの例外(Bypass)を許可しているか? その例外的なマージは、緊急時の対応など、今後も必要な運用か? 私たちのケースでは、導入後にこの問題が判明し、コードフリーズ直前の対応が必要となりました。 さて、次回はマージキューのポテンシャルを最大限に引き出すための「詰まり具合の可視化」と、パラメータチューニングについてご紹介します。
こんにちは、タイミーでバックエンドのテックリードをしている新谷 ( @euglena1215 ) です。 このシリーズでは 「モノリスRailsにマージキューを導入してデプロイフローを安定させる」 の続編として、導入時に工夫した点や直面した課題をTIPS形式で紹介しています。前回の記事では 「GitHubマージキューの制約:マージメソッドが1つに強制される」 について解説しました。 今回は、マージキューの特性を活かして CIの実行方法を最適化し、特に緊急時のデプロイを高速化した 話を紹介したいと思います。 Pull RequestにおけるCIは本当に必須か? マージキューの最も基本的な機能は、エンキューされたPull Request(PR)を 常に最新の master ブランチに取り込んだ状態でCIを実行する ことです。これによりmaster ブランチのCI成功が保証されるため、私たちはまず「master ブランチへのマージ後のCI」を不要と判断しました。 さらに、私たちはもう一歩踏み込んで考えました。 「そもそも、PR上でのCI実行も必須ではなくなったのでは?」 仮にPR単体でCIが失敗したとしても、その変更はマージキューのCIで検知され、キューから自動的に取り除かれます。master ブランチが壊れることはないため、PR作成時のCIはあくまで開発者のための任意実行とし、マージをブロックする「必須チェック」から外せるのではないか、という発想です。 CIを「必須」と「任意」に分ける方法 この「PRでのCIを必須としない」運用を実現するには、一つ技術的な壁がありました。 GitHubの仕様上の壁 GitHubの仕様では、PRの必須チェック(Required Check)とマージキューの必須チェックを分けることができません。マージキューでマージ前にチェックしたいCIはPRでも常に実行する必要があります。 こちらはマージキューへのフィードバックとして挙がっていますが、2025年7月時点では対応されていませんでした。 ref. https://github.com/orgs/community/discussions/46757#discussioncomment-4912738 PRでの必須チェックを外すためにチェックを外すと、マージキューでも必須ではなくなってしまい、CIが実行されないままマージされる問題が生じます。 ワークフロー分割による解決策 そこで我々は、CIのコアロジックを再利用可能なワークフロー( _ci.yml )として切り出し、それを呼び出す2つのワークフローに分割することで、この問題を解決しました。 1. ci.yml(マージキューでの必須CI) これをブランチ保護ルールの必須チェックに設定します。このワークフローは push イベントと merge_group イベントの両方でトリガーされますが、 github.event_name を判定し、 merge_group イベントでない場合は skip: true を渡すことで、CIの実行をスキップします。 これにより、「必須チェックとしては存在するが、PR上では即座に完了(スキップ)し、マージキューでのみ実行される」状態を作り出せます。 # .github/workflows/ci.yml name: ci on: push: branches: - '**' - '!master' merge_group: jobs: ci: # ... uses: ./.github/workflows/_ci.yml with: # merge_group イベントでない場合は true を渡し、ワークフローをスキップさせる skip: ${{ github.event_name != 'merge_group' }} secrets: inherit 2. ci_branch.yml(PRでの任意CI) こちらは必須チェックには設定しません。 push イベントでのみトリガーされ、常に skip: false を渡してCIを実行します。開発者はこのCIの結果を参考にしますが、完了を待たずにエンキューできます。 # .github/workflows/ci_branch.yml name: ci branch on: push: branches: - '**' - '!master' jobs: ci: uses: ./.github/workflows/_ci.yml with: # こちらは常に false を渡し、CIを実行させる skip: false secrets: inherit この構成により、「PR上ではCI実行は必須ではないが、マージキューではCI実行が必須」という状態を実現しました。 実行結果を確認する 挙動を確認するために、実行結果を確認してみましょう。 PR上では、ci.yml と ci_branch.yml が実行されます。必須であるci.ymlはほとんどのステップがskipされているので全体が数秒で確認できます。対して、ci_branch.ymlでは数分かかっていますが、必須ではないので実行途中でもマージキューにエンキューできます。 PR上でのci.ymlの実行結果 PR上でのci_branch.ymlの実行結果 対して、マージキュー上ではci.ymlのみが実行されます。マージキューで実行した場合、ci.ymlはskipされずに実行されるので、CIが失敗しているのにmasterブランチにマージされてしまうといったリスクはありません。 マージキュー上でのci.ymlの実行結果 障害対応のデプロイを10分短縮 この最適化は、特に緊急の修正(Revertなど)をデプロイする際に大きな効果を発揮します。 変更前 featureブランチのCI(10分) + masterマージ後のCI(10分) + デプロイ(5分) = 合計25分 変更後 マージキューのCI(10分) + デプロイ(5分) = 合計15分 結果として、障害発生から復旧までの時間を 10分短縮 できました。 まとめ マージキューはmaster ブランチを安定させるための機能ですが、その特性をうまく利用し、CIの実行方法を工夫することで、デプロイの安定化とデプロイの高速化を両立させることができました。まさに一石二鳥の改善だったと感じています。 次回は、マージキュー導入時に発覚した、GitHubのブランチ保護機能(Ruleset)との思わぬ非互換性について紹介します。
こんにちは、タイミーでバックエンドのテックリードをしている新谷 ( @euglena1215 ) です。 先日公開した記事 「モノリスRailsにマージキューを導入してデプロイフローを安定させる」 では、多くの開発者が関わるモノリスリポジトリのデプロイフローを安定させるために、GitHubのマージキューを導入した事例を紹介しました。 今回からは、導入にあたって直面した課題や、我々の開発プロセスにうまく組み込むために工夫した点などを、TIPSとして何回かに分けて紹介していきます。 シリーズ最初のトピックは、マージキューを導入すると直面するマージメソッドの制約についてです。 開発者の自由がなくなる?マージフローの変化 マージキューを導入すると、開発者のマージ作業のフローが大きく変わります。最も大きな変化は、開発者が直接「Merge」ボタンを押すのではなく、「Merge when ready」ボタンでエンキュー(マージキューに追加)する点です。 エンキューされたPull Requestのマージ作業そのものは、開発者ではなくbotが内部的に自動的に行うようになります。 マージメソッドを指定できない仕様 2025年7月時点でのGitHubマージキューの仕様では、各開発者がエンキュー後のマージメソッドを選ぶことはできません。代わりに、リポジトリの設定として、どのマージメソッド(Merge commit, Squash and merge, Rebase and merge)を使うかを指定しておく必要があります。 結果として、 これまで開発者が個人の好みでマージメソッドを選んでいた運用はできなくなり、全員が同じメソッドを使うことを強制されます。 我々が行った選択とそのプロセス マージキューを導入するにあたり、我々は Merge commit と Squash and merge のどちらに統一するか、という選択を迫られました。 各選択肢の課題の比較 それぞれの設定をデフォルトにした場合に、開発者にどのような影響が出るかを比較検討しました。 Squash and merge を選択した場合の課題: 意図的に複数のコミットに分けているプルリクエストが、マージ時に強制的に1つにまとめられてしまいます。さらに、GitHubのUI上で自動生成されるコミットメッセージは、個々のコミットメッセージを単純に連結したものになり、マージ時にメッセージをきれいに整形することができません。 Merge commit を選択した場合の課題: これまで feature branch 上で作業途中のコミットを細かく積み、マージ時にUI上で1つにまとめていた開発者にとっては、整形前のコミットがそのまま master ブランチの履歴に残ってしまうことになります。 我々の決定:「Merge commit」の採用と運用によるカバー 両者を比較した結果、我々はリポジトリのデフォルト設定として Merge commit の採用を決定しました。 決め手は、 Squash and merge を選択した際の「コミットメッセージが適切に整形できない」という制約の影響が大きいと判断したためです。 その上で、 Merge commit を選択した場合の課題(整形前のコミットが残ってしまう)については、運用でカバーする方針としました。 具体的には、コミットを1つにまとめたい開発者に対し、「マージキューに入れる前に、 feature branch 上で git rebase -i などを使って事前にコミットを整理してもらう」という協力をお願いすることにしました。 この運用により、意図したコミット履歴をそのまま残したいケースと、複数のコミットを1つにまとめてマージしたいケース、その両方に対応できると考えました。 この決定の背景と具体的な運用ルールをドキュメントにまとめ、開発者全員に協力を依頼することで、スムーズな移行を目指しました。 まとめ GitHubのマージキューはデプロイフローを安定させる有用なツールですが、一方で、チームの開発スタイルに影響を与える制約も存在します。特に、マージメソッドが1種類に固定される点は、導入前にチーム内でコンセンサスを取っておくべき重要なポイントです。 この「マージメソッドが強制的に固定される」という仕様は、見落とされがちなポイントだと思いましたので、最初のTIPSとして紹介しました。 次回は、マージキューの特性を活かして、障害対応時のCI待ち時間を短縮した工夫についてご紹介します。
GitHubマージキュー導入時のGitHub Actions CI設定変更 こんにちは、タイミーでPlatform Engineerをしている近藤です。 今回は、GitHubのマージキュー(Merge Queue)に対応するために、GitHub ActionsのCI設定を修正した話を紹介します。 TL;DR GitHubのマージキュー(Merge Queue)を導入する場合、以下の設定が必要です。 Rule Sets(Branch protection rule)で「Require status checks to pass」を有効化 「Merge Queue」の有効化 CIワークフロー(ci.yml)の変更 merge_group イベントの追加 gh-readonly-queue/** ブランチをpushイベントから除外 GitHub Actionsの従来のCIワークフロー まず、従来のCIワークフロー(ci.yml)の設定を振り返ります。元々の設定は以下のようになっていました。 name : ci on : push : branches : - '**' - '!master' tags-ignore : - '*' concurrency : group : ${{ github.workflow }}-${{ github.ref }} cancel-in-progress : true permissions : id-token : write contents : read pull-requests : write jobs : ci : uses : ./.github/workflows/_ci.yml secrets : inherit この設定では、masterブランチ以外のすべてのpushイベントでCIが実行されます。 デプロイまでの従来の流れ タイミーのdeployワークフローはGitHub Flowを採用していたため、以下のような流れになっていました。 PRを作成し、CIが通ることを確認。 PRをmasterブランチにマージ。 マージによってmasterにpushが発生し、デプロイ用ワークフロー(deploy_prod.yml)が実行される。 deploy_prod.yml は次のようになっています。 name : deploy_prod on : push : branches : - master jobs : deploy : runs-on : ubuntu-latest steps : - name : Checkout uses : actions/checkout@v4 # デプロイ処理... GitHubでの設定変更(Rule Sets) マージキューを使うには、GitHubの設定画面から「Rule Sets」(従来はブランチプロテクションルール)を設定します。 多くのケースではすでにステータスチェック必須(Require status checks to pass)の設定がされていると思いますので、その場合は「Merge Queue」を追加でONにするだけです。 GitHub ActionsのCIワークフロー変更 PRからマージキューに積まれた際、 gh-readonly-queue/xxxx というブランチが作成されるため、CIワークフロー(ci.yml)に以下の変更が必要になりました。 name : ci on : push : branches : - '**' - '!master' + - '!gh-readonly-queue/**' tags-ignore : - '*' + merge_group : concurrency : group : ${{ github.workflow }}-${{ github.ref }} cancel-in-progress : true permissions : id-token : write contents : read pull-requests : write jobs : ci : uses : ./.github/workflows/_ci.yml secrets : inherit ポイント merge_group イベントを追加することで、マージキューにエンキューされたときにCIが実行されます。 gh-readonly-queue/** を除外することで、不要な二重実行を防ぎます。 注意点 merge_group イベントは単独で定義できず、必ず他のイベントと一緒に定義する必要があります。 GitHub公式ドキュメント - merge_group The merge_group event cannot be the only event defined in a workflow. 変更が不要なワークフロー デプロイ系ワークフロー(例: deploy_prod.yml )など、masterブランチへのpushのみで動作するワークフローは、マージキュー対応後も変更不要です。 おわりに GitHubのマージキューは導入が比較的簡単ですが、既存のGitHub Actionsにも影響を与えます。本記事を参考に、スムーズにマージキューを導入していただければ幸いです。 最後までお読みいただき、ありがとうございました!
こんにちは、タイミーでバックエンドのテックリードをしている新谷 ( @euglena1215 ) です。 タイミーのバックエンドは、多くの開発者が関わるモノリスなRailsアプリケーションを中心に構成されています。本記事では、このモノリスリポジトリのデプロイフローを安定させるためにGitHubのマージキューを導入した事例を紹介します。 本記事が、masterブランチにマージしたコードでCIが頻繁に失敗し、開発プロセスに影響が出ているチームの参考になれば幸いです。 masterブランチのCIが頻繁に失敗していた タイミーのモノリスRailsリポジトリでは、1日に20件以上のPull Requestがマージされることもあります。多くの開発者が同時に開発を進める中で、ある問題が頻発していました。 それは「他の人の変更がmasterブランチに取り込まれたことに気付かず、古いmasterを元にしたPull Requestをマージしてしまい、結果的にmasterブランチでCIが失敗する」という事象です。 masterブランチでCIが失敗する図 この事象により、開発チームに次のような影響が出ていました。 リリース遅延 masterが一度CIに失敗すると、原因の特定と修正(Revertなど)が終わるまで、誰もデプロイできなくなります。これにより、ユーザーに届けたい価値をタイムリーに届けられない事態が発生していました。 コンテキストスイッチとコミュニケーションコストの増大 masterのCI失敗は、Slackでの全体周知、原因調査の依頼、マージの一時停止呼びかけなど、多くの開発者を巻き込むコミュニケーションを発生させ、チーム全体の生産性を低下させていました。 実際に、2025年のある2ヶ月間を調査したところ、masterブランチでのCI失敗のうち、 最新のmasterを取り込んでいれば防げた可能性が高いものは6件 ありました。この課題を解決するため、我々は解決策の検討を開始しました。 なぜ「マージキュー」だったのか? この問題を解決するにあたり、我々はGitHubマージキューを選択しました。その背景をご説明します。 まず、解決策として考えられる「すべてのPull Requestは、マージ直前に必ず手動で最新のmasterを取り込む」というルール運用は、1日に20件以上もマージされるリポジトリでは現実的ではありませんでした。CIの待ち時間や再レビューのコストを考えると、開発速度の低下は避けられないと判断しました。 一方で、タイミーでは既にGitHub Enterprise Cloudを導入済みでした。そのため、マージキューは追加コストや新たなセキュリティレビューなしに利用できる機能でした。 既存のプラットフォームの機能を活用することは、我々にとって合理的な判断でした。そのため、他のサードパーティツールを比較検討することはせず、マージキューの導入にフォーカスして調査を進めることにしました。 解決策:GitHubマージキューとは? GitHubのマージキューを改めて説明すると「masterブランチにマージされる前に、最新のmasterと合体させた状態でCIを実行し、成功したものだけを自動でマージする仕組み」です。 開発者がPull Requestをマージキューに追加すると、GitHubは内部的に一時的なブランチを作成し、その時点での最新のmasterとPRの変更をマージしてCIを実行します。CIが成功すれば、その変更がmasterにマージされる、という仕組みです。 【重要】GitHub Enterprise Cloudが前提 繰り返しになりますが、GitHubのマージキューはprivateリポジトリで利用する場合、GitHub TeamsプランではなくGitHub Enterprise Cloudプランの契約が必要となります。 詳しくは公式ドキュメントをご覧ください。 docs.github.com まとめ GitHubマージキューを導入したことで、課題であった「古いmasterとの競合によるCI失敗」はなくなり、masterブランチがCIの成功した状態を維持できるようになりました。 この結果は、ただ機能を有効化しただけで得られたものではありません。私たちは、本格導入に先立ち、マージキューをテスト環境で検証しました。その結果、ただ有効化するだけでは我々の開発フローとの互換性を保つのが難しく、いくつかのチューニングが必要なポイントが明らかになりました。 これらのポイントに事前に対処したことが、スムーズな導入の鍵となりました。 次回の記事では、この導入を成功に導いた、具体的な検証内容と、それに基づいて我々が実装したチューニング方法(GitHub Actionsのワークフロー設定など)について、詳しく解説していきたいと思います。 tech.timee.co.jp tech.timee.co.jp tech.timee.co.jp tech.timee.co.jp tech.timee.co.jp tech.timee.co.jp
タイミーでは、Flaky Test がデプロイの妨げになることで開発効率が悪化していました この問題を解決するため、AI エージェント「Devin」を活用し、Flaky Test の検出から修正プルリクエストの作成までを完全に自動化しました 結果、CIは安定し、開発者は本来の業務に集中できるようになったことで、開発体験が向上しました こんにちは!タイミーでバックエンドエンジニアとして働いている 福井 ( bary822 ) です。 皆さんは Flaky Test に悩まされた経験はないでしょうか? タイミーでも、Flaky Test によって CI の信頼性が低下し、開発者の貴重な時間を奪ってしまうという課題を抱えていました。 ある期間においては master ブランチにおけるテスト実行の 4.5% が Flaky Test によって失敗しており、20+回/日 の頻度でデプロイされていることを考えると1日に1名は CI を re-run せざるを得ない状態に陥っていました。 この記事では、根深い Flaky Test 問題を解決するために、Devin を活用して修正プルリクエストの作成を自動化し、CI の安定化と開発体験の向上を実現した取り組みについてご紹介します。 私たちが抱えていた課題 Flaky Test を放置すると開発チーム全体に様々な悪影響を及ぼします。私たちが直面していた主な課題は以下の通りです。 開発効率の悪化 : 問題ないはずの Pull Request の CI が Flaky Test によって失敗すると、開発者は本来不要な原因調査や CI の再実行に時間を費やすことになります。多くの人にとって一定の緊張が発生するデプロイ作業の一環として実行される CI が失敗するというのは精神的にも大きな負担となります。 デプロイの遅延 : master ブランチの CI が失敗すると、デプロイ担当者はそれが Flaky Test によるものかどうかを切り分ける調査を強いられていました。 Flaky Test だった場合は再実行によってその場を凌ぐことが常態化しており、迅速な価値提供の妨げとなっていました。これは、ビジネスの機会損失にも繋がりかねません。 CI における品質保証の機能不全 : テストの成否が不安定なため、master ブランチで既存機能が正しく動作することが保証されているかどうかを正確に判断できなくなります。私たちの場合はその多くが「テストは正しく書かれているが何らかの不安定な要因によって失敗することがある」ケースだったため、実質的な品質の低下はほとんど発生していませんでした。しかし、その反対(本来失敗すべきなのにたまたまパスしてしまう)が発生していたとしても「また Flaky か…」と見逃されてしまいコードの修正が遅れる可能性がありました。 これらの課題を解決し、開発者全員が安心して高速に開発を進められる環境を作るため、私たちは Flaky Test の早期発見と修正を自動化する仕組みの構築に乗り出しました。 解決策:Devin による Flaky Test 修正の完全自動化 私たちは、以下のステップで Flaky Test の特定から修正までを自動化する仕組みを考案しました。 Flaky Test の自動検出 : CI 環境で実行されるテストの実行データを Datadog (Test Optimization)に送信し、Flaky Test を自動で検出する Devin による修正PRの作成 : 新しい Flaky Test が検出されると、それをトリガーに GitHub Actions のワークフローを起動する。ワークフローは、テストファイル名やエラーメッセージなどの情報をプロンプトに含めて API 経由で Devin に渡し、修正プルリクエストの作成を依頼する。 レビューとマージ : Devin によって作成されたプルリクエストは、 CODEOWNERS の設定に基づいて適切なチームに自動でレビューが割り当てられます。チームは、Devin が提案した修正内容を確認し、必要に応じて変更を加え、マージします。 この仕組みの全体像は以下のようになっています。 Flaky Test の発見から修正の「叩き台」作成までを自動化する このフローにより、Flaky Test の発生から修正提案までが完全に自動化され、開発者は Devin が作成した Pull Request をレビューするだけでよくなりました。 もちろん Flaky Test の発見自体が誤検知である可能性もあるため、その場合はチームの判断でクローズします。 また、Devin が誤った原因仮説に基づいた望ましくない修正を提案する場合もあるため、必要なら追加の変更を行ったり、新しい Pull Request を作成したりして柔軟に対応します。 いずれにせよ Flaky な状態が疑われるテストが発見されると、ほとんど同じタイミングで担当するチームがそれを認識し、修正の「叩き台」がすでに作成されている状態を実現することができました。 Devin はどのようにテストを修正するのか? 「Devin が本当に Flaky Test を修正できるのか?」と疑問に思う方もいるかもしれません。 私たちも最初は半信半疑でしたが、Devin は当初の期待を上回るほど的確な修正を提案してくれています。 これは、Devin に渡しているプロンプトの一部です。再現手順の特定や、 Pull Request の体裁、修正の勘所などを細かく指示しています。 レビュアーやラベルなど、Pull Request 上で設定する静的な項目に関しては期待値を宣言的に定義し、CLIコマンドの返り値によってその検証を行うように指示しているのが重要なポイントです。 こうすることで、Devin 自身がセルフチェックを行いやすくして求める出力を安定的に得られるようにしています。 以下の Flaky Test の修正を行い、${レポジトリ名} に Pull Request を作成してください。 # テスト情報 ## テストファイル ${Flaky Test が発生したテストファイル名} ## テストケース ${Flaky Test が発生したテストケース名} ## エラーメッセージ(先頭20行) ${テスト失敗時のエラーメッセージとスタックトレース} ## 実行コマンド ${テストの実行コマンド} (CI環境ではテストファイルを分割して並列実行しているため、どのテストファイルをどの順番、Seed値で実行しているかの情報が必要) ## 問題発生時のコミット ${直前の Commit の SHA} # 作業内容 1. テストコードの修正 2. 修正後、当該テストをローカル環境で5回実行し、全て成功することを確認 - seed値を変えながらテストを実行する時は、1つ以上の他のテストファイルも同時に実行 - 複数のテストファイルに渡ってランダムな順番でテストが実行されるようにしたい 3. 以下の要件を満たす Pull Request をDraftで作成 - タイトル: flaky: (原因と修正内容を簡潔に記載) - コードオーナーの設定に従ってレビューリクエストを送信。コードオーナー不在の場合は ${コードオーナー不在の場合に対応する GitHub Team 名} に送信 4. CIが成功したら、Pull Request を Open に変更 # Pull Request の description に含める情報 - 発生していた問題の概要 - 修正内容とそれによって Flaky が解消されると判断した理由 - Datadog 上のテスト結果ページのURL # 重要な注意事項 ## 制約 - 修正内容は最小限に抑え、テストの意図を変更しないようにしてください。 - 他の spec ファイルで使用されている既存のパターンに合わせた実装を行ってください - 可能な限り修正前に失敗するまで条件を変えながらテストを実行し、失敗したときの実行コマンドなどの再現手順を明記してください。 - テストの失敗を再現するときには並列実行環境下で自然に発生し得る条件を設定してください。特定のデータを手動で作成するなどすることは禁止します。 - テストの修正によって Flaky が解消されると判断した理由を明記してください。 ## 検証コマンド 以下のコマンドで各項目が正しく設定されていることを確認してください: ### PRステータスが Open であることの確認 \`\`\` bash gh api repos/${レポジトリ名}/pulls/{pr _ number} --jq '.state, .draft' # 期待値: "open" と false が表示される \`\`\` ### レビュアーが追加されていることの確認 \`\`\` bash # 変更したファイルにコードオーナーが設定されている場合 gh api repos/${レポジトリ名}/pulls/{pr _ number}/requested _ reviewers # 期待値: teams配列に コードオーナーのTeam名 が含まれる # 変更したファイルにコードオーナーが設定されていない場合 gh api repos/${レポジトリ名}/pulls/{pr _ number}/requested _ reviewers # 期待値: teams配列に "${コードオーナー不在の場合に対応する GitHub Team 名}" が含まれる \`\`\` ### devin-fix-flaky-test ラベルが設定されていることの確認 \`\`\` bash gh api repos/${レポジトリ名}/issues/{pr _ number}/labels # 期待値: name が "devin-fix-flaky-test" のオブジェクトが含まれる \`\`\` # 参考情報 - テストはファイルごとに一定のまとまりで分割されて並列実行されており、ランダムに設定されたSeed値を使って実行順序を制御しています - それぞれの実行環境では独立したデータベースが用意されており、実行環境間でデータが共有されないようにしています このプロンプトに基づき、Devin は様々なパターンの Flaky Test を修正してくれました。 ここでは、その中から代表的な2つの例をご紹介します。 修正例1: バリデーションエラーによる不安定性の解消 開始、終了時間を定義する2つの DateTime 型のカラムによって計算される値に依存するバリデーションのテストにおいて、処理時間とタイミングによっては失敗するケースがありました。 Before: context ' ... ' do before do create( :offering , :just_working ) end end offering はいわゆる「求人」を表現するモデルです。 just_working trait では稼働時間がちょうど6時間になるように設定されています。 trait :just_working do start_at { Time .current.ago( 5 .hours) } end_at { Time .current.since( 1 .hour) } end 労働基準法では6時間を超えると45分以上の休憩が義務付けられます。この場合はギリギリ6時間なので休憩時間が0分でも offering レコードの保存に成功します。 しかし、開始・終了時間( start_at と end_at )はそれが設定されるときの現在時刻に依存しているため、 start_at が設定された後のタイミングでちょうど1秒をまたいでしまうと、 end_at = start_at + 6時間 + 1秒 となってしまうため、休憩時間が設定されていないとバリデーションエラーが発生してしまいます。 ActiveRecord :: RecordInvalid : 労働時間が 6 時間を超えています。法定休憩時間を満たすように休憩時間を設定してください。 After (Devinによる修正): context ' ... ' do before do create( :offering , :just_working , :with_rests ) # :with_rests trait を追加 end end Devinは、 with_rests trait を追加することで、6時間超の労働時間に対して法定休憩時間(45分以上)を自動的に設定するように修正しました。 これにより、バリデーションエラーを回避し、テストが安定して成功するようになりました。 修正例2:FactoryBot のランダムデータ生成による不安定性 FactoryBot で生成されるランダムなデータが、テスト対象のメソッドの条件分岐に影響を与えて Flaky になっていたケースがありました。 Before: describe ' ... ' do let( :client ) { create( :client ) } context ' ... ' do let( :serializer ) { BrandUserSerializer .new(brand_user, client_id : client.id) } let( :brand_user ) { build_stubbed( :brand_user ) } # brand_user に client が紐づく it { expect(serializer.kind).to eq :other } end end このとき BrandUserSerializer#kind メソッドは次のように実装されていました。 def kind if @brand_user .client_id == @client_id :manual else :other end end BrandUserSerializer のインスタンス生成時の第一引数として渡された brand_user に紐づく cliend_id と、第二引数として直接渡された client_id の値を比較し、同一であれば :manual を、そうでなければ :other を返します。 このテストでは異なる値が設定される :other を期待値としていました。しかし、 build_stubbed では ID がランダムに設定されるため、ごく僅かな確率で第二引数として渡された client.id の値と一致することがあります。 この場合 .kind は :manual を返すためテストが失敗してしまいます。 After (Devinによる修正): describe ' ... ' do let( :client ) { create( :client ) } context ' ... ' do let( :serializer ) { BrandUserSerializer .new(brand_user, client_id : client.id) } # 明示的に別の client を作成して確実に異なる client_id が返るようにする let( :other_client ) { create( :client ) } let( :brand_user ) { build_stubbed( :brand_user , client : other_client) } it { expect(serializer.kind).to eq :other } end end Devinは、明示的に other_client を作成し、 brand_user に設定することで、確実に異なる client_id を持つようにしました。 この変更により、serializerの条件分岐で正しく :other が返されるようになり、テストが安定して成功するようになりました。 導入後の成果と今後の展望 これを書いている時点で 3件 の Flaky Test を修正する Pull Request が Devin によって作成されましたが、そのうち 2件 は開発者によって変更が加えられることがなくマージされました。 結果として、CI の成功率は安定し、開発者は Flaky Test による手戻りや不要な調査から解放され、より価値のある機能開発に集中できるようになりました。 Devin が作成した Pull Request を「叩き台」として、チーム内で修正方針を議論したり、追加の変更を加えたりといった、より建設的な活動も生まれていることも重要なポイントです。 今後は、さらにプロンプトを洗練させ、より複雑な Flaky Test にも対応できるように改善を続けていく予定です。また、今回の成功を足がかりに、Flaky Test 修正以外の開発プロセスにも積極的に AI を活用していくことを検討しています。 おわりに 今回は、 Devin を活用して Flaky Test の修正を自動化し、CI の安定化と開発体験の向上を実現した事例をご紹介しました。AI を開発ワークフローに組み込むことで、これまで人間が時間をかけて対応していた退屈な作業をなくし、より創造的な仕事に集中できる環境を作ることができます。 この記事が、同じように Flaky Test に悩む開発者の皆さんにとって、少しでも参考になれば幸いです。 最後までお読みいただき、ありがとうございました!
はじめに こんにちは。タイミーでAndroidエンジニアをしている Hunachi(ふなち) です。 2025年6月25日から26日に開催されたdroidcon NYC 2025に参加してきました。このブログでは、droidcon NYCの雰囲気と、特に印象に残ったセッションについてご紹介します! droidcon NYC 2025の雰囲気 参加者は 700名以上 、セッションは4つのステージで 80以上 と、DroidKaigiとほぼ同規模か少し小さいくらいのイベントでした。 主にアメリカで働くAndroidエンジニアが集まっており、私が話した方々はニューヨーク近郊だけでなく、アメリカ各地から数時間かけて来ている方がほとんどでした。弊社社員を除く日本からの参加者には出会いませんでした。 また、同じ会場で Fluttercon も開催されており、Flutterエンジニアとの交流も楽しめました。 興味のあるセッションを多数聞けたのはもちろんのこと、海外のエンジニアの方々と交流できたのは貴重な経験でした。 英語をスラスラと喋れる訳ではないのですが、他の参加者の方々がとても優しく接してくださり、楽しい時間を過ごせました。Googleの社員の方やスピーカーの方に直接質問できる機会もあり、非常に有意義でした。 一緒にセッションを聞きいたりお話ししたりしてました! ランチの時間でも他の参加者と交流することができました! Day2には、前日に仲良くなった人たちと一緒にセッションを聞いたり、おしゃべりしたりできました。ランチの時間も他の参加者と交流することができ、自分から喋りかけに行けば他の参加者と楽しくコミュニケーションが取れる雰囲気でした 🤝 聞いてきたセッションの一部を紹介します! Panel: The Future of Dependency Injection in Modern Android このパネルディスカッションでは、現代のAndroid開発におけるDI(依存性注入)の未来について議論されていました。 KMP(Kotlin Multiplatform)では「Metro」というDIフレームワークがよく使われる。 DIの原則自体は複雑ではない。我々は問題解決に集中すべきで、DIのことを気にするのは良くない。 サービスロケーターは避けるべきで、依存関係はコンパイル時に解決すべき。 DIフレームワークは早めに導入を決定することが推奨で、移行にはコストがかかるため注意が必要。 CompositionLocal はグローバル変数のように使われることがあり、コンパイル時にエラーにならないためリスクがある。 など、AndroidやKMPの最前線を走っている方々からDIに関するお話を聞くことができて、とても勉強になりました。 Tackling Memory Issues on the Instagram Android App at Scale InstagramのAndroidアプリにおける大規模なメモリ問題への対処法についてのセッションでした。 アプリでユーザーがコンテンツを編集中に落とさないための工夫や、メモリが足りずにアプリがクラッシュする時の調査方法(HPROFファイルを使った調査)の説明がありました。 特に印象的だったのは、メモリについて詳しくなりたいなら「 Runtime.getRuntime() 」や「 /proc/meminfo 」から取得できるデータなど見ると良いという細かなアドバイスがあったことです。大半の普通のAndroidエンジニアは一生触れないだろう内容ですが、前職でメモリと向き合ったことのある私にとってはとても興味が湧く内容でした。 The Future of Android...And How to Prepare For It Androidの未来と、それに向けてどのように準備すべきかについてのパネルディスカッションでした。 AIの進化により、スクリプトだけで開発できる時代が来ており、将来的にはコードの70%がAIによって生成されるだろう。 エンジニアはより複雑な問題を解決するために働くようになってきている。 AIによるポジションの削減などもありますが、逆にAIのおかげで私たちもあらゆる分野で働けるようになるため、ポジティブな側面も多くある。 このようなカンファレンスでいろんな人と問題など色々なことについて話す等、エンジニア同士の交流も重要になってくる。 AIにより学ぶことも前より容易になっている。 一般的な知識(いろんな言語や分野)を身につけることが大切。 といった白熱したトークが行われていました。 弊社でもAIの活用はとても推奨されているのでAIを使った開発が日常になりつつはあるものの、このパネルディスカッションを聞いて、私ももっとAIを活用して今までよりも多くの分野で、より多くの作業量をこなすことができる人材になりたいなと思いました。 Career Office Hours with Stacy Devino Stacy Devino氏によるキャリアに関するオフィスアワーにも行きました。 キャリアを考える上で大切だと言われていたことのうち印象に残ったものは、 経済的に安心できる状況を作る AIでカバーできない範囲など ユニークなスキルを持つ 自分が何を楽しんで、何が得意かを認識する ビジネスプロセスや効率化について学習する レイオフの危機 を感じたら、事前に準備する の5つです。 レイオフが日本よりも身近なアメリカだからこその話も聞けてとても為になりました。 Server Driven UIs: the future of cross-platform rendering architectures サーバー駆動型UI(SDUI)についてのセッションでした。 SDUIはUIのデータをサーバー側に持たせて、動的なUI変更を可能にする仕組みのことなのですが、個人的にとても親しみのある内容でした。 タイミーでも取り入れられると嬉しいなと思いました。 Google社員の方や、スピーカーの方に質問してきた 出発前に社内のAndroidメンバーに聞いてきて欲しいことがあるか意見を聞きました。 そこで出てきた意見や個人的に気になっていたことをGoogle社員の方や、登壇者の方に質問してきました。 社内で質問したいことや気になるセッションを聞いた時のmiroのボード Googleの方に、"Ask Android" Office Hours の時間を使って質問をしました。 「Google的に、Adaptive layoutsを推してると思うけど、時間がないデザイナーが対応したいと思える情報ある?」 「Android用のMCPってどんなのがある?」 等の質問をしました。 Googleの方と2対1(Google社員の方2人、私1人)という贅沢な環境でたっぷり時間を使って質問することができました。また、Google I/Oの動画に出ていた方も数人おり、直接お話しできてとてもワクワクしました。Google社員の方がたくさんいるニューヨークだからこんな状況で質問できたと思うので、droidcon NYCに来た甲斐があったと思える瞬間の一つでした。 また、フリーの時間で、キャリアのセッションをしていたStacyさんという女性の方にキャリアと育児についての質問もさせていただきました。 自分にはまだ子供がいませんが、将来的に必要になるかもしれないアドバイスを多くもらえました。特に「子供を産んだり育てることは想像以上に大変だから金銭面でも時間の面でも余裕を持っておくことがオススメだよ。」「子供との時間、仕事両方大切だけど、その時々で優先順位を決めて行動しなさい。同時に両方を全力でするのは厳しいよ。」という言葉がとても心に響きました。 感想 初めての海外カンファレンスですごく緊張していたのですが、とっても楽しかったです! 私はまだ英語に苦手意識があったのですが、各自見たいセッションも異なるし、弊社メンバーで固まらずに別行動をしよう!となり、Day1の最初以外の大半の時間を別行動していました。このチャレンジのおかげで自分の力だけでも海外の方と仲良くなれるという自信をつけることができてとても嬉しかったです。 また、今回のdroidconはAIの話が多く、AIの影響による良い面や悪い面について考える良い機会にもなりました。上記で紹介していないのですが、Stacyさんのセッションで「AIの出現はComposeの出現と似たようなもので、怖がる必要はない。我々は変化に対応できる。」という話を聞き、ポジティブな意味でもっとAIと仲良くなれるように頑張ろうと思えました。 今回のカンファレンスで学んだことをこれからのキャリアや社内での振る舞いに活かしていきたいです。 関連記事 productpr.timee.co.jp tech.timee.co.jp おまけ 行くまでの準備 英語の勉強をしました。Native Campで会話をする練習をしたり、Duolingoで文法や単語を勉強しました。また、英語のドラマを毎日見て、英語に親しみを覚えるようにしました。 今年もGoogle I/Oの動画でモバイルに関連するものはほぼ全部見ました。去年より英語の勉強をした甲斐があり英語での視聴でもほぼ問題がなかったのでスラスラ見ることができました。 droidcon NYC 2025の自分用のアプリも作りました。作成時にまだ公式アプリがなかったためです。後から出てきたので用無しになりましたが、AIがどれくらい使いやすいのか知れる良い機会になりました。細かいエラーなどは手動で修正しつつ、大部分のコードをAIに書かせるというスタイルだと爆速でアプリが作れることがわかりました。この経験のおかげでdroidconの中で行われていたAIの議論にもよりついて行くことができた気がします! I'll be attending droidcon NYC 2025😻 To save sessions I want to attend, I developed an Android application for personal use. While it's not a polished app, I used Cursor so it only took me about four hours to create. AI is very powerful 🙀 pic.twitter.com/K2QbyoAkV7 — 🍥ふなち🍥 (@_hunachi) June 21, 2025 観光 カンファレンス以外では、ニューヨーク市内で観光も楽しみました。 サブウェイなどのローカルな飲食店や、ローカルなスーパーも色々と行きました。 チャンククッキーが好きなので、色々なお店でクッキーを買って食べたりもしました。 どのお店の店員さんもわからないことも教えてくれたりととても優しく過ごしやすかったです。乗る電車がわからなくなった時も、駅員さんと他の乗客の方々がめちゃくちゃ丁寧に道を教えてくれて感動しました😭 また機会があればニューヨークにもdroidconにも行きたいです!