Wilson Mar bio photo

Wilson Mar

Hello. Hire me!

Email me Calendar Skype call 310 320-7878

LinkedIn Twitter Gitter Instagram Youtube

Github Stackoverflow Pinterest

Begin to use Git and GitHub (DevHub) for software-driven (modular) continuous development

Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Cyrillic Russian   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean


This is a step-by-step hands-on tutorial on using the Salesforce DX (Developer eXperience) for continuous testing and development. Succinct and without hype. PROTIPs here present wisdom and knowledge from experience unique to this site. Unlike Trailhead’s instructions, this displays output from commands.

PROTIP: SFDX was announced in 2015 and entered Open Beta June 2017, available in all prod and business orgs.


Wade Wegner’s diagram and the table under it illustrate the shift being introduced by DX:

PROTIP: Various people have used different nicknames, so here they are together:

Slogan"Clicks, not code""Clicks AND versioned code"
Configurationconfig. among other metadata"config. as code"
Source of "Truth"What's in orgWhat's in VCS
VersioningCarry org. forwardWhat's in VCS
Unit of changeChange SetPackage 2GP
Workflow focus"org. centric""source-centric"
Org instances"nurture as dear pets""dispose like numbered cattle"
Env. for dev. testin sandboxes (SBX)in scratch orgs
Speed of releaseoccassionalcontinuous

The table above is explained in the text below:

Salesforce began with its “clicks, not code” slogan because Salesforce has made it so apps can be customized mostly within the GUI rather than coding internal configurations. This enabled “citizen developers” to customize their apps without a Computer Science degree.

And Salesforce has had Activity tracking which tracks every change to user data in the database.

Traditionally, changes are introduced by creating “change sets” tested within sandboxes which duplicate the production org. This means the development workflow is focused on what’s in the org., with org instances nutured as dear pets. For example, after Person accounts are enabled, there is no going back.

However, throughout the software development industry today, there is a movement toward storing configuration as code, of keeping metadata out from inside data in the org and into versioned code bases separate from the data.

The new “source of truth” for source-driven development is in the VCS (Version Control System) rather than in the production org. This means the configuration of the org exists outside the org. So experimental orgs can be easily created and tested without fear of disruption.

This transition is necessary to provide more flexibility to developers. This new approach puts versioning at the center of the workflow so that the state of an org can be brought back to any point in the past (like a time machine).

Such an approach requires more use of command-line terminals. That’s why I (not Salesforce) call it “clicks AND code”. CLI can completely replace the ANT deployment tool and unmanaged packages.

Each repo is distributed, meaning each clone of a repo is a complete duplicate with all version history. This means an Org with all its metadata can be worked on simultaneously by different people, instead of having to tag-team time on a change-set, each developer can test on his/own scratch orgs based on what each developer has on his/her own laptop. Reduced need for coordination enables faster, continuous testing and deployment to occur.

The bottom line of all this is to reduce the “friction” that keep changes from occurring more quickly and frequently – continuously rather than occassionally.

Enable Dev Hub in Production Org


PROTIP: Developer Edition Orgs cannot be enabled as a “Dev Hub”. Dev Hub can only be enabled on environments that have active paying users, such as Production or Business Orgs. See Intro to Environments.

BLAH: What that means is previously unlimited FREE Developer accounts will be limited to 30 days when working with scratch Orgs (which require Dev Hub to activate).

  1. Apply for a 30-day trial account which can be enabled with a “Dev Hub”:


    QUESTION: Can suffixed email names such as “me+v1@sane.com” and “me+v2@sane.com” be recognized as separate emails?

  2. You’ll get an email to validate.
  3. In Setup, Quick Find, search for “Dev Hub” and click on the response in the list.
  4. Click the Dev Hub toggle to “Enabled”.

    PROTIP: This cannot be undone.

DX Tools

DX consists of these new facilities:

  • Scratch (ephemeral/destructible) orgs created on the fly for temporary use for a “scope”
  • Dev Hub for managing scratch orgs
  • A Salesforce CLI binary that runs side-by-side with the Heroku CLI
  • Support for the Lightning Test service and Lightning linting to Salesforce CLI
  • Metadata reporting and export from orgs
  • Continuous integration with test automation

But the change is about more than the tools. Instead of building code and customizations around a monolithic org, code and customizations are built around artifact (a logical set of code) that represents a subset of the org that can be tested independently from other components in your org. This is so an artifact can be released independently.

