Salesforce 第二世代パッケージング (2GP) 開発者向け徹底ガイド

背景と応用シナリオ

Salesforce のアプリケーション開発と配布の世界において、パッケージングは不可欠なプロセスです。従来、First-Generation Packaging (第一世代パッケージング、以下 1GP) が主流でしたが、これは特定の開発組織 (Dev Org) に紐づき、ソースコードのバージョン管理との連携が難しいという課題を抱えていました。開発チームが大規模化し、CI/CD (継続的インテグレーション/継続的デプロイメント) のプラクティスが一般的になるにつれて、よりモダンで柔軟なアプローチが求められるようになりました。

そこで登場したのが Second-Generation Packaging (第二世代パッケージング、以下 2GP) です。2GP は、Salesforce DX (SFDX) という開発体験を刷新するツールセットの中核をなす機能であり、「ソースドリブン (Source-driven)」な開発モデルを前提としています。これは、組織の状態を正とするのではなく、Git などのバージョン管理システムにあるソースコードを信頼できる唯一の情報源 (Single Source of Truth) とするという考え方です。

Salesforce 開発者として、2GP を活用する主なシナリオは以下の通りです。

ISV (独立系ソフトウェアベンダー) アプリケーション開発

AppExchange でアプリケーションを配布する ISV パートナーにとって、2GP は必須のテクノロジーです。知的財産を保護する管理パッケージ (Managed Package) を、ソースコード中心の開発フローで構築できます。パッチバージョンの作成やアップグレードパスの管理も、より洗練された方法で行えます。

企業内での大規模な内製アプリケーション開発

大規模な企業では、複数の開発チームが並行して機能開発を進めることがよくあります。2GP のロック解除済みパッケージ (Unlocked Package) を利用することで、巨大な一枚岩のメタデータ群を、機能単位やドメイン単位の小さなパッケージに分割できます。これにより、各チームは独立して開発・テスト・リリースを行えるようになり、開発サイクルの高速化と競合リスクの低減が実現します。

CI/CD パイプラインとの統合

2GP は SFDX CLI (コマンドラインインターフェース) を通じて操作が完結するため、Jenkins、GitHub Actions、CircleCI といった CI/CD ツールとの親和性が非常に高いです。コードがリポジトリにマージされると、自動的にパッケージバージョンが作成され、テストが実行され、承認されれば後続の環境 (UAT、本番) へ自動でデプロイするといった、DevOps のベストプラクティスを Salesforce 開発に持ち込むことができます。


原理説明

2GP の仕組みを理解するには、いくつかの重要な概念を把握する必要があります。これらはすべて SFDX の開発モデルに基づいています。

Dev Hub (開発ハブ)

2GP の中心的な管理拠点となる特別な Salesforce 組織です。通常は本番組織やビジネス組織で有効化します。Dev Hub は、作成したパッケージ、パッケージバージョン、そして開発に使用するスクラッチ組織 (Scratch Org) のライフサイクルを一元管理する役割を担います。

Scratch Org (スクラッチ組織)

ソースコードから動的に作成できる、一時的で使い捨て可能な Salesforce 組織です。開発者は、クリーンな環境で新機能の開発やバグ修正、テストを行うことができます。開発が完了すれば、その組織は破棄できます。これにより、「組織の経年劣化」問題を回避し、常に予測可能な環境で開発を進めることができます。

sfdx-project.json

SFDX プロジェクトのルートディレクトリに配置される、最も重要な設定ファイルです。このファイルが、プロジェクトの構造、パッケージの定義、依存関係、名前空間などをすべて定義します。2GP はこのファイルを「設計図」として、パッケージとそのバージョンを作成します。

パッケージとパッケージバージョン

2GP における「パッケージ」とは、メタデータの集合を論理的にグループ化するための名前付きのコンテナです。実際にインストールやデプロイが行われるのは、このパッケージの特定の時点における不変のスナップショットである「パッケージバージョン (Package Version)」です。バージョン番号 (例: 1.2.0.3) によって一意に識別され、一度作成されたパッケージバージョンの内容は変更不可能です。これにより、どの環境にも全く同じコードベースがデプロイされることが保証されます。


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

1. プロジェクト設定: `sfdx-project.json` ファイルを定義し、パッケージ名、パス、依存関係などを設定します。

