複数チームでのアプリ開発におけるローカライズ文言の管理手法

こんにちは、ソフトウェア開発統括部の伊藤です。 フルスタックエンジニアとしてアプリとバックエンドそれぞれのチームに参加して開発をしています。

この記事はGO Inc. Advent Calendar 2024 8日目の記事です。

タクシーアプリ『GO』は2021年にはローカライゼーションの取り組みを開始し、2023年2月には全面的に英語をサポートました。 その際導入された多言語対応のワークフローを実践した結果、実際の開発チームの動きとそぐわないところが見えてきました。 2023年9月に入社した伊藤が、以前いた組織で直面して解決できなかった問題に共通する部分を感じて、この問題に向き合うことにしました。

オープンソースのツールを個人的に作り、それをベースとした社内ツールを開発して、ワークフローを改善してきました。 今回は2024年の今、タクシーアプリ『GO』のチームで実践しているローカライズ文言の管理方法についてご紹介します。

タクシーアプリ『GO』のアプリ開発の流れ

文言管理のワークフローの問題を話す前に、前提としてタクシーアプリ『GO』のアプリ開発チームの開発の流れを説明します。

『GO』アプリの開発チームでは、複数のチームで同じアプリを開発しています。 チームごとに機能の開発が割り振られます。規模の大きな開発では合同チームになったりすることもありますが、基本的にはそれぞれのチームは独立して開発を進めます。

開発が開始されるとdevelopブランチからtopicブランチを作成し、機能の開発を始めます。

それぞれのチームが機能ブランチを作って開発を開始する 1

ある程度機能が出揃ってくると、開発中の機能の中から何をリリースするかが決まり、リリースバージョンが決まります。 リリースバージョンが決まれば、rcブランチが作成され、topicブランチがマージされます。

リリースバージョンが決まれば、RCブランチを作成して機能ブランチをマージする

品管テストなどが問題なければ、メインブランチにマージされてタグを作成し、リリースされるという流れです。

メインブランチにマージしてリリースする

これはあくで理想的な動きがされた場合です。 問題になりがちなのは、ビジネスの要求や開発の進捗状況などにより、リリースする機能が前後したり、リリースが込み入る場合があるということです。

rcブランチが作成されるまではどの機能が先にrcにマージされるかはわかりませんし、リリースが込み入った場合は複数のrcブランチが作成されることもあります。 複数のrcブランチが作られている場合は差分を減らすためにも先行のバージョンから後続のrcブランチへの同期が行われる場合もあります。

複数のRCブランチで並行して作業するパターン

元のワークフローが合わなくなってきた

2023年2月のアプリの英語化の時に構築されたフローは、以下のようなものでした。

  • 文言管理用のリポジトリにtopicブランチを作成、GitHub Actionsによりtopicブランチに対応する文言管理ツールのプロジェクトが作成される。
  • topicブランチ上で、文言管理ツールのJSONファイルを更新。GitHub Actionsによりtopicブランチに対応する文言管理ツールのプロジェクトが更新される。
  • iOS/Android各アプリ側で文言ファイルを取得し、アプリのリポジトリにPull Reuqestを作成してマージする。
  • 機能開発が完了するタイミングでマージする。GitHub Actionsによりtopicブランチに対応する文言管理ツールのプロジェクトが削除される。

詳しくはiOSDC Japan 2023で髙橋が発表していますので、あわせてご覧ください。

実際の運用では、PdM/デザイナーがConfulenceの記事に定義する文言リソースを記載、エンジニアがそれをJSONに反映するという作業になっていました。

既存のワークフロー。エンジニアの手作業が複数回発生する

しかし、このワークフローにはいくつかの問題がありました。

  • リリースが前後する場合にtopicブランチ間のマージをする必要があります。その際に変更がコンフリクトしていた場合、前後関係を理解していなければ解消できず、その前後関係がわかりづらい。機能ごとの担当者が顔を突き合わせてマージするという作業が発生することもしばしば起こりました。
  • 各アプリのリポジトリ側に参照している文言管理ツールのプロジェクトIDを書き込む必要があった。アプリがリリースする際にこれを元に戻すということも必要で、その作業が漏れがちだった。
  • 文言管理リポジトリへの反映にgitの知識とGitHubのアカウントが必要。これだけのためにPdM/デザイナーがgitを理解し、GitHub Enterprise有料アカウントを割り当ててコミットしてもらうのは学習面でも費用面でもコストが高い。そのため、エンジニアが反映作業を代行することになっており、コードを書く時間が減っていた。
  • せっかく入っている文言管理ツールはJSONファイル置き場としてしか利用できていなかった。この文言管理ツールも費用がかかっていて、その費用は決して安いものではない。

個人的に問題と思っていたのが、複数のブランチが複雑に並行する際のマージが困難であることでした。 また、過去の組織でも文言管理ツールを検討してコストパフォーマンス面から断念した経緯もあり、文言管理ツールにかかっている費用や、その先で非エンジニアにGitHub Enterpriseアカウントを割り当てることになるのであれば、解決できる問題に比べて費用が見あっていなさそうだなという感触もありました。

軽量文言管理ツールhoshi

いろいろ考えているうちに、RubyのActive RecordやPythonのAlembicなどで使われるデータベースマイグレーションのような、変更を1ファイルごとに記述して順次適用させる手法を文言管理に適用することを思いつきました。 これまでの組織で遭遇した問題にも対処ができそうにも思えたので、プライベートの時間を使ってhoshiというツールを開発しました。

このツールでは変更単位で文言をYAMLに記載し、それを順次適用することで目的の出力を得ることができます。 例えば、バージョン1でhello_textを定義して、バージョン2でgoodbye_textを定義、バージョン3でhello_textの内容を変更するというのをそれぞれのファイルで表現し、バージョンを指定してツールに処理させることで、それぞれの変更が適用された文言ファイルを得られる仕組みになっています。

バージョン0.7.0現在、iOS/Androidの言語ファイル、i18next, next-intl形式、もしくは記述そのままのJSONが出力できます。

hoshiの文言運用をサポートする社内ツール

hoshiは「基本的なことをだけを提供し、周辺の機能は利用者側で自由に作ることができる」という設計思想のもと開発されています。 『GO』アプリの開発チームのワークフローに合わせるために社内向けのツールも開発しました。

GitHub Actions・Google App EngineGoogle SpreadsheetのApps Scriptを組み合わせて、以下のような仕組みを構築しました。

社内ツールの構成。Google App Engineで入稿APIと管理画面を構築した。

  • 文言データ入稿用のスプレッドシートに、hoshiのYAMLファイルと一対一となるシートを作成し、Apps Scriptを実行する
    • 文言管理ツール以前の運用でもスプレッドシートを使っていて、この時は文言管理ツールの設定を都度設定する必要がありました。今回はシート追加するのみで設定をする必要がないような仕組みで作られています。
  • Apps Scriptから文言データ入稿APIが呼ばれ、文言管理リポジトリにPull Requestが作成される
  • マージされるとGitHub Actionsがhoshiを実行し、Google Cloud Storageに出力を保存。この時、影響を受けるすべてのバージョンが再生成される。
  • 各プロジェクトでは取得したいバージョン名を指定して、Google Cloud Storageから文言ファイルを取得する。

また、入稿されている各バージョンのYAMLと、最終的な出力を確認できるページも用意しており、似たような表現がないかを確認することに使用されています。

出力確認ページの画面

この仕組みの開発には、Engineer Challenge WeekやアプリのビルドやCIで発生するスキマ時間を活用しました。

新しいワークフロー

この仕組みを用いて、チームでの文言管理運用は以下のようになりました。

  • デザイナーがFigmaでデザインを描く
  • PdMがFigmaから多言語化すべきテキストを抽出し、Confulenceページにまとめる
    • このConfulenceページはエンジニアが適用箇所を確認するほか、品質管理のチームがテストを作成するための基礎資料としても使用されます。
  • PdMがConfulenceページから文言入稿用のスプレッドシートにシートを作成して、Pull Request作成ボタンをクリックする
  • Apps Scriptが文言データ入稿APIを実行、文言データ入稿APIからGitHub Actionsが呼び出されてPull Requestが作成される
  • エンジニアが文言管理リポジトリの変更をマージ
  • iOS/Androidそれぞれのリポジトリに取り込んで反映

バージョン名には7桁のプレフィクスが付与されていて、機能ごとのリリース順を入れ替える必要が出た際はプレフィクスを変更してリリース順を調整します。 また、リリースバージョンごとにどの機能までが含まれるかを表すことを目的として、rcブランチの名前で空のファイルが設置されます。

得られた効果と今後の課題

このワークフローは2024年の頭に本格的に運用を開始して、少しずつブラッシュアップしながらほぼ1年運用してきて、エンジニアの作業は格段に減ったと実感しています。

  • PdMが直接Pull Requestを作成できるようになったので、変更のリクエストが気軽にできるようになった
  • エンジニアがアプリへ文言を反映させるのに必要な作業が減った
  • 機能間の文言定義に対する複雑なマージ作業がほぼ不要になった
  • 非エンジニア職へのGitHub Enterpriseアカウントの付与が必要なくなり、有償の文言管理ツールの利用もなくなるため、費用が減る(会社全体としてはまだ使用しているチームがある)

社内では、アプリの開発チーム以外でもこの仕組みが導入されはじめています。

もちろんまだ課題は残っています。 現状はPdMがConfuleceとスプレッドシートの2つの資料を管理している状況が気になっています。また、スプレッドシートを用いた仕組みは定義外の状態が入り込みやすいという問題があると思っています。 Confulenceから直接入稿できるようにする、現状のワークフローに沿った入稿画面を作るなどして重複した作業を減らせないかと検討しています。

おわりに

hoshiと社内ツールを用いた、実際のチームでの文言管理手法をご紹介しました。 hoshiを使った文言管理は、今回紹介した以外にもさまざまなチームで応用が可能ですので、触ってみてチームにあわせた運用を検討してみてはいかがでしょうか。(Starやコントリビューションなどもお待ちしております!)


  1. Emoji: Twemoji by Twitter, Inc and other contributors, CC-BY 4.0