What directories does a sfdx force:package:version:create include

2gpmanaged-packagesalesforcedx

I've typically worked where there is only one root directory in an SFDX project (force-app). So I've imagined that the packageDirectories in sfdx-project.json act as the source/sources of the files that are included when:

sfdx force:package:version:create ...

is run as they do when a:

sfdx force:source:push ...

is done.

But with --loglevel trace set, it appears that any SFDX format directory in the project is automatically pulled in.

So what is a good way to to ignore specific directories when 2GP is done? Or am I misunderstanding what I'm seeing?

A bit more detail os that the sfdx-project.json is:

{
    "packageDirectories": [
        {
            "path": "force-app",
            "default": true,
            "package": "xxx",
            "versionName": "yyy",
            "versionNumber": "2.0.0.NEXT",
            "dependencies": [
                {
                    "package": "zzz",
                    "versionNumber": "1.14.0.LATEST"
                }
            ],
            "definitionFile": "config/project-scratch-def.json"
        },
        {
            "path": "no-ns",
            "default": false
        }
    ],
    ...
}

and trace messages include references to the "no-ns" folder from that JSON:

The profile "XXXX Salesforce Platform User" from the "/Users/keithc/Dev/pe-27-jun-2022/pe/no-ns/main/default/profiles/XXX Salesforce Platform User.profile-meta.xml" directory was added to this package version.

and references to a separate "digital-experience" folder:

The profile "${name} Profile" from the "/Users/keithc/Dev/pe-27-jun-2022/pe/digital-experience/reference-with-tokens/main/default/profiles/${name} Profile.profile-meta.xml" directory was added to this package version.

which is a surprise. Including -d force-app makes no difference.

Best Answer

When you have multiple package directories, you actually associate just one of those with a given package.

Something like this:

{
  "namespace": "namespace",
  "sfdcLoginUrl": "https://login.salesforce.com",
  "sourceApiVersion": "48.0",
  "packageDirectories": [
    {
      "path": "force-app",
      "default": true,
      "package": "My Package",
      "versionNumber": "1.3.0.NEXT",
      "versionDescription": "Yes, this is my 2GP",
      "ancestorId": "My [email protected]",
      "definitionFile": "config/project-scratch-def.json",
      "postInstallScript": "namespace.MyInstaller"      ]
    },
    {
      "path": "force-unpackaged"
    }
  ],
  "packageAliases": {
    "My Package": "0HoXX000000xxxxXXX",
    "My [email protected]": "04t2Z000000yyyyXXX"
  }
}

Defines:

  1. The package's package directory (force-app).
  2. An "unpackaged" package directory that gets deployed but that is not incorporated into the package itself (force-unpackaged).

(NB: This is a sanitised version of a real sfdx-project.json where the material in force-unpackaged is most definitely not included in our 2GP.)

Importantly a package is created from a single package directory. This is how Salesforce can apply the "monorepo" approach; multiple packages defined in a single git repository by simply being sibling package directories in the one sfdx-project.json. (I do not follow the "monorepo" approach, but this simplifies handling of inter-package dependencies, when the packages are all 2GPs and share the same namespace.)

The key values are those "package", "versionNumber" and (as needed) "ancestorId" in the package directory definition; these map the package directory to a given package and allows versions to be created from that directory's content.

The documentation is a bit vague but does say that:

You can group similar code and source for an application or customization to better organize your team’s repository. Later, if you decide to use second-generation packages (2GP), these directories correspond to the actual 2GP packages.

My emphasis. A directory for a 2GP; directories for multiple 2GPs.

Additionally, you'll find information about the sfdx-project.json 2GP properties in the documentation.

Related Topic