Salesforce 第二世代パッケージ (2GP) によるスケーラブルなアプリケーション開発の実現

執筆者:Salesforce 開発者


背景と適用シナリオ

Salesforce プラットフォームでのアプリケーション開発において、コードやメタデータの配布、バージョン管理は極めて重要です。従来、この役割は主に First-Generation Packaging (1GP) (第一世代パッケージング) が担ってきましたが、今日の複雑でアジャイルな開発サイクルにおいては、いくつかの課題が浮き彫りになっていました。1GP は、パッケージの作成とバージョンアップが特定のパッケージング組織に強く紐づいており、ソース駆動開発や自動化との親和性が低いという特徴がありました。

こうした背景から、Salesforce は最新の開発手法に対応するため、Second-Generation Packaging (2GP) (第二世代パッケージング) を導入しました。2GP は、Salesforce DX (SFDX) ツールセットを中核に据えた、まったく新しいパッケージングモデルです。バージョン管理システム (VCS) を信頼できる唯一の情報源 (Source of Truth) とする、ソース駆動の開発フローを前提として設計されています。これにより、開発チームはよりモジュール化された、スケーラブルで、CI/CD (継続的インテグレーション/継続的デプロイメント) パイプラインに統合しやすいアプリケーション開発を実現できます。

適用シナリオ

2GP の適用シナリオは多岐にわたります。

  • ISV (独立系ソフトウェアベンダー) パートナー: AppExchange でアプリケーションを配布する ISV にとって、2GP は必須のテクノロジーです。管理パッケージ (Managed Package) を利用することで、知的財産 (IP) を保護しつつ、顧客に対して安定したアップグレードパスを提供できます。複数の依存関係を持つパッケージ群を体系的に管理できるため、複雑なソリューションの提供が容易になります。
  • 大規模な企業内開発: 複数の部門やチームが関わる大規模な Salesforce プロジェクトでは、機能ごとにパッケージを分割 (モジュール化) することで、開発の独立性を高め、デプロイのリスクを低減できます。ロック解除済みパッケージ (Unlocked Package) を使用すれば、組織内のメタデータを整理し、再利用可能なコンポーネントとして配布することが可能です。
  • CI/CD パイプラインの導入: 2GP はすべての操作が Salesforce CLI (SFDX) 経由で実行できるため、Jenkins、GitHub Actions、Azure DevOps といった自動化ツールとの連携が非常にスムーズです。これにより、パッケージバージョンの作成、テスト、プロモート、インストールといった一連のプロセスを完全に自動化できます。

原理説明

2GP の中核は、Dev Hub (開発ハブ) 組織と Salesforce CLI の連携にあります。Dev Hub は、スクラッチ組織の管理やパッケージ開発のライフサイクル全体を統括する中心的な役割を果たします。開発者は、ローカル環境でソースコードを編集し、Git などの VCS で管理します。そして、SFDX を通じて Dev Hub に指示を送り、パッケージの作成やバージョン管理を行います。

2GP の主要なコンセプト

  1. ソース駆動開発 (Source-Driven Development): 開発の正は、常にバージョン管理システム (例: Git) にあるソースコードです。Salesforce 組織内のメタデータは一時的なもの (スクラッチ組織など) と見なされ、開発の成果物はすべてソースコードとして管理されます。
  2. Dev Hub と名前空間 (Namespace): すべての 2GP パッケージは Dev Hub 組織に紐づけられます。管理パッケージを作成する場合、AppExchange で一意となる名前空間 (Namespace) を Dev Hub に登録する必要があります。この名前空間は、パッケージ内のすべてのコンポーネント (Apex クラス、オブジェクト、項目など) のプレフィックスとなり、他のパッケージとの競合を防ぎます。
  3. パッケージの種類:
    • Managed Package (管理パッケージ): 主に ISV が AppExchange でアプリケーションを配布するために使用します。Apex コードなどの知的財産は非表示になり、コンポーネントの削除や変更が制限されるため、アップグレード可能性が保護されます。
    • Unlocked Package (ロック解除済みパッケージ): 主に企業内開発で使用されます。インストール後にコンポーネントを自由に変更できるため、組織のメタデータをモジュール化し、チーム間で共有するのに適しています。
  4. パッケージの依存関係 (Dependencies): 2GP では、パッケージが他のパッケージに依存する関係を sfdx-project.json ファイルで明示的に定義できます。これにより、大規模なアプリケーションを複数の小さなパッケージに分割し、それぞれを独立して開発・バージョン管理することが可能になります。例えば、「基盤パッケージ」の上に「営業支援機能パッケージ」と「サービス支援機能パッケージ」を構築する、といった階層構造を実現できます。
  5. バージョン管理とライフサイクル: パッケージバージョンは不変 (Immutable) です。一度作成されたバージョン (例: 1.2.0.3) の内容は変更できません。バージョンは「ベータ版」として作成され、十分なテストを経て「リリース版」に昇格 (Promote) されます。この厳格なバージョン管理により、どの環境にどのバージョンのパッケージがインストールされているかを正確に追跡できます。

