【第二世代管理パッケージ(2GP)】開発のはじめかた

AppExchange 開発者のみなさま、こんにちは。

第二世代管理パッケージ(以下、2GP)が Winter ’20 に GA となってからそろそろ 2 年が経とうとしていますが、「頭の片隅にはあるけど第一世代からの移行もできないし二の足を踏んでいる」という方が多いのではないでしょうか?

これまで弊社でもリリースノートを見るたびに「これはまだ早いな」と判断をしてきましたが、新規に AppExchange アプリを開発することになり、「今からパッケージ開発環境を整備するなら 2GP だろう」ということで、2GP でのアップグレードにおいて気をつける点や転送アップグレードの方法など、パッケージを運用していくにあたり必要となる機能について検証してみました。

これから数回に分けて、2GP について弊社内で調査した知見をまとめていきます。

今回は「まずはじめに」ということで、2GP の概要と基本的な使い方について解説します。この記事で説明されていることは、ほぼ Salesforce DX 開発者ガイド第二世代管理パッケージに書かれていることですが、開発者ガイドを読み進めていくために「まずは概要を知りたい」という方に適した内容となっています。

本連載の記事が、これから AppExchange パッケージを新しく作成しようとしている開発者や、第一世代管理パッケージ(以下、1GP)から 2GP への移行を考えている開発者(Winter ’22 ではまだ開発プレビュー)の一助となれれば幸いです。

参考: パッケージ化: 第二世代管理パッケージの正式リリース

第二世代管理パッケージ(2GP)とは

2GP とは、SFDX をベースとした新しい管理パッケージとそれを作成するための開発環境のことです。

ポイント&クリック時代の 1GP では “パッケージ開発組織にデプロイされた Apex クラスやオブジェクト定義などをパッケージのコンポーネントとして選択しパッケージにする” という流れでしたが、2GP では Git などバージョン管理システムで管理されたソースコードから SFDX コマンドで直にパッケージを作成するという流れに大きく変わります。

これにより CI でパッケージを作成することが可能になり AppExchange のパッケージでもモダンな開発に近づけるというのがうたい文句です。

もちろん 1GP でも CI からパッケージを作成することはできたのですが、さらに手作業を排除できるので、より堅牢なパッケージ開発環境の構築が可能になることが期待できると思われます。

とはいえ、パッケージ開発組織がなくなったことで、開発中のバージョンを確認するにもコマンドを実行する必要があったり、転送アップグレードを利用するには独自にスクリプトを組まなければならなかったりなど、1GP に比べて導入のハードルが高いことは否めません。

しかし、コンポーネントの削除や 1GP からの移行などもできるようになり、次の次の Spring ’22 あたりでは、そろそろ本格的に 2GP を利用が開始できる状況になるのではと見込まれます。

参考:

第一世代管理パッケージ(1GP)との違い

1GPとの違いは、Salesforce DX 開発者ガイド「2GP と 1GP の管理パッケージの比較」に説明されていますが、われわれの目線で噛み砕いてみます。

バージョン管理システムが信頼できる情報源(ソース駆動型システム)になる

パッケージ開発組織で新規コンポーネントの追加などをする必要がなくなり、「デプロイはしたけど一部コンポーネントの追加を忘れていた」と言ったような手作業によるミスを防げます。

また、1GP では「パッケージ開発組織には余計なものを一切入れない」というのがベストプラクティスですが、どうしてもパッケージに入れないメタデータが入り込む余地があり、それを誤ってパッケージに含められてしまうという懸念もあります。

2GP ではソースから直にパッケージを作成されるため手作業によるミスが入るこむ余地を取り除けます。

また、パッケージに含めるメタデータと、パッケージに関連するメタデータを明確に分けることができるので、これまでパッケージ アップロード時には含められなかったテストなどもパッケージ作成時に実行することもできるようになりました。

Dev Hub がパッケージを所有

1GP では、パッケージがパッケージ開発組織に所属し、公開コンソールにパッケージ開発組織を接続することでリストと連携するという仕組みでした。

