Salesforce 第二世代パッケージ (2GP) の徹底解説:開発者のためのモダンなアプリケーション配布ガイド

背景と適用シナリオ

Salesforce 開発者の皆さん、こんにちは!本日は、現代の Salesforce アプリケーション開発と配布に不可欠なSecond-Generation Packaging (2GP) (第二世代パッケージ) について、開発者の視点から深く掘り下げていきたいと思います。

Salesforce のエコシステムでアプリケーションを構築・配布した経験がある方なら、First-Generation Packaging (1GP) (第一世代パッケージ) に馴染みがあるかもしれません。1GP は長年にわたり AppExchange パートナーの標準でしたが、いくつかの大きな課題を抱えていました。例えば、パッケージング組織という特定の組織が「信頼できる唯一の情報源 (Single Source of Truth)」となり、バージョン管理システム (VCS) との連携が難しく、自動化された CI/CD (継続的インテグレーション/継続的デプロイメント) パイプラインの構築が困難でした。

これらの課題を解決するために登場したのが 2GP です。2GP は、Salesforce DX (SFDX) という開発体験を向上させるためのツールセットを基盤としており、開発プロセスそのものを根本から変革します。2GP の最大の特徴は、ソース駆動 (Source-Driven) 開発モデルを採用している点です。つまり、組織ではなく、Git などのバージョン管理システムにあるソースコードが「信頼できる唯一の情報源」となります。

2GP の主な適用シナリオ

2GP は、以下のようなシナリオでその真価を発揮します。

1. ISV (独立系ソフトウェアベンダー) パートナーによる AppExchange アプリケーション開発:
AppExchange でアプリケーションを公開する ISV にとって、2GP はもはや標準です。知的財産を保護するManaged Package (管理パッケージ) を、自動化されたプロセスで、より高い信頼性をもって作成・配布できます。

2. 大企業における内製アプリケーションの管理:
複数の事業部やグローバル拠点を持つ大企業では、共通の機能やコンポーネントを複数の組織に展開する必要があります。2GP のUnlocked Package (ロック解除済みパッケージ) を使用することで、これらの内製アプリケーションをモジュール化し、一貫性のある方法で効率的に配布・管理できます。

3. コンサルティングパートナーによる再利用可能なソリューションの構築:
コンサルティングパートナーは、顧客向けのプロジェクトで開発した汎用的なコンポーネントやフレームワークを 2GP パッケージ化することで、将来のプロジェクトで迅速に再利用できます。これにより、開発効率が大幅に向上します。

4. DevOps プラクティスを導入するすべての開発チーム:
ソース駆動開発、自動テスト、CI/CD パイプラインは、現代のソフトウェア開発におけるベストプラクティスです。2GP は SFDX と密接に連携しているため、これらの DevOps プラクティスを Salesforce 開発にシームレスに導入するための基盤となります。


原理説明

2GP の仕組みを理解するには、いくつかの重要なコンセプトと登場人物を把握する必要があります。

・Dev Hub (Dev Hub 組織):
2GP の管理ハブとなる特別な Salesforce 組織です。通常は本番組織またはビジネス組織を Dev Hub として有効化します。すべてのパッケージ、パッケージバージョン、およびScratch Orgs (スクラッチ組織) はこの Dev Hub に関連付けられます。

・Namespace (名前空間):
管理パッケージを作成するために不可欠な、組織全体で一意のプレフィックスです。すべてのカスタムコンポーネント (オブジェクト、項目、Apex クラスなど) の API 参照名に付与され、他のパッケージやカスタマイズとの名前の競合を防ぎます。名前空間は一度 Dev Hub にリンクすると変更・解除ができないため、慎重な計画が必要です。

・Salesforce CLI (SFDX CLI):
2GP の操作は、すべてコマンドラインインターフェースである Salesforce CLI を通じて行われます。パッケージの作成、バージョニング、プロモーション、インストールなど、ライフサイクル全体をコマンドで管理します。

・sfdx-project.json:
SFDX プロジェクトのルートディレクトリに配置されるマニフェストファイルです。このファイル内で、パッケージの定義、依存関係、バージョン情報などを宣言的に管理します。

・Package Version (パッケージバージョン):
VCS の特定コミット(ブランチやタグ)から作成される、不変(イミュータブル)なパッケージのスナップショットです。一度作成されたバージョンの中身を変更することはできません。バグ修正や機能追加が必要な場合は、新しいバージョンを作成する必要があります。

2GP のライフサイクル