2. 開発: Dev Hub に接続し、スクラッチ組織を作成します。VS Code などのエディタでコードを書き、変更をスクラッチ組織にプッシュ (`sfdx force:source:push`) して動作確認します。

3. バージョン管理: 開発が完了したら、変更を Git などのバージョン管理システムにコミットします。

4. パッケージバージョン作成: CI/CD パイプラインまたは手動で SFDX CLI コマンドを実行し、パッケージバージョンを作成します。このプロセス中に Apex テストが実行され、コードカバー率がチェックされます。

5. テスト: 作成されたパッケージバージョンを QA 用の Sandbox や別のスクラッチ組織にインストールし、受け入れテストを実施します。

6. プロモートとリリース: テストに合格したパッケージバージョンを「リリース済み (Promoted)」に昇格させます。これにより、本番組織へのインストールが可能になります。

7. インストール: 最終的に、リリース済みのパッケージバージョンを本番組織にインストールします。


示例代码 (サンプルコード)

ここでは、2GP を利用する際の具体的な SFDX CLI コマンドと設定ファイルの例を、Salesforce 公式ドキュメントに基づいて紹介します。

1. sfdx-project.json の設定例

プロジェクトの心臓部である `sfdx-project.json` の設定例です。ここでは、`my-app-core` と `my-app-ui` という2つのパッケージを定義し、`my-app-ui` が `my-app-core` に依存している関係性を示しています。

{
  "packageDirectories": [
    {
      "path": "force-app/core",
      "package": "my-app-core",
      "versionName": "ver 0.1",
      "versionNumber": "0.1.0.NEXT",
      "default": false
    },
    {
      "path": "force-app/ui",
      "package": "my-app-ui",
      "versionName": "ver 0.1",
      "versionNumber": "0.1.0.NEXT",
      "default": true,
      "dependencies": [
        {
          "package": "my-app-core",
          "versionNumber": "0.1.0.LATEST"
        }
      ]
    }
  ],
  "namespace": "myapp",
  "sfdcLoginUrl": "https://login.salesforce.com",
  "sourceApiVersion": "58.0",
  "packageAliases": {
    "my-app-core": "0Ho5G000000xxxxCAQ",
    "my-app-ui": "0Ho5G000000yyyyCAQ"
  }
}

注釈:
- packageDirectories: プロジェクト内のどのディレクトリがどのパッケージに対応するかを定義します。 - path: パッケージのメタデータが格納されているディレクトリパス。 - package: パッケージのエイリアス名。CI/CD スクリプトなどで使用します。 - versionNumber: パッケージバージョンのテンプレート。`NEXT` はビルド番号を自動インクリメントすることを示します。 - dependencies: このパッケージが依存する他のパッケージを定義します。`LATEST` は指定したメジャー・マイナーバージョンの最新パッチバージョンを取得します。 - namespace: 管理パッケージの場合に設定する名前空間プレフィックス。 - packageAliases: パッケージ名と、Dev Hub に登録した際のパッケージ ID (0Ho...) を紐付けます。

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

`sfdx-project.json` で定義したパッケージを、Dev Hub 組織に登録するためのコマンドです。これは各パッケージに対して一度だけ実行します。

# ロック解除済みパッケージとして 'my-app-ui' を作成
sfdx force:package:create --name "my-app-ui" --description "My Application UI Layer" --packagetype Unlocked --path "force-app/ui" --targetdevhubhub "MyDevHub"

注釈:
- --name: パッケージのエイリアス名 (`sfdx-project.json` と一致させる)。 - --packagetype: `Unlocked` (ロック解除済み) または `Managed` (管理) を指定。 - --path: 対象となるディレクトリ。 - --targetdevhubhub: 認証済み Dev Hub 組織のエイリアス。

このコマンドが成功すると、`sfdx-project.json` の `packageAliases` に ID が自動的に追記されます。

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

開発が完了したソースコードから、インストール可能な不変のパッケージバージョンを作成します。

# 'my-app-ui' パッケージの新しいバージョンを作成
sfdx force:package:version:create --package "my-app-ui" --installationkey "P@ssw0rd123" --wait 10 --codecoverage --targetdevhubhub "MyDevHub"