示例代码

ここでは、Salesforce CLI (SFDX) を使用して、基本的なロック解除済みパッケージを作成し、バージョンを生成、インストールするまでの一連のフローを解説します。この操作はすべて、Dev Hub に接続されたターミナルまたはコマンドプロンプトから実行します。

1. パッケージの作成

まず、sfdx-project.json ファイルが配置されているプロジェクトのルートディレクトリで、パッケージを作成します。このコマンドは Dev Hub にパッケージの存在を登録するだけで、まだ中身 (バージョン) はありません。

# "my-app" という名前のロック解除済みパッケージを作成
# パッケージタイプは Unlocked
# パスは "force-app" (プロジェクト内のソースコードが格納されているディレクトリ)
# Dev Hub 組織のエイリアスは "MyDevHub"
sfdx force:package:create --name "my-app" --packagetype Unlocked --path "force-app" --targetdevhub "MyDevHub"

成功すると、sfdx-project.json ファイルにパッケージの情報 (エイリアスとパッケージID) が追記されます。

2. パッケージバージョンの作成

次に、現在のソースコードのスナップショットとして、パッケージのバージョンを作成します。バージョン番号は自動的にインクリメントされます。

# "my-app" パッケージの新しいバージョンを作成
# インストールキー (パスワード) を設定
# Dev Hub 組織のエイリアスは "MyDevHub"
# --wait 10 で最大10分間、バージョン作成が完了するのを待機
sfdx force:package:version:create --package "my-app" --installationkey "YourInstallKey" --targetdevhub "MyDevHub" --wait 10

このプロセスには数分かかることがあります。Salesforce がバックグラウンドでメタデータの検証やコンパイルを行うためです。完了すると、04t から始まるパッケージバージョン ID が表示されます。

3. パッケージバージョンの昇格 (リリース)

作成されたバージョンは、デフォルトでベータ版です。本番環境にインストールするには、リリース版に「昇格」させる必要があります。

# 先ほど作成したパッケージバージョンをリリース版に昇格
# --package には "04t" から始まるパッケージバージョンIDを指定
# Dev Hub 組織のエイリアスは "MyDevHub"
sfdx force:package:version:promote --package "my-app@1.0.0-1" --targetdevhub "MyDevHub"

注: my-app@1.0.0-1 の部分は、バージョン作成時に生成されたエイリアスまたは 04t... ID に置き換えてください。

4. パッケージのインストール

最後に、昇格させたパッケージバージョンをターゲットの組織 (スクラッチ組織や Sandbox) にインストールします。

# ターゲット組織 (エイリアス: MyTestOrg) にパッケージをインストール
# --package には昇格済みのパッケージバージョンIDを指定
# --wait 10 で最大10分間、インストールが完了するのを待機
# --securitytype AdminUsers で、システム管理者プロファイルにのみアクセス権を付与
sfdx force:package:install --package "my-app@1.0.0-1" --targetusername "MyTestOrg" --wait 10 --securitytype AdminUsers --publishwait 10

これらのコマンドをスクリプト化し、CI/CD パイプラインに組み込むことで、開発からデプロイまでの一連のプロセスを自動化することが 2GP の真価を発揮する鍵となります。


注意事項

