I’m a big fan of Salesforce DX, particularly Salesforce CLI and scratch orgs. As the Salesforce Extensions for Visual Studio Code matures, I’ve been doing more development in that editor for my projects at work and quick proof of concepts. I still highly support and use IlluminatedCloud plugin for IntelliJ for my open source projects because I prefer the richness of that IDE, its intellisense, and ease of issuing SOQL queries or running anonymous Apex. But I digress.

New to Salesforce DX? Learn on Trailhead with the Quick Start: Salesforce DX project.

New to Visual Studio Code? Learn on Trailhead with the Quick Start: Visual Studio Code for Salesforce Development project.

In recent releases, the Salesforce Extensions for Visual Studio Code is supporting projects better that follow either an org development model or a package development model. This means that you can deploy and retrieve metadata in either the source format or Metadata API format to any org, including scratch orgs, sandboxes, and production orgs.

One of these improvements is the introduction of the force:source:deploy command that understands how to deploy metadata in either format whereas the original force:source:push and force:mdapi:deploy commands only understand their file formats.

Example Deploy Commands

To deploy metadata defined in source format (e.g. Salesforce DX project):

sfdx force:source:deploy --sourcepath force-app

To deploy metadata defined in package.xml (e.g. Metadata API project):

sfdx force:source:deploy --manifest src/package.xml

You can find many more examples in the Develop Against Any Org documentation of the Salesforce DX Developer Guide.

So let’s see how Salesforce Extensions for Visual Studio Code is helping developers deploy to any org.

Set Up Your Environment

Learn how to install Salesforce CLI, Visual Studio Code, and the Salesforce Extensions by completing Quick Start: Visual Studio Code for Salesforce Development on Trailhead.

To activate the Salesforce Extensions, your project must include a sfdx-project.json file. You can run the command sfdx force:project:create -n myproj to scaffold a new Salesforce DX project and will create a sfdx-project.json file or you can create the file yourself with the following content to define the simplest configuration.

You also need to set your defaultusername config variable to point to a source-tracked org, such as a scratch org. The default username tells the Salesforce CLI, and subsequently the Salesforce Extensions, which org to perform actions against. Open the Command Palette and choose SFDX: Set a Default Org.

It is also by this config variable that Salesforce Extensions infers if the org is source-tracked or non-source-tracked to intelligently filter commands in the Command Palette or right-click context menu options to offer you actions that are relevant for the kind of org you’re developing against.

Let’s explore those command suggestions next.

Visual Studio Code and Source-Tracked Orgs

If your default username is a source-tracked org, such as a scratch org, you can run SFDX: Push Source or SFDX: Pull Source commands from the Command Palette. These equate to the CLI commands force:source:push and force:source:pull, respectively.

To deploy your metadata to any other org, open the Terminal and run the force:source:deploy command to deploy to a target org. Note in the following command we are using the --sourcepath argument to reference our directory of metadata that’s in the source format.

sfdx force:source:deploy \
--sourcepath force-app \
--targetusername <alias or username>

Visual Studio Code and Non-Source-Tracked Orgs

Like our project for developing against a source-tracked org, to use the Salesforce Extensions for project developing against non-source-tracked orgs we still need a sfdx-project.json file.

Traditionally, projects that work with Metadata API format have a folder named src instead of force-app. Whatever folder name you use, make sure to update the "path": "force-app" line in your sfdx-project.json file to specify the name of the folder containing your metadata.

The convenience for non-source-tracked orgs is that you can right-click on a file or folder in your project and choose the command SFDX: Deploy Source or SFDX: Retrieve Source. These equate to the CLI commands force:source:deploy and force:source:retrieve, respectively. Note, at the time of writing, these commands don’t appear in the Command Palette, only as right-click context menu options, and only for projects whose default username refers to a non-source-tracked org.

To then deploy your metadata to any other org, open the Terminal and run the force:source:deploy command to deploy to a target org. Note in the following command we are using the --manifest argument to reference our package.xml that refers to our metadata that’s in the Metadata API format.

sfdx force:source:deploy \
--manifest src/package.xml \
--targetusername <alias or username>

Develop Against Any Org

As we’ve seen, Salesforce Extensions provides the SFDX: Push / SFDX: Pull commands for projects developing against source-tracked orgs, and SFDX: Deploy Source / SFDX: Retrieve Source right-click context menu options for projects developing against non-source-tracked orgs.

But what if you want to deploy or retrieve specific pieces of metadata regardless the kind of org your project is developing against?

I appreciate what the push/pull commands do by auto-detecting the diffs between my local project and my scratch org, but sometimes I just want to deploy or retrieve specific files and bypass the change detection. And I don’t want to concern myself with whether I’m developing against a scratch org, a sandbox, a developer edition org, etc.

Sometimes I make changes in the org that I have no desire to be pulled down into my project, such as page layouts or toggling caching on/off or testing minor profile tweaks. Nor do I want to meticulously curate a .forceignore file to filter those changes out from being pulled into my project.

Other times I may delete files from my local project with no intent that I want that metadata deleted from my org, as the force:source:push command might attempt to do. Nor do I want to meticulously curate a .forceignore file to filter those changes out from being pushed into my org.

When I get into these situations with scratch orgs, I always fall back to using the force:source:deploy, force:source:retrieve, and force:source:delete commands. But since Salesforce Extensions don’t offer those options via the Command Palette or right-click context menu when the default username of my project refers to a source-tracked org, I have to run these commands from the command line.

Or do I?

Deploy, Retrieve, and Delete Source with Tasks

Visual Studio Code provides easy options for providing menus to run commands. You’ve seen this by using the Command Palette but you can also create your own simple Tasks without writing any code.

So I created my own tasks to deploy, retrieve, and delete source and made them available to run via the Terminal > Run Build Task… menu or the keyboard shortcut Ctrl+Shift+B (Windows) and Cmd+Shift+B (macOS).

Now I can quickly and easily deploy, retrieve, or delete the currently open file, or an entire folder of metadata, against my default org.

Try it yourself by creating a tasks.json file in your project’s .vscode folder and replacing the file’s contents with the following configuration.

Resources