Patching Releases

sfp-pro
sfp (community)

Availability

Overview

The sfp repo:patch command enables you to apply a specific release (or multiple releases) to a different branch by replacing the source code of packages with their corresponding versions from built artifacts. This is particularly useful for:

  • Hotfix scenarios - Apply production fixes to development branches

  • Release synchronization - Sync release branches with specific versions

  • Rollback preparation - Create branches with previous release states

  • Environment alignment - Ensure branches match deployed environments

How It Works

The repo patch process:

  1. Creates a temporary clone of your repository at the source branch

  2. Creates a new target branch from the source

  3. Fetches all artifacts specified in the release definition(s)

  4. Replaces package directories with the exact code from the artifacts

  5. Commits the changes to the target branch

  6. Pushes the patched branch to the remote repository

Command Usage

Basic Usage

sfp repo:patch --releasedefinitions path/to/release.yaml \
  --sourcebranchname main \
  --targetbranchname hotfix/release-1.2.3

With NPM Registry

sfp repo:patch --releasedefinitions path/to/release.yaml \
  --sourcebranchname main \
  --targetbranchname hotfix/release-1.2.3 \
  --npm \
  --scope mycompany

With Custom Script (Without NPM)

When artifacts are stored in a custom registry or storage system (not npm), you can use a custom script:

sfp repo:patch --releasedefinitions path/to/release.yaml \
  --sourcebranchname main \
  --targetbranchname hotfix/release-1.2.3 \
  --scriptpath scripts/fetch-artifact.sh

The custom script receives three parameters:

  1. Package name

  2. Version

  3. Target directory

Example script (scripts/fetch-artifact.sh):

#!/bin/bash
PACKAGE_NAME=$1
VERSION=$2
TARGET_DIR=$3

# Example: Download from S3
aws s3 cp s3://my-bucket/artifacts/${PACKAGE_NAME}-${VERSION}.zip ${TARGET_DIR}/
unzip ${TARGET_DIR}/${PACKAGE_NAME}-${VERSION}.zip -d ${TARGET_DIR}/${PACKAGE_NAME}

# Example: Download from Artifactory
curl -u ${ARTIFACTORY_USER}:${ARTIFACTORY_TOKEN} \
  -O ${TARGET_DIR}/${PACKAGE_NAME}.zip \
  https://artifactory.company.com/sfp-artifacts/${PACKAGE_NAME}/${VERSION}/${PACKAGE_NAME}.zip
unzip ${TARGET_DIR}/${PACKAGE_NAME}.zip -d ${TARGET_DIR}/${PACKAGE_NAME}

Multiple Release Definitions

sfp repo:patch \
  --releasedefinitions release1.yaml \
  --releasedefinitions release2.yaml \
  --sourcebranchname develop \
  --targetbranchname release/sprint-23

Command Flags

Flag
Description
Required

-p, --releasedefinitions

Path to release definition YAML file(s). Can be specified multiple times

Yes

-s, --sourcebranchname

Name of the source branch on which the alignment needs to be applied

Yes

-t, --targetbranchname

Name of the target branch to be created after the alignment

Yes

-f, --scriptpath

Path to script that authenticates and downloads artifacts from the registry (mutually exclusive with --npm)

No

--npm

Download artifacts from a pre-authenticated private npm registry (mutually exclusive with --scriptpath)

No

--scope

User or organization scope of the NPM package (required when using --npm)

No

--npmrcpath

Path to .npmrc file for authentication. Defaults to home directory

No

--loglevel

Logging level (trace, debug, info, warn, error, fatal)

No

Use Cases

1. Hotfix Application

When a production hotfix needs to be applied back to development:

# Apply production release back to develop branch
sfp repo:patch \
  --releasedefinitions releases/prod-hotfix-1.2.3.yaml \
  --sourcebranchname develop \
  --targetbranchname feature/apply-prod-hotfix

After patching, you can:

  1. Review the changes

  2. Create a pull request

  3. Merge the hotfix back into development