2GP では、Dev Hub が直にパッケージを管理するイメージになります。2GP では、Dev Hub にパッケージを作成してリリース版に昇格(Promote)すると自動で公開コンソールにパッケージが表示されます。

また、AppExchange アプリの場合は Dev Hub は PBO を利用することになります。SFDX では、パッケージの開発者は Dev Hub 組織へのログインが必要となるため、PBO のアカウントを発行する必要があります。開発のみで Sales Cloud の機能は利用しないユーザには、Free Limited Access ライセンスを利用することもできます。

名前空間を取得するためには組織が必要、それを名前空間組織と呼ぶ

パッケージで使用するグローバルな名前空間を取得するためには、1GP と同様に、「開発組織を用意して管理パッケージを作成し名前空間を取得する」必要があります。2GP ではこの組織で開発をしないので “名前空間組織” と呼ぶようです。

複数のパッケージで同じ名前空間を使用できる

できるのですが、いまいち、使い勝手的に出番がなさそうな機能です。

詳細は、パッケージの依存関係の記事で紹介します。

Salesforce CLI を使用して、すべてのパッケージ操作を自動化できる

Salesforce CLI を使用してすべてのパッケージ操作を自動化できますが、インストール/アンインストールに関しては「登録者組織に対するインストール/アンインストールができる」というわけではなく、あくまで自分が所有する組織に対してのみとなります。

登録者組織へのパッケージのアップグレードは、1GP と同様に転送アップグレードをすることになります。

パッケージバージョン管理ではブランチがサポートされる

AppExchange のパッケージでは、残念ながらほぼ利用する機会が無さそうな機能です。

しかし、このために自動化スクリプトを作成する負荷を追わなくてはならず、今のところ若干残念な機能となってしまっています。この詳細については、次回の記事で解説します。

パッチバージョンは、Salesforce CLI を使用して作成される

パッチバージョンを作成するために、パッチ組織を作成する必要がなくなります。

これまで、弊社では面倒でパッチ組織を利用していませんでしたが、2GP では利用する機会があるかもしれません。

ベータバージョンをリリースバージョンに昇格(Promote)

1GP では、パッケージアップロード時に、ベータバージョンかリリースバージョンかを選択して実行していましたが、2GP でパッケージバージョンを作成するとすべてベータバージョンとして作成されます。リリースバージョンを作成する場合は、「作成されているベータバージョンの 1 つを選択して、リリースバージョンへと昇格(Promote)する」という流れに変わります。

2GP 開発に必要な Salesforce 組織の準備

ここからは 2GP の雰囲気をつかめるように、簡単なパッケージのサンプルプロジェクトを例に、実際に 2GP でパッケージを作成してリリースバージョンに昇格する流れまでを体験していただきたいと思います。

まずは、2GP の開発に必要な組織の準備をしていきましょう。

説明に登場する PBO や Dev Hub 組織など、各組織について役割については「[2020年版8月版]おすすめのAppExchangeアプリ開発方法〜概要編〜」でも解説していますのでこちらも併せてご参照ください。

前提条件の確認

2GP のパッケージを作成するために、以下の Salesforce 組織が必要となります。

  • Dev Hub 組織
  • 名前空間組織

開発者の PC には、以下のソフトウェアのインストールが必要です。

  • Salesforce CLI
  • VSCode(オプション)

参考: 第二世代管理パッケージを作成する前に

Dev Hub 組織として利用する組織について

AppExchange に載せるパッケージの開発では、PBO を Dev Hub 組織として利用します。PBO の Dev Hub が有効化されていない場合は、Dev Hub を有効化します。

※ 注意: Dev Hub を有効化する前に “私のドメイン” を必ずリリースしておいてください。“私のドメイン” をリリースせずに Dev Hub を有効化してしまった場合は、名前空間レジストリの接続アプリケーション設定の変更が必要となります。

名前空間組織の用意

“名前空間組織” とは、1GP のパッケージ開発組織にあたります。

2GP では、名前空間を取得するためだけに用い、パッケージ自体の開発には使用しない組織であるため、“名前空間組織” と名称が変更されたようです。

