Skip to content

Instantly share code, notes, and snippets.

@v-rudkov
Last active March 13, 2024 08:52
Show Gist options
  • Save v-rudkov/238ff9d81205e34e16afc75048edca71 to your computer and use it in GitHub Desktop.
Save v-rudkov/238ff9d81205e34e16afc75048edca71 to your computer and use it in GitHub Desktop.

Creating an Unlocked Package

run sfdx docker container

$ cd /path/to/sfdx/projects
$ docker pull vadimrudkov/sfdx
$ docker run -it --rm -v "${PWD}:/home/sfdx" vadimrudkov/sfdx

create a new project

Authorize a Demo DevHub org if needed:

$ sfdx auth:device:login -d -a ddh

Create a new project:

$ sfdx force:project:create -n hello-world
$ cd hello-world
$ git init
$ git add .
$ git commit -m'Project scaffold'

add required components

$ sfdx force:apex:class:create -d force-app/main/default/classes/ -n HelloWorld
$ cat << 'EOF' > force-app/main/default/classes/HelloWorld.cls
public class HelloWorld {
    public String greeting;
    public HelloWorld() {
        this.greeting = 'Hello World!';
    }
}
EOF

$ sfdx force:apex:class:create -d force-app/main/default/classes/ -n HelloWorldTest
$ cat << 'EOF' > force-app/main/default/classes/HelloWorldTest.cls
@isTest
public class HelloWorldTest {
    @isTest static void testHelloWorld() {
        System.assertEquals('Hello World!', new HelloWorld().greeting);
    }
}
EOF

create a scratch org

Modify config/project-scratch-def.json

{
  "orgName": "Billie",
  "language": "en_US",
  "country": "DE",
  "edition": "Developer",
  "features": ["EnableSetPasswordInApi"],
  "settings": {
    "lightningExperienceSettings": {
      "enableS1DesktopEnabled": true
    },
    "mobileSettings": {
      "enableS1EncryptedStoragePref2": false
    },
    "userManagementSettings": {
      "enableNewProfileUI": true
    }
  }
}

Created a scratch org dev

$ sfdx force:org:create -f config/project-scratch-def.json -a dev -s

push the project

Push the project to the default (dev) scrach org

$ sfdx force:source:push

run tests

$ sfdx force:apex:test:run -n HelloWorldTest -r human

create package

$ sfdx force:package:beta:create --name hello-world --packagetype Unlocked --path force-app --nonamespace

add required dependencies to sfdx-project.json

$ git diff sfdx-project.json

Screenshot 2021-09-28 at 09 31 13

create package version

Please note, that it will add in the newly created version all the metadata components in the current project directory including untracked files.

$ sfdx force:package:beta:version:create --package $(package) -x --wait 10 --skipvalidation

install package

To install the last package version into the org test:

$ sfdx force:org:create -f config/project-scratch-def.json -a test
$ install_package test

This command should be run inside the project directory. It takes the project name pasing sfdx-project.json.

create GitHub repository

Create a new GitHub repository sfdx-hello-world. Commit the package and push it into the repository:

$ git add .
$ git commit -m'Hello World package'
$ git remote add origin git@github.com:v-rudkov/sfdx-hello-world.git
$ git push origin master

installing package into production

To install the package into production, first, we need to update the package version in sfdx-project.json:

            "versionName": "ver 0.1",
            "versionNumber": "0.1.0.NEXT"

Then create a package version with validation and code coverage:

$ sf package version create --package $(package) -x --wait 20 --code-coverage -f config/project-scratch-def.json

Then we need to promote this version:

$ sf package version promote --package $(latest_version)

Now it can be installed into production:

$ install_package pro

Troubleshooting

reached maximum number of custom objects

Creating a package version with code coverage ended up with multiple error messages and one of them was

Error EmailServiceOutboundEvent__e        reached maximum number of custom objects

It's a bit of misleading error message as it refers to custom objects and actually it is complaining about maximum number of platform event definitions which by default is 5.

To inscrease the maximum number add NumPlatformEvents:N to features in config/project-scratch-def.json:

"features": ["EnableSetPasswordInApi", "NumPlatformEvents:10"],

and to use new config use -f option while running sfdx force:package:version:create:

$ sfdx force:package:beta:version:create --package $(package) -x --wait 20 --codecoverage -f config/project-scratch-def.json

Field does not exist

Request in progress. Sleeping 30 seconds. Will wait a total of 1170 more seconds before timing out. Current Status='Verifying metadata'
ERROR running force:package:version:create:  Multiple errors occurred:
(1) <ClassName>: Field does not exist: <FieldName> on <ObjectName>

Solution 1

Delete the package id and generated a new package. Steps to install new package:

  • go to installed packages, 'View Components' for the old package and Remove all the components (this will remove the components from the package but not from the org)
  • deinstall the old package
  • install the new package

Solution 2 Use the new version of the package command:

$ sfdx force:package:beta:version:create ...
@DanWareing
Copy link

At the time of writing, using $ docker run -it -v "${PWD}:/home/sfdx" vadimrudkov/sfdx, inside a git bash terminal on a windows machine, running Docker version 20.10.7 and containerd 1.4.6 results in the following error:

docker: Error response from daemon: OCI runtime create failed: invalid mount {Destination:\Program Files\Git\home\sfdx Type:bind Source:/run/desktop/mnt/host/c/Users/Dan/Documents/GitHub;C Options:[rbind rprivate]}: mount destination \Program Files\Git\home\sfdx not absolute: unknown.

Some googling indicates that rolling-back containerd 'resolves' the issue', but it's also possible to execute the same command with an absolute path, e.g:
docker run -it -v "c:/Users/Dan/Documents/GitHub:/home/sfdx" vadimrudkov/sfdx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment