I've started using Processes and Flows and am really excited about these features -- but am still wrapping my mind about how to manage them in Version Control (which I use) and Continuous Integration (which I don't yet... but am trying to work in that direction).

The underlying challenge is that each time a process or flow is edited, the metadata file is renamed to reflect its update version, e.g. MyFlow-1.flow, MyFlow-2.flow, etc.

The Challenge for Version Control

If each version of the flow has its own file name, this makes it more complicated to track changes to flows. It seems like there could be two strategies here:

  1. Rename the files to remove the version number. I'd need a script to run through my src folder pre-commit, and remove the number so that my file name is always MyFlow.flow. This is an annoying extra step, but makes version control simpler. On the other hand, it probably makes deployment much harder.

  2. Track each file in version control with its original name. We'd need to be diligent about deleting MyFlow-1 in the commit where we add MyFlow-2 so that git would recognize this as a rename/move and show helpful diffs. Otherwise, the whole file appears to change with every change, which makes version control rather less useful.

The Challenge for Deployment/Continuous Integration

From my experiments so far, once a flow has been activated in a given environment, the metadata file can't be deployed again (either it is currently active, or has been active in the past and superseded).

That means that I need to prevent my previous flow versions from being included in a deployment package (either by not tracking them at all, or by using a script to delete earlier versions). I also need some way to determine whether the current version (in my repo) should be included in the deployment payload for a given environment or not.

I could imagine a script that (1) downloads flows from the target environment, and removes *.flow files from the payload if they already exist in the target environment, but that feels complicated. And it's even harder if I've removed the version numbers from my flow files.

Are you using flows in VS or CI? How are you managing these issues?

Note: I'm not sure whether VC and CI should be one question or two - depends on how integrated the strategy for dealing with these two challenges. If you think these should be separate questions, comment and I'll re-post.

  • 1
    I'm pretty sure that git hooks can do the first bit. The easiest-to-write hook would fail if there are are any duplicate flow names. – Charles Koppelman Mar 17 '15 at 4:58
  • Did you ever get solutions/workarounds for these issues? Looking at getting proc builder & flow into our CI environment right now and it looks to be a big pain. – jkraybill May 6 '15 at 1:23
  • Haven't gotten any good solutions. We're currently using my option (2), but aren't doing CI yet, and have a manual step in our deployment process to deal with the flows & processes. – Benj May 6 '15 at 2:14
  • 1
    There's a bit more helpful information about this still-unsolved issue at salesforce.stackexchange.com/a/81948/8748. – abd3721 Oct 28 '15 at 2:27

The trick is to disable the deployment of the flows with build property. Let say you want to skip flows deployment normally and just deploy them if they don't exist. You have to do following steps:

  1. Add following snippet to you src/package.xml

       <!--TO_REMOVED-->
       <types>
         <members>My_Flow-33</members> 
         <name>Flow </name>
       </types>
       <!--TO_DELETE-->

  1. Use following ant code

    <target name="flowRequired">
        <condition property="includeFlow">
            <equals arg1="${deployFlow}" arg2="true"/>
        </condition>
    </target>

    <target name="deployFlow" unless="includeFlow"  depends="flowRequired">
        <replace file="src/package.xml">
            <replacefilter value="" token="TO_REMOVED--"/>
        </replace>        
        <replace file="src/package.xml">
            <replacefilter value="" token="!--TO_DELETE"/>
        </replace> 
    </target>

In this setting if you don't pass parameter deployFlow or set it to false to you ant script it will replace the values in a way that that section becomes a comment in your package.xml file.

This is not a complete answer, but I'm putting it here in case this idea helps anyone else get a better picture.

FlowDefinition is metadata about the Flows (it sort of relates to Flows the same way that .cls-meta.xml relates to .cls files, and I'm not sure why it was modeled so differently).

The FlowDefinition file (spec) looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<FlowDefinition xmlns="http://soap.sforce.com/2006/04/metadata">
    <activeVersionNumber>5</activeVersionNumber>
</FlowDefinition>

If you track the FlowDefinition in git, you can use ant (or git) to add the proper suffix to your versioned file.

This means the process could look something like this:

  1. In our workspace, we just deal with the flow with suffix.
  2. A git filter:
    • on clean: drops the flow suffix when you stage flows if the suffix matches what's in the FlowDefinition (otherwise, you might overwrite an old version).
    • on smudge: appends the flow suffix from the FlowDefinition
    • Caveat: This is not necessarily a proper git filter since it violates the warning in the man file:

      In other words, the intent is that if someone unsets the filter driver definition, or does not have the appropriate filter program, the project should still be usable.:

  3. If you are deploying from the cloud, you'd need an ant task preprocessor that references FlowDefinition, appends the proper suffix to the flow, and also drops old flow versions.

I'm not sure this would work, but I think the FlowDefinition will help get somewhere workable.

There are two places this falls apart: First, if a flow is inactive, it won't have a FlowDefinition activeVersionNumber. I'm not even sure what the expected behavior is. Second, if a new version of the flow is in development but the old version is still active, you're basically toast. However, I'm not sure why a dev shop would operate that way, and I think it should be discouraged, so I don't mind this.

If anyone gets any further on this, please be in touch.

  • This might leave a little graveyard of deactivated MyFlow-1, MyFlow-2, etc. if the committer isn't careful to delete these, but it's an irrelevant graveyard since version control will be on MyFlow. Maybe you can .gitignore those? – Charles Koppelman Nov 4 '15 at 15:57
  • Really interesting approach. Why not use pre-commit/post-checkout rather than smudge & clean? That could allow you to prevent users from committing the numbered flows in the first place. If you wanted, you could also prevent committing a flow if it doesn't have a matching flow defintion. – Benj Nov 23 '15 at 18:07
  • @Benj That's a good question. I think that preventing committing a flow without a matching FlowDefinition is probably a good start. But to answer the original question, I pursued the hook approach briefly but couldn't find a way to rename files using git hooks. Also, a pre-commit hook that pukes when you commit something matching /-\d+\.flow/i would be useful for implementing this approach. – Charles Koppelman Nov 23 '15 at 18:22
  • Am I missing something on this? As far as I can tell, this won't work in an environment where the same flow is deployed multiple times, such as CI. – Nick Cook Jul 15 '16 at 3:50

It looks like this answer is properly coming in v44.0 (Winter '19):

Per release notes

When you retrieve or deploy the latest version of a flow, Salesforce no longer adds a number to the end of each flow name. Before you deploy flow metadata using API version 44.0, upgrade your flow files with Metadata API or Salesforce CLI or both to remove the version numbers.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.