Include spec reference
This topic is a technical reference for the format, syntax and processing rules of include specs and include files. For a more conceptual explanation of how they are used in OrgFlow, see managing included metadata.
Include specs
Processing of metadata in OrgFlow is opt-in which means no metadata is included in any processing by default. An include spec is a rule that indicates to OrgFlow that a particular metadata package, namespace, type, or item should be processed by an OrgFlow operation. Include specs can be specified directly as command-line arguments to some CLI commands, or they can be stored in a text file which can be loaded by OrgFlow during processing.
Syntax
The syntax of an include spec is:
[!]packageName[/namespacePrefix[/typeApiName[/folder][/itemApiName]]]
Each part plays a specific role in identifying metadata items:
Part | Role |
---|---|
! | Specifies that metadata matching this spec should be excluded rather than included. |
packageName | Specifies the name of the metadata package. For unpackaged metadata use unpackaged . |
namespacePrefix | Specifies the namespace prefix of the metadata, without the double underscore __ delimiter. For non-namespaced metadata use ~ . |
typeApiName | Specifies the API name of the metadata type (for example CustomObject or Workflow ). |
folder | Specifies the containing folder of the metadata items. Only valid (and required) for folderized metadata types (such as Report and Document ). |
itemApiName | Specifies the API name of the metadata items. |
The following rules apply:
- The
packageName
part is required - All other parts are optional but must specified from left to right (i.e. if a part is specified, all parts to the left of it must be specified also, except for
!
) - All parts are case-insensitive
- Glob patterns are supported in all parts except for
packageName
which must always be specified in its entirety
Some examples:
Include spec | Result |
---|---|
unpackaged | All metadata (in unpackaged space) |
unpackaged/SBQQ | All metadata with namespace prefix SBQQ__ |
unpackaged/~ | All non-namespaced metadata |
unpackaged/~/CustomObject | All non-namespaced custom and standard objects |
unpackaged/*/CustomObject | All custom and standard objects |
unpackaged/~/CustomObject/Account | The (non-namespaced) standard object Account |
unpackaged/*/Report/MyFolder | All reports in the folder named MyFolder |
unpackaged/*/ApexClass/Test_* | All Apex classes whose API names begins with Test_ |
Combining include specs
Multiple include specs can be combined to achieve the desired results.
An include spec can be inverted (essentially turned into an exclude spec) by preceding it with the !
character. An include spec that begins with !
signifies that metadata items that match the spec should be excluded. For example, !unpackaged/~/ApexTrigger
would exclude all non-namespaced Apex triggers.
Include specs are processed in the order in which they are specified, and each include spec takes precedence over all includes specs preceding it. This makes it possible to create a set of include specs that, for example, first includes a wide range of items, and then excludes a smaller subset of items, and then re-includes some individual items in a more fine-grained manner.
This capability, especially when coupled with glob patterns and the left-to-right incremental construction syntax, creates a rich and powerful metadata filtering mechanism.
For example, to include all non-namespaced metadata except for profiles and permission sets:
unpackaged/~
!unpackaged/~/Profile
!unpackaged/~/PermissionSet
Or to include all non-namespaced Apex classes, except for those that begin with Test_
, but always include the specific class Test_Controller
:
unpackaged/~/ApexClass
!unpackaged/~/ApexClass/Test_*
unpackaged/~/ApexClass/Test_Controller
Include files
An include file is simply a text file containing one or more include specs, according to the following rules:
- Each include spec must be placed on its own line
- Each include spec takes precedence over all includes specs preceding it
- The
#
character can be used to indicate the start of a comment; a comment can begin anywhere inside a line, and continues until the end of the line - Empty (or whitespace-only) lines can be used for visual structure and separation, and are ignored in parsing
The most commonly used include file is the .orgflowinclude
file stored at the root of your Git repository, which tells OrgFlow which subset of Salesforce metadata that should be tracked and flowed between environments in your stack.
You can also create ad-hoc include files and use them as input to some of the utility commands in the CLI, as an alternative to specifying include specs directly on the command line. The .orgflowinclude
file and ad-hoc include files share the same format and syntax.
Here is a simple example include file:
# Include all unpackaged items without a namespace:
unpackaged/~
# Exclude profiles:
!unpackaged/~/Profile
# Exclude all permission sets...
!unpackaged/~/PermissionSet
unpackaged/~/PermissionSet/Alpha* # ... except those beginning with Alpha
Nested types
Some metadata types are composite types which means they contain nested types (or more accurately, composite components contain nested components). CustomObject
and Workflow
are some common examples of composite types.
When matching one or more metadata types using the typeApiName
part of an include spec, each type is considered independently of any nested types or parent composite type. If you include a nested component without its parent, the parent component is only included as an empty placeholder (without any of its intrinsic properties or content elements) whenever required to contain the nested component. And conversely, if you include a composite component without any nested component, the composite item includes only its intrinsic properties.
Normally, you will want to include or exclude composite components together with their nested components.
For example, including objects includes only the objects themselves and their intrinsic properties (such as label and description) but not their nested items such as custom fields, indexes or list views. Any nested items must themselves be covered by the include specs in order to be included in the processing:
unpackaged/~/CustomObject # Includes all objects
unpackaged/~/CustomField # Includes all custom fields
unpackaged/~/Index # Includes all indexes
unpackaged/~/ListView # Includes all list views
This requires some extra care in some scenarios, such as when you want to include only a specific objects and its nested items. The include specs for the object and the nested items must be aligned to achieve the desired results. The cleanest and most maintainable way to achieve this is by using wildcards. Here's an example that includes only the custom object Alpha__c
and all its nested components:
unpackaged/~/CustomObject/Alpha__c # The custom object 'Alpha__c'
unpackaged/~/*/Alpha__c.* # All components of any type whose parent is named 'Alpha__c'
Folders
Due to the way the metadata API represents folder structures, the component name for a folderized component is comprised only of the last two segments (i.e. the file name and its immediate containing folder) even if the actual folder structure is deeper.
For example, let's say we have some reports stored in the following folder structure:
SomeFolder/
SomeSubfolder/
MyFancyReport
AnotherReport
To include all reports in this folder it would be natural to use the following include spec:
unpackaged/~/Report/SomeFolder/SomeSubfolder/* # ❌ WILL NOT WORK
However, because only the immediately containing folder is represented in a folderized component's name, the correct include spec is:
unpackaged/~/Report/SomeSubfolder/* # ✅ Works
Namespaces
Metadata that you create or customize in a standard non-namespaced Salesforce org is unpackaged and non-namespaced, which means it is not contained in a managed package and does not have a namespace prefix. As mentioned above, such metadata is specified using unpackaged
as the package name as ~
as the namespace prefix (meaning "no namespace prefix").
Metadata created by installing a managed package is exposed in two ways through the metadata API:
- In unpackaged space with the namespace prefix of the managed package
- In the managed package itself without a namespace prefix
This means that, for purposes of retrieval, you can target such metadata with include specs using either method. For example, let's say you have installed a managed packaged named "ACME Mapping Utilities" with the namespace prefix amu__
in your org, and you want to retrieve all custom objects provided by that package. Both of the following include specs would work:
# Retrieve the objects as projected in unpackaged space (with namespace prefix):
unpackaged/amu/CustomObject
# Retrieve the objects in their managed package (without namespace prefix):
ACME Mapping Utilities/~/CustomObject
The first method is recommended because OrgFlow can retrieve only the targeted components, which is much more efficient. With the second method, OrgFlow must retrieve the entire managed package "ACME Mapping Utilities" first, and then prune away all components except the targeted ones you wanted to include. The resulting metadata archive will also not be the same. With the first method, the retrieved metadata archive will contain the unpackaged
package. With the second method, it will contain the ACME Mapping Utilities
package.
Metadata created in a namespaced Salesforce developer org (normally used to build and distribute a managed package) in exposed through the metadata API as unpackaged and non-namespaced.