Most projects today configure the CI/CD to deploy all metadata from the git repository, even those that haven’t been changed.
When you are on a small project, you don’t have a problem deploying all the metadata every time and it doesn’t take a lot of time. But on large projects, deploying all metadata can take a long time.
From there comes the idea to be able to deploy only the modified metadata and this is what I will show you in this article.
Branching strategy
There is a sample of git flow
In my case, I have a git branch for every environnement and a feature branch for every user story. When I want to deploy my feature in the higher environment, I create a pull request to push my feature branch in the destination environment branch. When I create a pull request I want to validate my deployment before merging the pull request.
If you want to deploy a set of a user stories, you can use a promotion branch :
- Create a promotion branch from the destination branch with the name promotion/destinationbranch-XXXX
- Merge all feature branches you want to deploy with the promotion branch
- Create a pull request to push the promotion branch to the destination branch.
Implementation
Before starting, you must to do this step :
- Configure authentication.
- Create Global Variable on github repo (SF_USERNAME, SF_CONSUMER_KEY and SERVER_KEY_PASSWORD)
You can see this article to configure authentication with JWT
https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_auth_jwt_flow.htm
For the implementation I use
- Github actions
- SFDX
- Plugin SFDX Git Delta
Here is an example of YAML to validate your package during a pull request to an environment branch :
name: PROD-Validation
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
# Fetch all history commit
fetch-depth: 0
- uses: actions/setup-node@v1
with:
node-version: '14.6.0'
- name: Install SFDX & SFDX Git Delta
run: |
npm install sfdx-cli
echo y | node_modules/sfdx-cli/bin/run plugins:install sfdx-git-delta
- name: Generate package.xml
run: |
#Generate package.xml between the current branch &
node_modules/sfdx-cli/bin/run sgd:source:delta --to "HEAD" --from $(git merge-base HEAD origin/master) --output . -i .gitignore
echo "--- package.xml generated with added and modified metadata ---"
cat package/package.xml
- name: Authentication to PROD
run: |
echo "${SERVER_KEY_PASSWORD}" > server.key
node_modules/sfdx-cli/bin/run auth:jwt:grant --clientid ${{ secrets.SF_CONSUMER_KEY }} --jwtkeyfile server.key --username ${{ secrets.SF_USERNAME }} --setdefaultdevhubusername --setalias prod
env:
SERVER_KEY_PASSWORD: ${{ secrets.SERVER_KEY_PASSWORD }}
- name: Validation in PROD
run: |
node_modules/sfdx-cli/bin/run force:source:deploy -x package/package.xml -l RunLocalTests -u prod -c
Example of a Yaml to deploy to the environment after you merge the pull request :
name: PROD-Deployment
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: master
# Fetch all history commit
fetch-depth: 0
- uses: actions/setup-node@v1
with:
node-version: '14.6.0'
- name: Install SFDX & SFDX Git Delta
run: |
npm install sfdx-cli
echo y | node_modules/sfdx-cli/bin/run plugins:install sfdx-git-delta
- name: Generate package.xml
run: |
#Generate package.xml between the current branch &
node_modules/sfdx-cli/bin/run sgd:source:delta --to "HEAD" --from "HEAD^" --output .
echo "--- package.xml generated with added and modified metadata ---"
cat package/package.xml
- name: Authentication to Production
run: |
echo "${SERVER_KEY_PASSWORD}" > server.key
node_modules/sfdx-cli/bin/run auth:jwt:grant --clientid ${{ secrets.SF_CONSUMER_KEY }} --jwtkeyfile server.key --username ${{ secrets.SF_USERNAME }} --setdefaultdevhubusername --setalias prod
env:
SERVER_KEY_PASSWORD: ${{ secrets.SERVER_KEY_PASSWORD }}
- name: Deployement to PROD
run: |
node_modules/sfdx-cli/bin/run force:source:deploy -x package/package.xml -l RunLocalTests -u prod
Demo
For instance, I have a project where I already have existing metadata.
First I create a feature branch from the master branch that’s the name is feature/JIRA-00001 and then I edit a field on this feature branch.
I create a pull request and you can see the check as below.
You can also see the generated package.xml
All checks are okay, now you can merge your pull request.
Now you have a nice gift from Santa Claus ! 🎅
More
https://github.com/scolladon/sfdx-git-delta
https://docs.github.com/en/actions
The French version of this article is available here :
Salesforce CI/CD : Comment déployer uniquement le delta avec les Github actions ?