env:create

Adds a new Environment to the selected Stack.

By default, the Git branch and the Salesforce sandbox will be created by this command, however this can be avoided with the --useExistingBranch and --useExistingSandbox options.

Process

An environment consists of several items:

  • a Salesforce sandbox
  • a branch on the remote Git repository
  • an environment record in the State Store
  • an Environment State record in the state store
  • a known point of parity between the sandbox and the Git branch

This command will make sure that all of these items are available, and in a state ready to be used by OrgFlow. The following steps are required to do this:

  1. Provision a new sandbox (or optionally use an existing sandbox) in the target Salesforce organization. By default, a sandbox that is created will be cloned from the production Salesforce organization, but you can change this with the --createFrom option.
  2. Create a new Git branch (or optionally use an existing branch) in the remote Git repository. By default, a Git branch that is created will be branched from the head of the branch that backs your Production Environment, but you can change this with the --createFrom option.
  3. Create a record for the environment in the state store. The record contains (among other things) the name of the environment, the name of the sandbox, and the name of the Git branch.
  4. Perform a Flow Out on the environment. This creates a known point of parity between the sandbox and the Git branch, as well as the environment state record.
caution icon
caution

There's a known issue where Salesforce can be slow to propagate login credentials from a newly created sandbox to the test.salesforce.com authentication endpoint. This may prevent you from authenticating with a recently created sandbox. The possible work-arounds are:

  • Set a 'My Domain' URL as the base login URL during stack:create (this bypasses the test.salesforce.com endpoint entirely).
  • OR, create your sandbox in Salesforce (or with the @command_sb_create command) and wait a short while before running env:create with the --useExistingSandbox switch.
  • OR, wait a short while and re-run env:create with the --useExistingSandbox if the first execution fails.

