Table of Content
- What are Scratch Orgs
- Setting up SalesforceDX
- Authorize Salesforce Instance to be used with SFDX
- Create Scratch Org
- Move code to and from Scratch Org
- List of existing Orgs in SFDX
- Open Salesforce Org from SFDX
- Run Test Classes
- Setup Log Level
- Create Skeleton Workspace
- Generate Password for Scratch Org
- Enable Person Account
- Deploy and Retrieve metadata from Sandbox – Old Source Format
- Deploy and Retrieve metadata from Sandbox – New Source Format
- Set default username or default dev hub
- package.xml to SFDX format
- Sample Bash script to retrieve source code from developer or sandbox and convert to SFDX format
- Change SFDX API version
- Login to Salesforce Using Certificate / JWT
- Remove entry from org list or logout
- Install packages
- Create new Unlocked Package
- Updated Unlcokeed Package to new Version
- Promote Package for release
If we already have Salesforce Metadata API, Force.com IDE and other tools then why do we need one more tool like Salesforce DX ?
In tools like Changeset, Metadata API, or Force.com IDE, the source of truth is Sandbox. Although we can set up process and continuous integration (CI) to use some source code management (SCM) like Git or SVN. However, this kind of setup takes time, expertise, and a lot of effort.
Salesforce DX not only solves the above problem but
- Ability to consider SCM as a source of truth
- Use any favorite IDE or any SCM
- Powerful CLI to help minimize the complexity of setting up CI
- Updated Force.com IDE to support Salesforce DX if you are not comfortable with CLI
- and most important, spin-off Scratch Orgs within minutes through the script to quickly work on POC or package-based development
What are Scratch Orgs?
Salesforce DX can be enabled for any Salesforce instance and they are known as Developer Hub. One Developer Hub can have multiple Scratch Orgs. Scratch Orgs are temporary Salesforce org which can be created quickly and metadata can be deployed from SCM. These kind of Orgs can be used by developers to perform quick proof of concept or build and test packages. Once the package is built and saved back on SCM, scratch org can be destroyed easily.
If we already have developer orgs or sandboxes, why do we need scratch orgs ?
Because of compliance of most of the clients, we cannot move their code to developer org to perform some POC or package development, so developer org is out of questions anyway.
Now, let’s focus on Sandboxes. The use of sandboxes are mostly for end-to-end testing, integration testing, UAT or training. Sandboxes mostly represent either replica of production or future state of production which might be undergoing user acceptance testing (UAT). When we refresh Sandbox, we don’t get options on which metadata needs to be copied. Assume the situation, there is a defect on production and we need to go back in time and check how the system was behaving previously. Typical rollback scenario for sandboxes. We might have metadata stored somewhere, but we need to perform many iterations of destructive.xml to delete components from Sandbox. In this case, we can quickly spin off scratch org from source code and perform an analysis of historical code.
This is just one example, there are many scenarios and specifically for appexchange development companies.
I think we had lots of talks and are ready to roll now.
Setting up Salesforce DX
Install Heroku CLI and then run the below command
heroku plugins:install salesforcedx
Another way to install SalesforceDX during the pilot is to installer from here (Currently this URL is working however its location is not official). Once downloaded, install it. After installation makes sure the git command is working from the command line.
In Salesforce DX, the source of truth is source control. so we need a repository for the demo. For this blog post, let’s consider this repository. Run the below command to clone this repository
git clone https://github.com/forcedotcom/sfdx-simple cd sfdx-simple
Authorize Salesforce DX to login to Developer Hub Org
Below command will set org as default Developer Hub Org and will set its alias as my-devhub-org. It will open Salesforce login page in default browser for OAuth flow, where we need to login to Developer Hub org and authorize Salesforce DX.
sfdx force:auth:web:login --setdefaultdevhubusername --setalias my-devhub-org
Creating Scratch Org
To create a scratch org in Salesforce DX, we need to have workspace-scratch-def.json . Best place is to place it in config folder. This file already exists in Git repository we cloned initial however we would need to update it with our FirstName, lastName, Email and Org preferences. All supported preferences are listed here in Metadata documentation.
You can find official documentation on sample scratch org definition file and possible configuration values and features.
Below is a sample file
workspace-scratch-def.json
{
"Company": "Shivasoft",
"Country": "US",
"LastName": "Zaa",
"Email": "jitendra.Zaa@shivasoft.in",
"Edition": "Developer",
"OrgPreferences" : { "S1DesktopEnabled" : true }
}
Edition of Org can be Professional, developer or enterprise.
Once workspace-scratch-def.json created in config folder, run below command to create a scratch org. New scratch would be named as jitendra2_scratch and it can be configured by passing parameter to –setalias
Note : At a time of writing this post, scratch orgs auto deleted after 7 days however it may change when product goes GA.
sfdx force:org:create --setdefaultusername -f config/workspace-scratch-def.json --setalias jitendra2_scratch
Moving code to Scratch Org
To move code, we need to define sfdx-workspace.json which contains path of source code needed to be pushed. Below is sample file
simple sfdx-workspace.json
{
"PackageDirectories":
[
{
"Path": "force-app"
}
],
"Namespace": "",
"SourceApiVersion": "39.0"
}
sfdx-workspace.json with some more options
{
"Namespace" : "AcmeIncExample",
"SfdcLoginUrl" : "https://login.salesforce.com",
"SourceApiVersion": "39.0" ,
"PackageDirectories" :
[
{
"Path" : "helloWorld",
"Default": true
},
{ "Path" : "unpackaged" },
{ "Path" : "utils" }
]
}
Run below command to push metadata to default scratch org
sf project deploy start
Get metadata changes from Scratch Org or Pull changes
We can also get metadata changes done in scratch Org either from UI or deployment. It will only pull if metadata changes, not the whole Org.
sf project retrieve start
Getting list of all existing Orgs
Before creating scratch org, you may want to know about the existing orgs and their aliases. We can run below command
sfdx force:org:list
Open Salesforce Org from sfdx
Below command can be used to open Org from sfdx command line
sfdx force:org:open or sfdx force:org:open -u org_alias
Running Test classes using Salesforce DX
To run test classes using Salesforce DX , use below command
sfdx force:apex:test:run
Above command will return job Id, use that ID and run next command for status
sfdx force:apex:test:report -i JOBID_FROM_ABOVE_COMMAND
Setting up log Levels
Salesforce DX logs are generated at USER_Home_DIR/.sfdx/sfdx.log. We can set it either with each command or globally. By default only Error logs are recorded but we can change log level. To set log level with each command, we can use –loglevel DEBUG. To set log level globally we can use
//windows set SFDX_LOG_LEVEL=DEBUG //Or in unix Export SFDX_LOG_LEVEL=DEBUG
Currently below log levels are supported
- ERROR
- WARN
- INFO
- DEBUG
- TRACE
Creating skeleton workspace
We can automatically generate skeleton workspace using CLI which will create folder structure and json files with default value.
sfdx force:workspace:create --workspacename mywork OR sfdx force:workspace:create --workspacename mywork --defaultpackagedir myapp
Above command will create below folder structure
Password for scratch Orgs
When we create a scratch org using sfdx CLI, it does not display password and uses OAuth internally to communicate with scratch org. If we need to login to scratch org from non sfdx CLI, then we would need to generate a password. Below command can be used to generate password.
sfdx force:user:password:generate
Message :
Successfully set the password "26y271a" for user scratchorg1495650731268@shivasoft.in. You can see the password again by running "force:org:describe".
If we want to see password in future, then use below command
force:org:describe
Enable Person Account
Make sure below steps are completed in Salesforce Hub instance before running below sfdx script
- Create Record Type on Account
- Make sure OWD setting for contact is Controlled by Parent.
Below code in project-scratch-def.json file would create a Person Account
{
"orgName": "Person Account Scratch Org",
"edition": "Enterprise",
"features": ["PersonAccounts"]
}
Retrieve and Deploy code in Sandbox using SFDX – Old File Format
This blog post goes in detail, however, below is quick command
Retrieve Metadata from Sandbox
sfdx force:mdapi:retrieve -r ./mdAPIZip -u jzaa1 -k src/package.xml
Deploy Metadata to Sandbox
-- deploy zip file
sfdx force:mdapi:deploy -f ../mdAPIZip/unpackaged.zip -u jzaa1 -w 10
-- or deploy traditional file structure
sfdx force:mdapi:deploy -d ../mdAPIZip/unpackaged -u jzaa1 -w 10
Retrieve and Deploy code in Sandbox using SFDX – New Source Format
Deploy metadata to Sandbox or production using new source format
sfdx force:source:deploy -p force-app/main/default
Retrieve metadata from Sandbox of Production using new source format for existing components in default folder
sfdx force:source:retrieve -p force-app/main/default
Retrieve metadata from Sandbox / production on basis of package.xml in manifest folder
sfdx force:source:retrieve -x manifest/package.xml
Set Default Username or Default Devhub
Use below command to set default username for current project. For global use -g at end
$ sfdx force:config:set defaultusername=me@my.org defaultdevhubusername=me@myhub.org
$ sfdx force:config:set defaultdevhubusername=me@myhub.org -g
Convert Package.xml to SFDX format
sfdx force:mdapi:convert --rootdir "manifest"
In above command, –rootdir would be replaced by root path declared in sfdx-project.json
Sample Code Snippet to retrieve metadata from Developer or Sandbox Instance and convert to SFDX source format
echo "Retrieve Metadata from Developer instance"
echo "Command - sfdx force:mdapi:retrieve -r metadata -u pathtocode -k manifest/package.xml"
sfdx force:mdapi:retrieve -r tmp -u pathtocode -k manifest/package.xml
echo "Unzip results"
echo "Command - unzip -o tmp/unpackaged.zip -d manifest"
unzip -o tmp/unpackaged.zip -d manifest
echo "delete zipped result retrieved"
rm tmp/unpackaged.zip
echo "Move unzipped content to folder up"
mv manifest/unpackaged/* manifest
rm -r manifest/unpackaged
echo "Convert Manifest to SFDX format Source"
sfdx force:mdapi:convert --rootdir "manifest"
Change default SFDX API
Be default SFDX points to latest API of plugin. If I have SFDX installed for prerelease instances, that means it will not work for my developer or sandboxes because they are still on older API. In these scenarios, we can override SFDX API either globally or current project using below command.
sfdx force:config:set apiVersion=44.0 --global
or
sfdx force:config:set apiVersion=44.0
Login to Salesforce using Certificate / JWT
sfdx force:auth:jwt:grant
-r "https://login.salesforce.com"
-a orgalias
-f "PathtoKey/server.key"
-s -u username@salesforce.com -d
-i "ConsumerKey" --json
Remove entry from org list or logout
sfdx force:auth:logout
-u <usernamealias>
-p
You can also run below command to cleanup all orgs which are expired or deleted
sfdx force:org:list --clean
Install Package / Manage Package or Unlocked Package
sfdx force:package:install -p [packageId] -w 30 -u [scratchOrgName] -k [passwordIfAny]
You can find the list of a few Salesforce AppExchange here.
Create a new Unlocked Package
sfdx force:package:create -n <package_name> -d <Package Description> -t Unlocked -r force-app --json --wait 20 -e --codecoverage
Update Unlocked Package to new Version
sfdx force:package:version:create -p <package name> -d force-app -k <password> -w 10 -v <dev_hub_user_alias> -f config/project-scratch-def.json --releasenotesurl <url> --codecoverage
Example
sfdx force:package:version:create -a "Log framework 2.0 add on Package" -e "Nov 18 2020 release" -p log_framework -d force-app -k jit_opensource_pwd -w 80 -v Prod_unlocked -f config/project-scratch-def.json --releasenotesurl "https://jitendrazaa.com/blog/log_framework=%2FREADME.md&_a=preview" --codecoverage
Create Org Dependent Package
sfdx force:package:create -t Unlocked -r force-app -n <app name> --orgdependent
Update the package name or description
sfdx force:package:update --package "Expense App" --name "Expense Manager App" \
--description "New Description" --errornotificationusername me2@devhub.org
Promote Package for release
sfdx force:package:version:promote --package <package alias>
Example
sfdx force:package:version:promote --package "log_framework@0.9.0-4" -v Prod_unlocked
Governor Limit information
sfdx force:limits:api:display
Delete a Scratch Org
sfdx force:org:delete -u <org alias>
Leave a Reply