スクラッチ組織のメタデータ管理、あの時なぜ誤解したのか?開発者の苦い経験

C. 後から「やらなければよかった」と思った設計

当時の我々は、Salesforce DX とスクラッチ組織を導入したばかりだった。開発者の誰もが「自分のローカル環境で自由に開発し、その成果を簡単に共有できる」という触れ込みに興奮していた。特に、各開発者が独立したスクラッチ組織を持ち、そこで作成したメタデータをsfdx force:source:pullでローカルに取得し、Gitにプッシュするというフローは、従来のSandbox運用に比べて圧倒的に効率的だと信じていた。

この初期の判断、つまり**「スクラッチ組織で作成したメタデータはすべて、そのままGitリポジトリにプルしてコミットするべき」という暗黙の了解**が、後になってプロジェクトの足を引っ張ることになった。

開発者の「実験場」としてのスクラッチ組織が招いた混乱

スクラッチ組織は素晴らしい。新しいアイデアを試したり、検証したり、時にはドキュメントにもない挙動を確かめたりするのに最適だ。しかし、この「実験場」としての自由さが、共有リポジトリの管理においては諸刃の剣となった。

当時は、「もし動くものなら、それは価値がある」という考えが根底にあったように思う。だから、ある開発者がスクラッチ組織で新しいカスタムオブジェクトや項目、Apexクラスを試作したとする。それがたとえ、まだ要件定義が固まっていない、あるいはPoCレベルのコードであっても、多くの場合sfdx force:source:pullでローカルに取得され、そのままGitにコミットされてしまうことがあった。

何が問題だったかと言うと、

  • 不要なメタデータがリポジトリに混入: プロジェクトのスコープ外の「お試し」オブジェクトや項目がforce-app/main/default以下に蓄積された。これがCI/CDパイプラインを回すたびにデプロイされ、無駄なデプロイ時間と潜在的な競合を生み出した。
  • 定義の重複・競合: 複数の開発者が似たような機能やコンポーネントを独立して試作し、それぞれが異なる定義でコミットしようとすることが発生した。例えば、一時的なテスト用オブジェクトに似た名前をつけてしまい、マージ時に衝突したことが何度もあった。
  • リポジトリの肥大化と可読性の低下: 本来のプロジェクトに必要なメタデータと、実験的なメタデータが混在することで、コードベース全体の可読性が低下した。新しい開発者が参画した際、どれが本番デプロイ対象で、どれが一時的なものなのか判断に迷う事態になった。

特にひどかったのは、一時的なテスト用ApexクラスやLWCコンポーネントが、そのままリポジトリに残ってしまったケースだ。これらは本来、開発者のローカル環境で完結するか、テスト専用のブランチで管理されるべきだった。しかし、当時は「スクラッチ組織からプルしたものはすべて本流」という認識が強く、無邪気にコミットされていった。

project-scratch-def.json の取り扱いに関する後悔

もう一つの大きな後悔は、project-scratch-def.json の管理方法だ。これはスクラッチ組織を生成する際の「設計図」のようなものだが、ここもまた開発者の「実験場」の被害を受けた。

各開発者が自分のスクラッチ組織で特定の機能を有効にするために、featuressettingsブロックを勝手に修正し、そのままコミットしてしまうことがあった。例えば、メール設定やChatterの有効化など、特定のテストケースで一時的に必要な設定をこのファイルに追加してしまったのだ。

結果として、

  • スクラッチ組織の生成時間が伸びる: 不要な機能が有効にされることで、スクラッチ組織の生成に時間がかかるようになった。
  • 設定の不整合: 誰かが有効にした設定を別の人が不要だと思って削除したり、その逆があったりして、スクラッチ組織の挙動に一貫性がなくなった。
  • デバッグの複雑化: 本来無効であるべき機能が有効になっていることで、予期せぬエラーや挙動が発生し、デバッグが困難になることがあった。

当時は「必要な機能はここで定義すれば自動的に有効になるから便利だ」と考えていた。しかし、このファイルはプロジェクト全体の共通認識に基づいて、最小限かつ必要不可欠な設定のみを記述すべきだった。

今ならどうするのか

もしあの頃に戻れるなら、私は以下のようなルールとプラクティスを開発チームに提案するだろう。

  1. force-app ディレクトリへのコミットは厳格なレビューと目的意識を持つ:
    • 開発者は、スクラッチ組織で試作したものが本当にプロジェクトのコア機能の一部であり、永続的に必要なものなのかを自問自答する。
    • 「実験的な」メタデータは、個人の作業ブランチ内でのみ管理するか、ローカルの.sfdxディレクトリ内に留め、.gitignoreで明示的に除外する。
    • または、force-appの外に一時的な作業ディレクトリ(例: temp-dev)を作り、そこからスクラッチ組織にプッシュする仕組みを導入する。
    • sfdx force:source:pull は、必要な変更のみを慎重にプルする。全体を無思考にプルするのではなく、差分を確認し、本当に必要なものだけを選択的に取り込む意識付けを行う。
  2. project-scratch-def.json はコアチームが管理し、最小限に保つ:
    • このファイルは、プロジェクト全体で合意された「基本構成」のみを定義する。
    • 特定の開発者やテストで一時的に必要な機能は、個人のスクラッチ組織作成後に手動で有効にするか、または設定変更スクリプト(sfdx force:apex:executeなど)で対応する。
    • featuressettingsの追加は、チーム全体の合意と影響範囲の評価を必須とする。
  3. データの準備はスクリプト化を初期段階から推奨:
    • 開発初期からsfdx force:data:tree:importやApexスクリプト、またはテストクラス内のTest.loadData()を利用したデータ準備を標準プラクティスとする。
    • 手動でのデータ投入は、探索的な開発段階でのみ許容し、共有リポジトリに依存する開発では避ける。

結局のところ、スクラッチ組織が提供する「自由」は、開発者個人の生産性を高める一方で、チーム開発全体のリポジトリ品質管理には新たな課題をもたらす。このバランスをどう取るか、当時の私は甘く見ていた。


これは当時の自分向けのメモだ。あの時、もっと慎重に、そしてチーム全体での合意形成に時間をかけていれば、無駄な手戻りはもっと少なかったはずだ。

コメント