Environment:DevIntegration & QAUATStaging
FeaturesScratch DX OrgDeveloperPartial Copy Sandbox Full Sandbox
Data limit:200 MB200 MB (1 GB Pro)5 GB*Matches Prod.
Refresh:Ephemeral1 day5 days29 days
Customer data:--SampleAll data
API calls/24 hrs:? 15K (50K)--

(Number within parentheses are for Partner Developers.)

All sandboxes contain metadata (application and configuration information) which define reports, dashboards, price books, products, apps, and customizations in Setup. The data limit use of space for both metadata and customer data, consisting of standard and custom object records, documents, and attachments.

Partial Copy and Full Sandboxes are created based on specifications defined in a Sandbox template. It appears when searched in Setup only if you have permissions to view/edit them. An email is sent when a Sandbox finishes being populated.

* Up to 10,000 records per object can be stored.

A Full Sandbox (that is a nearly identical copy of all production data) is available only to Enterprise or Unlimited Edition customers. Sandboxes cost about 25% of total spend.

https://trailhead.salesforce.com/en/content/learn/modules/application-lifecycle-and-development-models Application Lifecycle and Development Models

https://trailhead.salesforce.com/content/learn/modules/declarative-change-set-development/plan-for-changes-to-your-org Change Set Development Model


DX is enabled by the rapid and near ubiquitous adoption of Git to store text in an efficient way that enables every change to be tracked (in an audit trail), which also enables fall-back to complete versions at any time in the past (like a time machine).

Git is actually both a specification and a program name. The creators of the first Git program (which include the same person who created Linux) open sourced the internal format of their program Git, thus enabling many programs to offer Git capability. This has enabled the Git source version control (SVC) approach to be overwhelmingly popular.

By contrast, competing SVC approaches (such as Subversion) are more cumbersome and less flexible because they take a command-and-control mindset rather than a distributed work mindset.

A clone of a Git repo contains the entire depth of history for the project. Whereas Subversion cloning provides a portion of the total project. This means that, in Subversion, people have to wait for all dependencies to be ready before releasing the whole. The Subversion checkout command locks portions of code from being changed, a whole different concept.

The checkout command in Git selects the specific points in time Git users can travel to. People using Git are always working with the entire state of the repo at whatever point in time one chooses. As part of checkout, branches mark specific points in time.

Salesforce calls this “Second Generation Packaging” (2GP) *.

With Salesforce DX, a local project is tied to a repository. Each project contains, at a minimum, one artifact. Each repository keeps a history of all work done for artifacts. Branches are used to track the changes for each release.

In more complex orgs, you may find it necessary to have multiple related artifacts developed as part of the same project. This happens when sets of components and customizations depend on others.

http://resources.docs.salesforce.com/rel1/doc/en-us/static/pdf/SF_Git_cheatsheet_web.pdf Git CheatSheet

Install SFDX CLI

