Day 13 : CI/CD Salesforce deploys only delta with github actions

By

5 minutes de lecture
Wrapped up gifts

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

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.

creation of a feature branch

I create a pull request and you can see the check as below.

creation of a pull request

You can also see the generated package.xml

Generate package.xml

All checks are okay, now you can merge your pull request.

All checks are okay & 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 ?

Read more posts