開発者としての一般的な 2GP のワークフローは以下のようになります。

1. Dev Hub の有効化と名前空間のリンク: 最初のステップとして、管理ハブとなる Dev Hub を有効化し、必要であれば名前空間をリンクします。 2. SFDX プロジェクトのセットアップ: VCS (Git) でリポジトリを管理し、`sfdx-project.json` ファイルでパッケージを定義します。 3. パッケージの登録: `sf package create` コマンドを実行し、Dev Hub にパッケージを登録します。これにより、パッケージ ID (0Ho) が生成されます。 4. 開発とテスト: スクラッチ組織を使用して新機能の開発やバグ修正を行い、ソースコードを VCS にコミットします。 5. パッケージバージョンの作成: `sf package version create` コマンドを実行し、VCS の特定コミットから新しいパッケージバージョンを作成します。このプロセスは Salesforce のサーバー上で非同期に実行されます。 6. バージョンのテスト: 作成されたパッケージバージョンをスクラッチ組織や Sandbox にインストールし、徹底的にテストします。 7. バージョンのプロモート: テストが完了し、リリース準備が整ったら、`sf package version promote` コマンドでバージョンを「リリース済み」ステータスに昇格させます。これにより、本番組織へのインストールが可能になります。 8. インストールとアップグレード: 顧客組織や本番組織にパッケージバージョンをインストールまたはアップグレードします。

このサイクル全体がコマンドラインで実行可能であるため、CI/CD ツールとの連携が非常に容易になり、開発プロセスの完全な自動化が実現できます。


示例代码

ここでは、Salesforce CLI を使用した 2GP の基本的な操作に関する公式ドキュメントベースのコード例を紹介します。

1. sfdx-project.json の設定例

まず、プロジェクトの根幹となる `sfdx-project.json` ファイルです。ここでパッケージの定義や依存関係を指定します。

{
  "packageDirectories": [
    {
      "path": "force-app",
      "default": true,
      "package": "MyAwesomePackage",
      "versionName": "ver 0.1",
      "versionNumber": "0.1.0.NEXT",
      "dependencies": [
        {
          "package": "BaseUtilitiesPackage@1.2.0.LATEST"
        }
      ]
    }
  ],
  "namespace": "my_ns",
  "sfdcLoginUrl": "https://login.salesforce.com",
  "sourceApiVersion": "58.0",
  "packageAliases": {
    "MyAwesomePackage": "0Ho5G000000xxxxCAY",
    "BaseUtilitiesPackage@1.2.0.LATEST": "04t5G000000xxxxCAA"
  }
}

詳細な注釈:
- packageDirectories: プロジェクト内のどのディレクトリがどのパッケージに属するかを定義します。
- path: パッケージ化するメタデータが含まれるディレクトリへのパス。
- package: パッケージのエイリアス名。CI/CD スクリプトなどで使用します。
- versionNumber: パッケージバージョンの番号テンプレート。`NEXT` はビルド番号を自動でインクリメントします。
- dependencies: このパッケージが依存する他の 2GP パッケージを定義します。この例では `BaseUtilitiesPackage` のバージョン 1.2.0 に依存しています。
- namespace: 管理パッケージの場合、ここに名前空間を指定します。
- packageAliases: パッケージ名やバージョンをパッケージ ID (0Ho) やパッケージバージョン ID (04t) にマッピングします。

2. パッケージの作成 (Dev Hub への登録)

`sfdx-project.json` で定義したパッケージを Dev Hub に登録するコマンドです。一度だけ実行します。

# MyAwesomePackageという名前の管理パッケージを作成
# --package-type は Managed または Unlocked を指定
# --target-dev-hub は Dev Hub 組織のエイリアス
sf package create --name "MyAwesomePackage" --package-type "Managed" --path "force-app" --target-dev-hub "MyDevHub"

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

開発が一段落し、VCS にコミットした後、不変のパッケージバージョンを作成します。

# MyAwesomePackage の新しいバージョンを作成
# --package は sfdx-project.json で定義したパッケージのエイリアス
# --installation-key はインストール時のパスワード
# --wait はコマンドが完了するまで待機する時間(分)
# --code-coverage は Apex コードカバレッジを計算し、75% 未満の場合は失敗させる (管理パッケージで必須)
# --version-name はバージョンのエイリアス
sf package version create --package "MyAwesomePackage" --installation-key "P@ssw0rd123" --wait 30 --code-coverage --version-name "Version 1.0 Release" --target-dev-hub "MyDevHub"