See https://developer.salesforce.com/tools/sfdxcli


    PROTIP: There is “brew install sfdx”. However:

    npm install --global sfdx-cli
  2. Verify version installed:

    sfdx version
     ▸    sfdx-cli: update available from 6.26.0 to 6.27.0-24408b4625
    sfdx-cli/6.26.0 (darwin-x64) node-v10.7.0


  3. Before upddating SFDX, update node and npm.

  4. Update SFDX

    sfdx update
     ▸    Use "npm install --global sfdx-cli" to update npm-based installations.
    sfdx-cli: Updating plugins... done
  5. As the response suggests, upgrade:

    npm install --global sfdx-cli

    The response include warnings about deprecated packages and vulnerabilities.

    /usr/local/bin/sfdx -> /usr/local/lib/node_modules/sfdx-cli/bin/run
           + sfdx-cli@6.44.0
    added 1315 packages in 57.348s

    You may need to run the command another time until you get an ending.

  6. Verify the version of the installed salesforcedx plug-in:

    sfdx plugins --core
    @salesforce/plugin-generator 0.0.10 (core)
    @salesforce/sfdx-trust 1.0.8 (core)
    builtins 1.0.0 (core)
    salesforcedx 43.11.0 (core)
  7. Get a list of operations under the force topic:

    sfdx force --help
    Usage: sfdx force: [-v] [--json] [--loglevel <string>] [flags]
     -v, --version        display the Salesforce API version
     --json               format output as json
     --loglevel LOGLEVEL  logging level for this command invocation
    Usage: sfdx force:COMMAND
    Help topics, type sfdx help TOPIC for more details:
     force:alias        manage username aliases
     force:apex         work with Apex code
     force:auth         authorize an org for use with the Salesforce CLI
     force:config       configure the Salesforce CLI
     force:data         manipulate records in your org
     force:doc          display help for force commands
     force:lightning    create and test Lightning component bundles
     force:limits       view your org’s limits
     force:mdapi        retrieve and deploy metadata using Metadata API
     force:org          manage your Salesforce DX orgs
     force:package      develop second-generation packages; install and uninstall first- and second-generation packages
     force:package1     develop first-generation managed and unmanaged packages
     force:project      set up a Salesforce DX project
     force:schema       view standard and custom objects
     force:source       sync your project with your orgs
     force:user         perform user-related admin tasks
     force:visualforce  create and edit Visualforce files
  8. Get a list of all commands, including the verb:

    sfdx force:doc:commands:list

    Expand the

    === Commands
      force:alias:list                    # list username aliases for the Salesforce CLI
      force:alias:set                     # set username aliases for the Salesforce CLI
      force:apex:class:create             # create an Apex class
      force:apex:execute                  # execute anonymous Apex code
      force:apex:log:get                  # fetch a debug log
      force:apex:log:list                 # list debug logs
      force:apex:log:tail                 # start debug logging and display logs
      force:apex:test:report              # display test results
      force:apex:test:run                 # invoke Apex tests
      force:apex:trigger:create           # create an Apex trigger
      force:auth:jwt:grant                # authorize an org using the JWT flow
      force:auth:logout                   # log out from authorized orgs
      force:auth:sfdxurl:store            # authorize an org using an SFDX auth URL
      force:auth:web:login                # authorize an org using the web login flow
      force:config:get                    # get config var values for given names
      force:config:list                   # list config vars for the Salesforce CLI
      force:config:set                    # set config vars for the Salesforce CLI
      force:data:bulk:delete              # bulk delete records from a csv file
      force:data:bulk:status              # view the status of a bulk data load job or batch
      force:data:bulk:upsert              # bulk upsert records from a CSV file
      force:data:record:create            # create a record
      force:data:record:delete            # delete a record
      force:data:record:get               # view a record
      force:data:record:update            # update a record
      force:data:soql:query               # execute a SOQL query
      force:data:tree:export              # export data from an org into sObject tree format for force:data:tree:import consumption
      force:data:tree:import              # import data into an org using SObject Tree Save API
      force:doc:commands:display          # display help for force commands
      force:doc:commands:list             # list the force commands
      force:lightning:app:create          # create a Lightning app
      force:lightning:component:create    # create a Lightning component
      force:lightning:event:create        # create a Lightning event
      force:lightning:interface:create    # create a Lightning interface
      force:lightning:test:create         # create a Lightning test
      force:lightning:test:install        # install Lightning Testing Service unmanaged package in your org
      force:lightning:test:run            # invoke Lightning component tests
      force:limits:api:display            # display current org’s limits
      force:mdapi:convert                 # convert metadata from the Metadata API format into the Salesforce DX format
      force:mdapi:deploy                  # deploy metadata to an org using Metadata API
      force:mdapi:deploy:report           # check the status of a metadata deployment
      force:mdapi:retrieve                # retrieve metadata from an org using Metadata API
      force:mdapi:retrieve:report         # check the status of a metadata retrieval
      force:org:create                    # create a scratch org
      force:org:delete                    # mark a scratch org for deletion
      force:org:display                   # get org description
      force:org:list                      # list all orgs you’ve created or authenticated to
      force:org:open                      # open an org in your browser
      force:org:shape:create              # create a snapshot of org edition, features, and licenses
      force:org:shape:delete              # delete all org shapes for a target org
      force:org:shape:list                # list all org shapes you’ve created
      force:package1:version:create       # create a first-generation package version in the release org
      force:package1:version:create:get   # retrieve the status of a package version creation request
      force:package1:version:display      # display details about a first-generation package version
      force:package1:version:list         # list package versions for the specified first-generation package or for the org
      force:package2:create               # (deprecated) create a second-generation package
      force:package2:list                 # (deprecated) list all second-generation packages in the Dev Hub org
      force:package2:update               # (deprecated) update a second-generation package
      force:package2:version:create       # (deprecated) create a second-generation package version
      force:package2:version:create:get   # (deprecated) retrieve a package version creation request
      force:package2:version:create:list  # (deprecated) list package version creation requests
      force:package2:version:get          # (deprecated) retrieve a package version in the Dev Hub org
      force:package2:version:list         # (deprecated) list all package versions in the Dev Hub org
      force:package2:version:update       # (deprecated) update a second-generation package version
      force:package:create                # create a package
      force:package:install               # install a package in the target org
      force:package:install:get           # (deprecated) retrieve the status of a package installation request
      force:package:install:report        # retrieve the status of a package installation request
      force:package:installed:list        # list the org’s installed packages
      force:package:list                  # list all packages in the Dev Hub org
      force:package:uninstall             # uninstall a second-generation package from the target org
      force:package:uninstall:get         # (deprecated) retrieve the status of a package uninstall request
      force:package:uninstall:report      # retrieve status of package uninstall request
      force:package:update                # update package details
      force:package:version:create        # create a package version
      force:package:version:create:list   # list package version creation requests
      force:package:version:create:report # retrieve details about a package version creation request
      force:package:version:list          # list all package versions in the Dev Hub org
      force:package:version:promote       # promote a package version to released
      force:package:version:report        # retrieve details about a package version in the Dev Hub org
      force:package:version:update        # update a package version
      force:project:create                # create a new SFDX project
      force:project:upgrade               # update project config files to the latest format
      force:schema:sobject:describe       # describe an object
      force:schema:sobject:list           # list all objects of a specified category
      force:source:convert                # convert Salesforce DX source into Metadata API format
      force:source:open                   # edit a Lightning Page with Lightning App Builder
      force:source:pull                   # pull source from the scratch org to the project
      force:source:push                   # push source to an org from the project
      force:source:status                 # list local changes and/or changes in a scratch org
      force:user:create                   # create a user for a scratch org
      force:user:display                  # displays information about a user of a scratch org
      force:user:list                     # lists all users of a scratch org
      force:user:password:generate        # generate a password for scratch org users
      force:user:permset:assign           # assign a permission set to one or more users of an org
      force:visualforce:component:create  # create a Visualforce component
      force:visualforce:page:create       # create a Visualforce page
  9. Get a list of just org operations:

    sfdx force:org --help
    Usage: sfdx force:org:COMMAND [command-specific-options]
    manage your Salesforce DX orgs
    sfdx force:org commands: (get help with sfdx help force:org:COMMAND)
     force:org:create        create a scratch org
     force:org:delete        mark a scratch org for deletion
     force:org:display       get org description
     force:org:list          list all orgs you’ve created or authenticated to
     force:org:open          open an org in your browser
     force:org:shape:create  create a snapshot of org edition, features, and licenses
     force:org:shape:delete  delete all org shapes for a target org
     force:org:shape:list    list all org shapes you’ve created

    Uninstall CLI

  10. Where installed:

  11. To uninstall:

    sfdx plugins:uninstall salesforcedx