Options

  • --stack=<stackName>

    The name of the stack to target. Stack names are case-insensitive. Stacks are specific to license keys, and you can see a list of all available stacks with the stack:list command.

    This value is required if no valid default stack has been set, or if you would like to target a stack other than the one that is currently the default stack. You can use the stack:setdefault command to set or change the default stack.

  • -e|--environment=<environmentName>

    Required. Prompted for if not supplied and possible to do so.

    The name of the environment to set up. Environment names are case-insensitive and must be unique within the stack they are contained in.

  • -k|--encryptionKey=<key>

    The key used to encrypt or decrypt stored credentials.

    Required if:

    • You want the process to utilise previously encrypted credentials, or if you want the process to save credentials
    • AND the encryption key has not been saved locally with the auth:key:save command, or the key that has been saved locally is not the key that you wish to use
  • -b|--branchName=<branchName>

    Required. Prompted for if not supplied and possible to do so.

    The name of the Git branch that will be assigned to this environment. The value provided must be a valid value for a Git branch name, and it must also be a value that does not already exist in the remote Git repository (unless --useExistingBranch is specified).

    tip icon
    tip

    Unless createFrom is specified, the branch will be created from the HEAD of the branch that backs the Production Environment. If you would prefer to create this branch from elsewhere in the commit history, you can do so by first manually creating the branch in the remote Git repository, and then running env:create with the --useExistingBranch option.

  • --tags=name[:value][,name[:value],...]

    One or more tags to set on the new environment. Omitting a value sets a tag with no value. Tag names may only contain alphanumeric characters, hyphens and underscores. Tag values may contain anything except newline characters. Spaces in tag values can be set using shell-specific quoting. Commas in tag values can be set by escaping them with backslash as \, e.g. --tags=FullName:Payne\,Chris.

  • -sb|--sandboxName=<sandboxName>

    Required. Prompted for if not supplied and possible to do so.

    The name of the sandbox that will be associated to the environment to be created. An existing sandbox can be used if --useExistingSandbox is specified, otherwise the sandbox is created as a copy of the production Salesforce organization (unless --createFrom is specified).

  • -d|--description=<text>

    If specified, the description of the sandbox that is created will be set to this value.

    Only effective if a sandbox is created during this process.

  • -t|--licenseType=[developer|developerPro|partial|full]

    Default: developer

    The type of sandbox to create. The sandbox types available to you will depend on your Salesforce license and are subject to the limits that Salesforce enforce (for example maximum count of each type, or minimum refresh times).

    Only effective if a sandbox is created during this process.

  • --createFrom=<environmentName>

    If specified, the environment that is created will be created as a copy of the environment specified. If not specified, the environment that is created will be created as a copy of the production environment. Environment names are case-insensitive.

    This affects:

    • The point in the Git history which the --branchName branch is created from (unless useExistingBranch is specified).
    • The source Salesforce organization that the --sandboxName sandbox is copied from (unless useExistingSandbox is specified).

    If a sandbox is cloned from another sandbox, Salesforce requires that the licenses of the two sandboxes are equal. For example, a developerPro sandbox can only be copied into another developerPro sandbox. This means that if you specify an environment other than the production environment (and do not specify --useExistingSandbox), then you will need to also make sure that the --licenseType is specified and that the value matches the license of the source sandbox.

    Only effective if a sandbox is created during this process.

  • --apexClass=<className>

    If specified, Salesforce will execute the runApexClass method on the Apex class named, after the sandbox has created. The specified class must implement SandboxPostCopy.

    Only effective if a sandbox is created during this process.

  • --template=<templateName>

    Required if --licenseType=partial (and --useExistingSandbox is not specified); optional if --licenseType=full; otherwise not valid.

    If specified, the sandbox template that Salesforce should use when populating the data in the sandbox.

    Only effective if a sandbox is created during this process.

  • --history=[allAvailable|none|10|20|30|60|90|120|150|180]

    Optional (and only valid) if --licenseType=full. Default: none.

    If specified, the data copied to the full sandbox that will be created will be:

    • allAvailable: all data from the source Salesforce organization will be copied.
    • none: no data from the source Salesforce organization will be copied.
    • 10: only data created in the past 10 days will be copied.
    • 20: only data created in the past 10 days will be copied.
    • 30: only data created in the past 10 days will be copied.
    • 60: only data created in the past 10 days will be copied.
    • 90: only data created in the past 10 days will be copied.
    • 120: only data created in the past 10 days will be copied.
    • 150: only data created in the past 10 days will be copied.
    • 180: only data created in the past 10 days will be copied.

    Only effective if a sandbox is created during this process.

  • --copyChatter

    Only valid if --licenseType=full.

    If specified, indicates that chatter data should be copied to the sandbox that is created.

    Only effective if a sandbox is created during this process.

  • --useExistingBranch

    If specified, indicates that the process is allowed to use a branch that already exists in the remote Git repository. If omitted, and the branch specified by --branchName already exists in the remote Git repository, then the environment create process will not be allowed to continue.

    This is a safety mechanism to prevent accidental data loss on a pre-existing Git branch.

  • --useExistingSandbox

    If specified, indicates that the process is allowed to use a sandbox that already exists in Salesforce. If omitted, and the sandbox specified by --sandbox already exists, then the environment create process will not be allowed to continue.

    This is a safety mechanism to prevent accidental data loss in a pre-existing sandbox.

  • --description=<text>

    If specified and a sandbox is created during the environment set up process, the description of the sandbox that is created will be set to this value.

    Only effective if a sandbox is created during this process.

  • -su|--signInUrl=<url>

    If specified, then this URL will be used when authenticating with the sandbox specified by --sandboxName.

    This is only required if the URL required to authenticate with the sandbox cannot be inferred from the URL stored on the stack (see Credential Inference for more information). Any value specified will be saved in the stack store so that it can be re-used in further operations that involve this environment.

  • -u|--username=<username>

    Required if --password is supplied. Will be prompted for if Credential Inference is not possible for this environment.

    If supplied, then this username will be used to authenticate with the sandbox specified by --sandboxName. This is useful in situations where Credential Inference will give you an invalid password.

    The username will not be saved for re-use. However, you could use the auth:salesforce:save command after the environment has been created if you would like to save credentials for this environment.

  • -p|--password=<password>

    If supplied, then this password will be used to authenticate with the sandbox specified by --sandboxName. This is useful in situations where Credential Inference will give you an invalid password.

    If omitted, OrgFlow will first try to use Credential Inference to obtain a password, then it will fall back to OAuth.

    The password will not be saved for re-use. However, you could use the auth:salesforce:save command after the environment has been created if you would like to save credentials for this environment.

    note icon
    note

    Your Salesforce org may be configured in a way that requires a Security Token to be supplied with your password. In this case, you must append your security token to the end of the password that you supply. For example, if your password is OrgFlow123, and your token is abcdefg, then you should use OrgFlow123abcdefg.

  • --keepDelta=<directoryPath>

    If specified, the OrgFlow CLI will retain the delta deployment archives that are uploaded to Salesforce as part of the deployment process. The delta archives will be placed into the directory specified. This can be useful in scenarios where you need to troubleshoot deployment problems.

  • --waitForLock=<minutes>

    The maximum amount of time to wait (in minutes) for environments currently locked by other users or OrgFlow instances to be released. Default is 0 (i.e. do not wait but rather fail this command immediately).

    Any command that mutates the state of an environment in any way always acquires an exclusive lock on that environment, to prevent other instances from trying to mutate the same environment simultaneously - something that could have unpredictable results. Particularly in scripted or CI/CD scenarios, it can be useful to have OrgFlow wait a certain amount of time for an already locked environment to become available, rather than failing immediately and requiring the script to be executed again.