2GP を利用する際には、いくつかの重要な点に注意する必要があります。

  • 権限: Dev Hub 組織で 2GP の操作を行うユーザーには、「第二世代パッケージの作成と更新」システム権限が必要です。また、CI/CD 用のインテグレーションユーザーには、適切な権限を持つプロファイルや権限セットを割り当てる必要があります。
  • API 制限: パッケージバージョンの作成やプロモートは、Dev Hub 組織の API コールを消費します。大規模な自動化パイプラインを構築する際は、組織の API 制限に注意し、必要に応じて制限緩和を検討してください。
  • パッケージの祖先 (Package Ancestry): 2GP では、バージョニングにおいて「祖先」の概念が重要です。あるバージョンから次のバージョンへアップグレードする際、その2つのバージョンは共通の祖先を持つ必要があります。例えば、バージョン 1.1 から 1.2 へのアップグレードは可能ですが、完全に異なるブランチから作成されたバージョンへの直接アップグレードはできません。sfdx-project.jsonancestorId または ancestorVersion を指定することで、この関係を管理します。
  • エラー処理: パッケージバージョンの作成時に Apex テストの失敗、メタデータの検証エラーなどが発生することがあります。CI/CD パイプラインでは、これらのエラーを適切に検知し、開発者にフィードバックする仕組みを構築することが重要です。バージョン作成リクエストのログを確認することで、詳細なエラー原因を特定できます。
  • メタデータカバレッジ: すべてのメタデータタイプが 2GP でサポートされているわけではありません。開発を始める前に、Salesforce の公式ドキュメントにある「Metadata Coverage Report」を確認し、パッケージ化したいコンポーネントがサポートされているかを確認することが不可欠です。サポートされていないメタデータは、手動または別のデプロイツールでの対応が必要になります。
  • 削除済みコンポーネントの伝播: 1GP とは異なり、2GP ではパッケージの新しいバージョンからコンポーネントを削除しても、インストール先の組織から自動的にそのコンポーネントが削除されることはありません。不要になったコンポーネントの削除は、別途アンインストールスクリプト (Destructive Changes) を用意するなど、手動での対応が必要です。

まとめとベストプラクティス

Second-Generation Packaging (2GP) は、単なるパッケージング技術の進化ではなく、Salesforce 開発のパラダイムシフトを促すものです。ソース駆動開発、モジュール化、そして自動化を前提としたこのモデルは、現代の開発チームが求める俊敏性と品質を両立させるための強力な基盤となります。

ベストプラクティス

  1. アプリケーションを小さく分割する (モジュール化): 巨大なモノリシックパッケージを一つ作るのではなく、機能ドメインごとにパッケージを分割しましょう。例えば、「基盤ライブラリ」「営業機能」「サービス機能」のように分割することで、各チームは独立して開発を進められ、影響範囲を限定したデプロイが可能になります。
  2. CI/CD パイプラインを積極的に活用する: 2GP の真価は自動化によって発揮されます。Git へのプッシュをトリガーに、パッケージバージョンの作成、スクラッチ組織でのテスト実行、ベータ版の QA 環境へのインストール、そして本番リリース候補の昇格といったプロセスを自動化することで、ヒューマンエラーを減らし、リリースサイクルを大幅に短縮できます。
  3. 依存関係を明確に定義する: sfdx-project.json を用いて、パッケージ間の依存関係を明確に管理します。これにより、インストール順序が保証され、予期せぬエラーを防ぐことができます。
  4. バージョン番号付け戦略を確立する: セマンティックバージョニング (例: MAJOR.MINOR.PATCH.BUILD) のような一貫したバージョン番号付けルールをチームで定め、どの変更が破壊的変更を含むのか、新機能追加なのか、バグ修正なのかを明確に伝えます。
  5. ベータ版を有効活用する: すべてのバージョンをいきなりリリース版にするのではなく、まずベータ版として作成し、CI パイプラインでの自動テストや QA チームによる手動テストを十分に行います。品質が担保されたバージョンのみをリリース版として昇格させることで、本番環境の安定性を高めます。

2GP への移行は学習コストを伴いますが、それに見合うだけの大きなメリットをもたらします。スケーラブルで保守性の高いアプリケーションを効率的に開発するために、ぜひ 2GP の活用を検討してください。

コメント