Skip to content

๐ŸŒฉ๏ธ SFDX Create Scratch Org โ€‹

This repository implements a simple GitHub composite action for creating Salesforce scratch orgs.

Usage โ€‹

In a GitHub workflow, the use of the action after installing the SF CLI and authorizing the respective DevHub Org could look like this:

yaml
# Least-privilege token: the workflow only reads the repository and talks to
# Salesforce via the CLI, it never writes back to GitHub.
permissions:
  contents: read

jobs:
  create-scratch-org:
    name: Create Scratch Org
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v7.0.1
        with:
          fetch-depth: 0
          persist-credentials: false # the GITHUB_TOKEN is not needed after the checkout - don't leave it in .git/config

      - name: Select Node Version
        uses: svierk/get-node-version@v1.5.1

      - name: Install SF CLI
        uses: svierk/sfdx-cli-setup@v1.1.3

      - name: Authorize DevHub
        uses: svierk/sfdx-login@v1.4.2
        with:
          client-id: ${{ secrets.SFDX_CONSUMER_KEY }}
          jwt-secret-key: ${{ secrets.SFDX_JWT_SECRET_KEY }}
          username: ${{ secrets.SFDX_USERNAME }}
          set-default: true
          set-default-dev-hub: true
          alias: devhub

      - name: Create Scratch Org
        id: scratch
        uses: svierk/sfdx-create-scratch-org@v1.3.1
        with:
          alias: scratch-${{ github.run_id }}
          name: ${{ inputs.name }}
          description: ${{ inputs.description }}
          admin-email: ${{ inputs.email }}
          set-default: true
          definition-file: config/project-scratch-def.json
          target-dev-hub: devhub
          duration-days: ${{ inputs.lifespan }}
          wait: 10
          generate-password: true # hands the login password over via the job summary

      - name: Package Installation
        if: ${{ inputs.install-packages }}
        uses: svierk/sfdx-package-installation@v1.2.1
        with:
          packages: ${{ inputs.packages }}
          wait: 30
          publish-wait: 20

      - name: Deploy Metadata
        if: ${{ inputs.deploy-metadata }}
        env:
          TARGET_ORG: ${{ steps.scratch.outputs.username }} # pass values through the environment, never interpolate them into the script
        run: sf project deploy start --target-org "$TARGET_ORG"

A few conventions the example follows and that are worth keeping in your own workflows:

  • Pin every uses: to an exact release tag (@v1.3.1), not to a branch like @main and not to a floating major like @v1. An update then becomes an explicit, reviewable change - ideally raised automatically by Dependabot.
  • Declare permissions: at workflow or job level. Creating a scratch org needs nothing but contents: read.
  • Keep secrets in secrets/env. Hand them to an action via its inputs, and pass anything dynamic into a run: script through env: instead of interpolating ${{ ... }} directly into the shell command.

The following actions were also used in the examples on this page:

Of course, the create scratch org action can be used flexibly and the respective approach can vary.

Inputs โ€‹

NameRequiredDefaultDescription
target-dev-hubyesUsername or alias of the Dev Hub org.
aliasnoAlias for the scratch org.
set-defaultnoSet the scratch org as your default org.
definition-filenoPath to a scratch org definition file (blueprint for the scratch org).
editionnoSalesforce edition, e.g. developer, enterprise. Overrides the definition file.
duration-daysnoNumber of days before the org expires (1โ€“30).
waitnoNumber of minutes to wait for the scratch org to be ready.
api-versionnoOverride the api version used for api requests.
client-idnoConsumer key of the Dev Hub connected app.
usernamenoUsername of the scratch org admin user. Omit to auto-generate a unique username.
descriptionnoDescription of the scratch org in the Dev Hub.
namenoName of the org, e.g. Acme Company.
releasenoRelease of the scratch org relative to the Dev Hub release.
admin-emailnoEmail address applied to the org's admin user.
source-orgno15-character ID of the org whose shape the new scratch org is based on.
generate-passwordnofalseGenerate a password for the scratch org admin user. The password is masked in the job log, but exposed in clear text via the job summary and the password output - anyone with access to the workflow run can read the summary.
step-summarynotrueWrite a result section to the GitHub Actions job summary. Set to false to avoid collisions with a custom workflow summary.

Outputs โ€‹

The action exposes the details of the newly created scratch org so that follow-up steps (deploy, test, delete) can target it without guessing the generated username:

NameDescription
usernameUsername of the created scratch org.
org-idID of the created scratch org.
passwordPassword of the scratch org admin user. Only set when generate-password is true. Registered as a secret, so it stays masked in the log of any follow-up step.
yaml
- name: Create Scratch Org
  id: scratch
  uses: svierk/sfdx-create-scratch-org@v1.3.1
  with:
    target-dev-hub: devhub
    definition-file: config/project-scratch-def.json
    duration-days: 1

- name: Deploy Metadata
  env:
    TARGET_ORG: ${{ steps.scratch.outputs.username }}
  run: sf project deploy start --target-org "$TARGET_ORG"

- name: Delete Scratch Org
  if: always() # release the org even when the deployment above failed
  uses: svierk/sfdx-delete-scratch-org@v1.1.2
  with:
    target-org: ${{ steps.scratch.outputs.username }}

Pairing the username output with SFDX Delete Scratch Org and if: always() is the recommended cleanup pattern for CI runs: the org is released again even if a previous step failed, and no step has to guess the generated username.

References โ€‹

The scratch org creation option supported by this GitHub composite action can be found in the Salesforce CLI Command Reference here:

More details can be found in the related Salesforce DX Developer Guide: Create Scratch Orgs

Releases โ€‹

Latest release notes can be found on the release page.

License โ€‹

The scripts and documentation in this project are released under the MIT License.


โžก๏ธ Full source & releases: svierk/sfdx-create-scratch-org

Released under the MIT License.