注釈:
- --package: バージョンを作成するパッケージのエイリアス名。 - --installationkey: インストール時に要求されるパスワード。セキュリティが重要なパッケージに設定します。 - --wait: バージョン作成プロセスの完了を待つ時間(分)。CI/CD スクリプトで重要です。 - --codecoverage: パッケージ内の Apex コードに対してテストを実行し、コードカバー率を計算します。管理パッケージでは、本番用リリースの際に 75% 以上のカバー率が必須です。

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

作成・テストされたベータ版のパッケージバージョンを、本番組織にインストール可能な「リリース済み」ステータスに昇格させます。

# 特定のパッケージバージョンをリリース済みに昇格させる
sfdx force:package:version:promote --package "my-app-ui@0.1.0-3" --targetdevhubhub "MyDevHub"

注釈:
- --package: 昇格させたいパッケージバージョン ID (`package_alias@version_number` の形式)。バージョン ID (04t...) を直接指定することも可能です。


注意事項

権限

2GP の操作を行うユーザーは、Dev Hub 組織で「第二世代パッケージの作成と更新」システム権限を持っている必要があります。通常は「システム管理者」プロファイルに含まれていますが、最小権限の原則に従い、専用の権限セットを作成して割り当てるのがベストプラクティスです。

API 制限

パッケージバージョンの作成やプロモーションは、Dev Hub 組織の API コールを消費します。特に、大規模な CI/CD パイプラインで頻繁にパッケージバージョンを作成する場合、Dev Hub 組織の API 制限に達する可能性があります。API 使用量を監視し、必要に応じて制限緩和を申請するなどの対策が必要です。また、スクラッチ組織の作成数にも日次および有効数の上限があるため、無駄なスクラッチ組織を定期的にクリーンアップする運用が求められます。

エラー処理

パッケージバージョンの作成は失敗することがあります。主な原因は以下の通りです。

- Apex テストの失敗: 1つでもテストが失敗すると、バージョン作成は中断されます。 - コードカバー率不足: `--codecoverage` を指定した場合、特に管理パッケージでは、カバー率が 75% を下回ると失敗します。 - メタデータの依存関係エラー: パッケージに含まれるコンポーネントが、パッケージ外の(そして依存関係にも定義されていない)コンポーネントを参照している場合に発生します。 - 存在しないコンポーネントの削除: destructiveChanges.xml で存在しないコンポーネントを削除しようとするとエラーになります。

エラーが発生した場合、CLI の出力や Dev Hub 組織の「パッケージマネージャ」画面で詳細なログを確認し、原因を特定して修正する必要があります。


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

Second-Generation Packaging (2GP) は、現代の Salesforce 開発におけるデファクトスタンダードです。ソースドリブンなアプローチを採用することで、開発プロセス全体の透明性、再現性、自動化レベルを劇的に向上させます。開発者として 2GP を使いこなすことは、高品質なアプリケーションを迅速に提供するための鍵となります。

ベストプラクティス

1. バージョン管理を徹底する: Git を Single Source of Truth とし、すべての変更をフィーチャーブランチで管理し、プルリクエストを通じてメインブランチにマージするフローを確立します。

2. パッケージを小さく、疎結合に保つ: 機能やドメインごとにパッケージを分割し、依存関係を明確に定義します(パッケージ指向設計)。これにより、再利用性が高まり、個別のリリースが容易になります。

3. CI/CD を積極的に導入する: パッケージバージョンの作成、テスト、プロモート、デプロイといった一連のプロセスを自動化します。これにより、手作業によるミスを防ぎ、リリースサイクルを短縮できます。

4. パッケージバージョンの命名規則を定める: `versionName` や `versionNumber` に一貫したルールを設けることで、どのバージョンがどの機能や修正を含んでいるかを容易に追跡できるようにします。

5. ロック解除済みパッケージを活用する: ISV でない限り、まずは柔軟性の高いロック解除済みパッケージから始めることを推奨します。組織内のメタデータを整理し、デプロイメントを高速化するための強力なツールです。

2GP は単なる新しいパッケージング技術ではなく、Salesforce 開発の文化そのものを変革するパラダイムシフトです。この強力なツールをマスターし、より効率的で堅牢な開発ライフサイクルを構築していきましょう。

コメント