How to push code to production with Visual Studio Code & DX

As of Summer '19 (v46.0), the INVALID_OPERATION errors you were hitting are no longer an issue!

force:source:deploy now works when deploying to production. See an example below:

sfdx force:source:deploy -m ApexClass:MyApexClass -l RunSpecifiedTests -r MyApexClass_Test -w 3 -u MyProductionOrg

You have two choices. First, you can use force:package commands to create an unlocked package. You can install this in production with force:package:install; it is similar to installing an AppExchange package. Otherwise, you would need to use force:source:convert to get a mdapi style format, then use force:mdapi:deploy with the relevant test level (e.g. RunLocalTests) and set rollbackOnError to true. Check out the Salesforce CLI Reference for specific details, or sfdx help force:<command> for command-level help direct from the console. I do not believe that you're currently allowed to create unlocked packages directly via the GUI, but you can open a terminal by using the Terminal > Create New Terminal option, which will open a sfdx environment by default.

The "SFDX: Deploy Code to org" command uses the sfdx force:source:deploy command, which according to the documentation only deploys to non-production orgs (at least as of Spring '19).

A nifty way to deploy to production with these new commands (as inspired by the documentation above) is as follows:

  1. Set the SFDX_MDAPI_TEMP_DIR environment variable to a place that's easily accessible (like the metadata folder within your current project):
  1. Retrieve the exact metadata you want to deploy to production, like as follows:
sfdx force:source:retrieve -m ApexClass:MyUtilClass,ApexClass:MyUtilClass_Test -u MySandboxOrg
  1. This will create a folder within your metadata folder with the metadata .zip file or package.xml file that you're looking for. Deploy from the zip file as follows (and feel free to add any other helpful options as specified in the mdapi Commands):
sfdx force:mdapi:deploy -f ./metadata/sdx_sourceRetrieve_1554058974901/ -u MyProductionOrg -w 3
  1. If the deployment takes longer than three minutes (as specified in the above -w 3 flag), then check your deployment status in the production org itself or via:
sfdx force:mdapi:deploy:report -u MyProductionOrg

This allows you to use the new force:source:retrieve command and have it auto-convert into metadata, without having to call force:source:convert manually