4. パッケージバージョンのプロモート

テストが完了したベータ版のパッケージバージョンを本番インストール可能な「リリース済み」状態に昇格させます。

# 作成したパッケージバージョンをプロモートする
# --package にはプロモートしたいバージョンID (04t) を指定する
sf package version promote --package "04t5G000001xxxxCAQ" --target-dev-hub "MyDevHub"

注意事項

2GP を扱う上で、開発者が特に注意すべき点がいくつかあります。

権限と設定

・Dev Hub の選択は永続的: 名前空間を一度 Dev Hub にリンクすると、そのリンクを解除したり、別の Dev Hub に変更したりすることはできません。この決定は非常に重要であり、慎重に行う必要があります。

・API 制限: パッケージバージョンの作成は非同期プロセスであり、Dev Hub 組織の API コールを消費します。大規模な CI/CD パイプラインで頻繁にバージョンを作成する場合、API 制限に達する可能性があるため、使用状況を監視する必要があります。

開発とバージョン管理

・コンポーネントの削除: 管理パッケージから一度グローバルに公開した Apex クラスやコンポーネントを削除することは非常に困難、あるいは不可能です。将来のアーキテクチャを考慮し、コンポーネントをパッケージに含めるかどうかは慎重に判断してください。初期段階では Unlocked Package を活用するのも良い戦略です。

・依存関係の管理: パッケージ間の依存関係は、`sfdx-project.json` で明示的に管理します。循環依存(AがBに依存し、BがAに依存する)は作成できないため、アーキテクチャを設計する際には依存関係の階層を明確にする必要があります。

・メタデータカバレッジ: すべてのメタデータタイプが 2GP でサポートされているわけではありません。開発を始める前に、Salesforce が提供する Metadata Coverage Report を確認し、パッケージ化したいコンポーネントがサポート対象であるかを確認することが重要です。

エラーハンドリング

パッケージバージョンの作成は、様々な理由で失敗することがあります。例えば、Apex テストの失敗、コードカバレッジ不足、必須属性の欠落などです。CI/CD パイプラインを構築する際は、バージョン作成コマンドの失敗を検知し、エラーログを解析して開発者にフィードバックする仕組みを組み込むことが不可欠です。


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

Second-Generation Packaging (2GP) は、単なる新しいパッケージング技術ではなく、Salesforce 開発を現代的なソフトウェアエンジニアリングの実践へと引き上げるためのパラダイムシフトです。ソース駆動のアプローチ、自動化、モジュール性により、開発チームはより高品質なアプリケーションを、より迅速かつ確実に提供できるようになります。

最後に、2GP を成功させるためのベストプラクティスをいくつか紹介します。

1. VCS を信頼できる唯一の情報源とする:
すべての変更は Git などの VCS を通じて行い、直接組織で変更を加えることは避けてください。ブランチ戦略 (GitFlow など) を定義し、チーム全員がそれに従うことが重要です。

2. アプリケーションをモジュール化する:
巨大なモノリシック(一枚岩)なパッケージは避け、アプリケーションを機能ごとに小さな独立したパッケージに分割しましょう。例えば、データモデル(オブジェクト、項目)の「基盤パッケージ」、ビジネスロジック(Apex)の「サーピスパッケージ」、UI(LWC)の「UI パッケージ」のように分割することで、再利用性が高まり、メンテナンスが容易になります。

3. CI/CD でライフサイクルを完全に自動化する:
GitHub Actions, GitLab CI, Jenkins などのツールを使用して、パッケージバージョンの作成、テスト、プロモーションのプロセスを自動化します。これにより、手動エラーが減り、開発者はコーディングに集中できます。

4. スクラッチ組織を最大限に活用する:
スクラッチ組織は、クリーンな環境で開発やテストを行うための強力なツールです。機能開発、パッケージバージョンのインストールテスト、回帰テストなど、あらゆる場面で積極的に活用してください。

5. バージョン番号にセマンティックバージョニングを採用する:
`MAJOR.MINOR.PATCH` (メジャー.マイナー.パッチ) のようなセマンティックバージョニング規約を導入し、バージョンの変更が破壊的変更を含むかどうかを明確に伝達できるようにしましょう。

2GP は学習コストが伴いますが、その投資は間違いなく、より堅牢でスケーラブル、そして管理しやすい Salesforce 開発エコシステムという形で報われるでしょう。ぜひ、次のプロジェクトから 2GP の導入を検討してみてください。

コメント