Developer Preview — This project is in active development. APIs may change. Provide feedback
Skip to content

CI/CD with GitHub Actions

The B2C Developer Tooling project provides official GitHub Actions for automating B2C Commerce operations in your CI/CD pipelines.

Overview

The official actions handle CLI installation, credential configuration, and Node.js setup automatically — so your workflow files stay focused on what you want to deploy rather than how to configure the tooling. High-level actions provide typed inputs for common operations like code deployment and data import, while a raw command passthrough covers everything else.

The actions are available from the SalesforceCommerceCloud/b2c-developer-tooling repository and support:

  • Code deployment — deploy cartridges with reload
  • Data import — import site archives in a single step
  • MRT deployment — push and deploy MRT storefront bundles
  • Job execution — run B2C jobs with wait and timeout
  • WebDAV uploads — upload files for data import, content, etc.
  • Any CLI command — raw passthrough for operations not covered by high-level actions

All actions are composite YAML — no compiled JavaScript, fully transparent and auditable. They cache the npm install across runs and expose structured JSON outputs for downstream workflow steps.

Authentication

Store credentials as GitHub repository secrets and non-sensitive configuration as repository variables.

Recommended secrets:

SecretDescription
SFCC_CLIENT_IDOAuth Client ID
SFCC_CLIENT_SECRETOAuth Client Secret
SFCC_USERNAMEWebDAV username
SFCC_PASSWORDWebDAV password/access key
SFCC_MRT_API_KEYMRT API key

Recommended variables:

VariableDescription
SFCC_SERVERB2C instance hostname
SFCC_MRT_PROJECTMRT project slug
SFCC_MRT_ENVIRONMENTMRT environment

Credentials can be passed per-action or set once with the setup action so they're available to all subsequent steps.

Quick Start: Deploy Cartridges

yaml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Install the B2C CLI and configure credentials for subsequent steps
      - uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/setup@v1
        with:
          client-id: ${{ secrets.SFCC_CLIENT_ID }}
          client-secret: ${{ secrets.SFCC_CLIENT_SECRET }}
          server: ${{ vars.SFCC_SERVER }}
          username: ${{ secrets.SFCC_USERNAME }}
          password: ${{ secrets.SFCC_PASSWORD }}

      # Run your build steps as usual
      - run: npm ci
      - run: npm run build

      # Generate a code version from the branch name and date
      - name: Set code version
        id: version
        run: |
          BRANCH=$(echo "$GITHUB_REF_NAME" | tr '/' '-')
          echo "code-version=${BRANCH}-$(date +%Y%m%d-%H%M%S)" >> "$GITHUB_OUTPUT"

      # Deploy cartridges — only operation-specific inputs needed
      - uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/code-deploy@v1
        with:
          code-version: ${{ steps.version.outputs.code-version }}
          reload: true

The setup step installs the CLI and configures credentials for all subsequent steps. Everything after that — your build, version calculation, and deploy — can focus on your project's needs.

Actions Reference

Root Action

uses: SalesforceCommerceCloud/b2c-developer-tooling@v1

Combines setup and command execution. Pass a command to run a CLI command, or omit it for setup-only.

InputDefaultDescription
commandCLI command to run
versionlatestCLI version to install
node-version22Node.js version
jsontrueParse JSON output
working-directory.Working directory
Auth inputsSee Authentication

Setup

uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/setup@v1

Installs the CLI and writes credentials to environment variables. Use this when you need multiple steps after setup.

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/setup@v1
  with:
    client-id: ${{ secrets.SFCC_CLIENT_ID }}
    client-secret: ${{ secrets.SFCC_CLIENT_SECRET }}
    server: ${{ vars.SFCC_SERVER }}
    plugins: |
      @myorg/b2c-plugin-custom
      sfcc-solutions-share/b2c-plugin-intellij-sfcc-config

Plugins are installed after the CLI and cached across runs. Each line is an npm package name or GitHub owner/repo.

Run

uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/run@v1

Executes any CLI command. Pairs with the setup action.

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/run@v1
  with:
    command: 'sandbox list --realm abcd'
InputDefaultDescription
command(required)CLI command to run
jsontrueAppend --json and parse output
working-directory.Working directory

Code Deploy

uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/code-deploy@v1

Deploy cartridges with typed inputs.

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/code-deploy@v1
  with:
    client-id: ${{ secrets.SFCC_CLIENT_ID }}
    client-secret: ${{ secrets.SFCC_CLIENT_SECRET }}
    server: ${{ vars.SFCC_SERVER }}
    username: ${{ secrets.SFCC_USERNAME }}
    password: ${{ secrets.SFCC_PASSWORD }}
    code-version: ${{ vars.SFCC_CODE_VERSION }}
    reload: true
    cartridges: 'app_storefront_base,app_custom'
InputDefaultDescription
cartridge-path.Path to cartridge source directory
reloadtrueActivate code version after deploy
code-versionCode version (overrides env)
cartridgesComma-separated cartridges to include
exclude-cartridgesComma-separated cartridges to exclude
deletefalseDelete existing cartridges first

Data Import

uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/data-import@v1

Import a site archive. Handles upload, job execution, waiting, and cleanup in one step.

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/data-import@v1
  with:
    client-id: ${{ secrets.SFCC_CLIENT_ID }}
    client-secret: ${{ secrets.SFCC_CLIENT_SECRET }}
    server: ${{ vars.SFCC_SERVER }}
    username: ${{ secrets.SFCC_USERNAME }}
    password: ${{ secrets.SFCC_PASSWORD }}
    target: './export/site-import.zip'
    timeout: 600
InputDefaultDescription
target(required)Local file, directory, or zip to import
timeoutTimeout in seconds
keep-archivefalseKeep archive on instance after import
show-logtrueShow job log on failure

MRT Deploy

uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/mrt-deploy@v1

Push and deploy an MRT bundle.

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/mrt-deploy@v1
  with:
    mrt-api-key: ${{ secrets.SFCC_MRT_API_KEY }}
    project: ${{ vars.SFCC_MRT_PROJECT }}
    environment: ${{ vars.SFCC_MRT_ENVIRONMENT }}
    build-directory: build
    message: 'Deploy from CI'
InputDefaultDescription
projectMRT project slug
environmentTarget environment
build-directorybuildLocal build directory
messageBundle message
bundle-idDeploy existing bundle by ID

Job Run

uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/job-run@v1

Execute a B2C job and optionally wait for completion.

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/job-run@v1
  with:
    job-id: 'sfcc-site-archive-import'
    wait: true
    timeout: 600
InputDefaultDescription
job-id(required)Job ID to execute
waittrueWait for completion
timeout900Timeout in seconds
parametersKEY=VALUE pairs, one per line
show-logtrueShow job log on failure

WebDAV Upload

uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/webdav-upload@v1

Upload files via WebDAV.

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/webdav-upload@v1
  with:
    local-path: './export/site-import.zip'
    remote-path: 'src/instance/'
    root: IMPEX
InputDefaultDescription
local-path(required)Local file or directory
remote-path(required)Remote destination path
rootIMPEXWebDAV root (IMPEX, TEMP, CARTRIDGES, etc.)

Patterns

Data Import Pipeline

Import a site archive:

yaml
name: Data Import

on:
  workflow_dispatch:
    inputs:
      import-file:
        description: 'Path to the site import archive'
        required: true
        default: 'export/site-import.zip'

jobs:
  import:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/data-import@v1
        with:
          client-id: ${{ secrets.SFCC_CLIENT_ID }}
          client-secret: ${{ secrets.SFCC_CLIENT_SECRET }}
          server: ${{ vars.SFCC_SERVER }}
          username: ${{ secrets.SFCC_USERNAME }}
          password: ${{ secrets.SFCC_PASSWORD }}
          target: ${{ github.event.inputs.import-file }}
          timeout: 600

MRT Release Deploy

Build and deploy an MRT storefront on release:

yaml
name: MRT Deploy

on:
  release:
    types: [published]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build storefront
        run: npm run build

      - uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/mrt-deploy@v1
        with:
          mrt-api-key: ${{ secrets.SFCC_MRT_API_KEY }}
          project: ${{ vars.SFCC_MRT_PROJECT }}
          environment: ${{ vars.SFCC_MRT_ENVIRONMENT }}
          build-directory: build
          message: 'Release ${{ github.event.release.tag_name }}'

Using Outputs

When json is enabled (the default), the result output contains the command's structured JSON. Reference it directly in downstream steps:

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/code-deploy@v1
  id: deploy
  with:
    code-version: v25_03_1
    reload: true

- name: Show deploy result
  run: echo '${{ steps.deploy.outputs.result }}'
json
{
  "cartridges": [
    { "name": "app_storefront_base", "dest": "app_storefront_base", "src": "..." },
    { "name": "app_custom", "dest": "app_custom", "src": "..." }
  ],
  "codeVersion": "v25_03_1",
  "reloaded": true
}

Actions exit with the CLI's exit code, so a failed job will fail the step. Use continue-on-error and fromJSON() when you need to inspect the result after a failure:

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/job-run@v1
  id: job
  continue-on-error: true
  with:
    job-id: 'sfcc-site-archive-import'
    wait: true

- name: Handle job failure
  if: steps.job.outputs.exit-code != '0'
  run: echo "Job failed with status ${{ fromJSON(steps.job.outputs.result).exit_status.code }}"

Version Pinning

Use the version input to pin the CLI version:

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling@v1
  with:
    version: '0.4.1'

Use @v1 for the latest stable action version (recommended). The floating v1 tag is updated on each backward-compatible release.

Plugins

The CLI supports plugins for custom configuration sources, HTTP middleware, and more. Install plugins in CI with the plugins input on the setup action:

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/setup@v1
  with:
    client-id: ${{ secrets.SFCC_CLIENT_ID }}
    client-secret: ${{ secrets.SFCC_CLIENT_SECRET }}
    server: ${{ vars.SFCC_SERVER }}
    plugins: |
      @myorg/b2c-plugin-custom
      sfcc-solutions-share/b2c-plugin-intellij-sfcc-config

Each line is an npm package name or GitHub owner/repo. Plugins are installed after the CLI and cached across workflow runs.

Logging

The setup action accepts a log-level input that sets SFCC_LOG_LEVEL for all subsequent steps:

yaml
- uses: SalesforceCommerceCloud/b2c-developer-tooling/actions/setup@v1
  with:
    log-level: debug

Available levels (most to least verbose): trace, debug, info (default), warn, error, silent.

You can also set the environment variable directly in your workflow:

yaml
env:
  SFCC_LOG_LEVEL: debug

Logs are always human-readable on stderr. The --json flag only controls the structured result on stdout. If you need machine-readable log lines (e.g., for log aggregation), set SFCC_JSON_LOGS=true.

CI Defaults

All actions automatically configure:

  • NO_COLOR=1 — clean log output without ANSI colors

Released under the Apache-2.0 License.