Salesforce 2GPをマスターする:アーキテクトのための第二世代パッケージングガイド

背景と適用シナリオ

Salesforce 建築家として、私たちは常にスケーラブルで、保守性が高く、俊敏なアプリケーション開発ライフサイクルを設計するという課題に直面しています。従来の変更セット (Change Sets) や第一世代パッケージング (First-Generation Packaging, 1GP) は、長年にわたり Salesforce のメタデータデプロイメントの主力でしたが、今日の DevOps (デブオプス) 中心の開発環境では、その限界が明らかになってきました。特に、モノリシックな組織構造、手動によるデプロイプロセス、そして複雑な依存関係の管理は、大規模なエンタープライズプロジェクトにおいて大きなボトルネックとなっていました。

このような背景から登場したのが、Second-Generation Packaging (2GP) (第二世代パッケージング) です。2GP は、Salesforce DX ツールセットを基盤とし、ソース駆動開発 (Source-Driven Development) の哲学を完全に採用した最新のアプリケーション配布モデルです。これは単なる技術的なアップグレードではなく、Salesforce 上でのアプリケーションの設計、構築、テスト、デプロイの方法を根本から変革するパラダイムシフトです。

アーキテクトの視点から見た 2GP の主な適用シナリオは以下の通りです:

エンタープライズアプリケーションのモジュール化

巨大で複雑な「幸福なスープ」状態の組織を、機能ドメインごとに分割された、独立して開発・デプロイ可能な複数のパッケージに分解します。例えば、「営業支援」「サービス管理」「請求処理」といった各ビジネス機能を個別のパッケージとして管理することで、チーム間の依存性を減らし、開発サイクルを高速化します。

ISV (独立系ソフトウェアベンダー) の製品開発

AppExchange でアプリケーションを配布する ISV にとって、2GP は必須のテクノロジーです。より柔軟な依存関係管理、パッチバージョンの作成、アップグレードパスの明確化など、商用アプリケーションのライフサイクル管理に必要な機能が強化されています。

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

2GP の操作はすべて Salesforce CLI (SFDX) を通じてコマンドラインで実行可能です。これにより、Jenkins, GitHub Actions, Azure DevOps といった CI/CD (継続的インテグレーション/継続的デプロイメント) ツールとのシームレスな統合が実現し、パッケージのバージョン作成、テスト、プロモーション、デプロイといった一連のプロセスを完全に自動化できます。


原理説明

2GP のアーキテクチャを理解するには、いくつかのコアコンセプトを把握する必要があります。これらは、従来の開発モデルとは異なる、新しい考え方に基づいています。

ソース駆動開発 (Source-Driven Development)

2GP の最も重要な原則は、Version Control System (VCS) (バージョン管理システム)、例えば Git を信頼できる唯一の情報源 (Single Source of Truth) とすることです。Salesforce 組織内のメタデータではなく、VCS 内のコードが「正」となります。開発者はローカルで変更を行い、VCS にコミットし、そのソースコードからパッケージバージョンが作成されます。これにより、変更の追跡、コードレビュー、チーム間のコラボレーションが劇的に改善されます。

Dev Hub とスクラッチ組織 (Scratch Orgs)

Dev Hub (開発ハブ) は、2GP の世界における司令塔です。これは、お持ちの番組織またはビジネス組織で有効化できる機能であり、作成したすべての 2GP パッケージ、名前空間、スクラッチ組織を管理・追跡する中心的な場所となります。一方、Scratch Orgs (スクラッチ組織) は、VCS のソースコードから作成される、一時的で使い捨て可能な Salesforce 環境です。開発者は、機能開発やテストのためにクリーンなスクラッチ組織を数分で作成し、作業完了後には破棄できます。これにより、「私の組織では動いたのに」という問題を防ぎ、環境の一貫性を保ちます。

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

2GP では、「パッケージ」とその「バージョン」が明確に区別されます。

  • パッケージ: メタデータの論理的なコンテナです。sfdx-project.json ファイルで定義され、VCS 内で一つのディレクトリとして管理されます。名前、名前空間、依存関係などの定義情報を持ちます。
  • パッケージバージョン: 特定の時点でのパッケージの不変なスナップショットです。一度作成されると、その内容は変更できません。各バージョンには `0.1.0.LATEST` のような一意のバージョン番号が付与され、これがインストールやデプロイの単位となります。この不変性が、デプロイの一貫性と再現性を保証します。

