4

TL;DR

Does the salesforce CLI have built in features that allow you to only deploy changes to a CI/CD pipeline?

Problem

Currently, wanting to move our non-profit to a CI/CD development model rather than a changeset model. I've watched a couple tutorials on this (see below). However, none of the things I've seen deploy's specific changes to the pipeline. They deploy the entire force-app/main/default. The problem is that with multiple devs working on the code base. If a developer pushes a folder to the repo with changes to File A, and I come behind their commit with an entire folder on File B, then my push will contain the old version of File A and create a merge conflict.

Is my understanding off on how the salesforce CLI currently works with it's various commands? How does a DevOps professional ensure that only files that are changed are the ones that go through the deployment process. Thanks

Tutorials and Other Posts:

Coding With The Force Advanced Patterns for CI/CD with Salesforce DX

Other Posts:

Salesforce CI CD deployment commands Salesforce CI CD deployment

3 Answers 3

5

Original Version

The problem is that with multiple devs working on the code base. If a developer pushes a folder to the repo with changes to File A, and I come behind their commit with an entire folder on File B, then my push will contain the old version of File A and overwrite the first Developers change.

This represents a problem in your software development lifecycle. You should never allow a PR that overwrites existing code to be merged. This should be a non-issue that is instantly caught in code review.

However, I also want to highlight that this may represent a misunderstanding of how (most) VCS systems work. In Git, you don't commit folders; you commit files. If User A merges changes to File A, and user B then makes changes to Files B and C in the same folder, no overwrite occurs: Git versions the files separately.

New Version

The problem is that with multiple devs working on the code base. If a developer pushes a folder to the repo with changes to File A, and I come behind their commit with an entire folder on File B, then my push will contain the old version of File A and create a merge conflict.

This is still a misunderstanding, unless possibly if you are using a source control system that is not Git or Mercurial. Folders are not versioned, files are. The scenario you describe would not result in a merge conflict, which would occur if the two developers modified the same file in ways that conflict with one another.

Merge conflicts are simply a part of life in team development. Ideally, they happen rarely because your code base is well structured and your developers work on separate stories. But they will happen, and you'll resolve them in source control before a merge takes place and before an org is ever touched by CI/CD.

Merge conflicts also have nothing to do with delta deployments. Delta deployments do not fix merge conflicts. If you fail to resolve a merge correctly, your source tree (your source of truth!) is now wrong, and out of sync with your org. That will cause problems at some point whether or not you use delta deployments.


More broadly, you can use a plugin to generate delta deployment packages. I personally think this is a bad practice. I advocate for either deploying all metadata every time, or (as sfdcfox described) using inherently-versioned packaging rather than deploying unpackaged metadata.

6
  • Thanks David. This is not my current deployment procedure. The CI/CD example links that I have seen so far. They are packaging the entire folder force-app and then using shell scripts that run in the circleCi yaml file config to deploy it as a metadata package. The issue is not so much with GitHub, but with the recommended implementations that I have seen thus far.
    – thinker
    Commented Aug 2, 2021 at 16:57
  • 2
    If you are using source control correctly, deploying the entire force-app folder is not an overwrite risk.
    – David Reed
    Commented Aug 2, 2021 at 17:20
  • Correct, I changed my original post to state merge conflict.
    – thinker
    Commented Aug 2, 2021 at 18:01
  • 3
    Your post still includes a misunderstanding, unless you are using a source control system that does not follow the same principles as common DVCSs like Git. I've updated my answer to address that point.
    – David Reed
    Commented Aug 2, 2021 at 18:08
  • 1
    Yes, that's how Git performs merges.
    – David Reed
    Commented Aug 2, 2021 at 21:38
5

A "proper" CI/CD will deliver changes to dev orgs (note: Scratch Orgs or Sandboxes) using force:source:push. Delivery to a final package, or for QA/UAT should be through force:package:version:create and then force:package:install. If installing to production, you need force:package:version:promote before force:package:install.

Under no circumstances should you be using force:source:deploy to deploy your code to any org if you want just delta updates. Also, generally speaking, at most one branch per org/package should be the source for CI deployments. This means that if an old version was deployed, this should be a merge-conflict problem that you'd have to resolve on the branch before completing the Pull Request to merge into that branch.

5
  • force:source:push only work with scratch orgs, correct? I need to look into the other commands you have listed and see if I've missed something.
    – thinker
    Commented Aug 2, 2021 at 16:49
  • 1
    @thinker See the link in the answer, they added source tracking for Scratch Orgs, though only for Dev and Dev Pro. Deployment to a uat would be a force:package:install.
    – sfdcfox
    Commented Aug 2, 2021 at 16:51
  • 1
    @thinker Edited to clarify.
    – sfdcfox
    Commented Aug 2, 2021 at 16:52
  • So on force:package:version:create I didn't see anything that would create the package for only the changed files.
    – thinker
    Commented Aug 2, 2021 at 16:58
  • 1
    @thinker The delta occurs on install, not on package upload. This means that the files are compared to each other, and then only those metadata that need to be updated are updated. This ensures you always have the desired package contents, even across different orgs.
    – sfdcfox
    Commented Aug 2, 2021 at 17:00
1

Does the salesforce CLI have built in features that allow you to only deploy changes to a CI/CD pipeline?

The standard CLI does not have such features. At least for the time being. However you can install some 3rd party plugins into SFDX CLI that may have such features as sfdx git delta, however, it is not an official plugin.

If a developer pushes a folder to the repo with changes to File A, and I come behind their commit with an entire folder on File B, then my push will contain the old version of File A and create a merge conflict.

That indicates some wrong branching strategy or CICD as you are pushing your source branch components instead of either:

  • target branch after the merge with your source branch
  • the local merge outcome between your source branch and the target branch

How does a DevOps professional ensure that only files that are changed are the ones that go through the deployment process

They have a pipeline that does that for them. There are many approaches towards deploying to Salesforce. You have to pick the one that suits your needs.

There were already answers in this thread for unlocked package-based deployment so another example can be using only git diff-based deployment using the command:

sfdx force:source:deploy --sourcepath path/to/copied/modified/files

Before you use that command you should create a map/list of added/modified/deleted files in the last merge (pull request, assuming no fast-forward option)

git diff --oneline --name-status --no-renames HEAD^

Then you can code in the pipeline to copy these items into some temporary folder that will be then deployed. The real difficulty is to not only copy-paste these items but also figure out what is needed/missing. For instance when only one component of lwc will be modified, therefore deployed - the others will be erased so you would need to ensure in the pipeline that the whole folder is always copied.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .