cumulusci.yml file is located in the project root directory. This
is where you define project dependencies, configure new tasks and flows,
customize standard tasks and flows for your project, and so much more!
cumulusci.yml file contains these top-level sections.
project: Contains information about the project’s associated package (if any) and GitHub repository. This section is largely generated by running
cci project init.
If you need custom markup that’s unique to your project, you can store it in a section called
tasks: Defines the tasks that are available to run in your project. See Task Configurations for configuration options in this section.
flows: Defines the flows that are available to run in your project. See Flow Configurations for configuration options in this section.
sources: Defines other CumulusCI projects whose tasks and flows you can use in automation. See Tasks and Flows from a Different Project for more information.
orgs: Defines the scratch org configurations that are available for your project. See Scratch Org Configurations for configuration options in this section.
plans: Contains any custom plans defined to install your project into a customer org. See the metadeploy_publish task for more information.
Each task configuration under the
tasks section of your
cumulusci.yml file defines a task that can be run using the
cci task run command, or included in a flow step. With a few simple
changes to this section, you can configure build automation
functionality to suit your project’s specific needs.
Override a Task Option#
If you repeatedly specify the same value for an option while running a task, you can configure CumulusCI to use that value as a default value.
For example: Let’s enforce a 90% code coverage requirement for Apex
code in your project. The
run_tests task, which executes all Apex
tests in a target org, can enforce code coverage at a given percentage
by passing the
run_tests: options: required_org_code_coverage_percent: 90
tasks section of the
cumulusci.yml file specifies this
option, CumulusCI overrides the default option with a value of
Whenever this task is executed, its customized options apply, unless
it’s further configured for a particular flow step.
Verify the change by looking for a default option value when running
cci task info <name>.
$ cci task info run_tests run_tests Description: Runs all apex tests Class: cumulusci.tasks.apex.testrunner.RunApexTests Command Syntax $ cci task run run_tests Options . . . -o required_org_code_coverage_percent PERCENTAGE Optional Require at least X percent code coverage across the org following the test run. Default: 90
Add a Custom Task#
To define a new task for your project, add the task name under the
tasks section of your
For example, let’s create a custom task named
deploys a set of reports stored in your project’s unpackaged metadata
First, look up the Python class associated with the standard task
deploy. From there we see that the
deploy task has a
Store the task under the
tasks section of the
deploy_reports: description: Deploy Reports class_path: cumulusci.tasks.salesforce.Deploy group: projectName options: path: unpackaged/config/reports
Be sure to include the value we retrieved for
consider adding a common
group attribute to make it easier to see the
tasks specific to your project when running
cci task list.
Congratulations! You created a new custom task in CumulusCI.
If you’ve built a custom task in Python, you can make it available to
the project by adding the task under the
tasks section of the
cumulusci.yml file. (Let’s assume that your task’s class is named
MyNewTaskClassName and exists in the file
tasks: my_new_task: description: Description of the task class_path: tasks.task_file.MyNewTaskClassName group: projectName
Use Variables for Task Options#
To reference a project configuration value within the
tasks section of
cumulusci.yml file, use the
For example, NPSP uses a variable for the project’s namespace by
setting a value of
variable is then referenced in the project’s custom
task where it’s passed as the value for the
A double underscore (
__) refers to a subsequent level in the
deploy_qa_config: description: Deploys additional fields used for QA purposes only class_path: cumulusci.tasks.salesforce.Deploy group: Salesforce Metadata options: path: unpackaged/config/qa namespace_inject: $project_config.project__package__namespace
In this instance, CumulusCI replaces the variable with the value under
project -> package -> namespace in the
cumulusci.yml file. Here is
project section of NPSP’s
cumulusci.yml file specifying
as the namespace value.
project: name: Cumulus package: name: Cumulus name_managed: Nonprofit Success Pack namespace: npsp api_version: 48.0 install_class: STG_InstallScript uninstall_class: STG_UninstallScript
Each flow configuration listed under the
flows section of your
cumulusci.yml file defines a flow that can be run using the
cci flow run command, or included as a step in another flow. With a
few simple changes to this section, you can configure sophisticated
build automation that execute workflows throughout your development
Add a Custom Flow#
To define a new flow for your project, add the flow name under the
flows section of your
cumulusci.yml file. Let’s define a new
greet_and_sleep: group: projectName description: Greets the user and then sleeps for 5 seconds. steps: 1: task: command options: command: echo 'Hello there!' 2: task: util_sleep
This flow is comprised of two tasks:
command greets the user by
echoing a string, and
util_sleep then tells CumulusCI to sleep for
You can reference how flows are defined in the universal cumulusci.yml file.
Add a Flow Step#
To add a step to a flow, first run
cci flow info <name> to see the
existing steps. In the following example we run this for the
$ cci flow info dev_org Description: Set up an org as a development environment for unmanaged metadata 1) flow: dependencies [from current folder] 1) task: update_dependencies 2) task: deploy_pre 2) flow: deploy_unmanaged 0) task: dx_convert_from when: project_config.project__source_format == "sfdx" and not org_config.scratch 1) task: unschedule_apex 2) task: update_package_xml when: project_config.project__source_format != "sfdx" or not org_config.scratch 3) task: deploy when: project_config.project__source_format != "sfdx" or not org_config.scratch 3.1) task: dx_push when: project_config.project__source_format == "sfdx" and org_config.scratch 4) task: uninstall_packaged_incremental when: project_config.project__source_format != "sfdx" or not org_config.scratch 3) flow: config_dev 1) task: deploy_post 2) task: update_admin_profile 4) task: snapshot_changes
Of this flow’s four steps, the first three are themselves flows, and the last is a task.
All non-negative numbers and decimals are valid as step numbers in a flow. You can add steps before, between, or after existing flow steps.
The following shows examples of values that you would use for the various scenarios:
Add a step before step 1 by inserting a step number greater than or equal to zero and less than 1 (such as 0, 0.3, or even 0.89334).
Add a step between steps 2 and 3 by inserting a step number greater than 2 or less than 3.
Add a step after all steps in the flow by inserting a step number greater than 4.
You could also customize the
dev_org flow to output an additional log
line as its final step:
dev_org: steps: 5: task: log options: line: dev_org flow has completed
Skip a Flow Step#
To skip a flow step, set the task or flow for that step number to the
For example, to skip the fourth step of the
dev_org flow, insert this
code under the
flows section of your
dev_org: steps: 4: task: None
task must be used when skipping a flow step that is a task.
flow must be used when skipping a flow step that corresponds
to a flow.
When CumulusCI detects a task or flow with a value of
None, the task
or flow is skipped.
Replace a Flow Step#
Replacing a flow step is easy; just note the name of the flow, step number, and task or flow you would like to run on the given step.
For example, to replace the default fourth step of the
with a custom task that loads data into a dev environment, specify the
custom task to run instead.
dev_org: steps: 4: task: load_data_dev
Configure Options on Tasks in Flows#
Specify options on specific tasks in a flow with this syntax:
<flow_to_modify>: steps: <step_number>: flow: <sub_flow_name> options: <task>: <option_name>: <value>
Replace all objects with
<> with the desired values.
For example, let’s examine the definition of the
ci_master flow from
ci_master: group: Continuous Integration description: Deploy the package metadata to the packaging org and prepare for managed package version upload. Intended for use against main branch commits. steps: 1: flow: dependencies options: update_dependencies: resolution_strategy: production 2: flow: deploy_packaging 3: flow: config_packaging
This flow specifies that when the subflow
dependencies runs, the
resolution_strategy option has a value of
production for the
update_dependencies task (which itself executes in the
when clause in a flow step to conditionally run that step. A
when clause is written in a Pythonic syntax that should evaluate to a
You can use the
project_config object to reference values from the
cumulusci.yml file to help with creation of the
condition. You can use the double underscore (
__) syntax to indicate
values at subsequent levels of the file. For example, you can reference
a project’s namespace with
You can also reference values on the
org_config object in
clauses. For example, it’s common to reference
when building automation that needs to behave differently in a scratch
org and a persistent org.
when clauses are frequently used in CumulusCI’s standard library to
conditionally run a step in a flow based on the source code format of
the project. Below is the configuration for the standard library flow
update_package_xml task will execute
only if the project’s source code format is not equal to “
build_feature_test_package: group: Release Operations description: Create a 2gp managed package version steps: 1: task: update_package_xml when: project_config.project__source_format != "sfdx" 2: task: create_package_version options: package_type: Managed package_name: $project_config.project__package__name Managed Feature Test version_base: latest_github_release version_type: minor skip_validation: True
See Use Variables for Task Options for more information.
Tasks and Flows from a Different Project#
It’s also possible to use tasks and flows from another project with
CumulusCI. The other project must be named under the
of the project
For example, when tasks or flows are referenced using the
namespace, CumulusCI fetches the source from the NPSP GitHub repository.
sources: npsp: github: https://github.com/SalesforceFoundation/NPSP
By default, CumulusCI uses the resolution strategy
will fetch the most recent production release, or the default branch if
there are no releases. By specifying
resolution_strategy, the behavior
can be changed to match desired dependency resolution behavior, such as
using beta releases or retrieving feature test packages from a commit
status. See for
more details about resolution strategies.
This feature requires that the referenced repository be readable (for example, it’s public, or CumulusCI’s GitHub service is configured with the token of a user who has read access to it).
It’s also possible to fetch a specific
release is one of
latest_beta. For example:
sources: eda: github: https://github.com/SalesforceFoundation/EDA release: latest npsp: github: https://github.com/SalesforceFoundation/NPSP tag: rel/3.163
You can also select a specific
branch. We recommend that most projects, however, use a resolution strategy.
When the repo is listed under
sources, it’s possible to run a task
$ cci task run npsp:robot
Or a flow…
$ cci flow run npsp:install_prod
Or even create a new flow that uses a flow from NPSP:
flows: install_npsp: steps: 1: flow: npsp:install_prod 2: flow: dev_org
This flow uses NPSP’s
install_prod flow to install NPSP as a managed
package, and then run this project’s own
Scratch Org Configurations#
This section defines the scratch org configurations that are available
without explicitly running
cci org scratch to create a new
configuration. For more information on using scratch orgs with
CumulusCI, see Manage Scratch Orgs.
Override Default Values#
These overrides pertain only to scratch orgs.
You can override these values for your org.
days(integer): Number of days for the scratch org to persist.
namespaced(boolean): Is the scratch org namespaced or not. Applies only to managed package projects.
config_file(string): Path to the org definition file to use when building the scratch org.
orgs: scratch: <org_name>: <key>: <value>
Replace all objects with
<> with the desired values.
For example, override the default number of days from 7 to 15 in the
orgs: dev: days: 15
CumulusCI merges multiple YAML files that enable
configuration at several distinct scopes. All of these files have the
cumulusci.yml, but live in different locations in the file
You can configure files at these scope levels: Project, Local Project and Global. Configurations have an order of override precedence (from highest to lowest):
One override only cascades over another when two configurations set a value for the same element on a task or flow.
Take for example, task
T which takes two options,
You can specify a default value for
opt1 in your project
cumulusci.yml file and a default value for
opt2 in your global
cumulusci.yml file, and you’ll see the expected result: both values
are available in the project. (The default of
opt1 is not exposed to
If you change your project
cumulusci.yml file to also specify a
default value for
opt2, this new default
opt2 value takes precedence
over the default
opt2 value specified in your global
cumulusci.yml file lives in the project root directory and
applies solely to this project. Changes here are committed back to a
remote repository so other team members can benefit from the
customizations. Configurations in this file apply solely to this
project, and take precedence over any configurations specified in the
cumulusci.yml file, but are overridden by configurations in the
Local Project Configurations#
Configurations in this
cumulusci.yml file apply solely to the project
with the given <projectname>, and take precedence over _all other
configuration scopes. If you want to make customizations to a project,
but don’t need them to be available to other team members, make those
Configuration of all CumulusCI projects on your machine.
Configurations in this file have a low precedence, and are overridden by
all other configurations except for those that are in the universal
There is one more configuration file that exists: the universal cumulusci.yml file that ships with CumulusCI itself. This file actually holds the lowest precedence of all, as all other scopes override this file’s contents. That said, it contains all of the definitions for the tasks, flows, and org configurations that come standard with CumulusCI.
cci task info and
cci flow info display all of the
information about a task’s or flow’s configuration. They display the
information in the standard library alongside any customizations defined
in your cumulusci.yml file.
Reference Task Return Values#
Current task return values are not documented, so finding return values set by a specific task (if any) requires you to read the source code for the given task.
It is sometimes useful for return values to be used as input by a subsequent task in the context of a flow. Tasks can set arbitrary return values on themselves while executing. These values can then be referenced by subsequent tasks in a flow.
To reference a return value on a previous task use the following syntax:
To discover what’s available for
return_value, find the source code
for an individual task in the CumulusCI
For example, let’s examine how CumulusCI defines the standard
upload_beta task in the universal
upload_beta: description: Uploads a beta release of the metadata currently in the packaging org class_path: cumulusci.tasks.salesforce.PackageUpload group: Release Operations
To see if anything is being set on
self.return_values, find the file
that defines the class
little digging yields that this class is defined in the file
and has a method called
self.return_values to a dictionary with these keys:
Now look at the standard
release_beta flow defined in the universal
release_beta: description: Upload and release a beta version of the metadata currently in packaging steps: 1: task: upload_beta options: name: Automated beta release 2: task: github_release options: version: ^^upload_beta.version_number 3: task: github_release_notes ignore_failure: True ## Attempt to generate release notes but don't fail build options: link_pr: True publish: True tag: ^^github_release.tag_name include_empty: True version_id: ^^upload_beta.version_id 4: task: github_master_to_feature
This flow shows how subsequent tasks can reference the return values of
a prior task. In this case, the
github_release task uses the
version_numer set by the
upload_beta task as an option value with
^^upload_beta.version_number syntax. Similarly, the
github_release_notes task uses the
version_id set by the
upload_beta task as an option value with the
cci task info <name> and
cci flow info <name> to see how a given
task or flow behaves with current configurations.
For example, the
util_sleep task has a
seconds option with a default
value of 5 seconds.
$ cci task info util_sleep util_sleep Description: Sleeps for N seconds Class: cumulusci.tasks.util.Sleep Command Syntax $ cci task run util_sleep Options -o seconds SECONDS Required The number of seconds to sleep Default: 5
To change the default value to 30 seconds for all projects on your
machine, add the desired value in your global
tasks: util_sleep: options: seconds: 30
cci task info util_sleep shows a default of 30 seconds.
$ cci task info util_sleep util_sleep Description: Sleeps for N seconds Class: cumulusci.tasks.util.Sleep Command Syntax $ cci task run util_sleep Options -o seconds SECONDS Required The number of seconds to sleep Default: 30
Displaying the active configuration for a given task or flow can help with cross-correlating which configuration scope affects a specific scenario.
cci task info and
cci flow info commands show information about
how a task or flow is currently configured. The information output by
these commands change as you make further customizations to your