執筆者:Salesforce 開発者
背景と適用シナリオ
Salesforce プラットフォームでのアプリケーション開発と配布の歴史において、パッケージングは常に中心的な役割を果たしてきました。長年にわたり、第一世代パッケージ (First-Generation Packaging, 1GP) が、特に AppExchange パートナー (ISV) にとって、アプリケーションを顧客組織に配布するための標準的なメカニズムでした。しかし、1GP は開発者組織 (Developer Edition org) に紐づいており、バージョン管理やソースコード駆動の開発、自動化といった最新の開発プラクティスとの親和性が低いという課題を抱えていました。
これらの課題に対応するために、Salesforce は Salesforce DX (Developer Experience) の一環として第二世代パッケージ (Second-Generation Packaging, 2GP) を導入しました。2GP は、現代的な開発ワークフローを全面的にサポートするために設計された、まったく新しいパッケージングモデルです。
開発者の視点から見た 2GP の主な適用シナリオは以下の通りです。
ISV (独立系ソフトウェアベンダー) 向けアプリケーション開発
AppExchange で配布される商用アプリケーションの開発に最適です。2GP は、名前空間 (namespace) を利用した知的財産の保護、厳格なバージョン管理、パッチバージョンの作成、CI/CD パイプラインとのシームレスな統合を提供し、チーム開発の効率を劇的に向上させます。
企業内でのモジュール型アプリケーション開発
大規模な企業では、複数の部門やビジネスユニットで共通して利用される機能を開発することがよくあります。2GP のアンロックパッケージ (Unlocked Package) を使用することで、これらの共通機能を独立したモジュールとしてパッケージ化し、社内の複数の Salesforce 組織に簡単に配布・更新できます。これにより、コードの再利用性が高まり、組織間の機能差異を最小限に抑えることができます。
CI/CD (継続的インテグレーション/継続的デプロイメント) の実現
2GP の操作はすべて Salesforce CLI (Command Line Interface) を通じて行われます。これにより、パッケージバージョンの作成、テスト、プロモーション、インストールといった一連のプロセスを完全に自動化できます。GitHub Actions, Jenkins, CircleCI などの CI/CD ツールと組み合わせることで、開発からデプロイまでのライフサイクルを効率化し、手作業によるエラーを削減できます。
本記事では、Salesforce 開発者の視点から 2GP の基本原理、具体的な操作方法、そして開発プロセスにおけるベストプラクティスについて詳しく解説していきます。
原理説明
2GP の仕組みを理解するには、Salesforce DX のエコシステム全体を把握することが重要です。2GP は単独の技術ではなく、バージョン管理システム (VCS)、Salesforce CLI、スクラッチ組織 (Scratch Orgs)、そして Dev Hub 組織が連携して機能します。
Dev Hub (開発ハブ)
Dev Hub (開発ハブ) は、2GP の世界における「最高信頼ソース (Source of Truth)」です。通常、本番組織または Business Org で有効化します。Dev Hub は以下の重要な役割を担います。
- パッケージの所有権: 作成したすべての 2GP パッケージは、特定の Dev Hub に関連付けられます。
- 名前空間の管理: マネージドパッケージ (Managed Package) で使用する名前空間は、Dev Hub にリンクされます。
- スクラッチ組織の作成と管理: 開発やテストに使用する使い捨ての Salesforce 組織であるスクラッチ組織は、Dev Hub を通じて作成・管理されます。
- パッケージバージョンの追跡: 作成されたすべてのパッケージバージョンの記録を一元管理します。
Salesforce DX プロジェクトとソース駆動開発
2GP 開発の出発点は、ローカルマシン上の Salesforce DX プロジェクトです。これは、特定のディレクトリ構造と設定ファイル sfdx-project.json
を持つフォルダです。開発者は、VS Code などのエディタでメタデータを直接編集し、Git などのバージョン管理システムでソースコードを管理します。このソース駆動開発 (Source-Driven Development) モデルこそが、1GP との最大の違いです。
sfdx-project.json
ファイルは、プロジェクトの中心的な設定ファイルであり、パッケージの定義、依存関係、名前空間などをここで宣言します。
パッケージとパッケージバージョン
2GP では、「パッケージ」と「パッケージバージョン」という2つの概念を明確に区別します。
- パッケージ (Package): メタデータコンポーネントの論理的なコンテナです。名前や説明などの基本情報を持ちますが、それ自体にソースコードは含まれません。一度作成すると、その ID (0Ho) は不変です。
- パッケージバージョン (Package Version): 特定の時点でのパッケージのメタデータの不変のスナップショットです。Git のコミットハッシュに似ています。各バージョンには、
major.minor.patch.build
(例: 1.2.0.5) 形式のバージョン番号が付与され、一度作成されると変更することはできません。インストールやアップグレードの単位はこのパッケージバージョンです。
依存関係管理
2GP の強力な機能の一つが、パッケージ間の依存関係 (dependencies) を明示的に定義できることです。例えば、「Package B」が「Package A」のコンポーネントを利用している場合、sfdx-project.json
内で「Package B は Package A のバージョン 1.5.0 以上に依存する」と宣言できます。これにより、インストール時に正しい順序とバージョンが適用されることが保証され、モジュール化されたアーキテクチャの構築が容易になります。
示例代码
ここでは、Salesforce CLI を使用して 2GP のライフサイクルを管理する具体的なコマンド例を、Salesforce 公式ドキュメントに基づいて紹介します。コマンドは、最新の sf
構文を推奨します。
1. sfdx-project.json の設定
まず、プロジェクトのルートにある sfdx-project.json
ファイルでパッケージを定義します。以下は、my-app
というパッケージを定義し、別のパッケージ (base-utils
) に依存する例です。
{ "packageDirectories": [ { "path": "force-app", "default": true, "package": "my-app", "versionName": "ver 0.1", "versionNumber": "0.1.0.NEXT", "dependencies": [ { "package": "base-utils@1.2.0", "versionNumber": "1.2.0.LATEST" } ] } ], "namespace": "myapp_ns", "sfdcLoginUrl": "https://login.salesforce.com", "sourceApiVersion": "58.0", "packageAliases": { "my-app": "0Ho5G000000xxxxCAY", "base-utils@1.2.0": "04t5G000001xxxxCAA" } }
注釈:
package
: パッケージのエイリアス(別名)を定義します。versionNumber
: 次に作成するパッケージバージョンの番号を定義します。NEXT
はビルド番号を自動インクリメントすることを示します。dependencies
: このパッケージが依存する他のパッケージを指定します。ここではbase-utils
パッケージのバージョン 1.2.0 に依存しています。packageAliases
: パッケージ名やバージョンを、実際のパッケージ ID (0Ho) やパッケージバージョン ID (04t) にマッピングします。
2. パッケージの作成
sfdx-project.json
でパッケージを定義したら、Dev Hub にそのパッケージのレコードを作成します。このコマンドは、パッケージごとに一度だけ実行します。
# Dev Hub 組織に 'my-app' という名前のパッケージを作成します。 # パッケージタイプは Managed (管理) です。 # --path で指定されたディレクトリ 'force-app' がこのパッケージに含まれるソースとなります。 sf package create --name "my-app" --package-type Managed --path force-app --target-dev-hub MyDevHub
成功すると、新しいパッケージ ID (0Ho...) が返され、sfdx-project.json
の packageAliases
に自動的に追加されます。
3. パッケージバージョンの作成
開発が完了し、新しいバージョンをリリースする準備ができたら、パッケージバージョンを作成します。これがパッケージングプロセスの中心です。
# 'my-app' パッケージの新しいバージョンを作成します。 # --installation-key: インストール時に必要なパスワードを設定します。 # --wait: コマンドが完了するまで待機する時間(分)を指定します。 # --code-coverage: Apex コードカバレッジを計算し、75% 未満の場合はバージョン作成を失敗させます。 # --version-name: バージョンに人間が読める名前を付けます。 sf package version create --package "my-app" --installation-key "MySuperSecretKey" --wait 20 --code-coverage --version-name "Spring '24 Release" --target-dev-hub MyDevHub
このプロセスには数分から数十分かかることがあります。成功すると、新しいパッケージバージョン ID (04t...) が返されます。
4. パッケージバージョンのプロモーション
作成されたパッケージバージョンは、デフォルトではベータ版です。本番組織にインストールしたり、AppExchange で公開したりするには、バージョンを「プロモート」してリリース済みにする必要があります。
# 直前に作成された 'my-app' パッケージの最新バージョンをプロモートします。 # --package フラグにパッケージバージョンID (04t) を直接指定することも可能です。 sf package version promote --package "my-app@0.1.0-1" --target-dev-hub MyDevHub
重要: プロモートされたバージョンは不変であり、削除することはできません。
5. パッケージのインストール
作成・プロモートしたパッケージバージョンを、テストのためにスクラッチ組織やサンドボックスにインストールします。
# 指定したターゲット組織 (スクラッチ組織やサンドボックス) にパッケージバージョンをインストールします。 # --package: インストールするパッケージバージョン ID またはエイリアスを指定します。 # --installation-key: バージョン作成時に設定したキーを入力します。 # --wait: インストールが完了するまで待機します。 sf package install --package "my-app@0.1.0-1" --target-org MyTestSandbox --installation-key "MySuperSecretKey" --wait 10
注意事項
権限
2GP を操作するには、Dev Hub 組織で適切な権限を持つユーザーが必要です。最低でも「第二世代パッケージの作成と更新」システム権限が必要です。通常は、「Salesforce DX」権限セットをユーザーに割り当てるのが最も簡単です。
API 制限
Salesforce にはガバナ制限が存在し、2GP も例外ではありません。特に注意すべきは、パッケージバージョンの作成制限です。24 時間以内に、1 つのパッケージに対して作成できるパッケージバージョンの数には上限があります(通常は 6 つ)。CI/CD パイプラインを設計する際は、この制限を考慮し、コミットごとにバージョンを作成するような設計は避けるべきです。
エラー処理
パッケージバージョンの作成は、様々な理由で失敗することがあります。
- Apex テストの失敗: すべての Apex テストが成功する必要があります。
- コードカバレッジ不足: マネージドパッケージの場合、
--code-coverage
フラグを付けると、全体のコードカバレッジが 75% 未満の場合に失敗します。 - メタデータの問題: サポートされていないメタデータタイプや、コンポーネント間の依存関係の欠如など。
バージョン作成に失敗した場合は、CLI から返されるログ ID を使用して、Dev Hub 組織の「パッケージ作成ログ」オブジェクトから詳細なエラーを確認できます。
アップグレード可能性とコンポーネントの削除
一度マネージドパッケージのリリース済みバージョンに含めたグローバルな Apex クラスやコンポーネントは、原則として削除できません。これは、そのコンポーネントをインストール済みの顧客組織で利用している可能性があるためです。コンポーネントを廃止したい場合は、@deprecated
アノテーションを使用するなどして非推奨とし、将来のバージョンで削除する計画を立てる必要があります。この制約は、パッケージのアーキテクチャを設計する上で非常に重要です。
まとめとベストプラクティス
第二世代パッケージ (2GP) は、Salesforce 開発者にとって、アプリケーションの構築、管理、配布の方法を根本的に変革する強力なツールです。ソース駆動開発、CI/CD との親和性、そして堅牢な依存関係管理により、1GP が抱えていた多くの課題を解決します。
2GP を最大限に活用するためのベストプラクティスを以下に示します。
- モジュール性を重視する: 巨大なモノリシック(一枚岩)なパッケージを作るのではなく、アプリケーションを機能ごとに論理的な小さなパッケージに分割しましょう。これにより、各モジュールを独立して開発、バージョン管理、リリースできるようになり、開発の俊敏性が向上します。
- CI/CD を積極的に導入する: パッケージバージョンの作成、テスト、プロモーション、デプロイのプロセスを自動化しましょう。これにより、リリースサイクルが短縮され、人為的ミスが減り、開発チームはより価値の高い作業に集中できます。
- スクラッチ組織を徹底的に活用する: 各機能ブランチやプルリクエストに対してスクラッチ組織を作成し、パッケージのインストール、テスト、動作確認を行いましょう。これにより、メインブランチにマージする前に問題を発見できます。
- 明確なバージョン管理戦略を持つ: セマンティックバージョニング (SemVer) などの規約に従い、バージョン番号 (major.minor.patch) を一貫して使用しましょう。これにより、パッケージの利用者に対して変更内容(破壊的変更、新機能、バグ修正)を明確に伝えることができます。
- アンロックパッケージを企業開発に活用する: 2GP は ISV だけのものではありません。企業内の開発チームは、アンロックパッケージを利用して、再利用可能なコンポーネントや基盤機能を複数の組織に効率的に展開できます。
2GP への移行には学習曲線が伴いますが、その投資は、より高速で、信頼性が高く、スケーラブルな開発プロセスという形で大きなリターンをもたらします。今こそ、Salesforce 開発の未来である 2GP を習得し、開発プラクティスを次のレベルへと引き上げる時です。
コメント
コメントを投稿