2GP でも 1GP と同様に環境ハブからパートナー開発組織を作成して(開発しないので通常の開発組織でも可)、パッケージを作成して使用する名前空間を登録します。

Dev Hub 組織(PBO)に名前空間組織を紐付ける

SFDX で名前空間を使用するためには、使用する Dev Hub 組織に名前空間組織を登録する必要があります。

アプリケーションランチャーで名前空間レジストリ開き、新規ボタンから名前空間組織を紐付けます

  1. Dev Hub 組織にログイン
  2. 名前空間レジストリを開く
  3. 名前空間リンクボタンをクリックするとログインが開くので、名前空間組織のユーザ名・パスワードを入力し、承認するとリンクされる

参照: 名前空間と Dev Hub 組織のリンク

2GP パッケージの作成手順

ここからは、SFDX コマンドを使って、実際にプロジェクトを作成してパッケージをリリースするまでの手順を確認していきます。

プロジェクトの作成

force:project:create コマンドを実行して SFDX プロジェクトを作成します。

sfdx force:project:create --projectname <プロジェクト名> --defaultpackagedir sfdx-src --namespace <名前空間>

–namespace オプションを付与していること以外は、通常の SFDX プロジェクトの作成と同じです。

以下は実際に実行したコマンド例です。プロジェクト名を「2gp-app」、名前空間「hrendoh2gp」を指定しています。以降の説明のコマンド例では、これらのプロジェクト名と名前空間を使用します。

$ sfdx force:project:create --projectname 2gp-app --defaultpackagedir sfdx-src --namespace hrendoh2gp

プロジェクトが作成されたらプロジェクトのディレクトリに移動しておきます。

作成されたプロジェクトの sfdx-project.json を開くと以下のように名前空間がセットされていますが、他は通常のSFDX プロジェクトと特に変わりはありません。

{
"packageDirectories": [
{
"path": "sfdx-src",
"default": true
}
],
"name": "2gp-app",
"namespace": "hrendoh2gp",
"sfdcLoginUrl": "https://login.salesforce.com",
"sourceApiVersion": "52.0"
}

Dev Hub 組織へログインする

以下のコマンドを実行して Dev Hub(PBO)にログインします。

sfdx auth:web:login -d -a <Dev Hubのエイリアス>

※ PBO には開発者用のユーザを作成する必要があります。Free Limited Access License の利用が便利です。

パッケージに含めるメタデータの準備

パッケージディレクトリ内が空でもパッケージの作成は可能ですが、パッケージバージョンの作成はできないため(「No matching source was found within the package root directory」が発生)、適当に Apex クラスとそのテストクラスを追加しておきます。

以下、コピペ用のコードになります。

// sfdx-src/main/default/classes/HelloWorld.cls
public with sharing class HelloWorld {
  public String greet(String name) { return 'Hello, ' + name; }
}

このテスト Apex クラス

@isTest
private class HelloWorldTest {
    @isTest
    static void testHelloWorld() {
        HelloWorld helloWorld = new HelloWorld();
        System.assertEquals('Hello, 2GP', helloWorld.greet('2GP'));
    }
}

パッケージの作成

パッケージの作成は force:package:create コマンドを実行します。指定しているオプションは以下のとおりです

  • –name (-n): パッケージ名を指定します。名前空間内で一意であれば OK です。
  • –packagetype (-t):、パッケージの種別、管理パッケージは「Managed」を指定します。
  • –path (-r): SFDXプロジェクトの packageDirectories から一つソースのパスを指定します。つまり 2GP のパッケージは sfdx プロジェクト内のディレクトリを複数指定することはできません。

パッケージの作成に成功するとパッケージ Id を確認できます。

$ sfdx force:package:create --name "Hello 2GP" --path sfdx-src --packagetype Managed
Successfully created a package. 0HoXXXXXXXXXXXXXXX
=== Ids
NAME VALUE
────────── ──────────────────
Package Id 0HoXXXXXXXXXXXXXXX

コマンド実行後 sfdx-project.json を確認するとにパッケージ情報が追加されていることが確認できます。

