Skip to content
Enhanced deployment automation for the Force.com platform
Java
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.settings
src
.classpath
.gitignore
LICENSE.md
README.md
circle.yml
pom.xml

README.md

ForceFlow is a simple library to automate build and deployment-related tasks on the Force.com platform. It is built on top of Apache Ant, so it can be used in combination with the Force.com migration tool and with any continuous integration or build solutions, such as Atlassian Bamboo or Jenkins CI.

Features so far

  • Schedule and abort Apex jobs
  • Manage remote site settings
  • Execute Apex code
  • Run Apex tests (with XML reports)
  • Insert and delete records
  • Support for flow deactivation and deletion (in conjunction with the Force.com migration tool)

Usage

Create a build file

If you are not familiar with Ant and you need a template for your script you can copy the one below.

<?xml version="1.0" encoding="UTF-8"?>
<project name="forceflow-sample" xmlns:ff="antlib:com.spaceheroes">

	<!-- 
	This assumes forceflow.jar is copied 
	in a folder named "lib"
	====================================== -->
	<path id="ant.additions.classpath">
		<fileset dir="./lib/" includes="*.jar"/>
	</path>
	<taskdef resource="antlib.xml" uri="antlib:com.spaceheroes" classpathref="ant.additions.classpath" />
	
	<!--
	You can now define Ant targets and 
	use any ForceFlow tasks within.
	====================================== -->

</project>

Execute Apex code

You can execute an Apex script as follows.

<ff:apex username="..." password="..." serverurl="...">
	<![CDATA[		
		List<Contact> cts = [SELECT id,Email FROM Contact WHERE (Email<>null AND (NOT Email LIKE '%.nospam'))];
		for (Contact ct : cts) { 
			ct.Email = ct.Email + '.nospam'; 
		}
		update cts;
	]]>
</ff:apex>

Remote Site Settings

Use this to create or update remote site settings.

<ff:remotesite name="Google_APIs" url="https://www.googleapis.com" disableProtocolSecurity="true" username="..." password="..." serverurl="...">
	Allows queries to the Google Maps API
</ff:remotesite>

Clear scheduled jobs

Use this tag to abort all the jobs that are currently scheduled.

<ff:clearschedule username="..." password="..." serverurl="..." /> 	

Use this tag to abort specific jobs that are currently scheduled.

<ff:clearschedule scheduleName="..." username="..." password="..." serverurl="..." />  

Schedule an Apex job

You can use this task to schedule the execution of a batch class.

<ff:scheduleapex username="..." password="..." serverurl="..." className="MySchedulableClass" cron="0 0 12 1/1 * ? *" />
or
<ff:scheduleapex username="..." password="..." serverurl="..." scheduleName="..." className="MySchedulableClass" cron="0 0 12 1/1 * ? *" />    

Insert a record

Works with both objects and custom settings.

<ff:insert object="Contact" username="..." password="..." serverurl="...">
	<property name="FirstName" value="Some"/>
	<property name="LastName" value="Dude"/>
	<property name="Email" value="somedude@salesforce.com"/>
</ff:insert>

Delete all records

You can delete all the records from an object or a custom settings. It's bulkified, so it works also with very large tables.

<ff:deleteall object="Contact" username="..." password="..." serverurl="..."/>

Run all tests (with XML test report)

Generates a full test report in the JUnit XML format (output file: test-report.xml). This report can be read by Atlassian Bamboo to display test results of a build.

<ff:runtests username="..." password="..." serverurl="..." />

Deactivate flows

It's possible to use ForceFlow in composition with the Force Migration Tool to deactivate all flows in a Salesforce organisation.

<target name="deactivateFlows">
       
    <delete dir="temp"/>

    <!-- Retrieve all the existing flows from the target org -->
    
    <ff:createFlowRetrieveAllManifest 
    	destinationPath="temp/existing" />
    
    <sf:retrieve 
        username="${sf.username}" 
        password="${sf.password}" 
        serverurl="${sf.serverurl}" 
        retrieveTarget="temp/existing" 
        unpackaged="temp/existing/package.xml"/>

    <!-- ForceFlow can then create an ad-hoc package to inactivate all the flows.
    	 such package can be deployed using the Force.com migration tool -->
	 
    <ff:createFlowInactivateManifest 
        sourcePath="temp/existing"  
        destinationPath="temp/inactivation" />
        
    <sf:deploy 
        username="${sf.username}" 
        password="${sf.password}" 
        serverurl="${sf.serverurl}" 
        deployRoot="temp/inactivation" />

    <delete dir="temp"/>
</target>

Delete Flows

It's possible to create an extra task that deletes flows. Bare in mind deactivation is required before deleting flows, so the two targets should be chained.

<target name="deleteFlows" depends="deactivateFlows">

	<delete dir="temp"/>
	
	<!-- Retrieve all the existing flows from the target org -->
	
	<ff:createFlowRetrieveAllManifest destinationPath="temp/existing" />
	<sf:retrieve 
		username="${sf.username}" 
		password="${sf.password}" 
		serverurl="${sf.serverurl}" 
		retrieveTarget="temp/existing" 
		unpackaged="temp/existing/package.xml" />

    <!-- ForceFlow can then create an ad-hoc destructiveChanges to delete all the flows.
    	 such destructive package can be deployed using the Force.com migration tool -->

        <ff:createFlowDeleteManifest 
		sourcePath="temp/existing" 
		destinationPath="temp/delete" />
        
	<sf:deploy 
		username="${sf.username}" 
		password="${sf.password}" 
		serverurl="${sf.serverurl}" 
		deployRoot="temp/delete" 
		ignoreWarnings="true" />
	
        <delete dir="temp"/>
    </target>

License

ForceFlow is available under the MIT license. Please see the LICENSE for details.

You can’t perform that action at this time.