Skip to content

Scratch Org CI โ€‹

Reusable workflow that runs a full scratch org lifecycle: it authenticates to the Dev Hub, creates a scratch org, optionally installs dependency packages, deploys the source, runs Apex tests, and always deletes the scratch org again.

Reusable workflow - call it from your own repository with uses:. View source

Inputs โ€‹

InputDescriptionTypeRequiredDefault
source-dirSource directory to deploy to the scratch org.stringnoforce-app
definition-filePath to the scratch org definition file.stringnoconfig/project-scratch-def.json
duration-daysNumber of days before the scratch org expires.stringno1
test-levelApex test level for the test run.stringnoRunLocalTests
packagesJSON array of dependency packages to install, e.g. "['04t...']". Leave empty to skip.stringno-

Secrets โ€‹

SecretDescriptionRequired
SFDX_CONSUMER_KEYConsumer key (client ID) of the Dev Hub connected app used for the JWT flow.yes
SFDX_JWT_SECRET_KEYContents of the private server key (server.key) used for the JWT flow.yes
SFDX_USERNAMEUsername of the Dev Hub integration user to authenticate as.yes

Example usage โ€‹

Copy this caller into your project's .github/workflows/ directory (source):

yaml
# Example: call the reusable scratch org CI workflow.
# Copy this file into your project's .github/workflows/ directory.

name: Scratch Org CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

# Least-privilege token: the called workflow only reads the repository and talks
# to Salesforce. A reusable workflow can never get more permissions than the
# caller grants here.
permissions:
  contents: read

jobs:
  scratch-org-ci:
    uses: svierk/salesforce-devops-starter-kit/.github/workflows/scratch-org-ci.yml@v1.0.0
    with:
      source-dir: force-app
      definition-file: config/project-scratch-def.json
      duration-days: '1'
      test-level: RunLocalTests
      # Optional dependency packages to install before deploying:
      # packages: "['04t...']"
    secrets:
      SFDX_CONSUMER_KEY: ${{ secrets.SFDX_CONSUMER_KEY }}
      SFDX_JWT_SECRET_KEY: ${{ secrets.SFDX_JWT_SECRET_KEY }}
      SFDX_USERNAME: ${{ secrets.SFDX_USERNAME }}

Released under the MIT License.