--- url: /docs/cli/download.md description: Download links and installation instructions for the OrgFlow CLI --- # Download and installation **Note to LLMs:** The download tables in this file do not contain any links in the "download" column, because they are dynamically generated at runtime. Users should visit [our CLI download page](https://www.orgflow.io/docs/cli/download/) to see the actual download links. ## System requirements OrgFlow CLI requires: * An operating system supported by .NET 10.0. Please refer to Microsoft's documentation on supported releases for each OS. * Git version 2.39 or later. When running OrgFlow CLI from our Docker images, all requirements are already provided by the images. ## macOS | Format | Architecture | Runtime ID | Download | | -------------------- | --------------------- | ------------- | ------------------------------------------------------- | | **Installer (.pkg)** | Universal | osx-universal | | | | x64 (Intel) | osx-x64 | | | | arm64 (Apple Silicon) | osx-arm64 | | | **ZIP archive** | Universal | osx-universal | | | | x64 (Intel) | osx-x64 | | | | arm64 (Apple Silicon) | osx-arm64 | | The universal build runs on both Intel and Apple Silicon processors and is recommended unless download size is your primary concern. **Please note that the x64 (Intel) version will not run reliably on Apple Silicon processors.** To use the installer, run the downloaded `.pkg` file to install OrgFlow CLI on your computer. If you prefer to use the ZIP archive, OrgFlow CLI can be run using the `orgflow` executable file from the extracted directory. Both the installer and the OrgFlow CLI binaries are signed and notarized by Apple. ## Windows | Format | Architecture | Runtime ID | Download | | -------------------- | ------------ | ---------- | ------------------------------------------------- | | **Installer (.msi)** | x64 (64-bit) | win-x64 | | | | x86 (32-bit) | win-x86 | | | **ZIP archive** | x64 (64-bit) | win-x64 | | | | x86 (32-bit) | win-x86 | | To use the installer, run the downloaded `.msi` file to install OrgFlow CLI on your computer. If you prefer to use the ZIP archive, OrgFlow CLI can be run using the `orgflow.exe` executable file from the extracted directory. ::: warning OrgFlow CLI for Windows is not yet signed When running the `.msi` installer, you may see warnings about running an unrecognized app or installing software from an unknown publisher. We plan to start signing our binaries and installer with a publisher certificate in the future. ::: ## Linux | Format | Architecture | Runtime ID | Download | | --------------- | ------------ | ----------- | ----------------------------------------------------- | | **ZIP archive** | x64 | linux-x64 | | | | arm64 | linux-arm64 | | OrgFlow CLI can be run using the `orgflow` executable file from the extracted directory. For more convenience, consider adding the directory to the `PATH` variable of your shell, or create a symlink to the `orgflow` executable in a default location such as `/usr/local/bin`. ## Docker Docker images for OrgFlow CLI can be found on Docker Hub: https://hub.docker.com/r/orgflow/cli Image tags correspond to the version of the OrgFlow CLI that they contain. To use the most recent version, use the `:latest` tag. To use to a specific version, use the tag that matches the full version number (e.g. `:3.2.2`). You can also use `:3.2.x` or `:3.x` to pin to a specific minor or major version, respectively. To run the OrgFlow CLI in a Docker container interactively: ```shellscript $ docker run --interactive --tty --rm orgflow/cli $ orgflow --help ``` ::: warning Windows compatibility We currently publish Docker images for `linux/amd64` and `linux/arm64` platforms only. **To run OrgFlow in a Docker container on Windows, your system must be configured to use Linux containers.** ::: While the image contains the OrgFlow CLI and all of its dependencies, you'll need to make sure that any required configuration values are set. These include the access token that you intend to use, the encryption key for your stack, as well as any required Git configuration and authentication. See the [initial setup](/docs/cli/initial-setup/) topic for details. ## GitHub Actions OrgFlow for GitHub Actions can be found here: https://github.com/marketplace/actions/orgflow-salesforce-devops-for-github Our `setup` action downloads, installs and configures OrgFlow CLI in your GitHub Actions workflow using a single step: ```yaml jobs: orgflow_job: runs-on: ubuntu-latest steps: # Download and install latest version - uses: orgflow-actions/setup@v2 with: access-token: ${{ secrets.ORGFLOW_ACCESSTOKEN }} env: ORGFLOW__ACCEPTEULA: "true" # Run any OrgFlow command - run: orgflow stack:list ``` See our [demo template repository](https://github.com/OrgFlow-Actions/demo) for complete sample workflows and a guided tutorial. ::: tip You are not required to use our actions in order to use OrgFlow CLI in your GitHub Actions workflows, but they do a lot of heavy lifting for you and ensure OrgFlow CLI is configured and invoked in a way that ensures an optimal experience in GitHub Actions. ::: ## Script or other CI/CD platform If you are looking to download and install the OrgFlow CLI in a scripting environment other than GitHub Actions, you will need to add steps to your script or pipeline to download the OrgFlow CLI in ZIP format, unzip it, and add the target directory to the `PATH` variable. The download URL pattern is `https://prod.orgflow.app/download/v2/cli//latest/zip`. Substitute `` with the runtime for the agent or host you're installing on. The following runtime IDs are available: * `osx-universal` * `osx-arm64` * `osx-x64` * `win-x64` * `win-x86` * `linux-arm64` * `linux-x64` You can also substitute `latest` with a version specifier if you'd like to pin your script or pipeline to a specific version or version range. To use to a specific version, use the full version number (e.g. `:3.2.2`). You can also use `:3.2.x` or `:3.x` to pin to a specific minor or major version, respectively. Once the OrgFlow CLI has been downloaded and installed, you'll need to make sure that any required configuration values are set. These include the access token that you intend to use, the encryption key for your stack, as well as any required Git configuration and authentication. See the [initial setup](/docs/cli/initial-setup/) topic for details. ## FAQ ### Why do I see warnings about running an unrecognized app or installing software from an unknown publisher? Our installer packages and binaries for Windows are not yet digitally signed or notarized. On Windows, when running the `.msi` installer package you may see warnings about running an unrecognized app or installing software from an unknown publisher. We plan to start signing and notarizing our binaries and installer packages for Windows with a publisher certificate in the future. ### Can I download and install OrgFlow CLI through Homebrew on macOS? Not currently. However, installation through Homebrew is on our backlog and we plan to provide this in the future. ### Can I download and install OrgFlow CLI through Chocolatey on Windows? Not currently. However, installation through Windows package managers such as Chocolatey or winget may be provided in the future. If this feature is important to you, please reach out to us at support@orgflow.io. ### Can I download and install OrgFlow CLI through my Linux distro package manager? Not currently. However, installation through Linux distro package managers may be provided in the future. If this feature is important to you, please reach out to us at support@orgflow.io. --- --- url: /docs/cli/initial-setup.md description: Instructions for setting up and configuring the OrgFlow CLI --- # Initial setup and configuration After [downloading and installing](/docs/cli/download/) the OrgFlow CLI, there's a few more one-time setup steps needed to get up and running. This topic assumes that you've added the installation folder to the `PATH` variable of your shell. If you skipped this step, just make sure that the current working directory of your terminal is the directory to which the OrgFlow CLI executable was installed. ## Access token For [process commands](/docs/cli/#command-categories) the OrgFlow CLI relies on an *access token* to designate which workspace to connect to, and to identify you and verify that you have the required permissions and access to the resources in that workspace (stacks, environments etc.) that you are trying use. ### Obtaining the access token Access tokens are scoped to a [workspace](/docs/core-concepts/workspaces/). If you do not already have a workspace, our [quick start guide](/docs/basics/quick-start/) explains how to create one. You cannot create a workspace with the OrgFlow CLI — it must be done through the [OrgFlow web app](https://www.orgflow.app). Navigate to the workspace, then go to the **settings** tab. You'll find the access token under the **basic information** section. ::: warning Keep your access token secret An access token provides full access to your workspace, equivalent to the **administrator** role. Keep it a secret and only share with those you trust. Avoid hardcoding your access token in scripts — use a secret store instead. If you suspect your access token might have been leaked or compromised, contact support@orgflow.io and we can rotate it. ::: ### Using the access token Every process command exposes an `--accessToken (-at)` argument that allows you to pass in an access token. Once you provide an access token, the token is cached locally so that you don't have to provide it to subsequent commands. To target a different workspace, simply provide the `--accessToken (-at)` argument again. If you run a command in interactive mode and an access token has not been provided or previously cached, the OrgFlow CLI will prompt you to provide one. ## Encryption key OrgFlow encrypts sensitive data (such as Salesforce credentials and Git passwords) at rest. To add an extra layer of security, each [stack](/docs/core-concepts/stacks/) is assigned a unique encryption key. The OrgFlow CLI cannot decrypt these sensitive values without being provided the correct encryption key. If you run a command that requires the encryption key to decrypt stored sensitive values, you will first need to obtain the correct encryption key through the \[OrgFlow web app] and then provide the encryption key to the OrgFlow CLI. ### Obtaining the encryption key Encryption keys are scoped to a [stack](/docs/core-concepts/stacks/). If you do not already have a stack, our [quick start guide](/docs/basics/quick-start/) explains how to create one. In the [OrgFlow web app](https://www.orgflow.app), navigate to the stack in question, then go to the **settings** tab. You'll find the encryption key under the **basic information** section. ### Using the encryption key The recommended way to provide an encryption key to the OrgFlow CLI is with the `auth:key:save` command. This command takes an encryption key (and optionally a stack name, see below for information on how to select a stack), and caches it locally so that it can be used in subsequent commands, for example: ```shellscript $ orgflow auth:key:save --encryptionKey=myencryptionkey --stack=mystack ``` Alternatively, you can provided encryption keys on a per-command basis by using the `--encryptionKey= (-k)` argument. This argument is present on every command that might need an encryption key, for example: ```shellscript $ orgflow env:flowin --environment=dev --encryptionKey=myencryptionkey ``` Any encryption key provided as command input (e.g. `--encryptionKey= (-k)`) take precedence over any encryption keys saved using the `auth:key:save` command. (This pattern applies throughout the OrgFlow CLI, not just to encryption keys.) ## Selecting a stack Most of the work that you do with the OrgFlow CLI will be within the context of a stack. Any process commands that operate within the context of a stack will have a `--stack=` argument or option. For example, to list all environments in a stack: ```shellscript $ $orgflow env:list --stack=mystack ``` It's also possible to set a *default stack* so that you can run commands without having to explicitly specify a stack each time. The command to do this is `stack:setdefault`, for example: ```shellscript orgflow stack:setdefault --stack=mystack ``` The default stack will be used only in cases where you haven't explicitly used the `--stack=` argument. If you want to view a list of all your stacks, you can run `orgflow stack:list`. This command also shows the selected default stack, if one has been set. ## Configuring Git The OrgFlow CLI uses your local Git installation and configuration when interacting with your Git repository. You will need to have Git installed and correctly configured on the device where you run the OrgFlow CLI. This means things like authentication and committer signatures need to be in place before OrgFlow can do any work with Git. A good rule of thumb is that if you are able to clone from and push to the remote repository then OrgFlow CLI will be able to do so too. The OrgFlow CLI assumes that the Git executable is available at `git`. If this is not the case then you can change this by setting the `ORGFLOW__GIT__EXECUTABLEPATH` environment variable. ## Setting up in a third-party CI/CD platform Most of the steps described above are required also when running the OrgFlow CLI on an agent or runner inside a third-party CI/CD platform. The only exception is configuring Git: on CI/CD platforms where an implicit backing Git repository is present (such as GitHub Actions or Azure Pipelines and others) the required Git configuration is usually already present. For GitHub Actions, this is all taken care of for you if you are using the [setup action](https://github.com/OrgFlow-Actions/setup). For other platforms, you will need to add the required steps to your pipelines or scripts. Hosted CI/CD agents are usually ephemeral, which means that you'll need to ensure that the installation and configuration steps are performed each time your jobs start. --- --- url: /docs/cli/troubleshooting.md description: Information about diagnosing issues with the OrgFlow CLI --- # Troubleshooting ## Logging Logging is the most important tool for troubleshooting issues when using the OrgFlow CLI. To enable logging, you can use the following two options with any command: * **`--logTo=`** If specified, a log file is written to the specified path. * **`--logLevel=[Verbose|Debug|Information|Warning|Error|Fatal]`** The minimum log level to be written to the log file; logs below this level will not be written. The default log level if not specified is `Information`. When logging is enabled, a log file with the detail level you specify in the `--logLevel` option is written to disk while the command executes. If the file already exists, new log data is appended to the end of the existing file. ### Tokens in log file paths The `--logTo=` option can be used with any command to have the OrgFlow CLI write logs to a file on disk. When specifying this option, the file path can contain one or more *tokens*. The following tokens are available: | Token | Result | | ------------------------------- | ----------------------------------------------------------- | | `{C}` or `{command}` | Name of command being executed, e.g. `env:flowin` | | `{T:format}` or `{time:format}` | UTC date and time of current command invocation (see below) | | `{U}` or `{user}` | Current local username | | `{M}` or `{machine}` | Name of local machine/computer | The same token can be specified more than once if needed. Tokens can be very useful when you want to vary the log file location and/or name based on things that vary, without having to specify a different value each time. This is most useful when specifying the log file path as a user setting or an environment variable, rather than directly as a command option. The `{T}`/`{time}` token needs to be specified with a format string that controls how the date is formatted into the log file path. Any standard or custom .NET DateTime format string is supported. Date and time formatting is performed using the current system locale. For more information, see: * [Standard date and time format strings](https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-date-and-time-format-strings) * [Custom date and time format strings](https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings) For example, the following `--logTo` option: ``` --logTo=/orgflow/{user}/logs/{time:yyyy-MM-dd}/{command}-{time:HHmm}.log ``` would make the OrgFlow CLI log to a file path similar to: ``` /orgflow/richard/logs/2021-10-06/env-flowin-1648.log ``` --- --- url: /docs/devops/apex-test-runs.md description: Conceptual deep-dive into running Apex tests using OrgFlow --- # Apex test runs OrgFlow can execute the Apex tests in your Salesforce orgs. This can be either as part of a deployment, or as part of an ad-hoc execution of tests. In both cases, OrgFlow will create an Apex test run. ## Starting Apex test runs Job types that can start Apex test runs are: * Flow out * Flow merge * Run Apex tests Flow out and flow merge will only start Apex test runs if Apex tests are executed as part of the deployment to Salesforce. To run Apex tests outside the context of a deployment, you can use the Run apex tests job type. This job can be started from either the **Environments** tab, or from the **Test runs** tab. This job type allows you control over which test classes or suites to run, as well as some other options such as stopping the Apex test run once a specific number of tests have failed. Apex test runs (that were started as part of an Apex test run job) can be re-run, either from the list of historical Apex test runs, or from the Apex test run details page. This is handy if you are working on an area of functionality and want to frequently re-run the tests that cover that area of functionality. ### On a recurring schedule A common scenario is to run Apex tests on a nightly (or other frequent) basis. This allows you to catch failing tests early so that the functionality under test can be fixed sooner - either before the failing tests block a deployment, or before your users start to notice issues with the functionality under test. This can be achieved with [schedules](/docs/core-concepts/schedules/), by creating a schedule that executes the Run apex tests job type. ### With the CLI Jobs started with the [OrgFlow CLI](/docs/cli/) will also create Apex test runs that can be viewed in the web app's UI. Optionally, the OrgFlow CLI can also produce a jUnit results file. This file can be read by other CI/CD platforms (such as GitHub, GitLab, and Azure DevOps) to allow them to display the test results in their own UI. ## Viewing Apex test runs A summary of the Apex test run is shown on the job details page whenever a job starts an Apex test run. The Apex test run is continuously updated as the tests are executed in Salesforce. This allows you to monitor the progress of the test run, and view any failures as soon as they happen. The Apex test run summary also includes a link to the Apex test run details page, where you can view the Apex test run in more details. You can also view a history of previous Apex test runs from the **Test runs** tab. This list of historical Apex test runs are filterable, so you can easily find the Apex test runs against a specific environment, or with a specific outcome. ::: info Apex test runs are subject to your data retention period Your subscription dictates the data retention period available to you. Apex test runs that are older than the maximum age allowed by your data retention period are automatically deleted by OrgFlow. See [billing](/docs/basics/billing/) for more information. ::: You can click each Apex test run in the list of historical runs to view it in more detail. Just like the Apex test run summary on the job detail pages, the Apex test run details pages are updates in real time as Salesforces executes each of your tests: ### Limitations The data contained within an Apex test run is collected from Salesforce by OrgFlow and then standardized in order to produce the output that you can see. This means that limitations in the data that Salesforce provides will affect the data in Apex test runs. There are currently two known limitations with this data: **The count of enqueued tests may be higher than the sum of the passed, skipped, and failed tests.** Salesforce doesn't include test set up methods in the count of enqueued tests, but it does include them in the list of test results, which causes this issue. **The list of test results may be incomplete while an Apex test run is running during a deployment.** When Apex tests are executed as part of a deployment, Salesforce reports the failing tests as and when they fail, but doesn't report on passed and skipped tests as they finish. Salesforce will however report on the overall count of tests executed as the deployment test run progresses. This means that you will be able to see the count of passed and skipped tests increase while the Apex test run is running, but you won't be able to see the passed or skipped tests appear in the list of executed tests until the Apex test run is finished. Failed tests will appear in this list as they fail, and passed and skipped tests all appear in the list once the Apex test run is finished. This issue does not affect Apex test runs executed outside the context of a deployment. --- --- url: /docs/security/git-authentication.md description: Details about how OrgFlow authenticates with customer's Git repository --- # Authenticating to Git OrgFlow needs to authenticate to your Git repository in order to do things like commit and push Salesforce metadata. OrgFlow uses only pure Git commands to interact with Git (i.e. no third-party or provider-specific APIs are used). This allows OrgFlow to support any Git repository. If your Git repository requires authentication (and most will), you will need to ensure that OrgFlow can authenticate to it. How Git authentication works depends on where you are running OrgFlow operations: in **OrgFlow's cloud** or using the **OrgFlow CLI** on devices or infrastructure managed by you. ## OrgFlow's cloud ::: info This section applies only when using your own Git repository If you're using a [managed repository](/docs/devops/managed-repos/), Git authentication in OrgFlow's cloud is automatically managed for you. ::: Jobs and other operations initiated through the OrgFlow web app execute on managed infrastructure in OrgFlow's cloud. OrgFlow's cloud can authenticate to remote Git repositories using either a *username and password*, or a *personal access token (PAT)*. For most commercial Git providers, a personal access token (PAT) is the only supported option (the PAT is given as the password, while the username is irrelevant can typically be set to any non-empty value). For internal or self-hosted Git services, username and password may be supported. Authentication using SSH keys are currently **not** supported in OrgFlow's cloud. The credentials used for authentication are taken from your [stack](/docs/core-concepts/stacks/). This means that, to support operations in OrgFlow's cloud, you need to have valid Git credentials saved in your stack. If you create a stack using the OrgFlow web app, you will be prompted to provide Git credentials during the stack creation process. These credentials as then saved in the stack for use later on. If you create a stack using the OrgFlow CLI, Git credentials won't be saved in OrgFlow's cloud automatically. If you create a stack this way but intend on running jobs through the web app (in OrgFlow's cloud) you'll need to explicitly [save credentials on the stack](#managing-saved-credentials). ::: info Securely storing Git credentials Git credentials saved in OrgFlow's cloud are [encrypted](/docs/security/encryption/). For teams with very strict security or compliance needs, it is also possible to never make any connections to your Git repository from our infrastructure at all, though this significantly restricts the functionality available through the OrgFlow web app. See [self-hosting](/docs/security/self-hosting/) for more information. ::: ## OrgFlow CLI Git authentication using the OrgFlow CLI works differently compared to OrgFlow's cloud - the CLI does not explicitly perform any authentication to your Git repository, and therefore does not use the Git credentials saved in your stack. Instead, it implicitly utilizes whatever authentication is configured on the device that you are running the CLI on. **Rule of thumb:** If you are able to clone, pull, and push to the remote repository (without Git prompting for authentication) using a terminal on the device you intend to run the OrgFlow CLI on, then the OrgFlow CLI will be able to do so too. How you configure Git authentication on the device is up to you. The most appropriate method will depend on context and your preferences: ### Local computer For local computer scenarios, especially when your repository is hosted by a commercial Git provider, the easiest and most popular way is to use [Git Credential Manager](https://github.com/git-ecosystem/git-credential-manager). Another popular way (though more technically advanced) is to use SSH keys, which is fully supported when using the OrgFlow CLI. ### CI/CD platforms For CI/CD platforms scenarios where your Git repository and the agent/runner are colocated (such as GitHub Actions or Azure Pipelines) Git authentication is often either preconfigured by the CI/CD platform and provided transparently, or can be easily configured using built-in functionality. ### Other ephemeral scenarios For other server- or cloud-based scenarios where the agent/runner might be ephemeral, and Git authentication is not provided automatically by the platform, you will need to make sure Git authentication is configured each time the agent/runner starts up, and you cannot rely on Git's interactive authentication prompts in such contexts. How you achieve this will depend on context and platform capabilities, but it will usually involve running a script early on in the pipeline to configure Git authentication. **The way we recommend** is to use a personal access token (PAT) stored as a secret and provided to your script or pipeline as a parameter, and then using a method known as ["The Simplest Bullet"](https://coolaj86.com/articles/vanilla-devops-git-credentials-cheatsheet/) in the beginning of your script or pipeline to configure transparent Git authentication. Here's an example assuming the repository is in GitHub and we have a PAT stored in the `$TOKEN` variable: ```shellscript # Handle all 3 styles of Git URL as authenticated HTTPS URLs: git config --global url."https://api:$TOKEN@github.com/".insteadOf "https://github.com/" git config --global url."https://ssh:$TOKEN@github.com/".insteadOf "ssh://git@github.com/" git config --global url."https://git:$TOKEN@github.com/".insteadOf "git@github.com:" ``` Another popular way is to use SSH keys, which is fully supported when using the OrgFlow CLI. ### Managed repositories When using the OrgFlow CLI, authentication to [managed repositories](/docs/devops/managed-repos/) works the same way as any other repository. You must have a GitHub user account to authenticate with, and that user account must be added as a contributor to the managed repository. After that you can use any of the authentication methods outlined above. ## Managing saved credentials Git credentials saved in OrgFlow's cloud for a stack can be managed from the **stack settings** page. ## Choosing a Git user account OrgFlow needs a Git user account with sufficient permissions to carry out the following tasks in your Git repository: * Clone the repository (read) * Push commits (write) * Optional: Force push (needed for snapshots and rollback functionality) * Optional: Create and delete branches (needed unless you create/delete all environment branches manually) If you have advanced security or compliance needs, and your Git provider supports it, you can use branch policies or other security mechanisms to limit permissions to only a subset of branches that OrgFlow actively uses. You will need to make sure that the user can perform the necessary actions against all of the branches in your OrgFlow stack. ## Creating personal access tokens (PATs) Most Git providers support personal access tokens (PATs) in one way or another. How to create access tokens varies by provider. Here are links to instructions for some commonly used commercial providers: * [Azure DevOps](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops\&tabs=Windows) * [Bitbucket](https://support.atlassian.com/bitbucket-cloud/docs/create-a-repository-access-token/) * [GitHub](https://github.com/settings/tokens/new?description=OrgFlow\&scopes=repo) * [GitLab](https://docs.gitlab.com/user/profile/personal_access_tokens/) If you provider's access tokens have *scopes* then you'll need to ensure that the [correct scopes](#choosing-a-git-user-account) are selected. Available scopes and their meanings differ between providers. ::: warning Consider access token expiration Pay close attention to the expiration date of the access tokens that you create. When an access token expires you will need to create a new one and update any saved Git credentials in OrgFlow accordingly. Choose a duration that's long enough to be practical and not risk frequent disruptions, but not long enough to constitute a security risk. ::: --- --- url: /docs/security/salesforce-authentication.md description: Details about how OrgFlow authenticates with customer's Salesforce orgs --- # Authenticating to Salesforce OrgFlow needs to connect to your Salesforce orgs in order to do things like check for metadata changes, deploy and retrieve metadata, run Apex tests, import and export data records, and more. OrgFlow supports two authentication methods when connecting to Salesforce: **browser-based authorization** and **credentials**. ## Browser-based authorization With browser-based Salesforce authorization, OrgFlow will prompt you to sign in to Salesforce using your web browser and authorize OrgFlow to connect. Once you have completed the authorization flow, Salesforce provides OrgFlow with an access token and a refresh token, and those are stored securely in OrgFlow's cloud. OrgFlow can use the saved tokens to connect to Salesforce for as long as they remain valid, meaning that you will only need to re-authenticate if those tokens get invalidated. This is the **simplest and most secure method** of authenticating to Salesforce because OrgFlow never sees the password that is used to authenticate. With this method, you will need to sign in using a web browser **at least once for every Salesforce org that OrgFlow connects to**. This means that jobs might pause to wait for user input, which delays completion of the job. For example, a **create environment** job that creates a new sandbox will need to pause and prompt for authorization, and then wait for a user to perform the sign-in and authorization flow in the new sandbox before it can proceed to add it to your stack. ### Token invalidation Access and refresh tokens can be invalidated or revoked by Salesforce, meaning that the tokens that are saved in OrgFlow's cloud are no longer valid. In this scenario OrgFlow will prompt for an authorization flow to be completed again. Actions that might invalidate or revoke access and refresh tokens include: * Refreshing a sandbox * Manually revoking tokens in the Salesforce setup UI * Access and refresh tokens expiring because of inactivity * Deactivation of the Salesforce user account that the tokens were issues for Tokens acquired using this method are not subject to Salesforce's password expiration policies. However, if the tokens expire or get invalidated, a non-expired password is required to sign-in again and complete a new authorization flow. ## Credentials With this method you provide OrgFlow with Salesforce *credentials*, consisting of a username, a password and possibly a [security token](#security-tokens). OrgFlow then uses these credentials to authenticate whenever it needs to connect to your Salesforce orgs. When also [saving those credentials](#saving-credentials), this is the **most convenient method** of authenticating to Salesforce because once credentials have been saved, OrgFlow can use them to connect to your Salesforce orgs without requiring user interaction. Additionally, you typically only need to provide credentials for your production org; OrgFlow can use [sign-in values transformation](#sign-in-values) to use those credentials also for sandboxes, which means OrgFlow will be able to create and manage sandboxes without the need for any user intervention. ::: tip Allow OAuth Username-Password Flow in your org settings When using credentials, OrgFlow Web uses the *OAuth Username-Password Flow* to authenticate to Salesforce. This flow is blocked by default in new orgs created on Summer ‘23 or later versions, and must be allowed in your organization's OAuth and OpenID Connect settings. ::: If you choose this method of authentication, you may want to consider excluding the selected user account from password expiration policies because, if the password expires, it must be changed and any saved credentials updated. ### Required security settings To use credentials to authenticate to Salesforce, you must ensure that your organization has enabled the OrgFlow Web ### Security tokens Depending on the security policies and configuration of the Salesforce orgs that you are authenticating to, you may need to also provide a [security token](https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_concepts_security.htm). When providing Salesforce credentials in the OrgFlow web app, we provide a specific text field the security token. However, if entering Salesforce credentials into the OrgFlow CLI, the security token must be appended to the end of the password. For example, if your password is `123456` and your security token is `abcdef`, then you need to enter `123456abcdef`. ### Saving credentials Credentials can be saved for reuse. Passwords and security tokens are [encrypted](/docs/security/encryption/) when they are saved. Credentials can be saved in two locations: #### OrgFlow's cloud Credentials saved in OrgFlow's cloud can be used by both the OrgFlow web app and the OrgFlow CLI. If you create a stack via the OrgFlow web app and choose to use credentials, your credentials will automatically be encrypted and saved in the OrgFlow cloud. Credentials saved in OrgFlow's cloud can be managed by both the OrgFlow web app (using the **stack settings** page), and the OrgFlow CLI (using the `auth:salesforce:save` command). #### On your device OrgFlow CLI can also save and read credentials on local disk on the device that the CLI is running on. This is useful if you don't want to save your credentials in OrgFlow's cloud, want to use different credentials on different devices, or want to override credentials saved in OrgFlow's cloud. Credentials saved locally on your device take precedence over those saved in OrgFlow's cloud. Credentials saved locally on your device can be managed using the `auth:salesforce:save` command. ## Choosing a Salesforce user account Regardless of the authentication method you choose, OrgFlow connects to Salesforce using a specific user account. It's important to make sure that this user has sufficient licenses and permissions for OrgFlow to fully operate. The selected user must be able to: * Retrieve and deploy metadata * Manage sandboxes * Run Apex tests * Read source tracking data (if enabled) Additionally, we recommend that you: * Use a dedicated user account only for OrgFlow * Use an [API-only user account](https://help.salesforce.com/s/articleView?id=platform.integration_user.htm\&type=5) * Consider excluding the user account from password expiration policies (if using username and password authentication) If you are a system administrator in your Salesforce production org, one option is to use your own user account. This may be suitable for evaluation, experimentation or for very small teams, but it has significant drawbacks. A more robust option is to create a new API-only production user account dedicated for this purpose, as described above. ## Sign-in values The details required for OrgFlow to connect to a Salesforce org are referred to as *sign-in values* and consist of: * Username * Optionally: * Custom sign-in URL * Password * Security token (depending on your Salesforce security settings) When you create a new stack, you provide sign-in values for connecting to your production org. These details are stored in the stack, and referred to as the *base* sign-in values. Sign-in values for connecting to an environment's Salesforce org can usually be *inferred* automatically from the base sign-in values stored on the stack. For the production environment, the base values on the stack can be used as they are. For sandbox environments, the settings on the stack can be *transformed* based on the sandbox name. The following table illustrates this transformation logic: | Setting | Base values | Sandbox ALPHA (inferred) | | ----------- | -------------------------------- | ----------------------------------------------- | | Sign-in URL | `https://acme.my.salesforce.com` | `https://acme--ALPHA.sandbox.my.salesforce.com` | | Username | `jane.doe@acme.com` | `jane.doe@acme.com.ALPHA` | | Password | `********` | (unchanged) | You can also configure sign-in values directly on an individual environment. These values will then override any inferred values. This can be useful in a variety of scenarios, such as when: * You have chosen not to store base sign-in values on the stack * A sandbox has different domain settings than your production org * You prefer to use a different authorization method or user account to connect to a sandbox than your production org * You prefer to use different production credentials for metadata flow than sandbox management ## Custom sign-in URL By default, OrgFlow will use `https://login.salesforce.com` (`https://test.salesforce.com` for sandboxes) to perform the initial browser-based authorization flow (or perform the initial validation of provided credentials). Upon successful authorization/validation, Salesforce provides OrgFlow with the [enhanced domain](https://help.salesforce.com/s/articleView?id=xcloud.domain_name_enhanced.htm\&type=5) for your org. OrgFlow will then use the enhanced domain for further requests to the same Salesforce org (regardless of which URL was used to sign in). You can also choose to provide your enhanced domain up-front as a *custom sign-in URL*. The enhanced domain of your production org is typically something similar to `https://[company].my.salesforce.com`. It is recommended that you provide your enhanced domain if possible; the legacy sign-in URLs may still work, but Salesforce discourages their use and, depending on your Salesforce security settings, they may have been disabled. --- --- url: /docs/basics/billing.md description: 'Details about OrgFlow''s pricing, licensing and billing models' --- # Billing OrgFlow's billing and pricing is based on the amount of resources that a workspace uses or has available to it. Every workspace comes with a certain amount of resources available for free. This means that **you can use OrgFlow for free, forever**, so long as you stay within the free resource allocations. If your needs grow beyond the free resource allocation, you can scale up each resource individually, and pay only for what you actually need. This plan is known as **OrgFlow Pay-as-you-go** and is the default for all new subscriptions. Billing is managed and performed at the [workspace](/docs/core-concepts/workspaces/) level, so billable resources are shared between all the [stacks](/docs/core-concepts/stacks/) in a workspace. ## Billable resources ### Environments The maximum allowable count of all [environments](/docs/devops/environments/) across all the stacks in a workspace. **Included for free:** 3 Environments can be increased for a fixed monthly fee. An increase in available environments will take effect immediately and the first charge will be prorated to the time remaining in your current billing cycle. A reduction will take effect at the start of your next billing cycle. If you try to create a new environment and you are currently using all of the environments available to you, the process will fail. ### Concurrent workers The number of [jobs](/docs/core-concepts/jobs/) that can run in parallel (simultaneously) across all the stacks in a single workspace is limited by the number of *concurrent workers* available to the workspace. **Included for free:** 2 Concurrent workers can be increased for a fixed monthly fee (up to a maximum of 8). An increase in your concurrent workers will take effect immediately and the first charge will be prorated to the time remaining in your current billing cycle. A reduction will take effect at the start of your next billing cycle. If you try to start a job to run on a managed worker within OrgFlow's cloud and you are currently using all of your available concurrent workers, the job will wait in a pending state until a worker becomes available. Jobs run using the [OrgFlow CLI](/docs/cli/) are not subject to the concurrent worker limit. ### Active worker minutes (DevOps) Active worker minutes (DevOps) are the number of minutes that jobs spend doing DevOps work (such as retrieving and deploying metadata) on hosted workers in OrgFlow's cloud. **Included for free:** 600 per month Active worker minutes (DevOps) are billed on a consumption basis. At the end of each billing cycle you will be charged for the total minutes used across all stacks in your workspace throughout the billing cycle (minus any free allocation). Minutes used are calculated at the end of each job and are visible at a per-job level on the job details pages. Partial minutes are rounded up to the nearest whole minute on a per-job basis (e.g. a job that does 1 minute and 50 seconds of active work will be billed for 2 worker minutes). Jobs run using the [OrgFlow CLI](/docs/cli/) do not count towards your DevOps worker minutes. ### Active worker minutes (Data) Active worker minutes (Data) are the number of minutes that jobs spend doing data work (such as importing or exporting data records) on hosted workers in OrgFlow's cloud. **Included for free:** 300 per month Active worker minutes (Data) are billed on a consumption basis. At the end of each billing cycle you will be charged for the total minutes used across all stacks in your workspace throughout the billing cycle (minus any free allocation). Minutes used are calculated at the end of each job and are visible at a per-job level on the job details pages. Partial minutes are rounded up to the nearest whole minute on a per-job basis (e.g. a job that does 1 minute and 50 seconds of active work will be billed for 2 worker minutes). Jobs run using the [OrgFlow CLI](/docs/cli/) do not count towards your data worker minutes. ### Passive worker minutes Passive worker minutes are the number of minutes that jobs spend waiting for user input on hosted workers in OrgFlow's cloud. **Included for free:** 1800 per month Passive worker minutes are billed on a consumption basis. At the end of each billing cycle you will be charged for the total minutes used across all stacks in your workspace throughout the billing cycle (minus any free allocation). Minutes used are calculated at the end of each job and are visible at a per-job level on the job details pages. Partial minutes are rounded up to the nearest whole minute on a per-job basis (e.g. a job that spends 45 seconds waiting for user input will be billed for 1 passive worker minute). Jobs run using the [OrgFlow CLI](/docs/cli/) do not count towards your passive worker minutes. ### Data retention Some historical data (such as Apex test runs, jobs, artifacts, snapshots etc.) is subject to a data retention period limit. Items older than this limit are automatically deleted, after which you will no longer be able to access or view this data. **Included for free:** 7 days The data retention period can be extended for a fixed monthly fee. An increase in your retention period will take effect immediately and the first charge will be prorated to the time remaining in your current billing cycle. A reduction will take effect at the start of your next billing cycle. ## Billing cycles The billing cycle for a workspace starts when the workspace is created and lasts for a month. At the start of each billing cycle the usage counters (and any free allocations) are reset. If your subscription includes any fixed monthly fees, you will be invoiced (and charged) for those at the start of each billing cycle. Resources billed on a consumption basis will be invoiced (and charged) at the start of the next billing cycle (i.e. once we know your total usage for the previous billing cycle). ## Viewing usage The **Billing and usage** page in your workspace shows your current usage and limits, as well as your subscription status and how far through your current billing cycle you are: ## Cost control Environment, concurrent worker, and data retention resources are limited by the quantity that you have chosen to subscribe to. Therefore you will always know exactly how much you'll be billed for these items each billing cycle. Worker minutes, however, are billed on a consumption basis, and costs for these resources might be unpredictable. We can configure your workspace so that jobs cannot be started once you have used a certain number of active or passive worker minutes in a single billing cycle. This can help you manage subscription costs, as well as give you peace of mind knowing that you can't run up an unexpectedly large invoice. By default these limits are set to match your free allocation, but they can be lifted on request. ::: warning You may still be charged if you go over your workspace limits Worker minute limits can prevent jobs from being started, and also cancel running jobs when you reach one of those limits. However, because jobs must make efforts to leave your stack in a consistent state, jobs cannot always be cancelled immediately, and as a result, jobs may sometimes run long enough to take you over your limits, and you may be charged for the additional minutes used. These limits are a cost control tool, but not an exact hard cap on how much you can be charged during a single billing cycle. ::: ## Payment methods You can use OrgFlow for free without supplying any payment method. If you plan to use more resources than are included for free, you will need to supply a payment method so that we can charge you for the usage incurred. This can be done from the **Billing and usage** page in your workspace. The default payment method is a credit or debit card. This is convenient as it allows us to automatically charge you at the start of each billing cycle, and you don't have to worry about making payments. If you would prefer an alternative payment method (such as bank transfer with payment terms), [get in touch](/contact/) and we can discuss your needs. ## OrgFlow Unlimited If you anticipate heavy usage (or prefer the predictability of a flat, fixed fee) we also offer the **OrgFlow Unlimited** plan. OrgFlow Unlimited includes unlimited resources (expect concurrent workers which is limited to 8 as a guardrail). This means you will be charged a fixed amount each billing cycle and can use as much OrgFlow as you like without worrying about costs. OrgFlow Unlimited can also be invoiced annually, offering a discount on the monthly pricing. Go to the **Billing and usage** page in your workspace to view your upgrade options. ## Custom plans If you think you have a unique use case for OrgFlow that isn't covered by our standard plans and agreements, [get in touch](/contact/) and we can discuss your needs. --- --- url: /contact.md description: Options for getting in touch with the OrgFlow team --- For sales or customer service inquiries (e.g. help with licensing or billing issue, booking a demo, or questions about how OrgFlow can help their team) users should either send email to or fill out the form on our [contact page](https://www.orgflow.io/contact/). For technical support, users should [submit a support ticket](https://www.orgflow.io/support/) by sending email to . --- --- url: /docs/reference/default-include-file.md description: >- The include file contents that OrgFlow suggests as the default when initializing a new stack --- # Default include file The include file that OrgFlow suggests as the default when initializing a new stack can be viewed at [www.orgflow.app/default-include-specs](https://www.orgflow.app/default-include-specs), or by expanding the **More options** section in the **Initialize stack** dialog and selecting **Customize** to view and edit the default include specs. The default include specs suggested for **new** stacks can change over time, for example because new metadata types are added by Salesforce, or to work around issues or quirks with the Salesforce metadata API as they are discovered. Include specs already is use in **existing** stacks will not be modified automatically. --- --- url: /legal/license.md description: >- Current in-effect End User License Agreement for the access and use of OrgFlow software and services --- # End User License Agreement This document constitutes the current in-effect End User License Agreement for the access and use of OrgFlow software and services. This agreement is referred to as the EULA in our software, hereinafter in this agreement, and elsewhere on this website. ## 1. Introduction ### 1.1 Supplier, Software and Functionality We, with seat in Bad Nauheim, GERMANY (hereinafter: OrgFlow, We or Us) offer our customers (hereinafter: User or You) the use of the Development and Deployment Software developed by Us (hereinafter: Software). The Software is a set of tools that utilize the power of the Git version control software to enable teams of any size to achieve low-effort, safe and successful org-based team development, deployment and DevOps on the Salesforce platform. In order to provide the Software We cooperate with other companies subject to this EULA. Inter alia, Microsoft Azure or Docker Inc. support Us in the provision of the Software. For more information, please visit our website at . **Please note** that for most practical purposes, use of the Software requires a Salesforce account on Your end (hereinafter: Salesforce); for more information on Salesforce see . We are not responsible for providing You with a Salesforce account, nor for supporting You in acquiring, running, administering or maintaining such a Salesforce account. **Please note further** that for most practical purposes, use of the Software requires a Git version control software on Your end (hereinafter: Git); for more information on Git see . We are not responsible for providing You with such Git version control software, nor for supporting You in acquiring, running, administering or maintaining such a Git version control software. ### 1.2 Acquisition Options with Regards to the Software The Software is comprised of and delivered to You as several distinct parts: * A product marketing website hosted by Us at (hereinafter: Website) * A web application hosted by Us at (hereinafter: Web App) * A cross-platform command-line executable (hereinafter: CLI) downloadable via our Web App or via our repositories in Docker Hub at (Docker Hub is owned and operated by Docker Inc.) or through other means, such as operating system package managers * A comprehensive set of REST-based APIs and back-end services hosted by Us which provide supporting functionality for the Website, Web App and CLI You may access the Software in any of the aforementioned ways. Acquisition of downloadable Software binaries (i.e. the CLI) does not require any registration, but use of the Software does require successful registration as stipulated in item 2 below. ### 1.3 Scope of this EULA Inter alia, this EULA stipulates who may use the Software, how the Software may be used, and provides for further relevant information and provisions regarding the contractual relationship between You and Us regarding the Software. Please take the time to read this EULA carefully before using the Software. **Any use of the Software requires that You accept this EULA and comply with the instructions and requirements contained herein during use at any time.** This EULA is available on our website at any time. However, We recommend that You save and/or print a copy of this EULA so that You may refer to it at any time. We currently offer the Software to **business customers only**, i.e. only to entrepreneurs in the sense of Section 14 of the German Civil Code (Bürgerliches Gesetzbuch, hereinafter: BGB) – an entrepreneur in that sense is any natural or legal person or a partnership with legal personality who or which, when entering into a legal transaction, acts in exercise of his or its trade, business or profession. **We do not offer the Software to consumers** (in the sense of Section 13 BGB) – i.e. to natural persons who enter into a legal agreement or transaction for purposes that predominantly are outside his or her trade, business or profession – since We do not conclude a contract with consumers and consumers may therefore not use the Software. This EULA constitutes and governs the contractual relationship between You and Us with regard to the Software and You accept that this EULA applies to the exclusion of any terms contained in any of Your own documents even if the same purport to provide that Your own or some other terms prevail. Your use of the Software constitutes Your acceptance of this EULA. Deviating general terms and conditions of You do not apply in any case, even if We do not expressly object to them. ### 1.4 Data Protection With regard to the processing of personal data in connection with Your use of the Software, please see our Privacy Policy, which is also available on our Website under [https://www.orgflow.io/legal/privacy](https://www.orgflow.io/legal/privacy/). Our Privacy Policy describes the personal data that We collect and how We use it and includes Your data subject rights as well as other information about our processing of personal data. Your own responsibility for processing personal data under applicable data privacy laws remains unaffected by any responsibility that We may also have if You process personal data from third parties via the Software. ### 1.5 Contact For all questions, explanations, correspondence or support regarding the use of the Software, please contact our support team: You can reach Us via our support page at . ## 2. Authentication, Access to and Use of the Software ### 2.1 Registration Acquisition of downloadable Software binaries (i.e. downloading of the binaries to a computer under Your control) is an unauthenticated and anonymous process (see item 1.2 above). However, Access to and Use of the Software requires Registration, which involves providing Us with same basic Registration Data in order to create individual User Accounts and a Workspace as described below. #### 2.1.1 User Account Access to the Software requires each User in or affiliated with Your organization to create an individual User Account via the Web App. A User Account is personal to each User, and used by Us to Authenticate and identify said User by means of a unique username (email address) and a password. When creating the User Account the User is required to provide a valid email address, a password, and His/Her full name. The User will thereafter use the provided email address and password to Authenticate Him/Herself in order to Access the Software. #### 2.1.2 Workspace Use of the Software furthermore requires You to create a Workspace via the Web App. A Workspace is a top-level container for all Your data and configuration in OrgFlow (hereinafter: Workspace Data) and usually corresponds to Your organization, or in some cases, a smaller team within Your organization. When creating the Workspace You are required to provide Your organization's officially registered legal entity name, and the full name and phone number of Your organization's primary contact. The creation of a Workspace implies acceptance of this EULA on behalf of Your organization, enters Your organization into a legal relationship with Us subject to the terms of this EULA, and must only be carried out by a User who is duly authorized to enter into legal and commercial agreements on behalf of Your organization. The User who creates a Workspace becomes its first Member and is also designated as the Workspace Owner. The Workspace Owner may subsequently Grant Access to other Users which then become additional Members of the Workspace. ### 2.2 Authentication and Security; Up-to-dateness The Registration Data You provide must be complete and correct. You may only provide information or personal data on other persons if You act within the scope of Your power of representation required for this purpose and within applicable data privacy laws. You are obliged to keep the Registration data up to date at all times. Contact information and billing information can be updated through Your account portal, which can be accessed at any time through the Web App. Authentication with the Software is done exclusively via a User Account. Access to Your Registration Data and Workspace Data is provided only to User Accounts to whom You Grant Access (see item 2.1.1 above) by adding them as Members in Your Workspace (hereinafter: Member User Accounts). The security of Your Registration Data and Workspace Data depends upon Your ability to only Grant Access to authorized Users, and upon the ability of those Users to keep their User Accounts secure. You are therefore solely responsible for keeping Your Registration Data, Workspace Data and Member User Accounts secure and confidential. All actions taken in connection with Your Registration Data, Workspace Data or Member User Accounts, whether authorized or not, shall be deemed to have been taken by You or on Your behalf with Your authorization. However, Your responsibility for the misuse of Your Registration Data, Workspace Data or Member User Accounts is limited to the extent that You become the victim of illegal attacks by third parties (e.g. hackers, thieves, fraudsters) despite having exercised due care, but the burden of proof with regard to such circumstances shall remain with You. In case You have any doubts or concerns about the confidentiality of Your Registration Data, Workspace Data or Member User Accounts, including, without limitation, any suspicion that another person knows or had access to Registration Data, Workspace Data or Member User Accounts without authorization, You must immediately inform Us accordingly by contacting our customer support at We will then work with You take necessary steps (within reason) to restore the security and confidentiality of Your Registration Data, Workspace Data and Member User Accounts. ### 2.3 Responsibility for Other Persons Using the Software Please note that You are responsible for the actions of any individuals who are Granted Access to the Software by You. You must therefore ensure that such Access only occurs if You have duly authorized those persons within the scope of this EULA, and that those persons comply with this EULA at all times. ## 3. License to Use OrgFlow Software; Subscription Fees; Payment ### 3.1 License Terms At the time when You create a Workspace via the Web App and accept the terms of this EULA, You enter into a legal relationship with Us. As part of that relationship We grant You a non-exclusive, non-transferable, non-sublicensable right to acquire, install, access, use and copy the Software subject to the terms of this EULA (hereinafter: License). The License governs Your **legal** relationship with Us. The right to copy is limited to the acquisition and installation of the downloadable Software binaries on a computer (physical or virtual) which is in Your immediate control in order to fulfill the Purpose of Use, and any copying which is required for the loading, display, running, transfer or storage of the Software as well as to the right to make a copy for security backup purposes, as stated in sec. 69d para. (2) German Copyright Act (Urheberrechtsgesetz, hereinafter: UrhG). You may not, nor may You allow any third party to, reverse engineer, decompile or attempt to discover any source code or underlying ideas or algorithms of the Software (however, sec. 69d, 69e UrhG shall remain unaffected). The License is a **company license** i.e. the Software may only be used by the You, Your employees, and Affiliates or Contractors/Agents of Yours who are acting on Your behalf by providing implementation, consulting or outsourcing services and are under a written agreement with You that will protect the Software subject to the same protections and restrictions otherwise stated in this Agreement. "Affiliate" shall mean any entity that controls, is controlled by or shares common control with You, where such control arises from either (a) a direct or indirect ownership interest of more than 50% or (b) the power to direct or cause the direction of the management and policies, whether through the ownership of voting stock, by contract, or otherwise, equal to that provided by a direct or indirect ownership of more than 50%. The use of the Software under Your License by any other third party is strictly prohibited. You are granted the License (i.e. the right to use the Software) only in accordance with the terms and conditions of this EULA. Any other use (e.g. circumvention of security mechanisms) is prohibited, unless otherwise agreed in individual cases. Except as otherwise provided in other agreements, Your rights of use in connection with the Software are limited to the term of this Agreement. You also have the duty to refrain from anything that could impair the use of the Software, in particular the introduction of trojans, viruses or other malware. Any manipulation, technical modification of the Software is prohibited. If You infringe upon any of the above provisions (or item 5 below), all Licenses granted to You under this Agreement shall immediately become ineffective and shall automatically terminate. In this case, You must immediately and completely cease using the Software and delete any copies You have made. ### 3.2 Scope of License The License is **consumption-based** and includes the right to consume a certain amount of OrgFlow-provided Resources per month. The following types of Resources are defined and metered by the Software: * A number of Environment Hours defined as the highest number of configured connections between a Salesforce org and a backing Git branch that existed during a one-hour period * A number of Active Worker Minutes (DevOps) defined as the total number of running minutes, across all jobs run on OrgFlow-provided managed worker instances in Your Workspace, spent performing active DevOps work * A number of Active Worker Minutes (Data) defined as the total number of running minutes, across all jobs run on OrgFlow-provided managed worker instances in Your Workspace, spent performing active data work * A number of Passive Worker Minutes defined as the total number of running minutes, across all jobs run on OrgFlow-provided managed worker instances in Your Workspace, spent passively awaiting input from Users * A number of Concurrent Workers defined as the maximum number of jobs that can be concurrently running in Your Workspace on OrgFlow-provided managed worker instances at any given point in time * A number of Retention Days defined as the minimum number of days during which We keep historical Workspace Data available to You The amount of Resource Consumption permitted by the License depends on the applicable Subscription, as described further below. The Subscription may include a limited or unlimited amount of Resources for free, or may include a limited or unlimited amount of Resources as part of a fixed monthly price. Consumed Resources beyond those included in the Subscription are billed automatically on a Pas-As-You-Go basis according to pricing information always available via our Website. ### 3.3 Subscriptions and Plans The License is associated with a Subscription which governs Your **commercial** relationship with Us. The following types of Subscriptions (i.e. Plans) are available: * Pay-As-You-Go (default) * Unlimited * Custom/bespoke plan for special requirements #### 3.3.1 Changing Plans; Upgrades and Downgrades The License is created with a "Pay-As-You-Go" Subscription by default. Because this type of Subscription is entirely consumption-based and has no pre-paid or fixed fees, it is not subject to forced billing periods or proration. You may cancel Your "Pay-As-You-Go" Subscription at any time via the Web App. You may also change Your "Pay-As-You-Go" Subscription to a different Plan at any time via the Web App, or by contacting Us. Doing so results in the immediate cancellation of Your "Pay-As-You-Go" Subscription and the immediate start of a new Subscription with Your chosen Plan. An "Unlimited" or custom/bespoke Subscription is subject to restrictions and proration with respect to its chosen billing period. If You cancel or downgrade Your Subscription (e.g. by changing back to the "Pay-As-You-Go" Plan or by adding/removing add-on products) during a billing period (month or year), the proration of upgrades/downgrades that occur in that period is carried out by Our billing provider Stripe automatically. Upgrades/additions take effect immediately and are prorated for the remainder of the billing period; Downgrades/removals take effect at the start of the next billing period. #### 3.3.2 Terms of Payment As long as Your Resource Consumption stays within the amount of Resources included for free in Your Subscription, You will not incur any charges from Us. As and when Your Resource Consumption grows beyond what is included for free, the overages are billed automatically on a Pay-As-You-Go basis which starts accruing a Subscription Fee balance in Your account. The Subscription Fee balance, plus any applicable taxes and duties, will be invoiced to You either whenever Your open balance reaches a certain billing threshold (determined by Us at Our discretion on a case-by-case basis), or at one-month intervals following the creation of Your Subscription, whichever occurs first. Invoices are due for payment 7 days after issuance, unless You have arranged alternative payment terms with Us. If We have already acquired a payment method from You (see item 3.3.3 below), we will attempt to charge the amount to this payment method immediately upon issuing the invoice. #### 3.3.3 Billing Information; Payment Methods We do not require or collect any billing information or payment methods from You up-front when You create a Workspace and start using the Software. You will only be required to provide billing information and a payment method when paying Your first invoice, which may or may not happen depending on Your Subscription and Resource Consumption (see item 3.3.2 above). #### 3.3.4 Termination In the event of termination by You or any other termination of Your use of the Software for any reason, no Subscription Fees will be refunded in whole or in part. If payment of the Subscription Fees is not made by the due date for payment, We reserve the right to deactivate the Software used by You by revoking Your License. Upon such revocation, Your Registration Data, Workspace Data and Member User Accounts will be retained by Us for a period of two month (unless You request an earlier deletion) and Your access to them can be restored by paying any due Subscription Fees. If payment of all due Subscription Fees is not made within two months, Your Registration Data and Workspace Data will be marked for deletion and will be physically deleted from Our systems within one more month. You shall not be entitled to make any deduction, set-off or retention in relation to any Subscription Fees payable unless Your counterclaim has been legally established and is undisputed or unacknowledged by Us. ### 3.4 License Duration and Extension The term of the License will be the Subscription Period which is defined as the indefinite term between the start and termination of the Subscription by either Party, unless otherwise agreed. Neither You nor We may properly terminate this EULA and the License. However, the right to terminate the License extraordinarily and immediately for good cause (sec. 314 BGB) shall remain unaffected for either party. ## 4. Availability, Responsibility ### 4.1 Availability The provision of the Software is the provision of a service to You on an "as is" basis and that service will be carried out by Us with reasonable care and skill. Beyond the statutory warranty, We do not provide any guarantees as to the performance of or use of the Software including with regard to the availability of the Software, but strive for continuous and uninterrupted availability and freedom from errors. We also reserve the right to further develop the functions and possible uses of the Software. The Software needs to be updated from time to time for objective reasons, such as bug fixing, functional enhancements, hardware compatibility adjustments, possible vulnerability closures, and similar cases. Such updates are also carried out in Your interest and can be downloaded and installed at Your discretion. Temporary restrictions on availability may also result from maintenance work or force majeure events. Further, the latest version can be downloaded and updated at any time You prefer, in the case You have an active subscription. Please note that, as the Software is subject to regular updates and revisions, OrgFlow cannot guarantee that previous versions remain operable for the whole applicable subscription cycle. In case an updated version will invalidate previous versions, OrgFlow will provide notice to You at least two weeks in advance. However, in such case You do not have the right to prematurely terminate Your Subscription in case You do not want to apply the respective update. Please contact Us if You have any problems or complaints regarding the use of the Software. ### 4.2 Accountability You are responsible for all requirements necessary to access the Software, such as sufficient Internet connection and bandwidth, hardware and/or the software You use, and the establishment of data connection points. You are responsible for providing and using appropriate security devices and virus scanners on Your devices. ## 5. Intellectual Property Rights All information published by Us via the Software, and the Software as such, in particular data, texts, images, graphics, maps, logos and their presentation, as well as any of our trade secrets or know how contained therein (hereinafter: Content) may only be used in accordance with this EULA and the applicable legal regulations. In particular, the use of any Content on third-party websites and/or platforms and/or beyond the use permitted under the License is prohibited. Your use of the Software does not grant You any right to use any intellectual property rights such as copyrights, trademarks or patents owned by Us, unless expressly stated otherwise. You may not transfer any Content or the Software as such to third parties (e.g. other companies) without our prior written consent, unless We have expressly agreed to this in writing. ## 6. Reporting; Liability; Indemnity Obligation ### 6.1 Reporting You must report any material defects and defects of title immediately after their discovery in writing (email is sufficient) and describing the detailed circumstances. We will then check Your complaint and decide on the removal or remedy of the defects. However, We shall only be liable for defects which already existed when the License was granted to the User if We are responsible for these defects; otherwise, the statutory provisions shall apply. ### 6.2 Liability To the extent permitted by law and unless expressly provided otherwise under this agreement our liability for claims and remedies irrespective of their nature, amount and legal basis shall be excluded. You shall be liable to Us for all losses, damages, costs, charges and expenses suffered or incurred by Us as a result of or in connection with any breach of this EULA by You. You shall indemnify Us against all claims, including claims for damages, which third parties assert against Us on account of a violation of their rights due to a use of the Software attributable directly or indirectly to You (e.g. via vicarious agents). You shall bear all necessary costs incurred by Us due to such an infringement of rights, including the usual reasonable costs for legal defence incurred by Us. You are free to prove that We have incurred lower costs. Your aforementioned obligations to indemnify do not apply if You can prove that You are not responsible for the breach of duty in question. You must notify Us immediately of any claims by third parties that You know or become aware of in connection with the use of the Software. ## 7. Transmissibility Claims or rights against Us relating to this EULA, the use of the Software or the License may not be assigned to any third party or otherwise disposed of or dealt with without our express prior written consent; such consent may not be unreasonably withheld by Us. This shall not apply if the claim is a monetary one and the legal transaction, which gave rise to the claim is a commercial transaction for both parties or the debtor is a legal entity under public law or a special fund under public law. ## 8. Termination of the Contract ### 8.1 Expiration of Subscription Period This EULA will be terminated automatically upon expiration of the Subscription Period (see item 3.4). Reasons include, but are not limited to, cancellation of the Subscription. Upon termination, Your right to use the Software expires. You can cancel a Subscription anytime through the account portal which You can access at any time through our Website. For a "Pay-As-You-Go" Subscription, cancellation becomes effective immediately. For an "Unlimited" or custom/bespoke Subscription, cancellation becomes effective by the end of the billing period during which the cancellation occurred (see items 3.3.1 and 3.3.4 above). ### 8.2 Extraordinary Right of Termination We are entitled to terminate this agreement if there is an important reason for doing so. This is the case if, taking into account all circumstances of the individual case and weighing the interests of both parties, We cannot reasonably be expected to continue the contractual relationship until the next agreed termination date or until the expiry of a period of notice. If the important reason consists in a breach of duty, termination is only permissible after the unsuccessful expiry of a period determined for remedy or after an unsuccessful warning, insofar as this is not dispensable by way of exception due to special circumstances. An important reason for Us exists if You have provided false information during Registration or in any other way significantly violated this EULA, especially in the case of violation of the License terms according to items 3.1 and 3.2 and 9. ### 8.3 Notification You will be informed about the deletion of Your User Account by corresponding messages to the email address registered for You. ## 9. Changes to this EULA Should this EULA be amended or supplemented (e.g. to meet legal or technical requirements), We will inform You immediately and in good time in advance. If You wish to continue to use the Software, You must agree to the modified EULA; otherwise You may exercise Your right to terminate the Agreement. Your consent will be deemed given, unless You have not notified Your refusal before the proposed date of entry into force of the modified EULA. If You don't agree to the modified EULA, We retain our right to terminate the agreement without notice for cause. ## 10. General Provisions ### 10.1 Enforceability (No Waiver) Your obligations set out in this EULA and/or contained in the Sale Agreements shall remain effective and enforceable even if We fail to enforce them partially and/or temporarily on any one or more occasions. ### 10.2 Dealing with Differences of Opinion We want You to be satisfied. Should there be any disagreement, please let Us talk about it. You can reach Us via the contact address given above. While We are negotiating our differences of opinion, any limitation period within which any claims should be brought is suspended. Should it not be possible to reach an agreement, legal recourse is open to You. ### 10.3 Place of Jurisdiction If You are a merchant, a legal entity under public law or a special fund under public law, the exclusive place of jurisdiction shall be Bad Nauheim, Germany; provided that any opposing mandatory places of jurisdiction for (possibly foreign) consumers shall remain unaffected. However, in addition, We are entitled to sue You before the court having jurisdiction at Your place of business. ### 10.4 Applicable Law This EULA shall be governed by German law with the exclusion of its conflict of laws provisions and the UN Convention on Contracts for the International Sale of Goods (CISG). ### 10.5 Contract Language The contractual language of this EULA and of the Software is English, unless otherwise agreed. This English version shall be the authoritative version in the event that further language versions of this EULA are provided by Us to You. ### 10.6 Priority of Individual Agreements Any deviating individual agreements with You shall take precedence over this EULA. However, such deviating individual agreement must be in writing to be effective. ### 10.7 Severability Clause Should any provision of this EULA between You and Us be or become invalid, this shall not affect the validity of the remaining provisions. If the invalid provision is an essential provision, the parties undertake to negotiate a valid provision together. --- --- url: /docs/devops/environments.md description: Conceptual deep-dive into OrgFlow environments --- # Environments An environment is a configured connection between a Salesforce org and a branch in your Git repository. It's used to keep the metadata in the Salesforce org and the Git branch in sync, by flowing metadata changes from org to branch (retrieving) and from branch to org (deploying). It's also used to flow metadata changes between different environments in the stack (merging). An environment consists of: * The name of a branch in your Git repository * Git commit settings (for example an optional commit message suffix) * Connection settings for a Salesforce org (production or sandbox) * API version selection settings * Tags * State to keep track of the metadata flow ## Production environment The *production environment* is simply the environment connected to your Salesforce production org. There must be exactly one production environment in the stack. The production environment is typically connected to the `main` or `master` branch in your repository. The production environment plays a key role in OrgFlow, but only because it's used to create and manage sandboxes. For purposes of metadata change flow and deployment, OrgFlow makes no practical distinction between your production environment and other environments. This means you are free to make changes directly in your production org, and push commits directly to your `main` branch, if you decide that's appropriate. Many teams choose to avoid making changes directly in production as a matter of risk management. OrgFlow, however, fully supports flowing changes both downstream and upstream, and imposes no such restrictions. From a business standpoint, your production org is of course treated with greater care and caution. Your production org is also normally considered the "single source of truth" whenever non-mergeable differences need to be reconciled, either between your production org and your `main` branch or between your production environment and sandbox environments. ## Sandbox environments As the name implies, *sandbox environments* are environments connected to Salesforce sandboxes. Sandbox environments are technically optional — there can be zero or more sandbox environments in the stack — but typically you will want some sandboxes in your stack in order to flow metadata changes between environments and get any meaningful DevOps work done. ### Structuring sandboxes You can create and manage as many sandbox environments in your stack as your Salesforce license supports and your workspace subscription limits allow. How frequently you create your sandbox environments, how you structure and name them, how you flow changes between them, when you delete them etc. is entirely up to you. Some example strategies include: * Sandbox per user story * Sandbox per larger project * Sandbox per developer * Sandbox for a particular purpose such as staging or user acceptance testing * Dedicated sandbox for hotfixes * A mix of the above ### Sandboxes are atomic In OrgFlow, changes are always flowed between environments by **merging between Git branches** — never as arbitrary copy/paste operations of individual files or metadata components. This brings a multitude of benefits: detailed change history, the ability to revert or roll back changes, automatic change detection, conflict detection and resolution — just to name a few. It also imposes an important restriction: all metadata changes made in a sandbox environment (and committed to its branch) are always merged to another environment **as a single cohesive unit of change**. Properly managed, this constraint is a huge advantage. It removes the tedious and error prone task of figuring out which changes depend on which other changes, in order to create a cohesive set of changes that will successfully deploy. You should always consider each sandbox environment *atomic* in terms of flowing metadata changes to other environments, and use the following rule-of-thumb to decide how to assign development efforts between sandboxes: * If two changes are **inextricably linked** (i.e. depend on each other, must be deployed together) they should be made in **the same** sandbox environment * If two changes are **potentially independent** (i.e. may need to be deployed at different times) they should be made in **two different** sandbox environments The second point is particularly important. For example, consider the following scenario: 1. Your team starts developing feature A and feature B in sandbox **ROMEO** 2. Features A and B are merged (atomically) into sandbox **TEST** 3. User acceptance testing is conducted in **TEST** 4. Feature A is accepted, but feature B is deemed **not ready for release** 5. Because features A and B come from the same sandbox and have been committed to the same Git branch, they can no longer be easily separated 6. Feature B is now blocking release of feature A ### Sandbox lifetime Environments can technically be short-lived or long-lived, depending on your needs. The longer a sandbox environment lives, the further it will inevitably drift from your production environment (and from other sandbox environments) in terms of data, users and groups, as well as metadata you have chosen to not include in the flow. Moreover, even if you regularly merge new changes into your sandbox environment from downstream (e.g. production), over time some of those changes will inevitably fail to deploy into the sandbox due to the other discrepancies (a normal and supported occurrence in OrgFlow, in itself). Such discrepancies that accumulate over time can lead to growing challenges in keeping the sandbox environment up to date. They can also be a source of merge conflicts, and they can make downstream deployments (for example deployments to production) either complete with a higher percentage of failed component or, in the worst case, fail due to failing Apex tests. ### Sandbox environment recommendations For the reasons outlined above, we strongly recommend that you **keep sandbox environments as small and short-lived as possible** by considering the following practices: * Don't create a sandbox until it is actually needed * Keep the scope of changes for a sandbox as small as possible, but no smaller * Keep inextricably linked changes together * Keep unrelated changes apart * If two changes **might** need to flow downstream at different times, always do them in two separate sandboxes * If development needs to be paused for a longer time, consider deleting the sandbox (while keeping the Git branch) and recreating a fresh sandbox from the Git branch later when development can resume * When a sandbox has been merged downstream and deployed, delete it * For staging and testing sandboxes, consider creating new ones for each release cycle ## Git settings ### Commit message suffix Each environment can optionally be configured with a *commit message suffix*, which is an arbitrary piece of text that OrgFlow will append to commit messages when committing Salesforce metadata changes to this environment's Git branch. This applies to commits made during inbound flow, but not to merges between environment branches, and not to OrgFlow's more technical commits such as metadata normalization and automatic package manifest updates. The suffix is separated from the main commit message by a blank line, in accordance with Git's conventional commit message format in which the first line is the subject and subsequent paragraphs form the body. A commit message suffix can be useful for example for tagging all commits made in a particular environment with a work item ID, which in turn allows integrations with work tracking systems (such as Azure DevOps or Jira) to automatically associate commits with the relevant work item. The commit message suffix can be set when the environment is created, either from the environment creation wizard in the web app or using the `--commitMessageSuffix` option of the `env:create` command in the OrgFlow CLI. It can be changed later at any time from the environment settings page in the web app. ## Salesforce org settings ### Sign-in values Sign-in values for connecting to an environment's Salesforce org can usually be *inferred* automatically from the *base* sign-in values stored in the stack, but you can also configure sign-in values directly on an individual environment, which will then override any inferred values. See [authenticating to Salesforce](/docs/security/salesforce-authentication/) for more information. ### API version selection mode You can also specify settings on an environment to control how OrgFlow selects with API version to use when connecting to the org. By default, these settings are not set on the environment, which means they will be inferred from the settings configured on the stack. This is recommended as it makes administration easier to manage API version settings for all environments in a single place. However, there are scenarios where you might like specific environments to use a different API version selection mode than the rest of the stack, such as during Salesforce preview windows. See the section about [managing API versions](/docs/devops/managing-api-versions/) to learn more. ## Tags Tags are arbitrary name-value pairs that you can add to environments. They are completely optional, but can be useful for a variety of purposes, such as: * To help keep environments organized * To add arbitrary information to environments that is useful to you * To use for enviroment selection in [schedules](/docs/core-concepts/schedules/) to make them more flexible * To help keep hard-coded environment identifiers out of scripts and CI/CD pipelines * To help avoid unnecessary commits and churn on your scripts and CI/CD pipelines Tags are a simple but powerful automation feature of OrgFlow. They allow you to build schedules, scripts, CI/CD pipelines and other forms of automation that treat environments differently without having to hard-code environment identifiers into your scripts. Instead, you can set different tags on different environments and base your script logic on those tags. Tags can either have no value (*value-less tags*) or any text value (*value tags*). Value-less tags are designed for purposes where there mere presense of the tag is sufficient, such as when representing and acting on boolean conditions (for example `IsDisabled` to indicate that an environment is temporarily disabled). Value tags are useful when you need to filter or carry out actions based on values that may differ between environments, such as send an email to the owner of an environment (for example `OwnerEmail:dimitrius@acme.com`). Neither tag names nor tag values carry any special meaning to OrgFlow; you decide what names and values make sense to you, what they mean and and what to use them for. Both tag names and tag values are **case-insensitive**. Tag names may only contain alphanumeric characters, hyphens and underscores. Tag values may contain anything except newline characters. Some examples: | Tag | Value | Description | | ------------ | ------------ | --------------------------------------------------------------------------------------------------------- | | `Team` | `Engagement` | Indicate which team has primary ownership of the environment. | | `Release` | `Aug 2025` | Indicate which release the feature is slated for. | | `IsInactive` | | Indicate that the environment should not receive upstream changes for the moment. | | `IsDeployed` | | Indicate that the environment has been merged and deployed to production, and is a candidate for cleanup. | | `Channel` | `#campaigns` | Indicate the name of a Slack channel where the feature can be discussed. | In the above examples, `IsInactive` and `IsDeployed` are value-less tags. They are named as boolean conditions in this example (starting with the word "is") but they don't have to be; naming is completely up to you. ### Use cases The potential use cases for tags are virtually unlimited and depend on your requirements, but here are some examples of what environment tags might be used for: * **Categorize and group** your environments and create schedules, scripts or CI/CD pipelines that apply particular logic or processing only for environments in a certain category or group. As an example, you might categorize all your environments as either `dev`, `test`, `staging`. You might then create a schedule that flows in changes to Git every night, but only for environments with the tag `Category:dev`, because no changes made in `test` and `staging` environments should be preserved. * Save **arbitrary values** on your environments and use those values as per-environment inputs to the logic or processing in your scripts or pipelines. As an example, you might designate a code owner for each development environment, and store the owner's email address on each environment with tags similar to `OwnerEmail:name@domain.com`. In your CI/CD pipelines, you might then send an email to the owner of any environment where merge conflicts are detected. * **Flag** your environments based on boolean semantics and use conditional logic or processing in your scripts or pipelines based on those flags. As an example, you might add a `noMergeFromDownstream` tag to some environments to allow environments to temporarily stop receiving automatic merges from downstream environments. In your schedule, you would then exclude any environments with this tag from processing. * **Link** your environments to external resources. When adding a tag you can use a fully qualified URL as the tag value, OrgFlow renders the tag value as a clickable link in the web app. As an example, you might link each environment to a user story in a work item tracking system with tags similar to `Story:https://acme.visualstudio.com/workitems/2164`. This can be useful for associating an environment with some external item in another system, for example a user story in a work tracking system, or a dedicated Slack channel where the environment's development efforts are discussed. ## Locks Whenever an operation runs in OrgFlow that might mutate the state of an environment (including files in its Git branch and metadata in its Salesforce org) OrgFlow puts a *lock* on the environment to ensure that it cannot be mutated by multiple operations running concurrently. Without this protection, an environment could end up in an inconsistent or corrupted state. An environment's lock status can be seen on the environments page in the web app: If an environment is already locked, and you start a new job that needs to lock the same environment, the new job waits up to 45 minutes for the existing lock to be released before failing. ### Operations requiring locks The following table shows some example operations and their resulting locks (this list is not exhaustive): | Operation | Locks | Why | | ----------------------------------- | ----- | ------------------------------------ | | Create environment A | A | Creates branch, creates+mutates org | | Flow in environment A | A | Mutates branch | | Flow out environment A | A | Mutates org | | Flow in environment A — check-only | - | No mutation | | Flow out environment A — check-only | - | No mutation | | Flow merge A to B | A + B | Mutates both branches and target org | | Flow merge A to B — no source in | B | Mutates target branch and org | | Flow merge A to B — git-only | B | Mutates target branch | | Flow merge A to B — check-only | - | No mutation | | Delete environment A | A | Deletes branch and/or org | ### Manually unlocking an environment In rare cases it may happen that an environment is left in a locked state by a job that terminated abruptly. This can happen if a managed worker gets terminated by cloud infrastructure due to maintenance or outages, or if you run an operation using the CLI and forcibly terminate the `orgflow` process. An environment being left in a permanent locked state prevents any further operations against that environment until the situation is resolved. In such cases the environment can be manually unlocked, either on the environment settings page in the web app, or using the `env:unlock` command in the OrgFlow CLI. --- --- url: /docs/data/export.md description: >- Querying and exporting data records from a Salesforce org into downloadable files --- # Exporting data from Salesforce OrgFlow's data export feature lets you query records from a Salesforce org and download the results as files. You can select objects and fields from a list, or write a custom SOQL query — and OrgFlow takes care of the rest, using the Salesforce Bulk API for fast and efficient retrieval. The exported data is saved as downloadable [artifacts](/docs/core-concepts/jobs/#artifacts) on the job, available in one or more [file formats](/docs/data/#file-formats) of your choosing. ## Starting a data export job To start an export job, navigate to the **Data** page in OrgFlow Web and select **Export data**. This opens the **Export data** dialog where you configure the inputs and options of the export job. If the Salesforce org you're looking to export data from is an environment in your stack, you can also open the **Export data** dialog from the **Environments** page, or from the details page of an individual environment; in this case the Salesforce org selection will be prepopulated. The following sections describe the available options. ### Salesforce org You must first select which Salesforce org to export from, by providing the org's **sign-in URL** and a **username**. OrgFlow will provide suggested sign-in URLs and usernames that it already knows about from your stack's environments and stored access tokens. You can also enter a different sign-in URL or username manually. Once a sign-in URL and username have been entered, OrgFlow will automatically verify your authentication. If the user has not previously been authorized, OrgFlow will initiate a Salesforce device code authorization flow to obtain the required access. ::: tip Use any Salesforce org Data operations can [target any Salesforce org](/docs/data/#targeting-any-salesforce-org) that you can authenticate to — the org doesn't have to be configured as an environment in your stack. ::: ### Selection mode There are two ways to specify what data to export: #### Simplified In simplified mode, you select a **Salesforce object** (e.g. `Account`, `Contact`, `Opportunity`) from a list. The list of available objects is populated based on which objects are queryable. Only objects visible to the selected Salesforce user are shown. Once you've selected an object, you then select one or more **fields** to include in the export. The list of available fields is populated based on which fields on the selected object are queryable. Only fields visible to the selected Salesforce user are shown. By default all available fields are pre-selected. You can also optionally set a **record limit** to cap the number of records exported. This mode is the easiest way to export data without needing to know or write SOQL. #### SOQL query In SOQL mode, you write a custom SOQL query directly. This gives you full control over the query, including the ability to use `WHERE` and `ORDER BY` clauses, and to traverse child to parent relationships. For example: ```sql SELECT Id, Name, Industry FROM Account WHERE CreatedDate = THIS_YEAR ``` Please note that not all SOQL language features are supported in Bulk API operations. Please refer to the SOQL considerations section in the [Salesforce Bulk API 2.0 Query documentation](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/queries.htm) for details. ### Include deleted records (query all) When enabled, deleted and archived records are included in the query results. This corresponds to the `queryAll` operation in the Salesforce Bulk API. This can be useful when you need to export a complete dataset that includes records in the recycle bin or records that have been archived. ::: tip Including the `IsDeleted` field in the query allows you to see which records in the results are archived/deleted. ::: ### Export files You can select one or more file formats for the exported data. At least one format must be selected. The available formats are **CSV**, **JSON**, **Parquet** and **Excel**. When multiple formats are selected, OrgFlow produces a separate downloadable file for each format, all containing the same data. See [file formats](/docs/data/#file-formats) for more about each format. ::: warning Excel is limited to 1,048,576 records Excel files are limited to a maximum of 1,048,576 records due to limitations in most software tools that can open them. If the export operation yields more than 1,048,576 records, no Excel result file will be created. ::: ## Job execution When you submit the export, OrgFlow provisions a [job](/docs/core-concepts/jobs/) to perform the export. The job executes the following steps: 1. OrgFlow authenticates to the target Salesforce org 2. If using simplified mode, OrgFlow constructs a SOQL query from the selected object, fields and optional record limit 3. OrgFlow creates a Bulk API query job in Salesforce 4. Salesforce processes the query and produces result batches 5. OrgFlow retrieves the result batches 6. OrgFlow converts the results to the selected file formats and saves them as downloadable artifacts on the job You can monitor the progress of the export on the job details page. When the export is complete, downloadable export files appear as [artifacts](/docs/core-concepts/jobs/#artifacts) on the job. ## Job result When the export completes, the job result shows the following statistics: | Statistic | Description | | ---------------- | ---------------------------------------------------- | | Records exported | The total number of records returned by the query | | Batches used | The number of Bulk API batches used for the query | The exported files are available as [artifacts](/docs/core-concepts/jobs/#artifacts) on the job and can be downloaded directly from the job details page. --- --- url: /docs/devops/flow-in.md description: >- Retrieving metadata changes from Salesforce orgs and committing to your Git repository --- # Flow in (retrieving from Salesforce) A core feature of OrgFlow is the ability to detect new metadata changes in a Salesforce org, retrieve those changes and commit them to a Git repository. We call this process *flow in* or sometimes *inbound flow*. Together, flow in and [flow out](/docs/devops/flow-out/) are key operations that help keep a Salesforce org in sync with a Git branch. This diagram outlines the overall steps of the flow in process: 1. Worker makes a temporary local clone of repository with environment's Git branch 2. Worker [retrieves metadata](#retrieving-metadata) from environment's Salesforce org to a temporary local folder 3. Worker [commits metadata changes](#committing-changes) to local Git branch 4. Worker pushes new commits to environment's remote Git branch (unless [check-only mode](#check-only) was selected) "Worker" in this context can be either a managed worker in OrgFlow's cloud, or the CLI running on your infrastructure. ## Starting a flow in job To start a flow in job using the OrgFlow web app, navigate to the **environments** page, open the **flow** dropdown menu and select the **flow in** menu item. This opens the **flow in** dialog where you configure the inputs and options of the flow in job: ::: info OrgFlow CLI To start a flow in job using the OrgFlow CLI, use the `env:flowin` command. ::: Many of the available options in the flow in dialog are self-explanatory. The following sections describe some options in more detail. ### Check only This option runs the flow in job in *check-only* mode. In this mode, the environment's state in OrgFlow's cloud remains unchanged and the committed changes are never pushed to the remote repository. The result is a dry run that does not impact the state of the environment or Git repository in any way, but still allows you to discover potential errors and inspect the job result. ### Retrieve mode There are two retrieve modes: *full* and *partial*. By default, OrgFlow will automatically select which mode to use, using partial when possible and safe but falling back to full when necessary. #### Full Full retrieve involves retrieving all of the metadata that is included by the [include specs](/docs/devops/managing-included-metadata/) and relying on Git to determine what's changed since the last flow in. At a high level, the process looks like this: 1. OrgFlow determines the metadata *types* that are included by the include specs 2. OrgFlow asks Salesforce for a list of all the metadata *items* of those types 3. All of the metadata items that match the include specs are retrieved from Salesforce This is the most thorough and well supported retrieval mode because it doesn't require source tracking, but it can be substantially slower than a partial retrieve due to the potentially large volume of metadata that is retrieved. #### Partial (source tracking) Partial retrieves utilize Salesforce's source tracking functionality to identify which metadata items have changed since the last flow in, and retrieves only the metadata that's changed. At a high level, the process looks like this: 1. OrgFlow maintains a baseline source tracking version number for each source tracked environment 2. OrgFlow asks Salesforce for all the source tracking records since the baseline version 3. Those source tracking records are filtered to include only the metadata items that are included by the [include specs](/docs/devops/managing-included-metadata/) 4. Those metadata items are retrieved from Salesforce using the metadata API This is the fastest retrieve mode because it typically results in only a small subset of metadata needing to be retrieved, greatly reducing the time it takes for the retrieve to complete. However, there are some [limitations and known issues with source tracking](#partial-retrieve-limitations). ### Collect retrieved metadata archives This options saves the "raw" retrieved metadata archives as [artifacts on the job](/docs/core-concepts/jobs/#artifacts), exactly as they were sent back from the metadata API before any processing was applied by OrgFlow. This can be helpful when diagnosing issues with inbound flow, for example to understand whether metadata in your repository looks a certain way because of OrgFlow's processing, or because Salesforce simply provided it in that way. One artifact is created per [retrieved batch](#batching). ### Merge conflicts The flow in process uses [merging of changes](#merging-changes) to safely commit incoming metadata changes from the environment's Salesforce org while preserving any undeployed changes in the Git branch. When the same component has changed both in the Git branch and in the Salesforce org, it is possible for *merge conflicts* to occur during flow in. The **merge conflicts** option lets you control how OrgFlow should behave when merge conflicts are detected. The **use semantic merge** option enables metadata-aware merge logic to help avoid some types of merge conflicts. See [merge conflicts](/docs/devops/merge-conflicts/) for more information about these options. ### Force Force mode resets the metadata in the Git repository to match the state of the metadata in the Salesforce org. It does this by bypassing the branching strategies used to support [merging changes](#merging-changes). The retrieved metadata is applied to and committed onto the head of the environment's branch. [Author attribution](#author-attribution) is still supported in force mode. ::: warning Be careful with undeployable components Force mode will reset everything in the Git branch to match the state of the Salesforce org. This means that undeployable components will also be reset. Undeployable components will almost certainly be ahead in the Git repository, compared to the Salesforce org. Resetting these components to match the org versions will revert these changes. ::: ## Partial retrieve limitations Partial retrieve is not always possible, and there are some [known issues with source tracking](#known-issues-with-source-tracking) that sometimes prevents metadata changes from being reliably detected in a Salesforce org. For a partial retrieve to be possible, **all** of the following criteria must be met: * Source tracking must be enabled in the Salesforce org * OrgFlow must have previously done a full retrieve of the environment in order to establish a baseline * The include specs must not have changed since the last flow in * [Force](#force-mode) mode must not be selected * The environment must have been flowed in in the past 30 days * There must not have been an external deployment since the last flow in of the environment An *external deployment* is a deployment that has been done with a tool other than OrgFlow, for example using changesets. External deployments may not update source tracking records for the metadata items that they touch, so OrgFlow cannot be confident that the source tracking history is complete if there has been an external deployment since the last flow in. ### Support for non-source tracked types Some metadata types do not support source tracking; OrgFlow is still able to support these types during a partial retrieve. It does this by effectively doing a [full retrieve](#full) of the types that are not supported by source tracking. The types that do not support source tracking vary with each Salesforce API version and can be seen in Salesforce's [metadata coverage report](https://developer.salesforce.com/docs/success/metadata-coverage-report/references/coverage-report/metadata-coverage-report.html). Because these types vary between Salesforce API versions, the types affected in each environment will be impacted by the [API version selection mode that you have chosen for the environment](/docs/devops/managing-api-versions/). ### Known issues with source tracking OrgFlow's partial retrieve functionality is powered by Salesforce's source tracking functionality, and it is only as good as Salesforce's ability to accurately maintain these source tracking records. Unfortunately there are some known issues with Salesforce that result in some changes not being reflected in Salesforce's source tracking. One example of this is deleting a custom field from a custom object. In this case, Salesforce should create a source tracking record to indicate that the field is deleted, but instead it simply does not create the record. If you encounter this issue, you should raise a case with Salesforce as we are not in a position do anything about it. This same issue will impact any tool that uses source tracking, including the Salesforce CLI. For this reason we suggest that you run flow in with full retrieve enabled from time to time in order to catch any changes that source tracking may have missed. ## Automatic change detection OrgFlow is capable of automatically detecting metadata changes in the environment's Salesforce org. This is achieved using a combination of two methods: * In case of [partial retrieve](#partial-source-tracking), OrgFlow queries the Salesforce org for new changes since the last flow in, to minimize the retrieve size * After retrieving metadata from the org, OrgFlow compares it to the metadata in the Git repository ([at the correct point in time](#merging-changes)), and identifies components that have changed This approach works regardless of retrieve mode, which means that you no longer need to worry about remembering which components need to be added to a deployment — even for orgs that do not have source tracking enabled (such as a production org). ## Merging changes Part of the magic of OrgFlow is its ability to *merge* changes in a Git repository with the changes in a Salesforce org, without one side overwriting the other. For example, if the help text of a custom field has been changed in Git, and someone else changes the description of the same field in the org, the flow in process will merge those two changes together, and neither change will be overwritten by the other. This is one of the fundamental pieces that enable OrgFlow to merge changes between environments without clobbering changes in one org with the changes from another org. See [understanding metadata version control](/docs/devops/metadata-version-control/) for more in-depth information on how OrgFlow utilizes Git to achieve this and other benefits. To enable this, OrgFlow maintains some state information about each included metadata item in an environment. The state information is stored in OrgFlow's cloud. Part of this state information includes commit hashes that OrgFlow can use to compare the current state of the metadata item in the Git repository to the state of the metadata item in the Salesforce org. This is what enables automatic change detection, and also allows the Git repository to be ahead of the Salesforce org without risking data loss during a flow in. ::: info What's stored in OrgFlow's cloud? The state information that is stored in OrgFlow's cloud does not include the metadata items themselves, but it does include the names and types of the metadata items, commit hashes, and source tracking version numbers. ::: Merging of changes can be bypassed by enabling [force mode](#force-mode) for the flow in job. ## Batching Regardless of retrieve mode, OrgFlow will usually split the metadata to be retrieved into smaller *batches* and retrieve several batches concurrently. This has two main benefits: * It's usually quicker to retrieve several smaller metadata archives from the metadata API in parallel, than it is to retrieve a single larger one * The metadata API imposes [limits](https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_metadata.htm) on the number of items and the total overall download size per retrieve, and splitting the retrieve into smaller batches allows OrgFlow to circumvent those limits. When deciding how to split the metadata to be retrieved into batches, OrgFlow must take into account several factors. Firstly, OrgFlow will determine an optimal batch size and from that the number of batches to retrieve. Then, OrgFlow must identify metadata items that need to be retrieved in the same batch. This is a crucial step because Salesforce's metadata API can return inconsistent results for some metadata types if those types take dependencies on other types or items that are not included in the same batch. The result of these batching requirements is that you may see some retrieve batches that are larger or smaller than others during a retrieve. This is normal behavior and is to be expected. There are cases where only a single batch will be retrieved: * The number of metadata items to be retrieved is very small and creating more than one batch would be inefficient * All of the metadata items to be retrieved must be retrieved in the same batch because of the limitations in the metadata API ## Author attribution When committing metadata to Git, OrgFlow attempts to identify the Salesforce user who last changed each metadata item that is to be committed. A combination of source tracking data (when available) and the **last modified by** property on the metadata item is used to determine this. OrgFlow will then commit changes by each author separately, assigning the identified Salesforce user as the author of each commit. The `Name` and `Email` fields from the `User` object in Salesforce are used to create the Git author string (i.e. `user.Name `). Author attribution helps to build up a rich history in Git, recording a name on each change made to your Salesforce metadata. ::: info Attributing multiple changes Author attribution is only able to record a single author per component and flow in. If two users have changed the same metadata item since the last flow in, then both changes will be attributed to the user who made their change last. To avoid "skipped" changes is Git history, flow in environments frequently. ::: Occasionally it won't be possible to attribute an author to a change (for example when a metadata item has been deleted and source tracking is not available for the org). In these cases the author will default to `Unknown Author `. --- --- url: /docs/devops/flow-merge.md description: >- Migrating metadata changes between Salesforce environments via your Git repository --- # Flow merge OrgFlow never copies metadata directly from one Salesforce org to another using retrieve and deploy. Instead, OrgFlow flows metadata changes between through the Git branches of configured Salesforce environments. We call this process *flow merge* or sometimes *merge flow*. Flow merge is essentially a composition of flow in, flow out and Git merge operations: * A flow in of the source environment * A flow in of the target environment * A Git merge from the source environment's branch into the target environment's branch * A flow out of the target environment By completing all these operations in combination, the result is that changes in both environment will have been committed to the Git repository, and changes in the source environment will have been safely merged with changes in the target environment, and deployed to the target environment's Salesforce org. The individual flow in and flow out operations can optionally be skipped depending on your needs. The following outlines the overall steps of the flow merge process: :::: tabs ::: tab Simplified 1. Worker [flows in](/docs/devops/flow-in/) the source and target environments concurrently 2. Worker merges the source environment's Git branch into the target environment's Git branch 3. Worker [flows out](/docs/devops/flow-out/) the target environment "Worker" in this context can be either a managed worker in OrgFlow's cloud, or the CLI running on your infrastructure. ::: ::: tab Detailed While the [simplified view](#simplified) is easier to understand, the flow merge process is technically not just two inbound flows followed by an outbound flow. This description is closer to what actually goes on behind the scenes: 1. Worker concurrently makes temporary local clones of repository, one with source environment's Git branch and one with target environment's Git branch 2. Worker retrieves metadata from source Salesforce org to a temporary local folder 3. Worker commits metadata changes to source Git branch 4. Worker retrieves metadata from target Salesforce org to a temporary local folder 5. Worker commits metadata changes to target Git branch 6. Worker merges from source Git branch into target Git branch 7. Worker determines changes in the target Git branch since last flow out and creates a delta archive 8. Worker deploys delta archive to target Salesforce org (or validates if [check-only mode](#check-only) was selected) 9. If any components failed, worker [repeats steps 7 and 8 while excluding failed components](/docs/devops/flow-out/#partial-success) 10. Worker pushes new commits to both environments' remote Git branches (unless [check-only mode](#check-only) was selected) Steps 3 and 4 execute concurrently for improved overall performance. "Worker" in this context can be either a managed worker in OrgFlow's cloud, or the CLI running on your infrastructure. ::: :::: ## Starting a flow merge job To start a flow merge job using the OrgFlow web app, navigate to the **environments** page, open the **flow** dropdown menu and select the **flow merge** menu item. This opens the **flow merge** dialog where you configure the inputs and options of the flow merge job: ::: info OrgFlow CLI To start a flow merge job using the OrgFlow CLI, use the `env:flowmerge` command. ::: Many of the available options in the flow merge dialog are self-explanatory. The following sections describe some options in more detail. ### Skipping parts of the process By default, a flow merge includes not only the Git merge from the source branch into the target branch, but also a flow in of both environments before the Git merge, and a flow out of the target environment after the Git merge. This ensures that any new metadata changes flow all the way from the source environment's Salesforce org to the target environment's Salesforce org, in as safe a manner as possible. You can skip one or more of these steps using the checkboxes next to the diagram at the top of the flow merge dialog: | Option | Description | | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | No source flow in | Skip retrieving new changes from the source Salesforce org; just merge from the current HEAD of the source Git branch. | | No target flow in | Skip retrieving new changes from the target Salesforce org; just merge with the current HEAD of the target Git branch. This option may increase the risk of clobber during deployment to target Salesforce org. | | No target flow out | Skip deploying the merged result to the target Salesforce org; leave the merged changes in the target Git branch. | For example, to speed up the flow merge job, you might skip the source and target flow in steps if you already know that neither environment's Salesforce org contains any new changes, perhaps because you have just run a flow in job on those environments. ### Check only This options runs the flow merge job in *check-only mode*. In this mode, the environment's state in OrgFlow's cloud remains unchanged, the committed changes are never pushed to the remote repository, and the deployments to Salesforce run as **validation deployments** (i.e. Salesforce will validate the deployment but not actually apply the changes to the metadata in the org). The result is a dry run that doesn't impact the state of the environment or Salesforce org in any way, but still allows you to discover potential merge conflicts and errors, and inspect the job result. ### Merge options When the same component has changed in both the source branch and the target branch, it is possible for *merge conflicts* to occur while merging between the two branches. The **merge conflicts** option lets you control how OrgFlow should behave when merge conflicts are detected. The **use semantic merge** option enables metadata-aware merge logic to help avoid some types of merge conflicts. See [merge conflicts](/docs/devops/merge-conflicts/) for more information about these options. The **allow unsupported API versions** option instructs OrgFlow to allow merging metadata into the target branch whose payload API version is not yet supported by target org's platform version. See [allowing unsupported API versions in merge operations](/docs/devops/managing-api-versions/#allowing-unsupported-api-versions-in-merge-operations) for more information about this option. ### Source and target flow in options Unless you selected to [skip the source or target flow in steps](#skipping-parts-of-the-process), you will see an expandable section of the dialog for configuring the options of the source and target flow in, respectively. See the [flow in](/docs/devops/flow-in/) topic for more information about the available options. ### Target flow out options Unless you selected to [skip the target flow out step](#skipping-parts-of-the-process), you will see an expandable section of the dialog for configuring the options of the target flow out. See the [flow out](/docs/devops/flow-out/) topic for more information about the available options. ### Artifact options These options lets you enable/disable collection of [job artifacts](/docs/core-concepts/jobs/#artifacts) during the flow merge job. The **collect retrieved metadata archives** option saves the "raw" retrieved metadata archives, exactly as they were sent back from the metadata API before any processing was applied by OrgFlow. This can be helpful when diagnosing issues with the merge flow, for example to understand whether metadata in your repository looks a certain way because of OrgFlow's processing, or because Salesforce simply provided it in that way. The **collect deployment archive artifacts** option saves the delta deployment metadata archives, exactly as they were uploaded to the metadata API by OrgFlow. This can be helpful when diagnosing issues with outbound flow, for example to understand the underlying reasons for deployment failures. --- --- url: /docs/devops/flow-out.md description: Deploying metadata changes from your Git repository to Salesforce orgs --- # Flow out (deploying to Salesforce) A core feature of OrgFlow is the ability to determine new metadata changes in a Git repository and deploy those changes into a Salesforce org. We call this process *flow out* or sometimes *outbound flow*. Together, flow out and [flow in](/docs/devops/flow-in/) are key processes that help keep a Salesforce org in sync with a Git branch. This diagram outlines the overall steps of the flow out process: 1. Worker makes a temporary local clone of repository with environment's Git branch 2. If [org comparison](#org-comparison) is used, worker retrieves metadata from environment's Salesforce org for comparison 3. Worker [determines changes](#diff-mode) in the local Git branch since last flow out and creates a delta archive 4. Worker [deploys delta archive](#deploying-metadata) to environment's Salesforce org (or validates if [check-only mode](#check-only) was selected) 5. If any components failed, worker [repeats steps 3 and 4 while excluding failed components](#partial-success) "Worker" in this context can be either a managed worker in OrgFlow's cloud, or the CLI running on your infrastructure. ## Starting a flow out job To start a flow out job using the OrgFlow web app, navigate to the **environments** page, open the **flow** dropdown menu and select the **flow out** menu item. This opens the **flow out** dialog where you configure the inputs and options of the flow out job: ::: info OrgFlow CLI To start a flow out job using the OrgFlow CLI, use the `env:flowout` command. ::: Many of the available options in the flow out dialog are self-explanatory. The following sections describe some options in more detail. ### Check only This options runs the flow out job in *check-only mode*. In this mode, the environment's state in OrgFlow's cloud remains unchanged and the deployments to Salesforce run as **validation deployments** (i.e. Salesforce will validate the deployment but not actually apply the changes to the metadata in the org). The result is a dry run that doesn't impact the state of the environment or Salesforce org in any way, but still allows you to discover potential errors and inspect the job result. ### Skip deployment review By default OrgFlow will pause before the first deployment attempt and wait for a user to review the detected differences, [select what to include in the deployment](#selective-deployment) and confirm to proceed. This option skips this review step and automatically proceeds with the deployment. Any exclusions (components **not** selected for deployment) that were in effect during the last succesful flow out will be retained, unless you also enable the [reset exclusions](#reset-exclusions) option. ### Reset exclusions When a user makes an active choice to *exclude* one or more metadata components from an outbound flow, this choice is remembered for subsequent outbound flows. Enabling this option clears this memory for the current environment, and reverts back to including all detected changes in the outbound flow. If you also enable the [check only](#check-only) option, exclusions are reset for the current outbound flow but not persisted. ### All or nothing [Partial success](#partial-success) can be disabled by enabling *all or nothing* mode. In this mode, OrgFlow attempts the first deployment like normal. However, if some components fail to deploy during the first attempt, the flow out process will switch to using [check-only mode](#check-only-mode) for the remainder of the deployment attempts. The result is that either **all** metadata changes are successfully deployed, or **none** of them are deployed and the org remains unchanged. Because OrgFlow continues to complete all the deployment attempts (now having switched to using [check-only mode](#check-only-mode) for the remaining attempts) you still get the full list of deployment failures across all the attempts. ### Diff mode OrgFlow automatically determines which metadata changes in an environment's Git branch are not yet in its Salesforce org. This means you don't need to worry about remembering which components need to be included in a deployment. The **diff mode** option lets you control which change detection mechanism OrgFlow should use for the flow out. There are two modes: *history diff* and *org comparison*. These two modes can produce slightly different results, so it's important to understand the difference between them. #### History diff History diff is quicker than org comparison, but there are some caveats to be aware of. This mechanism involves checking the Git history of each metadata item to identify those that have changed in the Git branch since OrgFlow knew they were last equal to the Salesforce org. It does not take into account changes made in the Salesforce org since then - only changes in the Git branch are considered. Because of this, deployments using history diff tend to be smaller, and take less time to calculate and deploy. If a component has changed **only** in the Salesforce org, it will not be identified as a difference by history diff. However, if a component has changed in the Git branch **and** the Salesforce org, the changes made in the Salesforce org may be overwritten by the changes in the Git branch. [Clobber detection](#clobber) can identify such components and warn you about potential clobber, but only if the Salesforce org has source tracking enabled. To ensure no changes in the org are clobbered by the deployment, you should first [flow in](/docs/devops/flow-in/) the environment to merge any changes in the Salesforce org into the Git branch, and then flow out immediately after. You should use this option by default if you don't mind that some of the included metadata in the Salesforce org might be ahead of the metadata in the Git branch. #### Org comparison Org comparison is more thorough and accurate than history diff, but also slower. This mechanism involves retrieving all the included metadata from the environment's Salesforce org, and comparing it to the metadata at the head of the Git branch. Any metadata items that differ between the retrieved items and the items at the head of the Git branch will be deployed. Because of this, any changes that are in the Salesforce org but not yet in the Git branch will be overwritten by the metadata that is being deployed. [Clobber detection](#clobber) can identify such components and warn you about potential clobber, but only if the Salesforce org has source tracking enabled. To ensure no changes in the org are clobbered by the deployment, you should first [flow in](/docs/devops/flow-in/) the environment to merge any changes in the Salesforce org into the Git branch, and then flow out immediately after. You should use this option in scenarios where history diff would not be sufficient, such as after refreshing the environment's sandbox, or in any scenario where you want to ensure that all of the included metadata in the environment's Salesforce org match the metadata at the head of the Git branch. #### Change detection results The following table shows the resulting metadata in the environment's Salesforce org after a successful flow out, for all combinations of changes and change detection mechanisms: | Changes | History diff | Org comparison | | ---------------------------------------- | ------------ | -------------- | | Component changed only in branch | Branch | Branch | | Component changed only in org | Org | Branch | | Component changed in both branch and org | Branch | Branch | The following table shows the same if a flow in were run immediately before the flow out: | Changes | History diff | Org comparison | | ---------------------------------------- | ------------- | -------------- | | Component changed only in branch | Branch | Branch | | Component changed only in org | Org | Org | | Component changed in both branch and org | Both (merged) | Both (merged) | ### Purge on delete The Salesforce metadata API has a [purge on delete](https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_deploy.htm#option_purgeOnDelete_desc) option for deployments. The flow out process also supports this option. Enabling purge on delete means that metadata items deleted by a deployment will bypass Salesforce's recycle bin and become immediately eligible for deletion in the org. ### Apex test options ### Clobber For orgs that have source tracking enabled, OrgFlow is able to determine whether clobber would occur if the deployment were to continue. Clobbering in this context means deploying a metadata item into a Salesforce org that would overwrite pre-existing changes to that metadata item. For example: If user A updates an Apex class in a sandbox to fix a bug, and user B deploys a version of the same Apex class that doesn't include the bug fix, then the bug fix will be removed (or "clobbered") by the deployment. Clobber detection works by querying the Salesforce org for source tracking records since the environment was last flowed in. Those records are compared to the metadata about to be deployed, and if there is any overlap then the deployment is determined to cause clobber. Because this feature depends on source tracking, it is subject to the same restrictions as [partial retrieve](/docs/devops/flow-in/#partial-retrieve-limitations). The clobber option lets you configure how OrgFlow should behave when clobber is detected. The default option is **automatic** which means OrgFlow will automatically proceed with the flow out if there is *potential* clobber, but abort the job before the deployment begins if *certain* clobber is detected. You can change this to either **accept** which means the flow out will proceed regardless, and **abort** which means OrgFlow will abort the job if *either potential or certain* clobber is detected. Potential clobber means OrgFlow cannot reliably determine whether a particular component would be clobbered or not, either because source tracking is not enabled in the Salesforce org, or because the component's type is not supported by source tracking. ### Max attempts This options lets you configure how many deployment attempts OrgFlow makes to try and achieve a partially successful outcome, before giving up and marking the entire process as failed. This option defaults to **5 attempts**, and it should normally not be necessary to increase it except for very problematic deployments, in which case you should consider whether a partial success with that many undeployed components is really desirable, or whether you should rather try to investigate and address the underlying reasons. ### Collect deployment archive artifacts This options saves the delta deployment metadata archives as [artifacts on the job](/docs/core-concepts/jobs/#artifacts), exactly as they were uploaded to the metadata API by OrgFlow. This can be helpful when diagnosing issues with outbound flow, for example to understand the underlying reasons for deployment failures. One artifact is created per [deployment attempt](#partial-success). ## Reviewing the deployment Unless you've enabled the [skip deployment review](#skip-deployment-review) option, OrgFlow pauses before the first deployment attempt and prompts for a user to review and confirm the contents of the proposed deployment. The **Review and confirm deployment** inquiry on the job timeline shows you the high-level counts of detected changes selected for deployment. Select **Review changes and select what to deploy** to see the deployment contents in more details. ### New vs. prior changes If [history diff](#history-diff) is used, the changes are diveded into two sections: * The **new changes** section contains new changes committed or merged to the environment's Git branch since the last successful outbound flow * The **prior changes** section contains changes that were excluded or failed to deploy in the last successful outbound flow This distinction can be very useful particularly during flow merge operations, because it helps you you focus on only the changes that are new to this outbound flow. ### Selecting what to include {#selective-deployment} Each detected change has a corresponding checkbox that allows you to select whether to include that change in the deployment. Unless you've enabled the [reset exclusions](#reset-exclusions) option, any components that were excluded in the previous outbound flow of this environment will default to unselected. Selection is possible only on actual metadata *components*, not on mere content items. For example, you can select or deselect the Aura component shown in the example, but not the individual resource files because those are not components in their own right; selection/deselection automatically applies to all items belonging to the Aura component. Deploying only a subset of changes can be useful in a variety of situations: 1. Undesired changes were detected only after they were merged into the target environment 2. Changes must be deployed in stages for business reasons 3. Situations where some types of changes cannot be deployed simultaneously due to bugs or limitations in the Salesforce metadata API and deployment engine 4. Certain "chicken-and-egg" problems where some components must first be deployed, so that some manual post-deployment step can then be performed, so that other components can finally be deployed successfully 5. Permanently excluding failing components that will never succeed, in order to avoid unnecessary deployment attempts and failure indications Unless you've enabled the [check-only](#check-only) option, any exclusions you make here are remembered for subsequent outbound flows. ### Standard/packaged metadata Some types of detected metadata changes are always excluded from deployments and cannot be selected: * *Standard* metadata components (built into the Salesforce platform) cannot be added or deleted by deployment. Instead you should ensure that enabled features, settings, licenses and permissions are consistent across the orgs in your stack. * *Packaged* metadata components (installed by managed packages) also cannot be added or deleted by deployment. Installed packages and their versions should instead be kept in sync across the orgs in your stack. In the example shown, the deleted custom field `AssetRelationship.RelationshipType` and the added custom field `BatchJob.NewStandardField` are both marked as **standard/packaged** and will be excluded from the deployment. ### Clobbered changes In situations where OrgFlow is able to reliably determine [clobber](#clobber), the review also includes information about changes in the target org that would be clobbered by changes in the deployment. In the example shown, the custom object `Lead` has been modified in the target org, and that change would be clobbered (overwritten) by the modification to the same custom object in the proposed deployment, if this component were to be included in the deployment. Based on this information you might consider to avoid this clobber by either excluding this component from the deployment or aborting the outbound flow, and then running a flow in operation on the environment in order to merge the changes in the org with the changes in the branch, before running the outbound flow again. ## Deploying metadata Once OrgFlow has determined changes that are candidates for deployment, and a user has selected what changes to actually include in the deployment, the flow out process moves on to deploying them into the Salesforce org via the metadata API. ### Partial success When deploying metadata into a Salesforce, it's possible that some metadata items to fail to deploy, especially into sandbox environments. As your codebase grows, the likelihood of components failing to deploy grows too. Sometimes the components that fail to deploy are benign or don't impact the area of functionality that you are wanting to merge into a new environment. Most Salesforce deployment tools would simply fail the deployment until all the errors have been fixed. OrgFlow however is capable of *partial success*, meaning that changes that **can** be deployed are not blocked by those that cannot. The process looks like this: 1. OrgFlow automatically identifies the components that need to be deployed 2. OrgFlow attempts to deploy all of those components 3. If any components fail, try again with the failed components excluded 4. Repeat the above step until either the deployment succeeds, or OrgFlow can no longer retry the deployment 5. If the deployment eventually succeeds, record any components that could not be deployed as [undeployed components](#undeployed-components) There are a number of reasons why OrgFlow may reach a point where it can no longer make any further deployment attempts. Some examples include: * Salesforce reports incorrect component names when they fail, preventing OrgFlow from excluding them from the next deployment attempt * The [maximum number of deployment attempts](#max-attempts) is reached * Every changed component is undeployable, so there's nothing left to try to deploy In most cases OrgFlow will be able to complete a partial deployment before any of the above conditions occur. ### Eventual consistency The purpose of partial success is to allow you to move changes between Salesforce orgs more easily, with a more forgiving deployment model. If a flow out succeeds partially, you can fix the issues that caused some components to fail, and then rerun the flow out. You can apply such fixes wherever is more practical: directly in the target environment's Git branch, in the Salesforce org, or even in a different OrgFlow environment followed by a new merge. In the meantime, additional changes can continue to flow in every direction — even changes made in the Salesforce org to the undeployable components themselves. Once those components can be deployed, they are no longer classed as undeployable components and the Git branch moves closer to consistency with the Salesforce org. This model can be throught of an application of the *eventual consistency* model in the context of Salesforce DevOps. For a deeper dive on this topic see our blog post [Applying the Eventual Consistency Model to Salesforce DevOps](https://medium.com/orgflow/applying-the-eventual-consistency-model-to-salesforce-devops-6a329daf6e5e). Here's a simple example of eventual consistency in action: Alice has been working on an Apex class in sandbox A. Her new Apex class references a custom field on `Account` called `First_Contact_Date__c`. Meanwhile, Bob has been cleaning up the production org and has deleted the `First_Contact_Date__c` custom field. Alice decides that she'd like to bring the latest production changes into her sandbox so she uses OrgFlow to merge from production into her sandbox environment. As part of the merge process, OrgFlow flows out the merged metadata. During the flow out, the `First_Contact_Date__c` field cannot be deleted from Alice's sandbox (because her Apex class depends on it), so OrgFlow excludes it from the deployment and completes a partially successful flow out of all the other changes that were merged in. Now, `First_Contact_Date__c` is an undeployable component in Alice's sandbox environment. She inspects the deployment error and realises that she needs to update her Apex class to no longer reference the deleted field. She logs into the Sandbox and makes the required changes to her Apex class. On the next flow out, the `First_Contact_Date__c` will be deployed (deleted) because she's resolved the issue that was preventing this in the first place. ## Undeployed components Because you can [optionally select what to include](#selective-deployment) in deployment, some detected changes might be omitted from the flow out. Additionally, because of [partial success](#partial-success), it's also possible for the flow out process to succeed even if some metadata items that *were* selected for deployment actually failed to deploy. In this situation, OrgFlow will create an *undeployed component* record for each metadata item for which changes were found in the branch, but which was not deployed to the org. The undeployed component records help OrgFlow keep track of changes in the environment's Git branch which have yet to be deployed. Undeployed component records are stored in OrgFlow's state store, and can be viewed in the web app. A count of the number of undeployed components is displayed on the **Environments** page (in yellow in the Git branch box of each environment): Clicking that count will take you to the **Undeployed components** tab of the environment details page: --- --- url: /docs/devops/flowing-changes.md description: Overview of flowing metadata changes between Salesforce environments --- # Flowing metadata changes The most central part of OrgFlow's DevOps capabilities is *flowing metadata changes* between Salesforce orgs. ## Flow operations There are three flow operations in OrgFlow, each documented in its own topic: | Operation | Figure | Description | | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | [Flow in](/docs/devops/flow-in/) | | Detect and retrieve new metadata changes from an environment's Salesforce org and commit them to its backing Git branch | | [Flow out](/docs/devops/flow-out/) | | Determine undeployed metadata changes in an environment's Git branch and deploy them to its Salesforce org | | [Flow merge](/docs/devops/flow-merge/) | | Merge metadata changes from a source environment into a target environment, while optionally retrieving from the environments' Salesforce orgs, and deploy the merged changes to the target environment's Salesforce org | Depending on context, we also sometimes refer to these as *inbound flow*, *outbound flow* and *merge flow*, respectively. ## Why "flow"? You might be wondering why we call it "flowing" as opposed to just "retrieving and deploying", "copying", "moving" or "syncing". We use the word "flow" to mean an **intelligent end-to-end change migration process** that involves more than those things. OrgFlow's magic lies in what these flow operations have in common: * Flow migrates **changes** - unchanged metadata is ignored (unless forced) * Flow **automatically determines** new changes * Flow migrates changes via a **Git repository** — not directly from org to org * Flow migrates changes via **merge** — not copy/paste * Flow **persists changes only no unexpected errors occur** during the process * Flow enables **partial success** and **eventual consistency** allowing changes to converge over time despite temporary discrepancies * Flow involves [environments in a stack](/docs/devops/environments/) — not arbitrary Salesforce orgs * Flow is driven by **environment state** such as unmerged commits or undeployed changes As you will see, things like retrieving, committing, merging and deploying are only parts of the larger overall change flow processes. Throughout this documentation, you will notice we use those words to refer to those smaller operations specifically, while using the term "flow" and "flowing" to refer to the larger overall change migration processes. ## Making changes in production Many teams using Salesforce are used to — and greatly appreciate — being able to customize it directly in production. This is one of the long-time strengths of Salesforce, because it makes the system so easy to tailor, with minimum ceremony. Even as teams start using sandboxes for more complex customization efforts, many still find it sensible to allow some smaller, simpler and more atomic metadata changes directly in production, without the added hassle of deploying them from a sandbox. Are changes in production inherently bad practice and incompatible with DevOps? Absolutely not, as long as there is adequate tooling in place to efficiently and safely handle it. OrgFlow fully supports changes made directly in production, through its ability to flow changes between environments **bidirectionally**, using the inherent merging and conflict resolution mechanisms in Git to safely reconcile the differences. ## Upstream/downstream While the environments in a stack are all related, they do not form an inherent *structure* within the stack. All environments in a stack are equivalent from a change flow perspective, and you can flow changes between any two environments as you see fit. There is **technically** no concept of downstream or upstream relationships between any two environments, nor are there any constraints forcing users to propagate or promote changes in any particular stages. However, **in practice** your Salesforce DevOps process will usually form an implicit directional stream of changes, where changes originate in development/feature sandboxes, flow via testing/staging sandboxes, and ultimately end up in your production environment. It is therefore very common in Salesforce DevOps contexts to reason about metadata change flow in terms of *downstream* and *upstream*. Flowing changes **downstream** means to flow them closer to their ultimate destination (typically your production environment), while flowing changes **upstream** means to flow changes in the other direction (sometimes called [*back-promotion* or *back-propagation*](#back-promotion)). Similarly, if changes typically flow from environment A to environment B on their way to their ultimate destination, then **B is said to be downstream of A** and **A is said to be upstream of B**. For admins and developers with a Salesforce background, who may not be accustomed to reasoning about change flow in these terms, the following illustration might be useful to help remember what downstream and upstream mean in a Salesforce DevOps context: ## Back-promotion of changes When a sandbox environment is created, its metadata starts out more or less identical to that in your production org. As time passes, the metadata in your production org changes. Metadata changes typically happen in your production environment for a variety of reasons: * Changes are merged from other environments in your stack * Admins [make changes directly in production](#making-changes-in-production) * Changes are deployed to production using change sets or some other third-party Salesforce deployment tool This means that, even if you make no changes to the sandbox, it starts to *diverge* or *drift* from your production org. The longer the sandbox exists, the more changes end up in production from elsewhere, and the farther the sandbox drifts. Left unchecked, this drift can present challenges: * Development in the sandbox is not based on the latest most relevant code * Hard or impossible merge conflicts when the sandbox changes are merged [downstream](#upstreamdownstream) * More failing components when the sandbox changes are deployed to downstream Salesforce orgs You can mitigate these challenges by ensuring that you continuously *back-promote* changes from production to upstream environments. This helps keep metadata changes aligned across all the environments in your stack, encourages more frequent releases, and reduces the likelihood of experiencing environment drift and deployment challenges. OrgFlow makes it easy to set up continuous back-promotion of changes by configuring [nightly upstream merge to run on a schedule](/docs/core-concepts/schedules/#nightly-upstream-merge-back-promotion). --- --- url: /docs/data/import.md description: >- Uploading and ingesting data records from a source file or URL into a Salesforce org --- # Importing data into Salesforce OrgFlow's data import feature lets you take data records from a source file in one of the [supported file formats](/docs/data/#file-formats) and ingest them into a Salesforce org. You can insert new records, update or upsert existing ones, or delete records — all powered by the Salesforce Bulk API for fast and efficient processing. After the import completes, OrgFlow produces result files that show how each record was processed, including any errors — making it easy to verify the outcome and troubleshoot failures. ## Starting a data import job To start an import job, navigate to the **Data** page in OrgFlow Web and select **Import data**. This opens the **Import data** dialog, where you configure the inputs and options of the import job. If the Salesforce org you're looking to import data into is an environment in your stack, you can also open the **Import data** dialog from the **Environments** page, or from the details page of an individual environment; in this case the Salesforce org selection will be prepopulated. The following sections describe the available options. ### Salesforce org You must first select which Salesforce org to import into, by providing the org's **sign-in URL** and a **username**. OrgFlow will provide suggested sign-in URLs and usernames that it already knows about from your stack's environments and stored access tokens. You can also enter a different sign-in URL or username manually. Once a sign-in URL and username have been entered, OrgFlow will automatically verify your authentication. If the user has not previously been authorized, OrgFlow will initiate a Salesforce device code authorization flow to obtain the required access. ::: tip Use any Salesforce org Data operations can [target any Salesforce org](/docs/data/#targeting-any-salesforce-org) that you can authenticate to — the org doesn't have to be configured as an environment in your stack. ::: ### Data source There are two ways to provide the source data: * Select a file from your computer to upload. The file is uploaded to OrgFlow's temporary storage and used as the data source for the import. Supported file types are `.csv`, `.json`, `.parquet` and `.xlsx`. * Provide a URL that points to a file hosted elsewhere. The URL must reference a file with one of the supported extensions (`.csv`, `.json`, `.parquet` or `.xlsx`). OrgFlow will fetch the file from this URL when the import job executes. Regardless of which method you choose, the data source needs to be in one of the [supported file formats](/docs/data/#file-formats). #### NULL values, empty strings, and #N/A OrgFlow automatically handles `NULL` values and empty strings in the source data, and passes these values on to the Salesforce Bulk API correctly. However, it's important to understand how Salesforce will handle these values: * A `NULL` value for a field will cause Salesforce to set the value of the field to `NULL` (i.e. blank out the field) * An empty string value will cause Salesforce to ignore that field for the record in question Salesforce requires that these values are uploaded to the Bulk API in a manner that it can understand. This requires converting `NULL` to the string literal `#N/A`, which is how Salesforce differentiates between fields that should be ignored and fields that should be set to `NULL`. OrgFlow handles this natively for you. However, this means that any source data that has a value of `#N/A` will also be interpreted by Salesforce as a `NULL` value. This is an unavoidable quirk of the Bulk API, and is something that you will need to consider if your source data contains the string value `#N/A`. For example, an update of the `Account` object with source data that looks like this: | Id | Name | Description | | -- | --------- | ------------------------- | | .. | Account 1 | "This is a great account" | | .. | Account 2 | "" | | .. | Account 3 | "#N/A" | | .. | Account 4 | NULL | Will result in these changes to the `Description` column in Salesforce: * **Account 1:** Set to "This is a great account" * **Account 2:** Ignored - any previous description will remain in place * **Account 3:** Set to `NULL` (cleared out) - Salesforce interprets `#N/A` as `NULL` * **Account 4:** Set to `NULL` (cleared out) - OrgFlow converts `NULL` to `#N/A`, Salesforce interprets `#N/A` as `NULL` ### Operation The **operation** determines what Salesforce does with the records in the source file. There are five available operations: | Operation | Description | Requires Id field | Requires external key field | | ----------- | --------------------------------------------------------------------------------------------------- | ----------------- | --------------------------- | | Insert | Create new records in the org | No | No | | Update | Update existing records in the org, matched by record Id | Yes | No | | Upsert | Insert new records or update existing ones, matched by an external key field | No | Yes | | Delete | Soft-delete records in the org (moved to recycle bin), matched by record Id | Yes | No | | Hard delete | Permanently delete records in the org (bypasses recycle bin), matched by record Id | Yes | No | The selected operation influences which Salesforce objects appear in the object picker, because different objects support different operations. ### Object Select the target **Salesforce object** that the records should be ingested into (e.g. `Account`, `Contact`, `Lead`). The list of available objects is dynamically populated based on the selected operation. Only objects visible to the selected Salesforce user are shown. ### External key field This option is shown only when the **upsert** operation is selected. You must select an **external key field** on the target object that OrgFlow will use to match incoming records against existing records in the org. If a record in the source file has a value that matches an existing record's external key field value, that record is updated. Otherwise, a new record is inserted. ### Batch size Optionally specify the maximum number of records to include in each Bulk API batch. Valid values are between 1 and 10,000. If left blank, OrgFlow uses a sensible default. Smaller batch sizes can be useful when importing records that trigger complex Apex logic or process automation, to avoid hitting governor limits. Larger batch sizes generally result in faster imports and help you stay under the daily [Bulk API batch limit](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/bulk_common_limits.htm). ### Result files Result files contain the original source data plus additional columns added by Salesforce, indicating how each record was processed. These additional columns typically include the record ID (for inserts), a success/failure indicator, and error messages for any records that failed. You can choose which file formats to use for the result files. The available formats are **CSV**, **JSON**, **Parquet** and **Excel**. You can choose more than one format, and you don't need to include the same format you used for the source. ::: warning Excel is limited to 1,048,576 records Excel files are limited to a maximum of 1,048,576 records due to limitations in most software tools that can open them. If your import operation contains more than 1,048,576 records, no Excel result file will be created. ::: ## Job execution When you submit the import, OrgFlow provisions a [job](/docs/core-concepts/jobs/) to perform the import. The job executes the following steps: 1. OrgFlow connects to the target Salesforce org 2. OrgFlow downloads and validates the source file, checking that its columns align with the target object's fields 3. OrgFlow splits the source data into batches 4. OrgFlow creates a Bulk API ingest job in Salesforce and uploads the batches 5. Salesforce processes the batches and produces per-record results 6. OrgFlow retrieves the results and merges them with the source data 7. OrgFlow saves the merged results as downloadable artifacts on the job You can monitor the progress of the import on the job details page. When the import is complete, downloadable result files appear as [artifacts](/docs/core-concepts/jobs/#artifacts) on the job. ### Column validation Before uploading data to Salesforce, OrgFlow validates that the columns in the source file are recognized fields on the target object. If there are columns in the source file that don't correspond to any field on the target object, OrgFlow will prompt you to decide whether to continue or abort. Columns that are not valid for the selected operation, or not visible to the selected Salesforce user, are automatically excluded. ## Job result When the import completes, the job result shows the following statistics: | Statistic | Description | | ----------------- | ------------------------------------------------------------------ | | Records processed | The number of records successfully processed by Salesforce | | Records failed | The number of records that failed to process | | Records uploaded | The total number of records submitted to the Bulk API | | Batches used | The number of Bulk API batches used | | Retries | The number of batch retries that were performed (if any) | The result files are available as [artifacts](/docs/core-concepts/jobs/#artifacts) on the job and can be downloaded directly from the job details page. They contain your original source data augmented with result columns from Salesforce, making it easy to understand how each record was processed and identify which records succeeded, which failed and why. --- --- url: /legal/imprint/_de.md description: OrgFlow GmbH corporate imprint in German language --- # Impressum ## 1. Anbieterangaben ## 2. Weitere Angaben Für von uns erbrachte Leistungen gelten unsere AGB. Sie finden sie unter https://www.orgflow.io/legal/license/ (in englischer Sprache). Hinweis zur Onlinestreitbeilegungs-Plattform (OS-Plattform): Wir sind aufgrund von Art. 14 Abs. 1 der Verordnung (EU) 524/2013 über Online-Streitbeilegung in Verbraucherangelegenheiten (ODR-Verordnung) gesetzlich verpflichtet, Sie auf die Europäische Online-Streitbeilegungs-Plattform (OS-Plattform) der Europäischen Kommission hinzuweisen. Sie können diese unter http://ec.europa.eu/odr erreichen. Weitere Informationen zur außergerichtlichen Streitbeilegung nach § 36 Verbraucherstreitbeilegungsgesetz: OrgFlow nimmt nicht an einem Streitbeilegungsverfahren vor einer Verbraucherschlichtungsstelle teil und wir sind dazu auch nicht verpflichtet. ## 3. Haftung Wir sind für die Inhalte unserer Internetseiten nach den Maßgaben der allgemeinen Gesetze, insbesondere nach § 7 Abs. 1 des Telemediengesetzes, verantwortlich. Alle Inhalte werden mit der gebotenen Sorgfalt und nach bestem Wissen erstellt. Soweit wir auf unseren Internetseiten mittels Hyperlink auf Internetseiten Dritter verweisen, können wir keine Gewähr für die fortwährende Aktualität, Richtigkeit und Vollständigkeit der verlinkten Inhalte übernehmen, da diese Inhalte außerhalb unseres Verantwortungsbereichs liegen und wir auf die zukünftige Gestaltung keinen Einfluss haben. Sollten aus Ihrer Sicht Inhalte gegen geltendes Recht verstoßen oder unangemessen sein, teilen Sie uns dies bitte mit. Die rechtlichen Hinweise auf dieser Seite sowie alle Fragen und Streitigkeiten im Zusammenhang mit der Gestaltung dieser Internetseite unterliegen dem Recht der Bundesrepublik Deutschland. ## 4. Urheberrechtshinweis Die auf unserer Internetseite vorhandenen Texte, Bilder, Fotos, Videos oder Grafiken unterliegen in der Regel dem Schutz des Urheberrechts. Jede unberechtigte Verwendung (insbesondere die Vervielfältigung, Bearbeitung oder Verbreitung) dieser urheberrechtsgeschützten Inhalte ist daher untersagt. Wenn Sie beabsichtigen, diese Inhalte oder Teile davon zu verwenden, kontaktieren Sie uns bitte im Voraus unter den obenstehenden Kontaktdaten. Soweit wir nicht selbst Inhaber der benötigten urheberrechtlichen Nutzungsrechte sein sollten, bemühen wir uns, einen Kontakt zum Berechtigten zu vermitteln. --- --- url: /legal/imprint/_en.md description: OrgFlow GmbH corporate imprint in English language --- # Imprint ## 1. Company information ## 2. Further information Our general terms and conditions apply to services provided by us. You can find them at https://www.orgflow.io/legal/license/. It is regulated therein that German law applies and that, as far as permissible, Bad Nauheim, Germany, is agreed as the place of jurisdiction. Note on the online dispute resolution platform: Based on Article 14 (1) of Regulation (EU) 524/2013 on online dispute resolution for consumer disputes, we are legally obliged to refer you to the European Online Dispute Resolution Platform of the European Commission. You can reach this at http://ec.europa.eu/odr. Further information on out-of-court dispute resolution according to Section 36 of the German Consumer Dispute Resolution Act ("Verbraucherstreitbeilegungsgesetz", VSBG): OrgFlow does not participate in a dispute resolution procedure before a consumer arbitration board and we are not obliged to do so. ## 3. Liability We are responsible for the contents of our websites in accordance with the provisions of general law, in particular in accordance with Section 7 Paragraph 1 of the German Telemedia Act ("Telemediengesetz", TMG). All contents are created with due care and to the best of our knowledge. Insofar as we refer to the Internet pages of third parties by means of hyperlinks on our Internet pages, we cannot assume any guarantee for the continuous topicality, correctness and completeness of the linked contents, as these contents are outside our area of responsibility and we have no influence on their future design. If, in your opinion, any content violates applicable law or is inappropriate, please let us know. The legal information on this page as well as all questions and disputes in connection with the design of this website are subject to the laws of the Federal Republic of Germany. ## 4. Copyright notice The texts, images, photos, videos or graphics available on our website are generally subject to copyright protection. Any unauthorized use (especially copying, editing or distribution) of these copyrighted contents is therefore prohibited. If you intend to use this content or parts thereof, please contact us in advance using the contact details above. If we ourselves are not the owner of the required copyright rights of use, we will endeavour to arrange contact with the entitled party. --- --- url: /docs/reference/include-specs.md description: >- Technical reference for the format, syntax and processing rules of include specs and include files --- # Include specs 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](/docs/devops/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](https://github.com/dazinator/DotNet.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](/docs/devops/environments/) in your [stack](/docs/core-concepts/stacks/). 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. --- --- url: /docs.md description: Overview of OrgFlow's features and overall architecture --- # Introduction to OrgFlow OrgFlow is a Salesforce DevOps and data platform that adds modern version control, deployment, automation and data management practices to the Salesforce platform. It helps you and your team effectively manage environments, deployments, metadata changes, automated testing, metadata backups, and bulk data operations. ## Feature overview OrgFlow provides all the functionality you need to build, manage, automate and operate a full end-to-end Salesforce DevOps process for the vast majority of scenarios, as well as powerful data management capabilities. OrgFlow is designed to accommodate a variety of use cases out of the box, using an intuitive web-based interface. For more advanced and customized use cases, OrgFlow is also designed to be flexible and extensible, so you can script, automate, integrate and compose it into wider overall Salesforce workflows. Here are some things you can do with OrgFlow: ### DevOps * Manage your Salesforce [environments](/docs/devops/environments/) * Continuously sync your Salesforce orgs with branches in your Git repository * Enjoy a granular version history and continuous backup of your Salesforce metadata * Flow metadata changes between environments * Detect and resolve merge conflicts * Roll back Salesforce environments to an earlier point in time * [Run Apex tests](/docs/devops/apex-test-runs/) * Manage Salesforce upgrades and API versions ### Data * [Export data](/docs/data/export/) from any Salesforce org in your choice of file format * [Import data](/docs/data/import/) into any Salesforce org using insert, update, upsert or delete operations ### General * Manage your [workspace](/docs/core-concepts/workspaces/) and its members * Run recurring operations unattended using [schedules](/docs/core-concepts/schedules/) * Use an intuitive web-based UI for day-to-day operations * Use a [cross-platform CLI](/docs/cli/) for scripting and automation * Securely store and share encrypted Git and Salesforce credentials * Integrate OrgFlow with your favorite CI/CD platform ## Architecture overview OrgFlow consists of three parts — **OrgFlow Web**, **OrgFlow CLI**, and **OrgFlow Cloud** — which play different roles for different purposes, and work together to provide all of OrgFlow's functionality. OrgFlow integrates with, and coordinates between, your Salesforce environments, your Git repository and (optionally) your CI/CD platform, as illustrated in this diagram: ### OrgFlow Web [OrgFlow Web](https://www.orgflow.app) is the main entry point to OrgFlow. It is a web application that allows you to access the full power of OrgFlow from within a web browser. When you run workloads from within OrgFlow Web, all processing is performed **on our infrastructure**. This makes OrgFlow Web a **low-code to no-code** solution with a very low barrier of entry, and not much of a learning curve. There's nothing to download and install — all you need is a web browser. ### OrgFlow CLI [OrgFlow CLI](/docs/cli/) enables more advanced or technical use cases for OrgFlow. It is a cross-platform command line tool, available for macOS, Windows and Linux, that you can download and run on devices and infrastructure outside of OrgFlow's domain. As a command line tool, OrgFlow CLI allows you to script, automate, integrate and orchestrate bigger overall processes. Think of it as an optional companion that you can use alongside OrgFlow Web. When you use OrgFlow CLI, all processing is performed **locally on the device** where you are running it. This makes OrgFlow CLI a **pro-code** solution, ideal for scenarios with strict security and compliance requirements, or when you simply want to integrate and compose OrgFlow into a wider overall process. For example, you could run the OrgFlow CLI in a third-party CI/CD platform (such as GitHub Actions) to validate the deployment and Apex test coverage of pull requests before they are merged. ### OrgFlow Cloud OrgFlow Cloud is what we call all the behind-the-scenes backend services and infrastructure that power OrgFlow. It is a collection of cloud services that do things like store all your workspace data, execute jobs that you start from OrgFlow Web, send email alerts, and keep track of the state of all your environments. As a user you won't really interact with OrgFlow Cloud directly, but both OrgFlow Web and OrgFlow CLI use it behind the scenes to enable the kind of seamless, stateful coordination of your Salesforce orgs and the branches in your Git repository that gives OrgFlow its magic. ### Salesforce This is the only thing that you need to bring yourself. OrgFlow's DevOps and data features connect to your Salesforce orgs, and you won't be able to use OrgFlow if you don't have at least one Salesforce org. If you're reading this you probably already have a Salesforce org. ### Git For OrgFlow's [DevOps](/docs/devops/) features, Git plays a central role. You might already have a Git provider, and if so you can bring your own Git repository. OrgFlow supports any standard Git repository so long as it can be accessed from our infrastructure. This includes any commercial Git provider such as GitHub, Azure Repos, GitLab, Bitbucket and so on, as well as self-hosted repositories that you might be running on internal infrastructure. You can even use a Git repository that is not accessible to the public Internet, but then you will need to use the [OrgFlow CLI](/docs/cli/) to run your DevOps workloads on a device that can connect to the repository. You can also choose to have OrgFlow create a [managed GitHub repository](/docs/devops/managed-repos/) on your behalf. ::: info Git is not required for data operations A Git repository is required to create a stack and to use OrgFlow's [DevOps features](/docs/devops/) (which use Git for metadata version control). OrgFlow's [data features](/docs/data/) do not use Git and can operate against any Salesforce org, but do require a stack in which to run. ::: ## Start for free Each OrgFlow subscription includes a limited amount of [free resources](/pricing/). This allowance should be enough to get you up and running, and use OrgFlow's powerful DevOps and data features for a small team. Additional resources are available on a Pay-as-you-go basis, so you can scale up gradually as your operations grow. ## Learn more See our [quick start guide](/docs/basics/quick-start/) if you want to dive right in. If you want some more background, read about some core concepts like [workspaces](/docs/core-concepts/workspaces/), [stacks](/docs/core-concepts/stacks/) and [environments](/docs/devops/environments/). If you're interested in scripting and automating OrgFlow, consider exploring the [OrgFlow CLI](/docs/cli/). If you're feeling curious about how OrgFlow can work within the context of an external CI/CD platform, we have a [demo repo](https://github.com/OrgFlow-Actions/demo) for GitHub Actions that can give you an idea and some inspiration (though we'd only recommend this once you already have a solid understanding of some of the more basic things). --- --- url: /docs/cli.md description: 'An introductory overview of the OrgFlow CLI, its use cases and general usage' --- # Introduction to OrgFlow CLI The OrgFlow CLI is a command line tool that packages the functionality of OrgFlow into a downloadable cross-platform executable. It complements OrgFlow Web for scenarios where running workflows from a terminal, in custom scripts or inside a CI/CD platform is preferable to running them through a web UI. ::: info DevOps vs. data operations The OrgFlow CLI currently supports [DevOps operations](/docs/devops/) only. [Data operations](/docs/data/) such as data import and export are available exclusively through OrgFlow Web. ::: ## Use cases For most use cases OrgFlow Web will be preferred for day-to-day operations. However, there are certain use cases where it might make more sense to use the OrgFlow CLI instead. ### CI/CD platform integration The most common use case for the OrgFlow CLI is probably as part of a pipeline in a third-party CI/CD platform (such as GitHub Actions, Azure Pipelines, Bitbucket Pipelines, GitLab CI/CD, or something else entirely). An example of this can be found in our [GitHub Actions demo repo](https://github.com/OrgFlow-Actions/demo). As long as the agent or runner that is executing the pipeline has the OrgFlow CLI installed, you can create rich and powerful scripts to integrate OrgFlow into your pipelines. We provide the OrgFlow CLI executable in a [variety of download formats](/docs/cli/download/) for easy installation on your agents, manually or scripted. We also provide a [Docker image](https://hub.docker.com/r/orgflow/cli) and a ready-made [GitHub action](https://github.com/marketplace/actions/orgflow-salesforce-devops-for-github) to make it even easier to get the OrgFlow CLI installed on your agents. Third-party CI/CD pipelines can also usually be triggered by events that jobs in OrgFlow Web cannot be triggered by. An example of this is a pipeline that is triggered when a pull request is opened in order to validate the result of the proposed merge and the resulting deployment into the target org. ### Local metadata processing OrgFlow CLI enables you to run OrgFlow on your local device, on a server that your company maintains, in cloud-based environments, or on a build agent hosted by a third party (such as GitHub, Bitbucket, or GitLab). When you run a command with OrgFlow CLI, all of the processing work is performed locally (on the device where you are running the OrgFlow CLI). This is useful in scenarios where you don't want your Salesforce metadata to be stored or processed on a device that is outside your organization's compliance boundary. ### Scripting and automation Being a command line tool, OrgFlow CLI allows you to script, automate, and chain processes together. You can create scripts (in Bash, PowerShell or any other scripting language) to automate your most frequently run tasks, or you can create runbooks and share them with your teams to help bring consistency to your DevOps work — just to name a few examples. OrgFlow CLI can run in any terminal on macOS, Windows and Linux. Some people also use it in Visual Studio Code (aka. VS Code) to complement their Salesforce development work by running OrgFlow commands directly from VS Code's integrated terminal. You can even create VS Code tasks that invoke the OrgFlow CLI to help automate some common workflows. OrgFlow CLI can optionally produce JSON formatted output, allowing you to take the output of a command and use it as input to something else. One example use case for this is to report on the outcome of a deployment by converting the output JSON into a human-readable Slack message and posting it in a Slack channel. ## OrgFlow CLI vs OrgFlow Web OrgFlow CLI is intended to **complement** OrgFlow Web. The two interfaces and their feature sets are optimized for different scenarios. Some functionality is available in one but not the other; other things are possible in both but can make more sense in one, depending on your needs and preferences. The main comparison points are: | Feature | OrgFlow Web | OrgFlow CLI | | :--------------------------------------- | :---------: | :---------: | | Create and manage workspaces and members | ✓ | | | Manage subscriptions and billing | ✓ | | | Create and manage stacks | ✓ | | | Low to no setup | ✓ | | | Compute provided by OrgFlow | ✓ | | | View historical Apex test runs | ✓ | | | View historical jobs | ✓ | | | Schedules | ✓ | | | Create and manage environments | ✓ | ✓ | | Flow metadata changes in and out | ✓ | ✓ | | Merge metadata between environments | ✓ | ✓ | | Run Apex tests | ✓ | ✓ | | Import and export data | ✓ | | | Snapshots and rollbacks | | ✓ | | Toolbox commands | | ✓ | | Local processing | | ✓ | | Advanced scripting and integrations | | ✓ | | CI/CD platform integration | | ✓ | ## Commands To interact with the OrgFlow CLI, you give it a *command* to run. Commands are made up of two parts: the command's *name* followed by the *arguments and options* for that command. Arguments are required inputs, and most commands will have these. Options are optional inputs, and every command has these. Options can occasionally become required based on the values of other inputs. Commands are passed into the OrgFlow CLI executable (usually named `orgflow`), so to run a command, you'll type `orgflow `. ### Discovering available commands Running `orgflow --help` will give you a list of available commands, along with a brief description of each. ### Discovering arguments and options Once you know which command you'd like to run, you'll need to know which arguments and options are available for that command. Running `orgflow --help` (for example `orgflow env:test --help`) will give you a list of all the arguments and options for the command. You'll also be given a list of *global options*. Global options are options that apply to every command in the OrgFlow CLI. They tend to control things like logging, output, error handling etc. An abridged version of this output might look like this: ```shellscript $ orgflow env:test --help USAGE: orgflow env:test --environment= [options] Arguments: --environment= (-e) Name of environment to run tests in Options: --encryptionKey= (-k) Key used to encrypt/decrypt stored credentials --classes=[,,...] (-c) Names of test classes to run ... --runAllTests[=true|false] (-a) Include non-local tests (default: false) Global options: --logLevel=verbose|debug|information|warning|error|fatal Verbosity level for diagnostic log file (default: information) ``` Argument and option names are prefixed with `--`. Some common arguments and options also have a short form alias, which is prefixed with `-`. Short form aliases are displayed enclosed in parentheses (as you can see in the example above). For example, `--environment=prod` and `-e=prod` are equivalent. Names and values are separated by `=`. Each name/value pair must be separated by whitespace, for example `--environment=prod --encryptionKey=123`. If you need to use `=` or whitespace characters in the input values, you can wrap the value in quotes (e.g. `--encryptionKey="my secret key ==="`). Sometimes empty strings are valid values. This usually denotes that a previously set value should be unset, for example `--encryptionKey=`. The output above shows argument and option names alongside their value notations. To interperet value notations: * `<>` indicates free form values * `|` indicates the value must be one of the values listed (separated by `|`) * `[]` indicates the value is optional * `,` indicates a list value - you can enter more than one value, separated by a `,` Omitting the value when specifying an argument or option name is only valid for `true|false` values. If you omit a value in this case, it's equivalent to specifying `true`. For example, `--runAllTests` and `--runAllTests=true` are equivalent. All of the following are valid examples: * `orgflow env:test --environment=uat --classes=test1,test2` * `orgflow env:test -e=uat --runAllTests` * `orgflow env:test --environment='my test env' --classes=test1,test2 -a=false` None of the following are valid: * `orgflow env:test` (required argument `--environment` not specified) * `orgflow env:test -e=my env --runAllTests` (whitespace in the `-e` value not surrounded by quotes) * `orgflow env:test --environment=prod --logLevel=max` (`max` is not a valid value for `--logLevel` ) ### Command categories OrgFlow CLI comes with a number of commands that are split into two categories: * **Process commands** are the high-level commands that you will use day to day. They act within the context of your workspace in the OrgFlow cloud, and interact with your stacks and environments. Process commands usually combine state management with the orchestration of multiple low-level operations. Most process commands are prefixed with the namespaces `stack:`, and `env:`. * **Toolbox commands** are low-level commands that allow you to interact directly with a Salesforce org, Salesforce metadata or a Git repository, independently of any workspace, stacks or environments. They allow you to do things like retrieve metadata from a Salesforce org, refresh a sandbox, or compare two metadata archives that are already on your local disk. Most toolbox commands are prefixed with the namespaces `md:`, `sb:`, and `tool:`. An example of how a process command is composed of several toolbox commands is the `env:flowin` command which will: * Clone the remote Git repository and check out the correct branch * Retrieve the correct metadata from the Salesforce org (equivalent to `md:retrieve`) * Inspect the environment state in the OrgFlow cloud in order to determine how metadata should be applied * Selectively (based on the environment state) apply the retrieved metadata to the metadata in the cloned Git repository (equivalent to `md:apply`) * Selectively (based on the environment state) commit the applied metadata to the clonedGit repository (equivalent to `md:gitcommit`) * Merge those commits back to the correct branch for the environment * Update the environment state in the OrgFlow cloud * Push the changes to the remote Git repository ## Interactive and unattended modes In some cases, the OrgFlow CLI can prompt for values and input if needed. Examples of this might be prompting for values for required arguments that weren't supplied, or prompting for confirmation to begin a deployment. The OrgFlow CLI can only prompt if it is able to receive input from the user. This is determined by checking whether or not the input stream (`stdin`) has been redirected. If the input stream *has not* been redirected, the OrgFlow CLI runs in **interactive** mode, and it is able to prompt. If the input stream *has* been redirected, the OrgFlow CLI runs in **unattended** mode, and it is unable to prompt. For example, unattended mode will be enabled if you run the OrgFlow CLI on a build agent as part of a CI/CD pipeline (because the agent will redirect the input stream and you as a user cannot provide input). ## Output The OrgFlow CLI sends output to two streams: **standard error** (`stderr`) and **standard output** (`stdout`). Standard output is used for the final output of a command; standard error is used for everything else (prompts, progress, error and information messages, etc.). This distinction is mostly pertinent in automation and scripting scenarios. In these cases, you can get the final output of each command (without worring about having to filter out the other lines that are printed) by reading or piping only the **standard output** stream. By default, the final output of each command is written in human readable form. This is great if you're manually running commands and want to inspect the output visually. However, in automation and scripting scenarios, you'll probably want the output in a machine readable format. Every command exposes a `--json` option that produces verbose JSON output. This allows you to take the output of a command and use it in your script to perform further tasks. --- --- url: /docs/core-concepts/jobs.md description: Conceptual deep-dive into executing long-running workloads as jobs in OrgFlow --- # Jobs Some operations that you perform in OrgFlow are executed instantly and synchronously when you click the button. This is mostly true for simple and quick operations that don't require significant processing, such as removing a member from your workspace. Other operations take a longer time to complete, require more complex processing, and might involve interacting with your Git repository and Salesforce orgs. Such operations not executed immediately when you click the button, but instead are queued as *jobs* for asynchronous execution in the background. Some examples of operations that are executed as jobs include: * Initializing a new stack * Creating and deleting environments * Retrieving metadata (flow in) * Deploying metadata (flow out) * Moving metadata between environments (flow merge) * Running Apex tests * Exporting data from a Salesforce org * Importing data into a Salesforce org Jobs can be monitored using the jobs page in the OrgFlow web app. This page shows currently running jobs, as well the full job history, in a single list that can be filtered on various job properties. ::: info Data retention Job history is subject to the data retention period included in your subscription. Jobs older than the data retention period are permanently deleted. Additionally, the job history shown in the web app is currently limited to 14 days, with no possibility to load older jobs (other than accessing them directly by job URL). We are planning to add ways to load more history. ::: ## Execution models ### Managed worker jobs Jobs that are started through the OrgFlow web app are executed by *managed workers*, which are essentially container instances running on infrastructure that we provide (the OrgFlow cloud). When a job gets queued for execution, a new managed worker is created, assigned to process that job, and then deleted. Each managed worker is dedicated to a single job, and managed workers are never shared between workspaces. #### Limits and billing The number of managed worker jobs that can execute simultaneously is constrained by the number of **concurrent workers** included in your subscription. Starting additional concurrent jobs beyond this limit will keep those jobs in a pending state until concurrent workers become available. Managed worker jobs are *metered*. Their execution time is categorized as follows: * **Active worker minutes (DevOps)** are the total number of minutes that the job spent doing actual DevOps work (such as retrieving or deploying metadata) * **Active worker minutes (Data)** are the total number of minutes that the job spent doing actual data work (such as importing or exporting data records) * **Passive worker minutes** are the total number of minutes that the job spent waiting for [input from a user](#inquiries) All subscriptions include a certain number of concurrent workers and a certain amount of worker minutes for free. Worker minutes consumed beyond the free allowance are billed on a consumption basis (see our [pricing page](/pricing/) for details). The amount of managed worker jobs you can run in a given billing period is constrained by the **active and passive worker minutes per month** limits configured in your workspace billing and usage settings. If any of those limits has been reached for the current billing period, starting additional jobs will fail. Unless you have provided payment details, those limits are hard-capped to the free allowance to ensure you don't incur any spending. ### CLI jobs Jobs can also be executed by *CLI workers* by running commands in the [OrgFlow CLI](/docs/cli/). Jobs started this way are executed fully by the CLI itself, and all work is performed using whatever compute resources and infrastructure you're running the CLI on. Because they run entirely on your infrastructure and don't consume OrgFlow-provided resources, CLI jobs are not metered and are not subject to the concurrent worker and worker minute constraints that apply to managed worker jobs. Both managed worker jobs and CLI jobs can be monitored using the jobs page in the web app, though CLI jobs currently show less detailed progress information. ## Job lifecycle The following diagram illustrates the important events and states a job transitions through during its lifecycle: For CLI jobs, the following apply: * **Pending** and **queued** states are skipped; jobs are created directly in **running** state * DevOps, data and passive worker minutes are not applicable ## Inquiries Jobs sometimes need input from a user before processing can continue. This is done using *inquiries*. When a job needs input, it initiates an inquiry and pauses execution while waiting for the user to respond. OrgFlow conducts the following types of inquiries: | Inquiry | Scenario | | ------------------------- | ------------------------------------------------------------------------------- | | Device code authorization | User needs to sign into a Salesforce org and authorize OrgFlow to connect to it | | Merge conflicts | User needs to resolve merge conflicts that could not be automatically resolved | | Deployment confirmation | User needs to review and confirm the contents of a deployment | Device code authorization inquiries are initiated whenever OrgFlow needs a new access token to connect to a connected Salesforce org (and no password has been saved). Merge conflict inquiries and deployment confirmation inquiries can be enabled or disabled on a per-job basis using job options. Merge conflicts can occur in a variety of scenarios, including during metadata retrieve (flow in) and during merge between environments (flow merge). See the topic about [merge conflicts](/docs/devops/merge-conflicts/) for more information. Inquiries are made visible on the job timeline on the job details page in the web app, where they can be examined and responded to by any user with sufficient permissions in the workspace. If no user responds to an inquiry within 10 minutes, and email is sent to the user who started the job. If no user responds to an inquiry within 18 hours, the inquiry times out and the job fails. The managed worker remains running while awaiting the inquiry. The time spent awaiting an inquiry is categorized as **passive worker minutes**. ::: info Inquiries in CLI jobs CLI jobs currently do not conduct inquiries through the web app. Instead the CLI uses the current shell to prompt for any input it requires. This can be impractical in some CI/CD scenarios; we are planning to add the ability for CLI jobs to conduct inquiries through the web app ::: ## Artifacts Most jobs produce output in the form of *artifacts*. Artifacts are essentially files collected by the worker during the processing of a job, stored in our infrastructure, and made available for download to users. OrgFlow collects the following types of artifacts: | Artifact | Description | Managed | CLI | | ------------------- | ----------------------------------------------------------------------------------------------------------- | ------- | ------ | | Output | Detailed results in JSON format; structure and contents are specific per job type | Yes | Yes | | Log | Log file in text format for diagnostic purposes | Yes | Yes | | Retrieved metadata | ZIP files for every batch of metadata as retrieved from Salesforce | Opt-in | **No** | | Deployment archive | Deployment ZIP files for every attempted deployment | Opt-out | Yes | | Data export | Exported Salesforce data in selected file formats | Yes | N/A | | Data import results | Source data used for Salesforce data import, plus columns with processing results, in selected file formats | Yes | N/A | | Data import source | Original copy of source data used for Salesforce data import | Yes | N/A | As seen in the above table, the CLI does not support collecting retrieved metadata artifacts. Instead the CLI provides arguments to save these items to the local file system on the machine where the CLI is executing. Artifacts can be downloaded from the job details page in the web app. ::: info Data retention Artifacts are stored in the OrgFlow cloud and are subject to the data retention period included in your subscription. Artifacts older than the data retention period are permanently deleted. ::: ## Dependencies Jobs can have *dependencies* on other jobs. One scenario where this is used, is when you start a **flow merge** job from one source environment into multiple target environments, and the job includes a **flow in** (retrieve) of the source environment. Let's say for example that you start a flow merge from environment **Production** into environments **Dev1** and **Dev2** and you configure the job to include a flow in (retrieve) of **Production**. When you submit this request, OrgFlow actually *expands* it into three separate jobs: 1. Flow in (retrieve) of environment **Production** 2. Flow merge from **Production** into **Dev1** (depends on #1) 3. Flow merge from **Production** into **Dev2** (depends on #1) This is done for efficiency. The flow in of **Production** only needs to happen once, so it can be executed to completion first, and its resulting commits in Git can then be used as the starting point by both other jobs. The flow merge into **Dev1** and **Dev2** must await the completion of the first job, but once done, these two jobs can then execute concurrently. ## Time limits Managed worker jobs are subject to the following time limits: * If a job has spent more than 6 hours in **pending** state, it is timed out * If a job has spent more than 8 hours in some combination of states other than **ended**, it is timed out * If a job has spent more than 4 hours awaiting a single inquiry, it is failed --- --- url: /docs/devops/managed-repos.md description: >- Conceptual deep-dive into using a Git repository provided and managed by OrgFlow --- # Managed repositories While OrgFlow allows you to bring your own Git repository, we can also create and manage one on your behalf. We call this a *managed repository*. Behind the scenes, managed repositories are just normal GitHub repositories that OrgFlow creates and manages for you. They provide a simpler experience than bringing your own Git repository, because: * You don't need a Git provider account * You don't need to create, configure and manage a Git repository * OrgFlow manages [authentication](/docs/security/git-authentication/) on your behalf ## Viewing, cloning, and working with managed repositories Managed repositories are private and belong to a private GitHub organization owned by OrgFlow. Managed repositories created for you are available only to OrgFlow and, optionally, to specific GitHub user accounts that you designate. They cannot be seen or discovered by other OrgFlow users or other GitHub users. By default, managed repositories are only visible to OrgFlow. You may not find this very useful if you wish to work with the repository directly, for example to view the committed Salesforce metadata, open and review pull requests, or modify metadata directly in the repository. To support these use cases, OrgFlow allows you to manage access to the repository by adding and removing user's access based on their GitHub usernames. GitHub users that have access to a managed repository do not necessarily need to have OrgFlow user accounts, and OrgFlow users that have access to a stack that uses a managed repository do not neccesarily need to have access to the managed repository. OrgFlow supports two levels of user access: * **Read-only**: allows users to view the repository in GitHub and clone the repository to a local device * **Read and write**: allows users to do everything that read-only users can do, plus push commits, branches, and tags to the remote repository ### Managing user access User access can be managed from the stack settings page. If the stack is connected to a managed repository, you'll see a `Manage access` button under the repository URL in the `Git connection` section. Clicking this button opens a dialog that allows you to view, invite, and remove users. When you invite a user, they will receive an email from GitHub asking them to accept the invitation. Once they accept the invitation they will have access to the repository. Make sure to use a GitHub username (and not an OrgFlow username) when inviting users! ::: tip About GitHub user accounts GitHub user accounts are free to create and are not tied to OrgFlow user accounts in any way. Users who do not yet have a GitHub account can sign up at [github.com](https://github.com). ::: If you need to change the access level of a user that already has access to the managed repository, you will need to first remove that user's access and then re-invite them. ## Transferring ownership Even if you started out with a managed repository for convenience, at some point in the future you might want to transition to using your own repository, for more control and to enable more advanced customization, integration and automation scenarios. To make this transition seamless, we support transferring ownership of your managed repository to your own GitHub organization at any time. To request ownership transfer of your managed repository, please [reach out to our support](/support/) and we will be happy to assist. After your repository has been transferred, the repository becomes subject to your own access control configuration in GitHub, and you must take any necessary steps to ensure continued access for your team. You must also [create a personal accesss token](/docs/security/git-authentication/#creating-personal-access-tokens-pats) and use it to configure your OrgFlow stack settings so that OrgFlow can continue to connect to the repository after the transfer. See the topic about [authenticating to Git](/docs/security/git-authentication/) for more information. --- --- url: /docs/devops/managing-api-versions.md description: How Salesforce version upgrades and API versions affect metadata change flow --- # Managing API versions This topic covers Salesforce API versions, how they affect your Salesforce DevOps workflows, and how to use the settings provided by OrgFlow to manage API versions effectively and achieve the desired results in your metadata change flow. ## API version layers Salesforce API versions are used in several different *layers* of the Salesforce APIs and the metadata you retrieve and deploy. Though the API version numbers available to you are the same, what they actually mean and how they work differs between different layers. ### Platform version The *platform version* of a Salesforce org is the version of Salesforce that's physically installed on the org (or, more accurately, on the *instance* that the org is hosted on). For example, after the major Salesforce release **Summer '25 (API version 64)** is installed on an org, that becomes the org's platform version. An org's platform version can also be thought of as **the highest API version supported by the org**. The platform version of a Salesforce org influences the payload of retrieved and deployed metadata, because when a new platform version is installed, the upgrade often modifies metadata **content** (for example, some new standard objects might be created as part of the upgrade). The platform version also (somewhat unintuitively) determines which metadata types are supported by source tracking. There is nothing you or OrgFlow can do to influence the platform version — it is entirely determined by the scheduling of Salesforce's maintenance operations. ### Metadata API endpoint version Regardless of the platform version, the Salesforce metadata API itself is versioned in two different ways. The first is the *endpoint version* which corresponds to two things: 1. The version number specified in the *endpoint URL* when calling the metadata API (e.g. `https://acme.my.salesforce.com/services/Soap/m/64.0` corresponds to metadata API endpoint version **64.0**) 2. The corresponding version of the *metadata API WSDL file* that describes the supported operations, requests and responses The endpoint version influences several limits that govern how OrgFlow can interact with the metadata API, such as the maximum number of metadata components that can be retrieved in a single batch, or the maximum allowable size of a deployment archive ZIP file. The endpoint version **does not** influence the payload of retrieved or deployed metadata. The endpoint version used by OrgFlow is hard-coded and not configurable. It only affects OrgFlow's source code and internal processing, and has no impact on the metadata payload you care about. Because the endpoint version and the corresponding metadata API WSDL file rarely change from one version to the next (at least not for the file-based and utility calls that OrgFlow relies on), we don't roll OrgFlow forward to newer endpoint versions very often. Whenever there are significant changes, and we feel that OrgFlow could benefit from them in some way, we will upgrade OrgFlow to use the newer endpoint version, but this will be transparent to you. ### Metadata payload API version The second way the Salesforce metadata API is versioned, is what we call the *payload API version*. It is independent of both the underlying platform version and the metadata API endpoint version used. The payload API version corresponds to three things: 1. The `asOfVersion` parameter provided when calling `describe()` and `listMetadata()` 2. The `apiVersion` property of a `RetrieveRequest` object provided when calling `retrieve()` 3. The `` element in package manifests inside retrieved and deployed metadata archives This is the most important API version layer to you, because it **significantly influences the payload of retrieved and deployed metadata**. Specifically, it determines the available metadata types, the structure and format of all metadata, as well as processing rules and semantics when retrieving and deploying. Because metadata flows between environments through Git merge, some care is needed to ensure that the same payload API version is used across all environments in your stack, also when they are on different platform versions. Therefore, the payload API version used by OrgFlow is [configurable](#api-version-settings) in several ways. ### Code API version Though technically unrelated to the metadata API, we should also mention the *code API version* which is the API version against which a given code-based metadata component is compiled and executed. It is independent of both the underlying platform version, the metadata API endpoint version used and the metadata payload API version. The code API version is determined by a developer when creating or editing a component, and is reflected in metadata payload through the `` element inside the `*-meta.xml` file of the component. It can be specified for the following metadata types (list is not exhaustive): * Apex classes * Apex triggers * VisualForce pages * Aura apps and components * Lightning web components * Flows The code API version is relevant in an OrgFlow context because it is **reflected the payload of retrieved and deployed metadata** and may cause deployment failures if metadata changes are flowed to environments where a particular code API version is not yet supported. ## Salesforce preview windows A new major Salesforce platform version is released to production three times per year: | Month | Release name | | -------- | ------------ | | February | Spring 'XX | | June | Summer 'XX | | October | Winter 'XX | The last 4 weeks (approximately) before every major release is known as the *preview window*. At the start of the preview window, any sandboxes hosted on *preview instances* are upgraded to a preview of the upcoming release, so that customers can try out the new features and test their solutions and customizations on the upcoming version. This is illustrated in the following diagram: So how do we know which sandboxes are on preview instances? Well, that depends on **when the sandbox was created or last refreshed**. Sandboxes created or refreshed during a preview window are provisioned on **non-preview instances**, while sandboxes created or refreshed outside any preview window are provisioned on **preview instances**, as illustrated in the following diagram: Many Salesforce customers find this sandbox refresh behavior somewhat counterintuitive and confusing at first, but you will need to get used to it because there is no way to influence it. It would make Salesforce DevOps a lot easier if customers were allowed to **choose** when creating or refreshing a sandbox, whether it should be provisioned on a preview or non-preview instance, but sadly this is not possible. As a result, you will need to plan your sandbox creation in relation to preview windows. Sometimes you may need to create a sandbox before you actually need it, to ensure it's provisioned on the right type of instance. See the topic [managing Salesforce version upgrades](/docs/guidance/managing-salesforce-upgrades/) for guidance and strategies you can use, including timing the creation of sandboxes ahead of time, as well as downgrading sandbox environments back down to non-preview version while retaining their unmerged changes. ## Metadata deployment compatibility During [Salesforce preview windows](#salesforce-preview-windows), you may find yourself in the situation where some of the orgs in your stack are on the **preview** [platform version](#platform-version) (i.e. sandboxes on preview instances) while others are on the **non-preview** platform version (i.e. production org, sandboxes on non-preview instances). This introduces some potential compatibility challenges when flowing changes between orgs. Metadata retrieved from an **older** platform version can generally be deployed to a **newer** platform version without any issues. Merging changes **from a non-preview environment to a preview environment** in OrgFlow is therefore fully supported and generally trouble-free. Going in the other direction, i.e. retrieving metadata from a **newer** platform version and deploying it to an **older** platform version, can range from fully successful in some cases to very problematic in other cases, depending on factors such as: * The [payload API versions](#metadata-payload-api-version) being used to retrieve and deploy * The amount of non-structural changes introduced in the newer version * Whether the newer [code API version](#code-api-version) was used for any code-based components in the deployment * The size and scope of the deployment (i.e. how many types and components are being deployed) OrgFlow tries to maximize the success rate by using a common payload API version supported by all environments in a stack (referred to as the *baseline* API version) by default. This ensures that any new metadata types, as well as any structure and format changes introduced in the newer version, are kept out of the metadata in your Git repository (and thus also not brought along when merging to other environments) until all environments support the newer version and it becomes the new baseline. As a safeguard, OrgFlow also prevents merging metadata with a given payload API version into an environment whose org doesn't yet support that payload API version. However, these default settings [can be overridden](#api-version-settings) to instruct OrgFlow to use the **newer** payload API version (referred to as the *latest* API version) for some or all environments in your stack, and also to allow merging metadata with the newer payload API version into an environment that doesn't yet support it. Furthermore, using the baseline payload API version does not insulate your metadata from **non-structural changes** (such as customizations of new standard objects created by a version upgrade), nor from using the **newer code API version** in code-based components. See the [cross-version bleed-through section below](#cross-version-bleed-through) for more information. Therefore, we recommend that you think twice before planning to merge changes **from a preview environment to a non-preview environment** in OrgFlow, and exercise caution when you do — even if you have configured both source and target to use the baseline API version. With that said, remember that deployments are not all-or-nothing in OrgFlow (unless you ask for it). Sometimes, a best-effort merge from a newer to an older platform version is warranted, even if a significant portion of the merged changes fail to deploy to the target org. Perhaps the failed components happen to contain changes you don't deem crucial, or perhaps they can be deployed to the target org later once it has been upgraded to the newer platform version. ## API version settings The API version settings provided by OrgFlow pertain to the [metadata payload API version](#metadata-payload-api-version), because this is the only API version layer over which OrgFlow has any influence, and it's also the layer with the most significant impact on the structure and format of the metadata in your Git repository, and hence your ability to flow that metadata between environments. ### API version selection mode OrgFlow can use one of two *API version selection modes* when connecting to an environment's Salesforce org: * **Baseline** mode uses the latest API version supported by both OrgFlow and **all environments in the stack** * **Latest** mode uses the latest API version supported by both OrgFlow and **the environment in question** The baseline API version is continuously determined by OrgFlow by querying for the supported API versions of all the Salesforce orgs in your stack, and checking which supported versions they have in common. The baseline version will usually correspond to the current non-preview version. In rare circumstances (such as when your production org is upgraded before all your sandboxes have been upgraded, or when you have no production org in your stack) OrgFlow may determine a preview version as the baseline, but this is usually inconsequential in such cases. Once an API version has been determined by OrgFlow as the baseline, the baseline can never drop down below that version. This is to prevent the baseline from potentially fluctuating as environments are added and removed from the stack, which could cause the structure and format of the metadata in your Git repository to change back and forth, and ultimately end up causing merge conflicts and deployment problems. The default API version selection mode is **baseline mode**. This mode maximizes metadata deployment compatibility between environments in your stack, by providing [some](#cross-version-bleed-through) insulation of your metadata from disparate platform versions during preview windows. The API version selection mode for your stack can be configured on the **stack settings** page under the **Salesforce connection** section: The stack setting applies to all environments in the stack by default, but you can also override the API version selection mode for individual environments on the **settings** tab on the **environment page**, under the **Salesforce connection** section: By default, all environments inherit the API version selection mode from the stack. This is recommended as it makes administration easier to manage API version settings for all environments in a single place. However, there are scenarios where you might like specific environments to use a different API version selection mode than the rest of the stack, such as during Salesforce preview windows. ### Allowing unsupported API versions in merge operations As mentioned earlier, OrgFlow prevents merging metadata with a given payload API version into the Git branch of an environment whose org doesn't yet support that payload API version. This is a safeguard designed to help protect you from inadvertently merging preview metadata into a non-preview environment's branch, only to realize later that it cannot be deployed to the target Salesforce org. (This safeguard applies only for merge operations initiated from OrgFlow Web or OrgFlow CLI - not for merge operations performed outside of OrgFlow.) There are legitimate cases where you might want to perform such a merge. If you know what you're doing, you can override the safeguard when starting a flow merge job in OrgFlow Web: In the OrgFlow CLI you can do the same using the `--allowUnsupportedApiVersions` option: ```shellscript $ orgflow env:flowmerge --from=Development1 --into=Production --allowUnsupportedApiVersions ``` ### Viewing API versions in use OrgFlow makes it easier for you to keep track of Salesforce versioning by providing an overview of all your sandboxes on the **environments** page. For each sandbox you can see which instance it's hosted on, which platform version it's running, and which metadata payload API version OrgFlow will use when retrieving and deploying metadata: ## API version support ### In OrgFlow The metadata structure and format for a given [metadata payload API version](#metadata-payload-api-version) is described by the *metadata description*, which OrgFlow fetches from the metadata API and uses to drive metadata processing. There are many quirks and omissions in the metadata description, however, so OrgFlow also contains a set of *processing rules* for every payload API version, which capture those omissions and ensure metadata is processed correctly. As a safety precaution, regardless of the API version selection mode in effect, OrgFlow will never use an API version than it does not have processing rules for. Instead, it will always select the newest API version supported by both the relevant orgs **and** its built-in ruleset. OrgFlow always contains support for the **current non-preview version**. OrgFlow normally also contains support for the **current preview version**. This support may not always be available on the first day of the [preview window](#salesforce-preview-windows), but typically no later than the middle of the preview window. Until then, OrgFlow will simply continue to interact with preview sandboxes using the current non-preview payload API version, even for environments using the **latest** API version selection mode. OrgFlow normally also contains support for a number of **older versions**. These are typically never used because no Salesforce orgs exist which require them, however they may be used if you attempt to have OrgFlow process older metadata archives stored in a Git branch or on your local file system. We continuously deprecate these as needed. OrgFlow currently contains supporting processing rules for the following metadata payload API versions: | Release name | API version | Status | | ------------ | ----------: | ----------------------- | | Winter '26 | 65.0 | **Current non-preview** | | Summer '25 | 64.0 | Superceded. | | Spring '25 | 63.0 | Superceded | | Winter '25 | 62.0 | Superceded | | Summer '25 | 61.0 | Superceded | As for [metadata API endpoint versions](#metadata-api-endpoint-version), OrgFlow always contains support for the version it uses to connect. However, this is an internal implementation detail that doesn't influence the metadata in your Git repository or anything else you see. As for [code API versions](#code-api-version) used in your code-based metadata components (such as Apex classes and triggers), these are opaque to OrgFlow and require no explicit support. ### In Salesforce Metadata API endpoint versions, metadata payload API versions and code API versions are all subject to the same availability and support lifecycle in Salesforce. The versions available in any given org ranges from the current platform version of the org, all the way back to the oldest supported version. Salesforce maintains compatibility with older versions for a long time, and then eventually deprecates them in a controlled manner, with plenty of advance warning, when they become so old that it is no longer feasible to support them. ## Cross-version "bleed-through" The settings and mechanisms described in this topic go a long way towards minimizing the impact of API and metadata version differences between environments, but they cannot completely insulate you even if you always use baseline mode for all your environments. Differences in metadata content from orgs that are on different platform versions sometimes "bleed through" even if OrgFlow uses the same API version when retrieving from them. This is just inherent behavior of the metadata API, and beyond OrgFlow's control. Let's look at a couple of examples, assuming the current major version in production is **Spring '25 (API version 63.0)** and we are entering the preview window for **Summer '25 (API version 64.0)**. One case is when **the upgrade itself modifies metadata content**, but not necessarily its structure or format. For example, when a sandbox on a preview instance is upgraded to version **64.0**, some new standard objects might be created as part of the upgrade. These standard objects will appear in retrieved metadata even if using API version **63.0** when retrieving, because standard objects as a metadata type is supported in both versions, and not something new to the preview. Any customizations you make to these standard objects in a preview environment (for example, adding a custom field) will be retrieved, but will fail to deploy to non-preview environments, because those standard objects don't exist there yet. Another case is **explicitly configured API versions for code-based components**, which is completely independent of the API version used to retrieve. For example, if you create an Apex class in a preview environment targeting version **64.0** (in fact, a new Apex class will target the latest available API version by default) then, even if OrgFlow retrieves it using version **63.0**, it will still target version **64.0** in its `*-meta.xml` file and therefore fail to deploy to non-preview environments. These were just two examples; there are several other cases where modifications caused by upgrading an org to a preview platform version will "bleed through" into non-preview metadata, in ways that will fail to deploy to a non-preview org. For this reason, some care is needed when you are planning your release timeline. You must consider **which** environments your changes will flow through, and **when** to create those environments to ensure they end up the correct instance type with respect to how metadata should flow to and from them. Each environment may need to be on either a preview or a non-preview instance, depending on how downstream merges will align with the beginning and end of any preview windows that happen to overlap with your release cycle. See the topic [managing Salesforce version upgrades](/docs/guidance/managing-salesforce-upgrades/) for guidance and strategies you can use, including timing the creation of sandboxes ahead of time, as well as downgrading sandbox environments back down to non-preview version while retaining their unmerged changes. --- --- url: /docs/devops/managing-included-metadata.md description: >- Controlling which Salesforce metadata should be covered by OrgFlow's change flow --- # Managing included metadata OrgFlow deals only with Salesforce metadata that you have chosen to *include* in the metadata change flow. Metadata that is **included** is tracked by OrgFlow's automatic change detection, stored and versioned in your Git repository, flowed between your Salesforce orgs in your Git branches, and flowed between the environments in your stack. Metadata that is **not included** is effectively **ignored by OrgFlow** and kept out of your Git repository and your metadata change flow. It is as if OrgFlow cannot see this metadata in your Salesforce orgs. Every stack has a configurable set of filtering rules that dictate which subset of your Salesforce metadata should be included in the metadata change flow. These filtering rules are known as [*include specs*](/docs/reference/include-specs/#include-specs). Metadata components matching the include specs constitute *included metadata*, all other metadata components constitute *excluded metadata*. These filtering rules (include specs) are stored in a file named `.orgflowinclude` in the root of the Git repository. This file is known as the [*include file*](/docs/reference/include-specs/#include-files) of your stack. The include file is versioned, branched and merged alongside your Salesforce metadata. Therefore, while the included metadata settings cover the whole stack, they can temporarily diverge between environments in the stack and ultimately converge as branches are merged — just like the included metadata itself. See the [include specs reference](/docs/reference/include-specs/#include-specs-reference) for detailed information about the syntax and semantics of include specs and include files. ## Choosing what to include When you initialize a new stack, OrgFlow suggests a [default include file](/docs/reference/default-include-file/) designed to cover the Salesforce metadata types most commonly customized in sandboxes and deployed across environments. You can accept the default suggestion, or change it — either during stack initialization or [later on for an existing stack](#changing-included-metadata-in-an-existing-stack). Choosing which metadata to include is a balance between several factors: * The **more** metadata you include, the longer it takes to complete flow operations such as retrieving, merging and deploying metadata, and the higher the risk of merge conflicts and deployment issues caused by metadata changes you don't actually care about. * The **less** metadata you include, the higher the risk that included changes fail to deploy across environments because they depend on changes that are **not** included. * The **less** metadata you include, the more likely you will need to modify in a sandbox some component that wasn't included when the sandbox was created ([more on this below](#changing-included-metadata-in-an-existing-stack)). * Some metadata types are normally **created by users** rather than customized by admins/developers, and are **managed like user data**, and should therefore normally be **excluded**. Examples include reports and dashboards. * Some metadata types **cannot be modified in production** and should therefore normally be **included**. Examples include Apex, Visualforce and Lightning Aura metadata. Keeping the above considerations in mind, decide carefully which metadata you include in the change flow when creating a stack. You should also continuously reassess as you iterate over your releases, and review the include file at regular intervals to ensure it still aligns with your Salesforce DevOps objectives. ### Opt-in vs. opt-out Your include file can be structured using an *opt-in* or *opt-out* approach. With the opt-in approach, you start with an empty include file (which includes nothing) and explicitly **add inclusions** for any metadata you **want to include** in the flow: ``` # Include only layouts and quick actions: unpackaged/~/Layout unpackaged/~/QuickAction ``` This is the approach used by the [default include file](/docs/reference/default-include-file/), and has the following benefits: * Keeps metadata scope tighter, and retrieve and deploy operations consequently quicker * Minimizes risk of merge conflicts and deployment failures * Reduces instability over time, because new types of metadata introduced by Salesforce major releases are not automatically included in the change flow With the opt-out approach, you start your include file with a line that includes all unpackaged metadata and explicitly **add exclusions** for any metadata you **DO NOT want to include** in the flow: ``` # Include all unpackaged and non-namespaced metadata: unpackaged/~ # Exclude reports, dashboards, profiles and permission sets: !unpackaged/~/Report !unpackaged/~/Dashboard !unpackaged/~/Profile !unpackaged/~/PermissionSet ``` This approach has the following benefits: * Minimizes risk of having to [change included metadata for already existing sandboxes](#changing-included-metadata-in-an-existing-stack) and deal with the resulting potential clobber * Automatically covers new types of metadata introduced by Salesforce major releases Which approach you choose is up to you, and ultimately depends on which benefits are more important to you. You don't have to pick one approach and stick with it forever; you can change from one approach to the other at any time, so long as you keep in mind the considerations described below. ## Changing included metadata in an existing stack A stack is typically a long-lived entity (often more or less permanent) and it can be difficult to predict when you create the stack which metadata your team will want to flow in the future — especially since new metadata types are continuously added to the platform. Fortunately, you can make changes to the include file in an existing stack to add or remove included metadata over time. The steps for changing the included metadata in a stack are: 1. [Make the necessary changes to the include file](#editing-the-include-file) in the production branch (usually `main` or `master`) 2. [Flow in](/docs/devops/flow-in/) the production environment to have the metadata added/removed in your Git repository 3. [Flow merge](/docs/devops/flow-merge/) from production into sandbox environments (if any) ### Considerations for existing metadata Depending on the current environments in the stack and the metadata you intend to add or remove to the include file, there are some important considerations that you need to be aware of. These are illustrated in the following diagram, and explained in more detail below. **Are there currently any sandboxes in your stack?** If your stack currently contains only your production org (i.e. no sandbox environments) then you can freely change the included metadata in any way you like. The added/removed metadata will simply be reflected in the production branch (typically `main` or `master`) after the next flow in, and copied to any future sandboxes. **Are you adding any *existing* metadata to the flow?** OrgFlow's metadata change flow [relies heavily on Git version control](/docs/devops/metadata-version-control/) in order to achieve its magic features, such as [safely merging changes from multiple sources](/docs/devops/metadata-version-control/#safe-merging-of-changes) and [automatic conflict detection and resolution](/docs/devops/metadata-version-control/#conflict-detection-and-resolution). To work its magic when changes to the same component are made in more than one place, Git requires the two modified versions to share a *common ancestor* in version history. For OrgFlow to **safely** flow modifications of a given component between two environments, the component must exist with identical content in both Git branches before those modifications are made. Or expressed more technically, the two branches must both contain a shared commit at which the component was identical across the two environments — that's the common ancestor commit. When you modify your include file so that it now includes metadata components which **already exist in both your production org and sandboxes** but which were not previously included in the flow, those components are **added** in each Git branch separately. The production branch is then merged into each sandbox branch (following the steps described above). **Has the existing metadata been *changed* on either side?** Components that are identical between production and each sandbox are simply accepted, and a common ancestor is established. However, components that are **different** between production and the sandbox obviously indicate that the component was changed (either in production, or in the sandbox, or both) since the sandbox was created. Such components will yield *merge conflicts*. Because there is not yet a common ancestor at this point, Git cannot determine what changed where — only that the two versions differ. Therefore, OrgFlow will not be able resolve this merge conflict automatically, or even offer a [three-way compare or merge](/docs/devops/metadata-version-control/#comparing-environments). Instead you must resolve these merge conflicts by accepting **either production or the sandbox version of each component as a whole**. The differences between production and sandbox can be visualized at the source line level, but without any indication of what changed where. This means there is a high risk of clobber, and you need to exercise a more caution. OrgFlow must essentially **copy/paste** (not merge) the new included metadata once, either from production to sandbox or the other way around, in order to establish the common ancestor commit we discussed above. This is simply an inherent constraint of Git's change flow, and is usually considered a small price for all the benefits that Git provides. Once you have resolved any conflicts, the chosen version of each component becomes the common ancestor, and future changes to the component can be tracked across — and merged safely between — all environments. ### Editing the include file Editing the include file in your repository can be done in many different ways with many different tools, and how you do it is ultimately a matter of personal preference. If you are using a commercial Git provider like GitHub or Azure Repos, you can easily edit the file and commit the changes straight to the branch via their respective web interfaces. Another option is to clone the repository to your local computer and use desktop Git tools, the Git command-line interface, or an IDE with built-in Git tools such as Visual Studio Code to check out the correct branch, edit the `.orgflowinclude` file, commit your changes and push the commit back to the remote repository. When making changes to the include file, refer to the [include specs reference](/docs/reference/include-specs/#include-specs-reference) for detailed information about the syntax and semantics of include specs and include files. ## Sandbox initialization When you request to create a new sandbox, Salesforce copies existing metadata and configuration from the source org (normally your production org) into the new sandbox. If choose to create a **Full** or **Partial Copy** sandbox, all metadata is copied unmodified. However, if you choose to create a **Developer** or **Developer Pro** sandbox where available storage space is more constrained, some *mutations* are applied during the metadata copy process: * Some categories of metadata items (e.g. `ContentAsset` and `Document`) are **omitted** from the copy process * Any metadata items that *reference* the omitted items are **modified** to remove those references This results in a newly created sandbox whose metadata is not identical to your production org. The sandbox branch is identical to the production branch, but it does not match the sandbox itself. In a version controlled context this is not a good starting point; the sandbox environment needs a baseline where the metadata is identical between the newly created sandbox and the backing branch, so that OrgFlow can use this as the common ancestor for safely tracking and flowing changes. When preparing a new sandbox environment, OrgFlow therefore attempts to *initialize* the newly created sandbox and revert the mutations applied by Salesforce during the copy process, in order to establish a starting point where there is full parity between production and the new sandbox, and between the sandbox and the branch. ### Including `ContentAsset` metadata It can be necessary to include a subset of `ContentAsset` metadata in the flow because `ContentAsset` items are often referenced by other metadata such as `CustomApplication` and `CustomTab`. Because the `ContentAsset` items in a production org can amount to storage space much larger than what a normal Developer or Developer Pro sandbox allows, Salesforce omits `ContentAsset` metadata from the sandbox copy process, and automatically removes references to them from other metadata. For the same reason, the [default include file](/docs/reference/default-include-file/) also does not include any `ContentAsset` metadata. If **all** `ContentAsset` items were included by default, the initialization described above might fail because the attempted deployment would exceed the sandbox storage limits. On the other hand, if we include for example one or more `CustomApplication` or `CustomTab` components that **reference** `ContentAsset` items, but we don't include the referenced `ContentAsset` items themselves, then the initialization will likely fail for those components, because the `ContentAsset` items they reference don't exist in the sandbox. This means that OrgFlow cannot establish initial parity for those components, and change flow must therefore be disabled for those components for the lifetime of the sandbox. OrgFlow is not currently able to determine which `ContentAsset` items are referenced by other included metadata and therefore must be included in the flow. Instead, we recommend that that you standardize on a naming pattern for `ContentAsset` items that allows you to easily identify and include only those `ContentAsset` items that are referenced by other metadata in the flow, while excluding other `ContentAsset` metadata that would risk exceeding the Developer or Developer Pro sandbox storage limits. For example, whenever you add `ContentAsset` items that you reference from other metadata, you might prefix such `ContentAsset` items with `FLOW_` and always name them accordingly. You could then add the following line to include **only** those content assets in the flow: ``` unpackaged/~/ContentAsset/FLOW_* ``` This would allow OrgFlow to initialize new sandboxes with only this subset of `ContentAsset` items (which are unlikely to exceed the available sandbox storage space) which in turn also allows OrgFlow to initialize the metadata components (such as `CustomApplication` and `CustomTab`) where those `ContentAsset` items were referenced, thereby achieving full initial parity. ## Excluding deleted `Flow` components Starting with API version `44.0` it became more complicated to delete `Flow` components via the metadata API. In API versions `44.0` and greater, to delete a `Flow` component in a deployment, **all versions** of that flow in the target org must be deleted simultaneously in the same deployment. But since it's also no longer possible to retrieve a list of flow versions through the metadata API, OrgFlow is currently not able to delete `Flow` components. It is recommended that, immediately after completing a production deployment containing deleted `Flow` components, you **exclude** the deleted flows from the change flow before merging upstream, in order avoid having older versions of those deleted `Flow` components "reappear" in upstream environments. For example, let's say you have completed a flow merge to production, and the changes included deletions of two flows `Alpha` and `Beta`. The deployment of those two deleted flows fails, with the metadata API reporting the error message `Insufficient access rights on cross-reference id`, so you manually delete them from your production org as a post-deployment step. You then add the following lines to the end of `.orgflowinclude` file in the production branch (typically `main`): ``` # Exclude deleted flows to prevent them from reappearing: !unpackaged/~/Flow/Alpha !unpackaged/~/Flow/Beta ``` After that, you run a flow in job with the **force** option enabled in order to clear out any deployment failures and "start over" with the metadata as it now looks in production, as the new established baseline. After that, you run a flow merge job to merge all new changes from your production environment into all upstream environments. The exclusions you added to the `.orgflowinclude` file are now merged into all upstream environments, which prevents older versions of these flows from reappearing in those environments as a result of OrgFlow's inability to delete them there. If you later decide to repurpose the name of a previously deleted flow when creating a new flow, you will need to remove the corresponding exclusion line from your `.orgflowinclude` file. --- --- url: /docs/data.md description: Overview of OrgFlow's features for managing Salesforce data --- # Managing Salesforce data OrgFlow's data features let you move record data into and out of your Salesforce orgs quickly and easily. Powered by Salesforce's Bulk API and Pub/Sub API, these features are designed for speed and scale while remaining simple to use. ## Data operations There are currently two data operations in OrgFlow: | Operation | Description | | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | [Export data from Salesforce](./export/) | Query records from a Salesforce org and download them as files in your choice of format | | [Import data into Salesforce](./import/) | Upload records from a source file or URL and ingest them into a Salesforce org using insert, update, upsert or delete operations | ## Data vs. DevOps OrgFlow has two main product areas: **DevOps** and **Data**. The DevOps features deal with flowing changes to Salesforce *metadata* (the structure and configuration of your org) using Git-based version control, while the data features deal with Salesforce *data* (the actual records stored in your org) and operate independently of any Git repository. The two areas share underlying infrastructure and common functionality such as [workspaces](/docs/core-concepts/workspaces/), [stacks](/docs/core-concepts/stacks/), [jobs](/docs/core-concepts/jobs/) and [schedules](/docs/core-concepts/schedules/), but they serve different purposes and are operated independently. ## Targeting any Salesforce org Unlike DevOps operations which operate on [environments](/docs/devops/environments/) in your stack, data operations can target **any Salesforce org** that you can authenticate to — it doesn't have to be an org that is configured as an environment in your stack. This means you can use OrgFlow's data features against production orgs, sandboxes, scratch orgs and developer editions, regardless of whether those orgs are participating in your DevOps workflow. You can of course also use OrgFlow's data features on Salesforce orgs that form environments in your stack, and OrgFlow provides convenient shortcuts to start data operations from environments in your stack. To be used with OrgFlow's data features, a Salesforce org must support: * Salesforce REST API * [Salesforce Bulk API](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/asynch_api_intro.htm) For best performance in query operations, also make sure [query job platform events](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/subscribe_platform_events_beta.htm) are enabled in the Salesforce org (see [below](#salesforce-bulk-api-and-pubsub-api) for details). ## File formats Both import and export support multiple file formats: | Format | Extension | Description | | ------- | ---------- | ----------------------------------------------------------------- | | CSV | `.csv` | Comma-separated values — widely supported and easy to work with | | JSON | `.json` | JavaScript Object Notation — useful for structured data pipelines | | Parquet | `.parquet` | Columnar format — efficient for large datasets and analytics | | Excel | `.xlsx` | Microsoft Excel workbook — convenient for manual review and edits | When exporting, you can select one or more formats and OrgFlow will produce a downloadable file for each. When importing, the source file can be in any of these formats. ::: tip The files produced by an export operation can be used directly by an import operation. This makes it easy to export data from one Salesforce org and import it into another. ::: ### Choosing a format Each format has trade-offs in terms of processing speed, file size and compatibility: * **Parquet** is the fastest format for OrgFlow to process and produces compact files. If speed is your priority, Parquet is the best choice. It is well-suited for large datasets and integrates easily with data analytics tools, but is not human-readable and requires specialized software to open. * **CSV** offers a good balance of speed, compatibility and simplicity. CSV files are fast to process, easy to open in any text editor or spreadsheet application, and are widely supported across tools and platforms. This makes CSV a good general-purpose default and a lightweight alternative to Excel. * **JSON** is useful when you need structured data for programmatic consumption or data pipelines. However, because field names are repeated for every record, JSON files can become very large with wide or large datasets compared to other formats. * **Excel** is convenient for manual review and editing in spreadsheet applications, but is significantly slower for OrgFlow to process than the other formats. If you don't specifically need an Excel file, consider using CSV instead for better performance. Excel files are also limited to a maximum of 1,048,576 records (see below). ::: warning Excel is limited to 1,048,576 records Excel files are limited to a maximum of 1,048,576 records due to limitations in most software tools that can open them. If the dataset for a data operation (import or export) contains more than 1,048,576 records, no Excel result file will be created. ::: ## Data operations and jobs Data operations run as [jobs](/docs/core-concepts/jobs/) in OrgFlow, just like DevOps operations. This means they benefit from the same job infrastructure, and features such as real-time progress monitoring, job timeline, artifacts and job history. Data operations are metered separately from DevOps operations and their active worker minutes are categorized as **active worker minutes (data)**. Passive worker minutes are the same for both DevOps and data operations. See the [billing](/docs/basics/billing/) topic for more information about worker minutes and billing. ## Salesforce Bulk API and Pub/Sub API Under the hood, OrgFlow uses the [Salesforce Bulk API](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/asynch_api_intro.htm) to query and ingest data. The Bulk API is optimized for processing large volumes of records efficiently. OrgFlow automatically handles the details of creating Bulk API jobs, splitting data into batches, and retrieving results — so you can focus on the data itself rather than the API mechanics. OrgFlow uses Bulk API V2 for query operations, and Bulk API V1 for anything else. For query operations, OrgFlow takes performance a step further by combining the Bulk API with the [Salesforce Pub/Sub API](https://developer.salesforce.com/docs/platform/pub-sub-api/overview). Rather than having to wait until the whole Bulk API job is completed in Salesforce, OrgFlow subscribes to [`BulkApi2JobEvent` platform event notifications](https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/sforce_api_objects_bulkapi2jobevent.htm) via the Pub/Sub API which allows it to process batches as and when they are ready. This translates into significant performance gains, since OrgFlow can download, transform and process early batches while the Bulk API job continues to produce subsequent batches in Salesforce. At the time of writing, `BulkApi2JobEvent` platform events are still in preview and [must be enabled in your Salesforce org](https://developer.salesforce.com/docs/atlas.en-us.api_asynch.meta/api_asynch/subscribe_platform_events_beta.htm). If this feature is not enabled, or if no `BulkApi2JobEvent` platform events are detected through the Pub/Sub API for any other reason, OrgFlow gracefully falls back to continuously polling for Bulk API job completion. This typically makes the data operation slower overall, but produces the same result in the end. --- --- url: /docs/devops/merge-conflicts.md description: >- Understanding and resolving merge conflicts during metadata flow operations in OrgFlow --- # Merge conflicts When you use OrgFlow to flow metadata changes between Salesforce environments, you are fundamentally using Git's merge capabilities under the hood. This means that merge conflicts — a normal and well-understood part of any version control workflow — can and do occur. This topic explains what merge conflicts are, when they happen in OrgFlow, and how to resolve them. ## What are merge conflicts? A merge conflict occurs when Git attempts to combine changes from two different sources and finds that the same lines in the same file have been modified in different, incompatible ways. In such cases Git cannot automatically determine which version is correct, so it raises a conflict and asks a human to decide. In a typical software development workflow, merge conflicts arise when two developers change the same lines of the same file in two different branches, and someone then tries to merge those branches together. Only **overlapping changes** produce conflicts — if two developers change **different** lines of the same file, or change different files entirely, Git merges those changes automatically without any conflict. ### Merge conflicts in Salesforce DevOps In Salesforce DevOps, merge conflicts arise from the same underlying cause, but the changes are not always introduced by developers committing code changes in the traditional sense. Instead, changes can come from a multitude of sources: * Admins configuring metadata directly in production or in a sandbox * Developers writing Apex, Lightning components or other code in a sandbox * Automated tools or managed packages updating metadata in an org * Commits pushed directly to a Git branch When two such sources of change modify the same lines of the same metadata component, and those changes are merged together — whether during a [flow in](/docs/devops/flow-in/), a [flow merge](/docs/devops/flow-merge/), or an external Git merge — a merge conflict occurs. Because Salesforce metadata is stored as XML, merge conflicts in Salesforce metadata look a bit different from conflicts in typical programming languages. A conflict might involve two environments having changed the `` and `