依存関係の明示的な管理

アーキテクトにとって最も強力な機能の一つが、パッケージ間の依存関係を明示的に定義できることです。`sfdx-project.json` ファイル内で、あるパッケージが他のどのパッケージのどのバージョンに依存しているかを宣言できます。これにより、複雑なアプリケーションを複数の疎結合なパッケージ群として設計することが可能になります。Salesforce はパッケージのインストール時にこの依存関係を解決し、必要なパッケージが正しい順序でインストールされることを保証します。

2GPには主に2つのタイプがあります:

  • Managed 2GP (管理パッケージ): 主に ISV が AppExchange でアプリケーションを配布するために使用します。知的財産 (Apex コードなど) を保護し、アップグレードをスムーズに行うための機能が提供されます。
  • Unlocked Packages (ロック解除済みパッケージ): 主にエンタープライズの内部開発で使用されます。メタデータをバンドルして組織から組織へと移行するための手段であり、インストール後にコンポーネントを変更できる柔軟性があります。


サンプルコード

2GP のライフサイクルは、主に sfdx-project.json ファイルの定義と Salesforce CLI コマンドの実行によって管理されます。

sfdx-project.json の設定例

これはプロジェクトのルートに配置されるマニフェストファイルであり、パッケージの定義、依存関係、名前空間などを指定します。

{
  "packageDirectories": [
    {
      "path": "force-app",
      "default": true,
      "package": "dreamhouse",
      "versionName": "ver 0.1",
      "versionNumber": "0.1.0.NEXT",
      "dependencies": [
        {
          "package": "base-objects@1.2.0"
        }
      ]
    },
    {
      "path": "base-app",
      "package": "base-objects",
      "versionName": "ver 1.2",
      "versionNumber": "1.2.0.NEXT",
      "default": false
    }
  ],
  "namespace": "dreamhouse",
  "sfdcLoginUrl": "https://login.salesforce.com",
  "sourceApiVersion": "58.0",
  "packageAliases": {
    "dreamhouse": "0Ho...省略...",
    "base-objects@1.2.0": "04t...省略..."
  }
}

詳細な解説:

  • packageDirectories: プロジェクト内のどのディレクトリがどのパッケージに対応するかを定義する配列です。
  • path: パッケージのメタデータが含まれるディレクトリのパス。
  • package: パッケージのエイリアス (別名)。CLI コマンドでこの名前を使用します。
  • versionNumber: パッケージバージョンのテンプレート。`NEXT` はバージョン作成時に自動的にインクリメントされるキーワードです。
  • dependencies: このパッケージが依存する他のパッケージを指定します。この例では、`dreamhouse` パッケージが `base-objects` パッケージのバージョン `1.2.0` に依存していることを示しています。
  • namespace: Dev Hub にリンクされた名前空間。管理パッケージを作成する場合に必須です。
  • packageAliases: パッケージ名やバージョン名を、`0Ho` や `04t` から始まる実際のパッケージ ID やバージョン ID にマッピングします。これは CLI によって自動的に管理されます。

CLI コマンドによるパッケージライフサイクル管理

以下は、2GP パッケージを作成し、バージョンを付け、インストールするまでの一連の基本的な CLI コマンドです。

1. パッケージの作成

まず、`sfdx-project.json` で定義した情報に基づいて、Dev Hub にパッケージを登録します。

# 'dreamhouse' という名前の管理パッケージを作成する
# --package-type Managed: パッケージタイプを Managed (管理) に指定
# --target-dev-hub: 操作対象の Dev Hub 組織のエイリアス
sf package create --name dreamhouse --package-type Managed --path force-app --target-dev-hub MyDevHub

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

VCS の現在の状態から、不変のパッケージバージョンを作成します。これは非同期プロセスです。

# 'dreamhouse' パッケージの新しいバージョンを作成する
# --package: 対象となるパッケージのエイリアス
# --installation-key: インストール時に要求されるパスワード (保護のため)
# --wait: コマンドが完了するまで待機する時間 (分)
# --code-coverage: Apex コードのカバレッジを計算し、75%未満の場合はバージョン作成を失敗させる
sf package version create --package dreamhouse --installation-key myPassword123 --wait 20 --code-coverage --target-dev-hub MyDevHub

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

作成されたバージョンは `Beta` 状態です。本番環境にインストールするには `Released` (リリース済み) にプロモート (昇格) する必要があります。

