cumulusci.core package


exception cumulusci.core.exceptions.AntTargetException[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raised when a generic Ant target error occurs

exception cumulusci.core.exceptions.ApexCompilationException[source]

Bases: cumulusci.core.exceptions.CumulusCIFailure

Raise when apex compilation fails

exception cumulusci.core.exceptions.ApexException[source]

Bases: cumulusci.core.exceptions.CumulusCIFailure

Raise when an Apex Exception is raised in an org

exception cumulusci.core.exceptions.ApexTestException[source]

Bases: cumulusci.core.exceptions.CumulusCIFailure

Raised when a build fails because of an Apex test failure

exception cumulusci.core.exceptions.BrowserTestFailure[source]

Bases: cumulusci.core.exceptions.CumulusCIFailure

Raise when browser tests fail

exception cumulusci.core.exceptions.BulkDataException[source]

Bases: cumulusci.core.exceptions.CumulusCIFailure

Raise for errors from bulkdata tasks

exception cumulusci.core.exceptions.CommandException[source]

Bases: cumulusci.core.exceptions.CumulusCIFailure

Raise for errors coming from spawned CLI subprocesses

exception cumulusci.core.exceptions.ConfigError(message=None, config_name=None)[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raised when a configuration enounters an error

exception cumulusci.core.exceptions.ConfigMergeError(message=None, config_name=None)[source]

Bases: cumulusci.core.exceptions.ConfigError

Raised when merging configuration fails.

exception cumulusci.core.exceptions.CumulusCIException[source]

Bases: Exception

Base class for all CumulusCI Exceptions

exception cumulusci.core.exceptions.CumulusCIFailure[source]

Bases: cumulusci.core.exceptions.CumulusCIException

An exception representing a failure such as a Metadata deployment failure or a test failure. CI systems can handle these to determine fail vs error status

exception cumulusci.core.exceptions.CumulusCIUsageError[source]

Bases: cumulusci.core.exceptions.CumulusCIException

An exception thrown due to improper usage which should be resolvable by proper usage

exception cumulusci.core.exceptions.DependencyResolutionError[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raised when an issue is encountered while resolving a static dependency map

exception cumulusci.core.exceptions.DeploymentException[source]

Bases: cumulusci.core.exceptions.CumulusCIFailure

Raised when a metadata api deployment error occurs

exception cumulusci.core.exceptions.FlowConfigError[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raised when a flow configuration encounters an error

exception cumulusci.core.exceptions.FlowInfiniteLoopError[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raised when a flow configuration creates a infinite loop

exception cumulusci.core.exceptions.FlowNotFoundError[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raise when flow is not found in project config

exception cumulusci.core.exceptions.FlowNotReadyError[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raise when flow is called before it has been prepared

exception cumulusci.core.exceptions.GithubApiError[source]

Bases: cumulusci.core.exceptions.CumulusCIException

exception cumulusci.core.exceptions.GithubApiNoResultsError[source]

Bases: cumulusci.core.exceptions.CumulusCIException

exception cumulusci.core.exceptions.GithubApiNotFoundError[source]

Bases: cumulusci.core.exceptions.CumulusCIException

exception cumulusci.core.exceptions.GithubApiUnauthorized[source]

Bases: cumulusci.core.exceptions.CumulusCIException

exception cumulusci.core.exceptions.GithubException[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raise for errors related to GitHub

exception cumulusci.core.exceptions.KeychainKeyNotFound[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raised when the keychain key couldn’t be found

exception cumulusci.core.exceptions.KeychainNotFound[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raised when no keychain could be found

exception cumulusci.core.exceptions.NamespaceNotFoundError[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raise when namespace is not found in project includes

exception cumulusci.core.exceptions.NotInProject[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raised when no project can be found in the current context

exception cumulusci.core.exceptions.OrgNotFound[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raised when no org could be found by a given name in the project keychain

exception cumulusci.core.exceptions.ProjectConfigNotFound[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raised when a project is found in the current context but no configuration was found for the project

exception cumulusci.core.exceptions.ProjectMinimumVersionError[source]

Bases: cumulusci.core.exceptions.CumulusCIException

exception cumulusci.core.exceptions.PushApiObjectNotFound[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raise when Salesforce Push API object is not found

exception cumulusci.core.exceptions.RobotTestFailure[source]

Bases: cumulusci.core.exceptions.CumulusCIFailure

Raise when a robot test fails in a test suite

exception cumulusci.core.exceptions.SOQLQueryException[source]

Bases: cumulusci.core.exceptions.CumulusCIFailure

Raise for errors related to Salesforce DX

exception cumulusci.core.exceptions.SalesforceCredentialsException[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raise when Salesforce credentials are invalid

exception cumulusci.core.exceptions.SalesforceDXException[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raise for errors related to Salesforce DX

exception cumulusci.core.exceptions.SalesforceException[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raise for errors related to Salesforce

exception cumulusci.core.exceptions.ScratchOrgException[source]

Bases: cumulusci.core.exceptions.CumulusCIException

Raise for errors related to scratch orgs

exception cumulusci.core.exceptions.ServiceNotConfigured[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raised when no service configuration could be found by a given name in the project keychain

exception cumulusci.core.exceptions.ServiceNotValid[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raised when no service configuration could be found by a given name in the project configuration

exception cumulusci.core.exceptions.TaskNotFoundError[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raise when task is not found in project config

exception cumulusci.core.exceptions.TaskOptionsError[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raise when a task’s options are invalid

exception cumulusci.core.exceptions.TaskRequiresSalesforceOrg[source]

Bases: cumulusci.core.exceptions.CumulusCIUsageError

Raise when a task that requires a Salesforce org_config is not initialized with an org_config

FlowRunner contains the logic for actually running a flow.

Flows are an integral part of CCI, they actually do the thing. We’ve been getting along quite nicely with BaseFlow, which turns a flow definition into a callable object that runs the flow in one fell swoop. We named it BaseFlow thinking that, like tasks, specific flows might subclass it to extend behavior. In practice, unlike BaseTask, subclasses ended up representing variations in how the flow should actually be executed. We added callback hooks like pre_task and post_task for host systems embedding cci, like web apps, to inspect the flow in progress.

BaseFlow suited us well.

FlowRunner is a v2 API for flows in CCI. There are two objects of interest:

  • FlowCoordinator: takes a flow_config & runtime options to create a set of StepSpecs - Meant to replace the public API of BaseFlow, including override hooks. - Precomputes a flat list of steps, instead of running Flow recursively.
  • TaskRunner: encapsulates the actual task running, result providing logic.

Upon initialization, FlowRunner:

  • Creates a logger
  • Validates that there are no cycles in the given flow_config
  • Validates that the flow_config is using new-style-steps
  • Collects a list of StepSpec objects that define what the flow will do.

Upon running the flow, FlowRunner:

  • Refreshes the org credentials
  • Runs each StepSpec in order
    • Logs the task or skip
    • Updates any ^^ task option values with return_values references
    • Creates a TaskRunner to run the task and get the result
    • Re-raise any fatal exceptions from the task, if not ignore_failure.
    • collects StepResults into the flow.


  • Imports the actual task module.
  • Constructs an instance of the BaseTask subclass.
  • Runs/calls the task instance.
  • Returns results or exception into an immutable StepResult

Option values/overrides can be passed in at a number of levels, in increasing order of priority:

  • Task default (i.e. .tasks__TASKNAME__options)
  • Flow definition task options (i.e. .flows__FLOWNAME__steps__STEPNUM__options)
  • Flow definition subflow options (i.e. .flows__FLOWNAME__steps__STEPNUM__options__TASKNAME)
    see dev_org_namespaced for an example
  • Flow runtime (i.e. on the commandline)
class cumulusci.core.flowrunner.CachedTaskRunner(cache, task_name)[source]

Bases: object

Runs a task and caches the result in a TaskCache

class cumulusci.core.flowrunner.FlowCallback[source]

Bases: object

A place for code running a flow to inject callbacks to run during the flow.

A subclass of FlowCallback can use its own constructor to track context, e.g. to refer to a Django model:

class CustomFlowCallback(FlowCallback):
def __init__(self, model):
self.model = model
def post_task(self, step, result):
# do something to record state on self.model

(An instance of the custom FlowCallback class would be passed to FlowCoordinator.)

post_task(step, result)[source]
class cumulusci.core.flowrunner.FlowCoordinator(project_config, flow_config, name=None, options=None, skip=None, callbacks=None)[source]

Bases: object

classmethod from_steps(project_config, steps, name=None, callbacks=None)[source]

Returns an output string that contains the description of the flow, the sequence of tasks and subflows, and any “when” conditions associated with tasks.


Handle dynamic option value lookups in the format ^^task_name.attr

class cumulusci.core.flowrunner.PreflightFlowCoordinator(project_config, flow_config, name=None, options=None, skip=None, callbacks=None)[source]

Bases: cumulusci.core.flowrunner.FlowCoordinator

Coordinates running preflight checks instead of the actual flow steps.

evaluate_check(check, jinja2_context)[source]
class cumulusci.core.flowrunner.StepResult(step_num, task_name, path, result, return_values, exception)

Bases: tuple


Alias for field number 5


Alias for field number 2


Alias for field number 3


Alias for field number 4


Alias for field number 0


Alias for field number 1

class cumulusci.core.flowrunner.StepSpec(step_num, task_name, task_config, task_class, project_config, allow_failure=False, from_flow=None, skip=None, when=None)[source]

Bases: object

simple namespace to describe what the flowrunner should do each step

class cumulusci.core.flowrunner.TaskCache(flow)[source]

Bases: object

Provides access to named tasks and caches their results.

This is intended for use in a jinja2 expression context so that multiple expressions evaluated in the same context can avoid running a task more than once with the same options.

class cumulusci.core.flowrunner.TaskRunner(step, org_config, flow=None)[source]

Bases: object

TaskRunner encapsulates the job of instantiating and running a task.

classmethod from_flow(flow, step)[source]

Run a step.


Wraps the github3 library to configure request retries.

cumulusci.core.github.add_labels_to_pull_request(repo, pull_request, *labels)[source]

Adds a label to a pull request via the issue object Args: * repo: Repository object * pull_request: ShortPullRequest object that exists in repo * labels: list(str) of labels to add to the pull request

cumulusci.core.github.create_gist(github, description, files)[source]

Creates a gist with the given description and files.

github - an description - str files - A dict of files in the form of {filename:{‘content’: content},…}

cumulusci.core.github.create_pull_request(repo, branch_name, base=None, title=None)[source]

Creates a pull request for the given branch

cumulusci.core.github.find_latest_release(repo, include_beta=None)[source]
cumulusci.core.github.find_previous_release(repo, prefix=None)[source]
cumulusci.core.github.get_github_api(username=None, password=None)[source]

Old API that only handles logging in as a user.

Here for backwards-compatibility during the transition.

cumulusci.core.github.get_github_api_for_repo(keychain, owner, repo)[source]
cumulusci.core.github.get_pull_requests_by_commit(github, repo, commit_sha)[source]
cumulusci.core.github.get_pull_requests_by_head(repo, branch_name)[source]

Returns all pull requests with head equal to the given branch name.

cumulusci.core.github.get_pull_requests_with_base_branch(repo, base_branch_name, head=None, state=None)[source]

Returns a list of pull requests with the given base branch

cumulusci.core.github.is_label_on_pull_request(repo, pull_request, label_name)[source]

Returns True if the given label is on the pull request with the given pull request number. False otherwise.


Takes a github3.pulls.ShortPullRequest object

class cumulusci.core.runtime.BaseCumulusCI(*args, load_keychain=True, **kwargs)[source]

Bases: object


alias of cumulusci.core.flowrunner.FlowCallback

get_flow(name, options=None)[source]

Get a primed and readytogo flow coordinator.


alias of cumulusci.core.config.BaseGlobalConfig.BaseGlobalConfig


alias of cumulusci.core.keychain.BaseProjectKeychain.BaseProjectKeychain


alias of cumulusci.core.config.project_config.BaseProjectConfig

cumulusci.core.sfdx.sfdx(command, username=None, log_note=None, access_token=None, args=None, env=None, capture_output=True, check_return=False)[source]

Call an sfdx command and capture its output.

Be sure to quote user input that is part of the command using shell_quote.

Returns a sarge Command instance with returncode, stdout, stderr


Tasks are the basic unit of execution in CumulusCI.

Subclass BaseTask or a descendant to define custom task logic

class cumulusci.core.tasks.BaseTask(project_config, task_config, org_config=None, flow=None, name=None, stepnum=None, **kwargs)[source]

Bases: object

BaseTask provides the core execution logic for a Task

Subclass BaseTask and provide a _run_task() method with your code.

salesforce_task = False
task_docs = ''
task_options = {}
class cumulusci.core.template_utils.FakerTemplateLibrary(locale=None)[source]

Bases: object

A Jinja template library to add the objects to templates

class cumulusci.core.template_utils.StringGenerator(func)[source]

Bases: object

Sometimes in templates you want a reference to a variable to call a function.

For example:

>>> x = template_utils.StringGenerator(
>>> print(f"{x}")
>>> x = template_utils.StringGenerator(lambda:str(random.random()))
>>> print(f"{x}")
>>> print(f"{x}")

A Jinja template library to add the objects to templates

cumulusci.core.template_utils.format_str(value, variables=None, fake=<cumulusci.core.template_utils.FakerTemplateLibrary object>)[source]

Utilities for CumulusCI Core

import_global: task class defn import helper process_bool_arg: determine true/false for a commandline arg decode_to_unicode: get unicode string from sf api


decode ISO-8859-1 to unicode, when using sf api

cumulusci.core.utils.dictmerge(a, b, name=None)[source]

Deeply merge two dict``s that consist of lists, dicts, and scalars. This function (recursively) merges ``b INTO a, does not copy any values, and returns a.

based on NOTE: tuples and arbitrary objects are NOT handled and will raise TypeError


Import a class from a string module class path


Import a class from a string module class path


recursively deep-merge the configs into one another (highest priority comes first)

cumulusci.core.utils.parse_datetime(dt_str, format)[source]

Create a timezone-aware datetime object from a datetime string.


Determine True/False from argument


Convert a list of glob patterns or filenames into a list of files The initial list can take the form of a comma-separated string or a proper list. Order is preserved, but duplicates will be removed.

Note: this function processes glob patterns, but doesn’t validate that the files actually exist. For example, if the pattern is ‘’ and there is no file named ‘’, the literal string ‘’ will be included in the returned files.

Similarly, if the pattern is ‘.baz’ and it doesn’t match any files, the literal string ‘.baz’ will be returned.


Parse a string into a list separated by commas with whitespace stripped


Process an arg in the format “aa:bb,cc:dd”

Module contents