{
  "packageDirectories": [
    {
      "path": "sfdx-src",
      "default": true,
      "package": "Hello 2GP",
      "versionName": "ver 0.1",
      "versionNumber": "0.1.0.NEXT"
    }
  ],
  "name": "2gp-app",
  "namespace": "hrendoh2gp",
  "sfdcLoginUrl": "https://login.salesforce.com",
  "sourceApiVersion": "52.0",
  "packageAliases": {
    "Hello 2GP": "0HoXXXXXXXXXXXXXXX"
  }
}

参考:

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

パッケージバージョンは 1GP のバージョンと同じメジャー、マイナー、パッチバージョンの 3 桁に加えてビルドバージョンの 4 桁で管理します。

また、1GP のバージョン番号は、マイナーバージョンは前のバージョンから自動でインクリメントされましたが、2GP は明示的に指定する必要があります。

パッケージバージョンの作成は force:package:version:create コマンドを実行します。

指定しているオプションは以下のとおりです

  • –package (-p): パッケージ名を指定します。パッケージ Id を指定することもできます。
  • –versionname (-a): バージョン名を指定します。1GP のバージョン名にあたります。
  • –versionnumber (-n): バージョン番号を指定します。
  • –codecoverage (-c): コードカバレッジをパッケージに含めます。リリースパッケージに昇格するバージョンには必須です。
  • –installationkeybypass (-x): インストールキー、おそらくインストールにパスワードを要求しないケースはこちらを指定します。
$ sfdx force:package:version:create --package "Hello 2GP" --versionname "ver 0.1" --versionnumber "0.1.0.NEXT" --codecoverage --installationkeybypass --wait 10
Successfully created the package version [08cXXXXXXXXXXXXXXX]. Subscriber Package Version Id: 04tXXXXXXXXXXXXXXX
Package Installation URL: https://login.salesforce.com/packaging/installPackage.apexp?p0=04tXXXXXXXXXXXXXXX
As an alternative, you can use the "sfdx force:package:install" command.

パッケージバージョンの作成に成功するとその Id を確認できますこの時点でのパッケージバージョンは 1GP で言うところのベータバージョンのパッケージにあたります。

バージョン番号は、sfdx-project.json の packageDirectories の管理パッケージに指定したパスの versionNumber で指定することもできますが、CI による自動化など運用を考えるとコマンドオプションで指定する方が一般的になるかと思います。

また、–codecoverage オプションはリリースパッケージに昇格するためには必須です。カバー率を含めないとリリースバージョンに昇格する際にテストカバー率が 75 %以下である旨を示す以下のエラーが返されます。

ERROR running force:package:version:promote:  このバージョンではコードカバー率は実行されていません。コードカバー率は、バージョンの作成中に実行され、バージョンを昇格するための最小カバー率要件を満たしている必要があります。

作成したバージョンは force:package:version:list コマンドで確認できます。

$ sfdx force:package:version:list --packages "Hello 2GP"
=== Package Versions [1]
Package Name Namespace Version Name Version Subscriber Package Version Id Alias Installation Key Released Validation Skipped Ancestor Ancestor Version Branch
──────────── ────────── ──────────── ─────── ───────────────────────────── ───────────────── ──────────────── ──────── ────────────────── ──────── ──────────────── ──────
Hello 2GP hrendoh2gp ver 0.1 0.1.0.1 04tXXXXXXXXXXXXXXX Hello 2GP@0.1.0-1 false false false

force:package:version:list コマンドは、デフォルトのまたはオプションで指定した Dev Hub 組織に所属するすべてのパッケージのバージョンを返します。Dev Hub 組織に複数のパッケージが含まれている場合は –packages オプションを指定して絞り込むことができます。

2 つ目のバージョンを作成する際は、sfdx-project.json ファイルに ancestorId または ancestorVersion を指定する必要がありますが、このあたりは次回の記事で詳しく説明します。

参考:

リリース バージョンの作成

force:package:version:create で作成されたバージョンはベータバージョンにあたるため本番組織へのインストール、アップグレードができないバージョンとなります。

2GP でリリースバージョンを作成するには、作成されたビルドバージョンから 1 つをリリースバージョンとして昇格(Promote)させる手順を取ります。

