I want to take my company to the next level - and start implementing Version Control and also CI/CD workflow process.

I tried investigating a bit, and also start working with BitBucket - but just found myself wondering about the best strategy to manage the transition.

Today, we are small team (2 developers and few admins), and we are all working on the same enviroment (full sandbox - due to data dependency for new development testing).

Also, because we are 2 developers who are working on the same enviroment - there can be code conflicts or if we both working on the same class - even overwritten each other code.

I want to understand - what is the approach in which I should build my strategy ? Important to say that we are not doing any changes directly on Prod - but only on full, and after qa - moving the changes to Production.

Also, for the start - I just want to implement this process for the dev team. Should we create different sandbox for each developer and pulling any changes from the main repository ? Also, what is the best way to manage my repository ? Should I create Branch for each of the sandbox above ?

Any help we be appreciated. Thanks !

3 Answers 3


You should Google and find out more about SFDX and scratch orgs as these tools were designed for "version control first" development. Each developer can create short-lived scratch orgs and your CI can do the same. But this does require your work to only have dependencies on a reasonably easy to re-create target environment. So you need to look into that first and work out how to automatically create the minimum required base environment (of both components and data). The good news is that SFDX includes lots of features to help automate that.

In the version control, yes you can create branches per feature or per release or per developer. I recommend that you keep things simple though: branches are easy to create but branch merges can become a nightmare. Favour short-lived focussed branches (a day or two) that all get merged into a simple mainline setup. Keep this illustration by Jonny LeRoy in mind when thinking about branches:

branches diverge

Where I work, we typically create a branch per feature, then use a pull request for the code review, then merge to the long-lived branch.

If you are using managed packages, then the upgrade path for those constrains what you can change and so is a significant constraint for what you can and cannot do as far as long-lived branches in version control. Typically you need just a mainline branch and a branch per patch version.


On Continuous Integration (CI), we did some work for Jenkins (as we were already using that) to cut down on repeated logic as we have many projects that is available here https://claimvantage.github.io/sfdx-jenkins-shared-library/.

If we were starting from scratch, we may well have picked a different CI system e.g. CumulusCI.

And FYI, we use GitHub.

  • Worth noting that git is a good choice for VCS and works well with sfdx. You can then choose from on-premise, GitHub, Bitbucket etc. as you see fit. Worth noting that if you select Bitbucket you can use "pipelines" for the CI handling - however, given how long it can take to create a scratch org and push all your metadata then run all unit tests you will quickly run out of free "CPU" minutes and will find you have to pay (despite the fact that the Bitbucket pipeline processing is simply waiting for response from Salesforce 90% of the time).
    – Phil W
    Oct 30, 2020 at 9:34
  • 1
    Hi Phil, Think you should move these comments to another answer (that would get my +1).
    – Keith C
    Oct 30, 2020 at 9:37

As Keith C stated in his excellent answer, there are some good sources for detail on use of SFDX, leveraging scratch orgs.

My tuppence extra is that selecting git as your VCS is a great choice; many IDEs support git (including VSCode and IntelliJ IDEA, both of which can be used for Salesforce development) and you'll find many Salesforce-related resources in public git repositories.

Which git implementation you select comes down to personal/corporate choice. However, in order to support CI (e.g. on attempt to merge a PR to your master or patch branches) you need one that allows you to execute scripted processing.

We use Bitbucket with "pipelines" - we have a Docker image for CLI use of sfdx during pipeline execution. The majority of the time spent executing the pipeline is actually spent waiting for Salesforce to create a scratch org, then waiting for sfdx to finish pushing all the metadata and finally waiting for sfdx to complete executing the unit tests.

Whilst Bitbucket comes with free "CPU minutes" for pipeline execution, you'll find these are used up really quickly - though YMMV - and you'll have to pay for the minutes the CI executes for (even though all the real CPU usage is on the Salesforce side, not in Bitbucket).

In terms of a branching strategy, since we develop and maintain a managed package we have patch branches as well as the master branch.

We use a branch per bug, task or user story. When the code is ready we use a PR (pull request) to get it reviewed, and then (on success) the PR is merged, triggering the CI.

NB: When necessary we back-port a bug fix to a patch branch by creating a bug-specific branch against the patch branch, cherry pick the fix commit back, create a PR and merge it. We have blocked direct commits to master and the patch branches which is why we always use a PR.

Every time we have a new branch (or when CI is executed) we also create a new scratch org. It is to the scratch org that we push all the metadata.