2. Environment Synchronization

Ensure a branch matches exactly what's deployed in an environment:

# Sync UAT branch with UAT release
sfp repo:patch \
  --releasedefinitions releases/uat-release-2.0.0.yaml \
  --sourcebranchname main \
  --targetbranchname uat-sync

3. Rollback Preparation

Create a branch with a previous release state for potential rollback:

# Create rollback branch with previous release
sfp repo:patch \
  --releasedefinitions releases/previous-release.yaml \
  --sourcebranchname main \
  --targetbranchname rollback/v1.9.0

4. Release Branch Creation

Create a release branch with specific package versions:

# Create release branch with exact versions
sfp repo:patch \
  --releasedefinitions releases/sprint-23.yaml \
  --sourcebranchname develop \
  --targetbranchname release/sprint-23

Integration with Release Workflow

The repo patch command fits into the release workflow at several points:

After Production Release

# 1. Release to production
sfp release --path releases/prod-release.yaml \
  --targetusername prod

# 2. Patch the release back to develop
sfp repo:patch \
  --releasedefinitions releases/prod-release.yaml \
  --sourcebranchname develop \
  --targetbranchname feature/prod-sync

# 3. Create PR to merge changes
gh pr create --base develop --head feature/prod-sync

During Hotfix Process

# 1. Create hotfix branch from production release
sfp repo:patch \
  --releasedefinitions releases/current-prod.yaml \
  --sourcebranchname main \
  --targetbranchname hotfix/urgent-fix

# 2. Make fixes on hotfix branch
git checkout hotfix/urgent-fix
# ... make changes ...

# 3. Build and release hotfix
sfp build --branch hotfix/urgent-fix
sfp release --path releases/hotfix.yaml --targetusername prod

# 4. Patch hotfix back to develop
sfp repo:patch \
  --releasedefinitions releases/hotfix.yaml \
  --sourcebranchname develop \
  --targetbranchname feature/apply-hotfix

Important Considerations

Package Structure

  • The command replaces entire package directories

  • Any local changes in the target branch packages will be overwritten

  • Non-package files (configs, scripts) are preserved from the source branch

Version Alignment

  • Ensures exact version alignment with released artifacts

  • Useful for maintaining version consistency across branches

  • Helps prevent version drift between environments

Git History

  • Creates a clean commit with all package changes

  • Preserves the relationship to the source branch

  • Makes it easy to track what release was applied

Troubleshooting

Artifacts Not Found

# Ensure artifacts are available in the registry
sfp artifacts:query --npm --scope mycompany

# Or check local artifacts directory
ls -la artifacts/

Package Not in Project

If a package exists in the release but not in the source branch:

  • The package will be added to the project

  • Update sfdx-project.json after patching if needed

Merge Conflicts

After patching, if merging causes conflicts:

  1. The patched branch has the exact release state

  2. Carefully review conflicts

  3. Generally, prefer the patched version for package code

  4. Preserve local changes for configuration files

Example Workflow

Here's a complete example of using repo patch in a release workflow:

# 1. Generate release definition for production
sfp releasedefinition:generate \
  --gitref main \
  --releaseconfig config/prod-release.yaml \
  --directory releases \
  --releasename "prod-v2.0.0"

# 2. Release to production
sfp release \
  --path releases/prod-v2.0.0.yaml \
  --targetusername production

# 3. Patch production release back to develop
sfp repo:patch \
  --releasedefinitions releases/prod-v2.0.0.yaml \
  --sourcebranchname develop \
  --targetbranchname feature/prod-v2-sync

# 4. Create and merge PR
git checkout feature/prod-v2-sync
git push origin feature/prod-v2-sync
gh pr create \
  --title "Sync develop with Production v2.0.0" \
  --body "Applying production release artifacts back to develop" \
  --base develop

# 5. After merge, continue development
git checkout develop
git pull origin develop

This ensures that your development branch always contains the exact code that's running in production, preventing drift between environments.

Last updated