リリースバージョンを作成するには、Dev Hub にログインするユーザーにシステム管理者権限「パッケージバージョンをリリース済みに昇格」が付与されている必要があります。

パッケージのリリースは、force:package:version:promote を使用します。–-packageオプションに昇格させるベータバージョンのエイリアス(packageAliases)またはバージョン Id を指定します。

$ sfdx force:package:version:promote --package "Hello 2GP@0.1.0-1"
Are you sure you want to release package version Hello 2GP@0.1.0-1? You can't undo this action. Release package (y/n)?: y
Successfully promoted the package version, ID: 04tXXXXXXXXXXXXXXX, to released. Starting in Winter ‘21, only unlocked package versions that have met the minimum 75% code coverage requirement can be promoted. Code coverage minimums aren’t enforced on org-dependent unlocked packages.

昇格したパッケージは、以下のように Released 列が true となっています。

$ sfdx force:pacakge:version:list --packages "Hello 2GP"
=== Package Versions [1]
Package Name Namespace Version Name Version Subscriber Package Version Id Alias Installation Key Released Validation Skipped Ancestor Ancestor Version Branch
──────────── ────────── ──────────── ─────── ───────────────────────────── ───────────────── ──────────────── ──────── ────────────────── ──────── ──────────────── ──────
Hello 2GP hrendoh2gp ver 0.1 0.1.0.1 04tXXXXXXXXXXXXXXX Hello 2GP@0.1.0-1 false true false

参考:

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

バージョンを作成したパッケージは、SFDX コマンドで他の組織にインストールすることができます。

開発者ガイド CLI を使用したパッケージのインストール には「スクラッチ組織または対象登録者組織にパッケージをインストールできます」とありますが、あくまで SFDX コマンドを使用するため CLI からログイン可能な組織のみが対象となります。

パッケージをインストールしている登録者組織全体へアップグレードを実施したい場合は、これまでどおり転送アップグレードを実行する必要があります(という認識です)。

パッケージのインストールは force:package:install コマンドを使用します。

  • –package (-p): 04t で始まるパッケージバージョン Id またはパッケージエイリアスを指定します。
  • –publishwait (-b): パッケージバージョンは作成されてから対象組織で利用可能になるまではタイムラグがあります。その待ち時間(分単位)を指定できます。
$ sfdx force:package:install --package "Hello 2GP@0.1.0-1" -u target-org --wait 10 --publishwait 10
Waiting for the package install request to complete. Status = IN_PROGRESS
Waiting for the package install request to complete. Status = IN_PROGRESS
Waiting for the package install request to complete. Status = IN_PROGRESS
Successfully installed package [04tXXXXXXXXXXXXXXX]

対象組織で、インストールされたパッケージは force:package:installed:list コマンドで確認できます。

$ sfdx force:package:installed:list -u hrendoh-pdev
› Warning: sfdx-cli update available from 7.110.0 to 7.117.0.
=== Installed Package Versions [1]
ID Package ID Package Name Namespace Package Version ID Version Name Version
────────────────── ────────────────── ──────────── ────────── ────────────────── ──────────── ───────
0A3XXXXXXXXXXXXXXX 033XXXXXXXXXXXXXXX Hello 2GP hrendoh2gp 04tXXXXXXXXXXXXXXX ver 0.1 0.1.0.1

参考

AppExchange での公開

ここまで、パッケージのリリースまでの手順を確認してきましたが、実は注意が必要な部分があります。

というのも、PBO の Dev Hub に作成したパッケージのリリースバージョンを作成すると 2GP では自動で公開コンソールに登録されてしまいます。

残念ながら弊社の公開コンソールには、試しに作ったパッケージが表示されてしまっています。さらに、パッケージはリリースすると削除できませんのでご注意ください。

参考: AppExchange でのアプリケーションの公開

まとめ

今回は「まずはじめに」ということで、2GP の概要と基本的な使い方について解説してきました。2GP の開発の流れを、ざっくり把握いただけたのではないでしょうか。

次回は、2GP での「バージョンとアップグレードの関係性」と、2GP の目玉機能である “ブランチ” について詳しく解説します。