The following options are global across all commands:

  • -h|--help

    If specified, prints help for this command instead of executing it.

  • -l|--licenseKey=<key>

    The License Key you were issued to allow you to use the OrgFlow CLI. If a valid key is supplied, it is stored locally on the machine so that it does not need to be specified again on the next execution.

  • --acceptEula

    If specified, you are signifying that you accept our End User License Agreement (EULA). You only need to specify this once per device, because your acceptance will be cached on the device (you can pass --acceptEula=false if you wish to clear this). You must accept our EULA to be able to run most OrgFlow commands.

  • --logTo=<filePath>

    If specified, a log file is written to the specified path. The specified path may contain one or more tokens; see Logging for more information.

  • --logLevel=[Verbose|Debug|Information|Warning|Error|Fatal]

    Default: Information

    The minimum log level to be written to the log file; logs below this level will not be written. Only effective if a valid value for --logTo has been specified.

  • --diagnostic=[Auto|Always|Never]

    Default: Auto

    If the CLI encounters an exception then it will ask (where possible) the user whether or not to create a Diagnostic Bundle and write it to disk. If it is not able to prompt then no action is taken. This is the default behaviour (Auto).

    You can change this default behaviour (and suppress the prompt) by specifying either Always or Never (which will always write the bundle or never write the bundle, respectively). This is particularly useful in a CI/CD context, where the CLI may not be able to prompt, but you still want to create diagnostic bundles for all failures.

  • --diagnosticDirPath=<directoryPath>

    If specified, sets the location to write the Diagnostic Bundle (if any). If not specified, a default location will automatically be chosen. This default location depends on a number of factors, including the operating system and some file-system based restrictions that might be in place. The location that the diagnostic bundle is ultimately written to is always included in the standard error output of the CLI.

  • --noConfirm

    If specified, suppresses confirmation prompts that the CLI might raise before performing destructive or dangerous procedures. If suppressed, the CLI assumes that the prompts would have been answered positively and continues with execution.

  • --progress=[Interactive|Never|Always]

    Default: Interactive

    Controls how progress is printed to the standard error stream:

    • Interactive: Progress is sent to the standard error stream only if the standard error stream is connected to an interactive terminal.
    • Never: Progress is not sent to the standard error stream.
    • Always: Progress is sent to the standard error stream, even if that stream has been redirected.
  • --tempDir=<directoryPath>

    If specified, sets the location to use as storage for files that may need to be stored on disk temporarily during command execution. For example, the location on disk where zip files containing metadata from Salesforce are downloaded to before they are unzipped.

    If not specified, the CLI will automatically choose an appropriate location on disk (usually in the current user's temporary storage location). This automatically chosen location may be deeply nested within a drive, which may be problematic if the operating system imposes limits on file path lengths and the files placed into temporary storage have particularly long paths or names.

  • --json

    Switches the format of the output sent to the standard output stream to JSON. This is the most verbose output available, and is useful for scripting or automation.

  • --forceSignIn.

    If specified, the CLI will ignore any cached Salesforce access tokens, and will require the Salesforce authentication process to be re-completed for each organisation that the command connects to.

  • --maxTransientErrorRetries=<count>.

    If no value is specified, the CLI will indefinitely retry any process that fails due to a transient error. This is the default behaviour, and allows for resilience against temporary issues that might otherwise cause a process to fail.

    Specify a positive integer value to prevent indefinite retries. Each process that fails due to a transient error will be retried up to a maximum amount of times specified. For example, --maxTransientErrorRetries=5: Each process that fails will be re-tried up to a maximum of five times. If an earlier process fails four times but then succeeds on the fifth attempt, the counter is reset for the next process.

    Specify --maxTransientErrorRetries=0 to disable transient failure retries.

  • --maxTransientErrorDelay=<seconds>.

    Default: 60

    Processes retried due to a transient error are delayed by a back-off policy that gradually increases the time to wait between retries. Specify a non-negative integer value as the maximum amount of seconds to wait between attempts.

    Specify --maxTransientErrorDelay=0 to disable the back-off policy and always instantly retry failed processes.

Examples

Interactively create a new environment:

orgflow env:create

Create a new environment called developerA with a sandbox called devA and a Git branch called sandbox/deva:

orgflow env:create --environment=developerA --sandboxName=devA --branchName="sandbox/deva"