Patching Releases
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:
- Creates a temporary clone of your repository at the source branch
- Creates a new target branch from the source
- Fetches all artifacts specified in the release definition(s)
- Replaces package directories with the exact code from the artifacts
- Commits the changes to the target branch
- 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.3With NPM Registry
sfp repo:patch --releasedefinitions path/to/release.yaml \
--sourcebranchname main \
--targetbranchname hotfix/release-1.2.3 \
--npm \
--scope mycompanyWith 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.shThe custom script receives three parameters:
- Package name
- Version
- 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-23Command 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-hotfixAfter patching, you can:
- Review the changes
- Create a pull request
- 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-sync3. 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.04. 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-23Integration with Release Workflow
The repo patch command fits into the release workflow at several points:
After Production Release
# 1. Release to production
sfp release -p 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-syncDuring 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 -p releases/hotfix.yaml --targetorg prod
# 4. Patch hotfix back to develop
sfp repo:patch \
--releasedefinitions releases/hotfix.yaml \
--sourcebranchname develop \
--targetbranchname feature/apply-hotfixImportant 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:
- The patched branch has the exact release state
- Carefully review conflicts
- Generally, prefer the patched version for package code
- 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
mkdir -p releases
sfp releasecandidate generate \
--gitref main \
--configfile config/prod-release.yaml \
--releasename "prod-v2.0.0" \
--repository myorg/myrepo \
--nopublish \
--output releases/prod-v2.0.0.yaml
# 2. Release to production
sfp release \
-p releases/prod-v2.0.0.yaml \
--targetorg 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 developThis ensures that your development branch always contains the exact code that's running in production, preventing drift between environments.