# 作成したパッケージバージョンを Released 状態にプロモートする
# --package: プロモートするバージョンを含むパッケージのエイリアスまたは 04t ID
sf package version promote --package "dreamhouse@0.1.0-1" --target-dev-hub MyDevHub

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

作成したパッケージバージョンを、スクラッチ組織や本番組織などのターゲット組織にインストールします。

# 特定の組織にパッケージバージョンをインストールする
# --target-org: インストール先の組織のエイリアス
# --package: インストールするパッケージバージョンのエイリアスまたは 04t ID
sf package install --target-org MyTestOrg --package "dreamhouse@0.1.0-1" --installation-key myPassword123 --wait 10

注意事項

アーキテクトとして 2GP 戦略を策定する際には、以下の点に注意する必要があります。

権限と Dev Hub 戦略

2GP 操作を実行するユーザーには、Dev Hub 組織で「第二世代パッケージの作成と更新」システム権限が必要です。また、エンタープライズ全体で単一の Dev Hub を使用するのか、ビジネスユニットごとに分離するのか、という Dev Hub 戦略を早期に決定することが重要です。単一 Dev Hub は管理を一元化できますが、大規模な組織では名前空間の競合や管理の複雑化を招く可能性があります。

API 制限

パッケージバージョンの作成はリソースを消費する非同期プロセスであり、24時間あたりの作成数には制限があります。CI/CD パイプラインを設計する際は、この制限を考慮し、無駄なバージョン作成を避けるようなワークフロー(例:特定のブランチへのマージ時のみバージョンを作成する)を検討する必要があります。

エラー処理

バージョン作成時のエラー(メタデータのコンパイルエラー、テストの失敗、コードカバレッジ不足など)は、CLI の出力や Dev Hub の「パッケージ化ジョブ」で確認できます。エラーの原因を特定しやすくするために、CI/CD パイプラインには、ジョブ ID をログに出力し、失敗時に詳細なログを取得する仕組みを組み込むべきです。

パッケージの祖先 (Package Ancestry)

2GP には祖先 (ancestry) という重要な概念があります。パッケージバージョンをアップグレード可能にするには、新しいバージョンが直前のバージョンを「祖先」として指定する必要があります。`sfdx-project.json` で `ancestorVersion` を指定することで、アップグレードパスを定義します。この祖先関係を誤ると、アップグレードインストールが失敗する可能性があるため、バージョニング戦略を慎重に計画することが不可欠です。


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

Second-Generation Packaging (2GP) は、Salesforce プラットフォームにおける現代的なアプリケーション開発とデプロイメントの基盤です。アーキテクトとして 2GP を採用することは、技術的な選択以上の意味を持ちます。それは、チームの開発プロセスをモダナイズし、ガバナンスを強化し、ビジネスの要求に迅速に対応できる、スケーラブルで俊敏なアーキテクチャを構築するための戦略的な決断です。

2GP の導入を成功させるためのベストプラクティスを以下に示します。

  1. モジュール性を重視した設計: アプリケーションを論理的な機能ドメインに分割し、それぞれを独立したパッケージとして設計します。これにより、再利用性が向上し、影響範囲が限定され、チームは並行して作業を進めやすくなります。
  2. 依存関係の最小化と明確化: パッケージ間の依存関係は疎結合になるように設計します。循環参照を避け、`sfdx-project.json` で依存関係を常に明示的に宣言します。
  3. バージョン管理システムの徹底活用: Git を信頼できる唯一の情報源とし、ブランチ戦略 (Git Flow や GitHub Flow など) を定義して、コードの統合とリリースプロセスを標準化します。
  4. CI/CD による完全自動化: パッケージバージョンの作成、テスト、プロモーション、デプロイに至るまでの全プロセスを自動化します。これにより、手動エラーを排除し、一貫性のある高品質なリリースを実現します。
  5. バージョニング戦略の策定: セマンティックバージョニング (例: `MAJOR.MINOR.PATCH`) などの規約を採用し、いつメジャーバージョンを上げるのか、いつパッチをリリースするのかについて明確なルールを定めます。

2GP は、Salesforce 開発の複雑さを管理するための強力なツールセットを提供してくれます。これを戦略的に活用することで、私たちは、変化に強く、保守しやすく、そしてビジネス価値を継続的に提供できるエンタープライズアーキテクチャを構築することができるのです。

コメント