Developers always use the scratch orgs for any development against the bug fix, task or user story they are working on, and only that developer accesses this scratch org (except in a new specific cases). All our unit tests generate all the test data they need and we have some Apex for generating data to give something for the developer to play with.

Our CI is all about ensuring that the latest versions of the code, in master and in patch branches, have no test failures and have enough test coverage. We don't ever push our metadata directly to any orgs other than scratch orgs. The creation of the package is handled separately (though still based on the content of git). As such, developers never push anything to any sandboxes or production environments. This is something only done once we have an official package release available, and is done by the implementers rather than developers.

  • Hi Phil - thanks for your response. Currently we are working with IntlliJ IDE - and as I saw, it works really good with BitBucket. For now, we are not looking for CI/CD to Production. What I really want to understand is how should the work process should look like - meaning, the fact that we are 2 developers, where each one develop his own stuff (currenly on the same enviroment) - and want to avoid code conflict but at the same time - keeping our work up to date. Do we need to create 2 different sandbox for each developer ? And if so, how can I achieve my goal ?
    – Omnia
    Oct 31, 2020 at 8:07
  • I have extended my answer to address some of what you ask about. You don't need to use sandboxes.
    – Phil W
    Oct 31, 2020 at 14:36

Although Keith and Phil answers are great, personally I want to touch your current setup.

  1. Developing on Full Sandbox is... controversial idea. You can refresh sandbox only once a month. That means if one of devs/admins would make some changes which will for example completely alter your data, you will be blocked with full fledged performance testing for example.
  2. There are two paths currently which can be used in terms of diving work to separate environments for each developer.
    • Sandboxes (developer)
    • Scratch orgs (sfdx approach)

Scratch orgs were described already. Those have one con currently (which I hope would be 'fixed' when shape orgs would be out of beta). You cannot create metdata/settings copy of your production. You need to at least once setup everything manually, turning on needed features of an org for example. Sandbox is ready to use, but still you will need to turn something on if it's not available on production. Ideally you will need to creat config file for a scratch org and data loading scripts + data to load (so you can play with it like on your full org). It takes time. But it's worth of your time.

In terms of setup of an orgs for development, testing etc. Different comapnies have different approach. I can share on of the setups I've used, basing solely on sandboxes.

  • Production
  • Full sandbox used for final testing
  • UAT (developer pro) which was used for... acceptance testing by client. In your case probably redundant.
  • QA (developer pro -> more storage limits) for our internall testing.
  • One sandbox per developer/consultant(admin). Developer type one.

CI + Branching We had

  • Master/Production branch for final changes. From this branch, changes were deployed into prod.
  • UAT (not needed for you)
  • QA branch. CI was set to deploy from this branch for example 4 times a day to a QA sandbox.
  • Development branch. All feature branches were merged here after creating Pull request and passing code review. CI after merging pull request was either running validation run against QA sandbox or running deploy to CI sandbox which was additional one only for testing deploys (we had a lot of issues with validations for some time)
  • Feature branches which were branches for each developer developing a new feature.

This is only an example. In your case it would be sufficient to have scratch orgs for developers, than QA sandbox for testing and then full for final tests. If you are brave you can use Full for everything. (I do not recommend it though)

  • Using the features, um, feature we can turn on all the features we need on our scratch orgs at creation, except for setting up shield encryption the needed a small amount of scripting. This wasn't an issue for us since sfdx supports anonymous apex execution, so just became part of the over-all flow for creating the dev or CI environment.
    – Phil W
    Oct 31, 2020 at 16:46
  • Additionally, I see no need to do a "four times a day" approach if your git system supports scripted execution on PR creation or when merge is requested (Bitbucket supports this, as I believe does GitHub). Simply look out for appropriate events and run the CI build and test process. Of course, there is still a need for actual QA, but that is something you can do before final release to production, in a freshly created QA org (we use scratch orgs for this too, albeit with different scripting since we want to install the package not push the metadata).
    – Phil W
    Oct 31, 2020 at 16:51
  • And of course there is UAT that allows you to check, on a sandbox, that things like package upgrades work.
    – Phil W
    Oct 31, 2020 at 16:52
  • I agree with everything. What I've described is super simple setup. Why 4 times a day? We were limited with jenkins executors. Only 2.... Therefore most of the time both of them were occupied. You can do more or less everything with scripting the problem is that you need to write those scripts. And our op have small team. KISS :) Oct 31, 2020 at 18:45
  • Scratch orgs make sure you have a clean org with exactly the metadata you require. It is the most robust way to validate what you have in git works.
    – Phil W
    Oct 31, 2020 at 22:23

You must log in to answer this question.

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