Sample DX project

On your local machine (laptop), perform these steps to obtain assets from GitHub to create a scratch org:

  1. Create a “subject” folder or navigate to an existing one:

  2. Install Git https://help.github.com/articles/set-up-git/

  3. Download a sample repo from GitHub - the Dreamforce ’16 Developer Keynote sample application, called the DreamHouse app stored in GitHub. It’s author is listed as Wade Wegner, Salesforce SVP Product Management:

    git clone https://github.com/forcedotcom/sfdx-dreamhouse.git
    cd sfdx-dreamhouse
    git clone https://github.com/forcedotcom/sfdx-simple.git
    cd sfdx-simple
    sfdx force:auth:web:login -d -a "Hub Org"
    sfdx force:config:set defaultdevhubusername=someone@gmail.com
    sfdx force:org:create -s -f config/project-scratch-def.json

    Login DevHub

  4. Login DevHub which manages scratch, defining a default:

    sfdx force:auth:web:login -d -a DevHub
  5. If there is more than one account:

    PROTIP: Use the email and password that you established with that 30-day trial.

  6. If an “Allow Access” page appears, click “Allow”.
  7. Type password in the Salesforce authentication web page pop-up.

    The page that appears should have an Org. that has DevHub as the default app:


  8. Copy the host name portion of the URI for the Dev Hub Org., such as:

  9. Close the browser because we’re working with the CLI here.

    Script orgInit.sh

    github.com/dreamhouse-sfdx has a scripts folder containing orgInit.sh:

    Scratch orgs config

  10. In a Terminal at the sdfx-dreamhouse root folder.

    The json -file specified defines the “scope” of the app, which includes the Salesforce edition and preferences for features the app is enabled to work with (such as S1Desktop and Chatter):

     "orgName": "Salesforce DX Company",
     "edition": "Developer",
     "orgPreferences" : {
         "enabled": ["S1DesktopEnabled"]

    PROTIP: The project-scratch-def.json temporarily overrides enterprise-level scope settings during test runs defined in the enterprise-scratch-def.json:

      "orgName": "Your Company",
      "edition": "Enterprise",
      "orgPreferences": {
     "enabled": [
     "disabled": [

    Other features: “S1DesktopEnabled”,”AuthorApex”,”NetworksEnabled”,”Communities”

  11. Create an empty scratch org with an -alias named “demo1”:

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

    -n –durationdays 7 can also be added to limit the time.

    The command takes a while for sample response such as:

    Successfully created scratch org: 00D0q0000000q6gEAA, username: test-iydplvaqyiko@example.com
  12. Copy down in a file the response scratch org ID and its username.

    A scratch org is a dedicated, configurable, and short-term Salesforce environments that are quickly spun up within a Dev Hub Org. when starting a new project, a new feature branch, or a feature test.

    List Orgs

  13. List orgs

    sfdx force:org:list
    === Orgs
      ALIAS   USERNAME                ORG ID              CONNECTED STATUS
    ───  ──────  ──────────────────────  ──────────────────  ────────────────
    (D)  DevHub  wilsonmar@gmail.com     00Df2000000BaJcEAK  Connected
      ALIAS  SCRATCH ORG NAME       USERNAME                       ORG ID              EXPIRATION DATE
    ───  ─────  ─────────────────────  ─────────────────────────────  ──────────────────  ───────────────
    (U)  demo1  Salesforce DX Company  test-iydplvaqyiko@example.com  00D0q0000000q6gEAA  2018-08-19

    PROTIP: The default lifetime duration is 7 days from creation.

    Display orgs

    sfdx force:org:display

    Expand the Terminal window or use smaller font:

    === Org Description
    KEY              VALUE
    ───────────────  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────
    Access Token     00D0q0000000q6g!ARkAQIlr.EB_hhK5lPcFiPKsScAPVqoqtTCap8nHArYvN5Gv.aw6obwbUffVQt0bKhdm7mmwVqAcb4r3PMEqRIntAtfoabcd
    Alias            demo1
    Client Id        SalesforceDevelopmentExperience
    Created By       wilsonmar@gmail.com
    Created Date     2018-08-12T07:04:42.000+0000
    Dev Hub Id       wilsonmar@gmail.com
    Edition          Developer
    Expiration Date  2018-08-19
    Id               00D0q0000000q6gEAA
    Instance Url     https://page-connect-1530-dev-ed.cs64.my.salesforce.com
    Org Name         Salesforce DX Company
    Status           Active
    Username         test-iydplvaqyiko@example.com
  14. Check status:

    sfdx force:source:status

    A long list appears:

    STATE                     FULL NAME    TYPE        PROJECT PATH
    ─────                     ──────────   ──────────  ─────────────────────────────────
    Local Deleted             MyClass      ApexClass   /MyClass.cls-meta.xml

    Push Orgs

  15. Push app metadata into the current scratch org:

    sfdx force:source:push

    PROTIP: Metadata about the project is defined in the .project file:

    <?xml version="1.0" encoding="UTF-8"?>

    TODO: force-app

    Assign permissions

  16. Assign the dreamhouse permission set to the default user “dreamhouse”:

    sfdx force:user:permset:assign -n dreamhouse \
    --permsetname Dreamhouse

    Load data

  17. Apply the data folder which specifies app objects handled by the app. With Dreamhouse, it’s properties for sale and what brokers are trying to sell them.

    sfdx force:data:tree:import --plan data/sample-data-plan.json

    The sample-data-plan.json specifies a json file for each app object handled by the app and whether its reference is for “saveRefs” or “resolveRefs”:

     "sobject": "Broker__c",
     "saveRefs": true,
     "files": [
     "sobject": "Property__c",
     "resolveRefs": true,
     "files": [

    Each json file defines the records for each object type. A record within brokers-data.json contains these attributes and properties:

       "attributes": {
         "type": "Broker__c",
         "referenceId": "CarolineBrookerRef"
       "name": "Caroline Kingsley",
      "Title__c": "Senior Broker",
     "Phone__c": "617-244-3672",
     "Mobile_Phone__c": "617-244-3672",
     "Email__c": "caroline@dreamhouse.demo",
     "Picture__c": "https://s3-us-west-1.amazonaws.com/sfdc-demo/people/caroline_kingsley.jpg"

    A record within properties-data.json contains information about the property listed.

    Open Org

  18. Open org using the alias and automatically log in with cached authentication token (rather than passwords).

    sfdx force:org:open -u demo

    This should pop up a browser window containing Salesforce UI.

    At this point we have a brand-new empty scratch org. Next we populate it with the source we first pulled out of GitHub. For this, we use the source synchronization APIs, also available in the CLI.

    On Salesforce UX

  19. In Setup, type theme in the Quick Find box. Click Themes and Branding,
  20. Flip the toggle to hide background images in Lightning Experience.
  21. Select “DreamHouse” in the App Launcher.

  22. Click the (real estate) Properties tab and notice that there are 12 new properties.
  23. Click the Brokers tab and see that there are eight new brokers.

  24. Click the Data Import tab and click Initialize Sample Data

    List packages

    sfdx force:package2:list

    Delete Org

  25. Delete org using alias:

    sfdx force:org:delete -u demo
    Enqueue scratch org with name: demo for deletion? Are you sure (y/n)?

    Now repeat scratch org creation and continue.

    DX App Assets

    Let’s analyze Dreamhouse files at the root of the project repo:

    The settings.json file within folder .vscode saves Visual Studio Code preferences.

    Other similar files may be added for other IDEs.

    The .gitignore file specifies files and folders which are not to be uploaded to the team/public repository (DevHub or GitHub). This goes with the .git folder created by Git when cloning.

    QUESTION: A .forceignore file in the repo root folder is used to exclude source When Syncing or Converting. As a generic example, it contains this to ignore LESS files:


    The sxdx-project.json file specifies external attributes:

      "packageDirectories": [
       "path": "force-app",
       "default": true
      "namespace": "",
      "sfdcLoginUrl": "https://login.salesforce.com",
      "sourceApiVersion": "42.0"

    The .salesforcedx.yaml (hidden file) specifies processing options:

    scratch-org-def: config/project-scratch-def.json
    assign-permset: false
    permset-name: dreamhouse
    run-apex-tests: true
    delete-scratch-org: false
    show-scratch-org-url: true

force-app folder

Under /main/default/classes are the minimum needed. But Dreamhouse has the full set:

.sfdx top folder

Inder the .sfdx top-level folder is a folder named “tools” that contains the apex.db (database definiton).

What’s in apex.db is defined within .sfdx/typings/lwc/apex/.ts (Typescript) files.


TODO: Setup Test

  1. Test Permissions
  2. Test Data

    PROTIP: Scratch orgs are meant for use by individual developers rather than a team sandbox.

    HOW? SFDX keeps track of both changes you make locally as well as any in your scratch org.

    SFDX transforms large source files into smaller files to provide more project flexibility and reduce merge conflicts.

TODO: Run Test thru DevHub

  1. Run test
  2. Determine result

    Retrieve metadata source from an org and convert it to Salesforce DX format stored in a VCS repo.

  3. Make changes using editor

    PROTIP: Any changes made within a scratch org (using point-and-click) needs to be tracked in the Git source to be repeatable.

  4. Repeat test cycle with the Metadata API package created in the build phase.

    When proven ready:

  5. Deploy on a sandbox, a representation of the production org.

  6. In a sandbox, replicate and test the steps to release into the production org.

  7. TODO: Deploy to production

Metadata export from orgs

PROTIP: Metadata in existing orgs can be extracted into source code for storage in GitHub in sfdx-project.json files. This is easier said than done because there are several sources:

  • Metadata API
  • Salesforce DX Source Tracking to do push and pull
  • Packaging
  • Change Sets
  • Apex MD API
  • Tooling API

A special token is used in CI runs.

VIDEO: In 2018, documentation about metadata is disparate, it’s non consistent, not easy to find and navigate.” A Metadata Report generated from each org lists for each Metadata Type whether it’s exposed by the Metadata API, in source tracking, and unlocked packaging, all in one place.

These instructions are based on video:

The strategy is to, over time, to identify unpackaged metadata and organize them into Salesforce DX packages.

  1. Enable your org with Salesforce DX DevHub and 2nd Generation Packaging.

    In Setup, search for “Dev Hub”.


  2. Convert metadata in the org calling the Metadata API (mdapi):

    sfdx force:mdapi:convert --rootdir mdapi-source --outputdir force-app

    See the App Development with Salesforce DX module:

  3. Identify and put shared components in shared package of artifacts.

    PROTIP: Metadata components can only live in one artifact at a time. So shared Metadata components should live as shared components in a single base artifact.

  4. Use the Salesforce CLI and your testing org to create a package.xml that identifies the components of the artifact.

  5. Construct the command with the current date/time:

    sfdx force:package2:create --containeroptions Unlocked --name "Expense 2018.08.11 10:49"

    PROTIP: “Unlocked” allows full editability. “Locked” does not allow editability. There are different icons to flag the difference in the Apex classes screen.

  6. Highlight and copy the VALUE for package2 output (such as “0H00000008OQdKAM”) and paste it in the sdfx-project.json file:

    "path": "force-app",
    "id": "0H00000008OQdKAM",
    "versionName": "Expense App",
    "versionDescription": "Move Expense App metadata into a package2",
    "versionNumber": "1.0.0.NEXT",
    "default": true

    The “NEXT” is a token which will be auto-incremented.

  7. Queue version creation from source:

    sfdx force:package2:version:create --directory force-app
  8. Grab the Id returned, such as:

  9. Install the package:

    sfdx force:package:install --wait 2 --id 04tB0000000IaLi
  10. Refresh the org UI to view Installed Packages.

  11. Click View Components, Package Components.
  12. Click “View dependencies”.

    There is warning that changes done in the UI needs to be changed in the code as well.

  13. Make changes in the code.
  14. Increment the versionNumber.
  15. Do a build.

  16. Create a VCS repository for each artifact.

  17. Build release cycles specific to those applications.

Social community

SFDX Chatter Success Community group

Look for Twitter tag #SalesforceDX

#BASFDUG (Bay Area/San Francisco Dev User Group) has a the /TwitchSF channel, and YouTube channel (bit.ly/2kMVC8q).

Continuous Integration

  1. Sign up for an account at https://travis-ci.org/ using your GitHub account.

    PROTIP: Plans begin from $69 per month for 1 concurrent job.

  2. Click Authorize travis-ci to log in with your GitHub credentials, then enter your GitHub password.

  3. Fork to your own GitHub account a repo that has a .travisci.yml file for processing by Travis CI, a cloud-based continuous integration (CI) service for building and testing software projects hosted on GitHub:

    git clone https://github.com/forcedotcom/sfdx-travisci.git
    cd sfdx-travisci

    The .travisci.yml file:

    sudo: true
    os: trusty
    cache: false
           - URL=https://developer.salesforce.com/media/salesforce-cli/sfdx-linux-amd64.tar.xz
           - openssl aes-256-cbc -K $encrypted_b1fbf710b918_key -iv $encrypted_b1fbf710b918_iv
      -in assets/server.key.enc -out assets/server.key -d
           - export SFDX_AUTOUPDATE_DISABLE=false
           - export SFDX_USE_GENERIC_UNIX_KEYCHAIN=true
           - export SFDX_DOMAIN_RETRY=300
           - export SFDX_DISABLE_APP_HUB=true
           - export SFDX_LOG_LEVEL=DEBUG
           - mkdir sfdx
           - wget -qO- $URL | tar xJ -C sfdx --strip-components 1
           - "./sfdx/install"
           - export PATH=./sfdx/$(pwd):$PATH
           - sfdx --version
           - sfdx plugins --core
           - sfdx force:auth:jwt:grant --clientid $CONSUMERKEY --jwtkeyfile assets/server.key --username $USERNAME --setdefaultdevhubusername -a HubOrg
           - sfdx force:org:create -v HubOrg -s -f config/project-scratch-def.json -a ciorg --wait 2
           - sfdx force:org:display -u ciorg
           - sfdx force:source:push -u ciorg
           - sfdx force:apex:test:run -u ciorg --wait 10
           - sfdx force:org:delete -u ciorg -p
  4. Run test and get results in a human-readable format:

    sfdx force:apex:test:run --resultformat human

    Alternately, specify “junit” to view results using JUnit4 tools used by continuous integration.

Rock stars

Salesforce ISV Technical Evangelists Vivek M. Chawla, Peter Martin, and Danny Chang talk in their this January, 2018 video going through this slidedeck to explain their end-to-end model for ISV application design and developer workflow using SFDX, GitHub, CircleCI, and First-Generation Packaging by applying https://github.com/sfdx-isv/sfdx-falcon-template and https://github.com/sfdx-isv/sfdx-falcon-demo app. Talk to them at sfdx-falcon-group for partners only.

Scott Wells

Introduction to Serverless Applications Feb 3, 2018 [1:04:24] by Austen Collins (@Austen Collins, austin@serverless.com), founder and CEO of Serverless, Inc:


Rohit Mehta (@rohitforce), Product Manager

Dileep Burki, Sr. Product Manager:

Josh Kaplan (@JoshSFDC), Product Manager

Wade Wegner (@WadeWegner), Salesforce SVP Product Management

Others from Salesforce Developers on YouTube:

Ruth Sears-Blazej (@ruth_sfdc_docs) write docs about SFDC.

Happy Trails

Trailhead project: Quick Start: Salesforce DX [40 mins] Use the Salesforce command-line interface to create, convert, and deploy apps.

Trailmix: Salesforce DX [13 hrs 55 mins] +5650

Trail: Quick Start: Salesforce DX consists of modules:

https://trailhead.salesforce.com/trails/sfdx_get_started?trailmix_creator_id=00550000006FetYAAS&trailmix_id=salesforce-dx Get Started with Salesforce DX

Process Design Without Limits

The above replace many Workbooks


https://developer.secure.force.com/cookbook/ Best practices and code samples



https://engineering.salesforce.com/@_jamesward James Ward, Director, Open Source and Engineering Engagement at Salesforce, wrote https://engineering.salesforce.com/adopting-kubernetes-46b6c13b204b Adopting Kubernetes

Misc notes


QUESTION: ISVs (Service Vendors) who build customized Salesforce apps persona-based customizations.

Keir Bowden: SalesforceDX — View from the Coal Face from Nov 19, 2016 talks about the new Force.com IDE being tightly integrated with the new CLI, combining the Heroku toolbelt with the Force CLI.

Salesforce DX Product Manager AMA 27 Feb 2018

https://developer.salesforce.com/events/webinars/adopting-salesforce-dx August 17, 2017

https://www.youtube.com/watch?v=VSa7PgIANvs Continuous integration in Salesforce Using Jenkins and Git in 20 minutes by Jitendra Zaa Mar 22, 2015

  • https://success.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A000000Lg5U Packaging 2 Beta Trailblazer Community

  • https://www.youtube.com/watch?v=Prlurg2ORnU&list=PLJC5QQjmffkSOVDNGPSEUIMrIrOtmBkBO&index=1 How Everyone Can Leverage Salesforce DX Packaging

  • https://success.salesforce.com/_ui/core/chatter/groups/GroupProfilePage?g=0F93A000000HTp1 Salesforce DX Trailblazer Community

  • https://developer.salesforce.com/docs/atlas.en-us.214.0.sfdx_dev.meta/sfdx_dev/sfdx_dev_dev2gp.htm Develop Packages (Beta)

  • https://www.youtube.com/watch?v=cb8AWg-lFPQ Achieving Next-Generation Agility with Salesforce DX

More about Salesforce

This is one of a series about Salesforce

  1. Salesforce index

  2. Salesforce Ohana (about the Salesforce company, offices, mascots, emojis, and store)
  3. Salesforce Glossary (of acronyms)
  4. Salesforce Events (Conferences, local Meetups, ) to meet people face-to-face
  5. Salesforce Exhibitors (at Dreamforce)
  6. Salesforce Onboarding (Trailhead and IDEs)
  7. Salesforce Rock Stars (and influencers)

  8. Salesforce Offerings (Clouds, Industries, Domains, GitHub, editions, pricing, features, versions)
  9. Salesforce Certifications (training and exams)
  10. Salesforce Projects, Superbadges, and Sample Apps
  11. Salesforce myTrailhead for custom Trailhead content

  12. Salesforce Project Plans
  13. Salesforce Jobs (within Salesforce, with partners, etc.)
  14. Salesforce User Roles and Personas

  15. Salesforce Apps (in AppExchange)
  16. Salesforce Alexa
  17. Salesforce Heroku (external apps)
  18. Salesforce DX (Developer eXperience)

  19. Salesforce Non-Profit support
  20. Salesforce NPSP (Non-Profit Success Pack) performance (with Gatling)

  21. Salesforce Data Management
  22. Salesforce Einstein
  23. Salesforce Selenium (test automation)

It’s unfair to lump in @Benioff among biliionaires. Does Amazon provide free in-depth training? Benoiff started Salesforce with a nonprofit arm