私が所属したチームのワークフローと継続的改善の取り組み
筆者は、株式会社オプティマインドの元データインフラ(DI)チームに所属していたが、最近チーム再編によって別チームへ異動した。元DIチームでは、チームワークフローについて様々な取り組みを実践してきており、これらの知見と経験を他のエンジニアにも糧になると信じ、今回は一部の内容を記事化しようと思った。
そもそも何のためのワークフローなのか
仕事の流れが一定的な手順に沿った大枠がワークフローとなるが、そもそも何のためにこれらのワークフローを作るのか、を最初に考えてみたい。
仕事をうまく進める上ではいろんな要素を考えないといけなく、マネジメントしていく必要がある。プロジェクトをどう管理するか、開発の流れをどうするか、ブランチ戦略どうするか、リリースフローどうするかなど。ただ、これらの課題は、とにかくそれぞれルール・ガイドラインを作っておけば良い話ではないと考えている。少なくとも、DIチームでは、これらのワークフローをよりチームに適するように、実践と振り返りをしつつ、継続的に改善を計らっている。
そういう意味で、アジャイル思考と根本的に共通しており、我々の仕事の継続的改善、そしてその仕事の流れを決めているワークフローに対しての継続的改善、という2つのレイヤーが存在しているのではないかと。
今回は、元チームでの継続的改善についての取り組みについて共有する。
ワークフローの定義
簡単に定義しておくと、特定の目的達成のために必要となる一連の手順から構成されている。
- 一連の手順
- 主語(担当者)
- 条件
- インプットとアウトプット
- 目標(アウトカム)
といったキーワードを意識すると良いワークフローになりそうで、仮に作成時に一回で全てクリアにならなくても、改善し続ける心構えで継続していくことが大事かと思う。
各種ワークフローについて
ソフトウェア開発のコンテキストにおいて、どんなワークフローがあるかを考えると、
- プロジェクトとタスク管理
- 開発
- テスト
- リリース・デプロイ
- コミュニケーション・チームワーク
- ドキュメンテーション・知識共有
- 監視・危機対応
- ...
などの側面が考えられる。今回は主に、プロジェクト管理、開発→テスト→リリース、コミュニケーションとチームワークについてのワークフローを紹介したい。
プロジェクトとタスク管理
プロジェクト管理はあくまでも一つ一つのプロジェクトを対象に定義されているものではあるが、DIチーム内ではその延長線に、直接プロジェクトに関わる「開発タスク」と直接に関わらない「ボール」に分けられている。
開発タスク
幾つかのプロジェクトがあるが、メインのものはJIRAを運用して管理している。JIRAでは、後のスクラムのところでも触れるが、マイルストーンとスプリントゴールの設定、タスクDoDなど詳細の定義、タスク経過をコメント内に記録など重要な機能がある。
それで、JIRAのタスクを追うためには、dailyが毎日午前に開催されいている。dailyは前半と後半に分けられていて、各自の進捗報告15分程度+小話15分程度(プラス事務連絡)という形であった。
デイリーは、プロジェクト管理の意味でも、チーム間交流でも大事な日課として認識されている。基本的ファシリーはランダムで決めているので、リーダーかマネージャーに集中するとかのことはない。
各自の進捗の記録を残すためには、先ほどのJIRAとは別で、毎日の仕事の振り返りと今日の計画を立つという意味で、Rangeというサービスを利用している。ここで、昨日の予定、実績、今日の予定の軸(テンプレ化)で情報共有をし、各自の報告に対して他のメンバーがコメント・質問する。その場で問題を発見したり、認識を揃えたりする働きはある。
また、最初のデイリーでは進捗報告、事務連絡、小話との構成であったが、各種改善が進む中で、KPT、ボール、ワーキングアグリメントの確認が追加されるようになった。
デイリーで進捗を追うことは、
- 認識の共有 → このタスク担当していない他のメンバーにもシェアし、他の人は何やっているかがわからない状態を避ける
- 問題の提起 → 何か作業にブロックされているかを、その場でアドバイスをもらったり、後に別途話したりする決断がしやすい
との積極的な面が強いと考えている。
また、プロジェクト管理の意味であまり関係ないかもしれないが、最後に小話でファシリーが選ぶランダムな話題について雑談を行う。例えば週明けの場合は週末について共有したり、最近みた面白いアニメとか、食べた美味しい料理とか、いろんな話題について話し合い、メンバー間の交流を促進することができる。このような些細なコミュニケーションは、心理的安全性を高めることができ、よりフラットで誠実なチームの雰囲気を作り出すことに繋がる良い取り組みだと認識している。
ボール
ボール自体はプロジェクト管理の意味で範疇外にはなるが、実際にチームでいろんなイベントや些細な対応など、円滑にさせるために不可欠な部分だと考えている。例えば、勉強会の内容選定とか、MTGの時間調整とか、slackワークフローの作成とか、社外への問い合わせなどなど。
この部分に関しては、最初(約一年前)はweekly/monthlyといった定例時に、google docを作って、振り返りのセッションでチェックリストを作っていた。
ただ、先週Aさんが担当すべきボールは、今週のweekly時に、「あっ、忘れました!」といった事象も時々ありました。また、毎回のweekly/monthly定例の内容が、MTG後チェックされることがなくなり、追うためのシステム・ルールも存在しなかった。
タスクは作ったが、遂行しなかったら意味がなくなる。こういった問題を解決するために、チームでは2つの改善を計らった:
- 開発タスク以外に各種「雑務」をボールマスターで看板ボードの形で管理する
- きちんとタスクを追うことができるように、dailyの時にみんなで確認する
ボールマスターをより活用させるために、あとで紹介するが、スクラムイベントの振り返り、monthly定例の振り返り、ないしdailyとか随時追加可能にした。
開発関連
この部分に関しては、開発→テスト→レビュー→リリースのサイクルで考える。
まず大前提として、ブランチ戦略と各環境について要約は以下となる。
- ブランチ戦略
- リモートレポはGitHubにて管理
- 基本github flow、よりアジャイルに動ける
- main → feature → mainとの流れ
- 環境
- ローカル+クラウド上のdev/stg/prd
- DIチームではインフラ周りのリソースが多く、クラウド上しか動作検証できない状況が多い
開発とテスト
フィーチャーブランチを切って、プルリクを出すまでは各自の自由で、コミット頻度とかメッセージの長さとか特に決まりはない。ほとんどのワークフローは、PRを出してからの部分にあたる。
- ローカルのコミットフックでリンター、フォーマッターでコードチェック
- PR時はドラフト状態で出す
- on pushのタイミングにCIが行う
- インフラのコードはIaC化しており、terraformのバリデーション、リンターなどが走る
- 動作検証のために、クラウド環境をスラックワークフローで予約する
- 同時開発の時にクラウド上リソースの変更で競合しないためのロックシステム
- 誰が、どの時間枠、何のモジュール、どの環境を指定することで、Googleカレンダーと同期
- dev/stg環境に手動トリガーのCDワークフローを実行
- CD終了時に別レポにある、E2Eテスト専用のテストクライエントのCIワークフローをトリガーさせる
- stgの方はprdと同じリソースなので原則としてstg検証が必須(これは一回devでokなのにstgで❌のリリース事故でWAに追加された)
- CD適応後に状況に応じて手動で動作確認する(クラウド上のリソース確認したり、ローカルからリクエスト投げたりするなど)
- 問題なければPRに検証内容をテンプレに記入し、ドラフト状態から外す
レビュー
PRのドラフト状態を外す=ready for reviewなので、上記の流れが終わると、次にレビューの段階に入る。
- レビューガイドライン(ドキュメント化)を元にレビューを進める
- googleのガイドラインを参考に作成
- on PR Openのタイミングで、CIがレビュアーを2名指名
- 各レポジトリーにコードオーナーを2-3名で指定
- コードオーナー1名+他メンバー1名のアプルーブが必要
- コメントのニュアンスがより伝わるように、絵文字アイコンを運用
- must = 🚫 => 修正必要、マージ不可
- nits = ⚠️ => 注意喚起
- imo = 💡 => アイディア
- ask = ❓ => 質問
- fyi = 📖 => 情報提供
- 次にリリースするために、次の条件が必須となる
- 指定された2名レビュアーからのアプルーブ
- CIがパスしている
- 最新のメインとマージしている
レビューは非常に大事な一環であって、また別機会で紹介するが、findy teamsを運用して色々とデータを見ながら改善を計らった。
リリース
最後はリリースとなる。CICDは標準化されているので、この辺りは割とシンプルになっている。
- リリースフローの手順書(ドキュメント化)を元に進める
- 決まった時間帯にリリース(9:00-17:00)
- 万が一の時に他のメンバーもいそうな時間帯が良い
- ダウンタイム発生の場合は、お客さんへの影響(もしくは他の各種テスト)を考慮してリリースタイミングを調整する
- スラックチャンネルでリリース通知(テンプレート化)を出す
- PR内容、ステップ、顧客影響有無などを記入
- ステップを踏んでPRをmainへマージ
- ここで各種CIとCDが走るので、その結果を確認
- 確認結果次第で、リリース終了か、問題のある場合はリバートする
コミュニケーションとチームワーク
いうまでもないが、ここはメンバー間の交流と協力がかなり重視される。これらをうまくいけるようには、根本的に心理的安全性を高めることが大事だと感じている。
日常のコミュニケーションについて、オプティマインドではフルリモートのメンバーも多く、オンラインの形がメインになる。チームではslack, gather, google meet, notion, mirroといったツールを活用し、コミュニケーションを取っていた。
各種定例
定例会議は、チーム全員顔合わせて、チーム全体のプロジェクトの進捗確認、目標管理などの議論の場である。独り言を避けるために、他の人の発言を傾聴して、リアクションすることが重視されている。このリアクションは、
もちろん質疑・コメントだけではなく、オンラインの形で成り立つが、マイクオフの時にも使える絵文字を活用している。
定例の取り組みについて、スクラムを本格導入することを境目に分けられる。導入前はdaily, weekly, monthlyではあったが、導入後のweeklyを、各種スクラムイベントに吸収されたため、daily, scrum weekly, monthlyとなっている。
特にmonthlyでは、チーム全体が目標に向かっているか、方向はずれていないかを意識する役割が大事で、会社の一組織として、きちんと価値提供できているかの振り返りにもなっている。
また、リーダーとメンバーの間に、月1の頻度で1on1が開催されている。ここは近況確認、目標確認以外にも、色々と技術情報の共有とか、長期的目標の相談とか、これまでの人生の振り返りとか、さまざまな話題で行われていた。
なお、チーム限定ではないが、会社全体でクォーター毎に集まるイベントがあり、最近では月1の集まりが始まっている。オフラインで顔を見たり、チームでイベントでのアクティビティをクリアしたり、一緒にご飯を食べたり、話をしたりすると、心理的安全性にも貢献できるし、間接的にはチームワークをより円滑にさせているかと思われる。
スクラム
去年までは、スクラムマスターとのロールが足りない、全てのイベントをやっていないといった意味で、不完全なスクラムをやっていたが、1月から専任のスクラムマスターが参入することで、正式スタートすることになった。
それからは、毎週refinement → planing → review → retrospective各種イベントを遂行するようになった。1スプリント=1週間、水曜レビュー+振り返り+リファインメント、木曜朝にスタートする形で開催されるようになった。
各ステップを少し見てみると、
- POがリファインメントまでバックログ優先順位を整理
- タスクは各自追加OK
- タスク種類をコード、アラート、ドキュメント関連の3種類
- 各種タスクのDoDのテンプレートがJIRA上で作成されている
- プラス具体的に各タスクのスコープのDoD
- タスクの完了がより客観的な観点から管理できる
- 各種タスクのDoDのテンプレートがJIRA上で作成されている
- タスクの詳細は、背景、実装方針、参考資料、関連リソースといった内容のテンプレで作成
- 誰が取るかは決まっていなく、誰でもわかるように書きたい
- リファインメントは時間をとってじっくりと共通認識できるまでやる
- 重さ(SP)はみんなで見積もる
- 重さのズレ=認識のズレ
- タスク内容のどこを増やせば良いか、何が不明瞭になりやすいかがわかる
- 場合によってリファインメントの時間を増やす
- 重さ(SP)はみんなで見積もる
- プランニングはスプリントゴールに向けてタスク配分する
- POがスプリントゴール定義し、みんなでコメント・確認する
- 開発メンバー各自自ら進んでタスクを取る
- コンテキストが欠けても良く、詳しいメンバーと共同作業する
- レビューは完成状況だけの報告でサクサクと進める
- レトロでKeep Problem Tryで振り返りする
- KPTで現れた問題と解決策は内容によってボールマスターかWAに追加
- ミローでテンプレ化
計測
元DIチームでは、DORAと開発サイクルタイムの数値を見て、月1回の振り返りを開催している。月を単位に比較し、その数値の変化が議論の起点となる。計測に関しては、また別途の機会で詳しく記事にしたいと考えており、詳細は割愛する。
WA
working agreementというのは、ワークフローだけではなく、チームの文化として定着させるための位置付けにもある。
- 振り返りで現れたものを共通認識に定着したい場合はこちらに追記
- dailyでKPTと交互に確認
- タスク作成したとか、改善策練り出したとか、実践がないと意味がない
- その実践が忘れられないように、定着させるためには非常に有用
- 助け合いの文化
- 背景の違うメンバーが揃い、コンテキストに差がある
- にしても、モブプロ推奨して、違う分野のタスクも遂行できるようになる
- 「責任を持ってやり切る」≠「一人の力で完遂する」
- ポジティブな言葉でフィードバックするよう心がける
- 例えばレビュー時はよく問題指摘の傾向が強いが、「このパターンはすばら!」、「こんな書き方知らなかった」とか、
- 否定する前提として、代案と理由があり、それが議論をより「建設的」な方向へ導く
特に、助け合いの文化は、オプティマインドで強調されている謙遜力の現れでもある。常に謙遜でいられる人は、他の人への敬意と感謝を忘れず、自分と他人の成長に貢献する力を持っている。この力を持つ人たちがチームを組むと、助け合いの文化が必然的に生まれると思う。
Bonuslyでボーナスをもらう
bonuslyというサービスを導入しており、メンバー間の助け合いを促進するシステムである。毎月一人100コインを他のメンバーへあげられ、コインを持って〇〇コーヒーのギフト券を引換することができる。そういった意味で、助け合い、感謝しあい、美味しいコーヒーがご褒美になる、という取り組みとも言える。
何に感謝すれば良いかというと、些細なことでもよく、ドキュメントのレビューありがとうとか、共同作業で助かったとか、〇〇について教えてくれてありがとうとか、とにかく日常の「感謝」が集まる場となっている。
この感謝の対象が誰か一人に集中しないか、との心配もあるかもしれないが、ここで考えられる対策として、
- チームリーダーの工夫
- メンバーを適才適所に目標設定にアドバイスする→違う分野を担当してもらうことで、知識の共有が発生しやすく、感謝の場面も生まれやすい
- レビューが一人に、最終決定が一人に集約する構造をせず、民主化を計らう(ただリスク管理の意味でリーダーは責任を持って最終決断することは別)ことで、全員が意見を出し合うことが活発になる
- 大小に拘らず、些細なことでも積極的に感謝を発信する
- 日常のコミュニケーションチャンネルに通知が来るようにする
- 例えばslack利用しているなら、slackのチャンネルで、AさんがBさんへ感謝の〇〇メッセージを送ったとか、メンション付きで届く
- 無意識的に、模倣を促進させる効果がある
終わりに
元DIチームで取り組んでいてたワークフローは他にも色々と存在する。スラックの活用、Notionでのドキュメンテーション、監視、勉強会など。
冒頭でも触れたが、ワークフローの目的というのは、仕事を継続的に改善するためだと考えている。さらに、ワークフロー自体も継続的に改善することが大事で、この継続的に改善するため思考は、アジャイルのact -> plan -> do -> checkと共通している。
元DIチームのバージョンをまとめると、ワークフローの改善というメタワークフローは以下となる。行動して、振り返りで問題発見して、それに対してプランを立てて、また行動で実践して、さらに振り返りで改善・ブラッシュアップする、というループとなるかと。
今回は多少技術から離れる内容であったが、ソフトウェア開発はワンマンショーではなく、チームプレーだと信じているし、その同じ思いを持っている方々に何か参考になれれば何より。
オプティマインドは、「世界を少しでも良くしたい」「大きな社会課題に挑みたい」という熱い気持ちを胸に秘めたメンバーが集まり、自社のミッションである「新しい世界を技術で創る」べく、日々技術に磨きをかけています。
また、自社のビジョンである「世界のラストワンマイルを最適化する」ために何ができるのか、ひとりひとりがしっかりと考えながら、真摯に向き合っています。
わたしたちのミッション・ビジョンに共感頂ける方、一緒に伴走してくださる方、ちょっとでもオプティマインドが気になる方、お気軽にドアノックしてください。
カジュアル面談でお会いできることを楽しみにしております。
ぜひ一緒に、大きな社会課題に挑みながら、新しい世界を創っていきましょう!
Discussion