salesforce-buildpack2

by rscot138

GitHub Readme.md

Heroku Buildpack for Salesforce

This is the official Heroku buildpack for Salesforce apps. This buildpack enables various Salesforce specific development operations such as creating scratch orgs and pushing source, creating and installing Unlocked Packages, running Apex unit tests, and deploying metadata. It uses https://github.com/heroku/salesforce-cli-buildpack to download and setup the Salesforce CLI and jq.

Below you'll find information on the requirements in your Salesforce project repository and the config vars required to operate the buildpack. To painlessly setup your Heroku Pipeline, use the setup scripts.

To see an example Salesforce project that's configured to use Heroku Pipelines and CI, see salesforce-dx-pipeline-sample.

Requirements

This buildpack requires the following to be present in the Salesforce app repository you're connecting to the pipeline.

  1. app.json: The app.json is a Heroku-specific file that provides instructions to this buildpack. In particular, the app.json provides information used by review apps that are created when a pull request is initiated.

    • buildpacks: Specifies the buildpacks used by the review apps.

      "buildpacks": [
        {
          "url": "https://github.com/heroku/salesforce-cli-buildpack#v3"
        },
        {
          "url": "https://github.com/douglascayers/salesforce-buildpack2#v1"
        },
        {
          "url": "heroku/nodejs"
        }
      ],
      
    • env: Specifies config vars and the values in the review app.

      "env": {
        "SFDX_DEV_HUB_AUTH_URL": {
          "required": true
        },
        "SFDX_BUILDPACK_DEBUG": {
          "required": true
        },
        "HEROKU_APP_NAME" : {
          "required": true
        },
        "OAUTH_SALESFORCE_CLIENT_ID" : {
          "required": true
        },
        "OAUTH_SALESFORCE_CLIENT_SECRET" : {
          "required": true
        },
        "OAUTH_SALESFORCE_LOGIN_URL" : {
          "required": true
        },
        "OAUTH_SALESFORCE_REDIRECT_URI" : {
          "required": true
        }
      },
      
    • environments/tests/scripts: Specifies the scripts used to invoke CI tests. These test scripts are created automatically if they are not found locally.

      "environments": {
        "test": {
          "scripts": {
            "test-setup":
              "./vendor/sfdx/release.sh ci-$HEROKU_TEST_RUN_COMMIT_VERSION && ./bin/test-setup.sh",
            "test": "./bin/test.sh"
          }
        }
      },
      
    • scripts/pre-predestroy: Specifies the script to run when a review app is destroyed. This script is automatically generated by the buildpack, so you don't have to specify anything.

      "scripts": {
        "pr-predestroy": "./bin/ra-org-delete.sh"
      },
      
  2. sfdx.yml: This yaml file also provides information to the buildpack but specifically related to the Salesforce DX project. Here you can specify information related to how your app is configured and setup.

    scratch-org-def: config/project-scratch-def.json
    assign-permset: false
    permset-name:
    run-apex-tests: true
    apex-test-format: tap
    show-scratch-org-url: false
    open-path:
    import-data: false
    data-plans:
    
  3. sfdx-project.json: If you are using Unlocked Packages, which is the default behavior, you'll need to ensure the required packaging data is in your sfdx-project.json file.

    "packageDirectories": [
    {
      "path": "force-app",
      "default": true,
      "id": "0Ho6A0000000000",
      "versionNumber": "1.0.0.NEXT",
      "versionName": "Summer '18"
    }
    

Config Vars

The buildpack uses config vars associated with each Heroku App to control the execution of the buildpack. These config vars are used across all stages. Below are the suggested defaults for Heroku apps in the respective stages.

Review

Review apps are created and destroyed automatically as scratch orgs, therefore you do not set up their config vars directly. Instead, their config vars are inherited from the development stage's config vars (listed below). Only the config vars whose names are listed in the env property of app.json are copied to the review apps.

Development

  • STAGE=DEV: Instructs the buildpack that this app stage is DEV.

  • SFDX_CREATE_PACKAGE_VERSION=true: Instructs the buildpack to create a new package version from the source.

  • SFDX_INSTALL_PACKAGE_VERSION=true: Instructs the buildpack that it will perform a package install. Setting this value to false (or excluding it) will cause the buildpack to perform a force:source:convert followed by a force:mdapi:deploy.

  • SFDX_PACKAGE_NAME="$PACKAGE_NAME": Tells the buildpack the name of the package to create and install.

  • SFDX_BUILDPACK_DEBUG=true: Instructs the buildpack to display debug information in the Heroku logs.

  • SFDX_DEV_HUB_AUTH_URL: Provides credentials to the buildpack for connecting to the Dev Hub. You can get this value by running sfdx force:org:display --verbose --json against your Dev Hub and grabbing the sfdxAuthUrl.

  • SFDX_AUTH_URL: Provides credentials to the buildpack for connecting to the org used by Development (typically a dev integration environment). You can get this value by running sfdx force:org:display --verbose --json against your org and grabbing the sfdxAuthUrl.

  • OAUTH_SALESFORCE_CLIENT_ID: A Connected App consumer key. See the "One-Click Login" section in this document.

  • OAUTH_SALESFORCE_CLIENT_SECRET: A Connected App consumer secret. See the "One-Click Login" section in this document.

  • OAUTH_SALESFORCE_LOGIN_URL: The login URL to the org with the Connected App. See the "One-Click Login" section in this document.

  • OAUTH_SALESFORCE_REDIRECT_URI: The Heroku app URL to redirect back to, which has this buildpack deployed. See the "One-Click Login" section in this document.

Staging

These values are the same as development stage but with the following considerations.

  • STAGE=STAGING: Instructs the buildpack that this app stage is STAGING.

  • SFDX_CREATE_PACKAGE_VERSION=false: Typically you don't want to create a new package version at each stage. So this value should be false.

  • SFDX_AUTH_URL: This should map to your staging environment, typically a full sandbox.

Production

These values are the same as staging stage but with the following considerations.

  • STAGE=PROD: Instructs the buildpack that this app stage is PROD.

  • SFDX_AUTH_URL: This should map to your production environment.

One-Click Login to Salesforce Orgs via Heroku App URLs

Reminder, Salesforce metadata deployed to Heroku does not result in a runnable app on the Heroku platform (yet?). So by default, clicking the "Open App" button on a Heroku app, or navigating to its URL (e.g. https://yourappname.herokuapp.com) would result in an application error page. To get into the underlying Salesforce org, you would still need to know its credentials.

For your convenience, the Salesforce buildpack supports one-click access to the Salesforce environments of your pipeline when you click the "Open App" button in Heroku or navigate to the Heroku app's URL by bundling a simple Node.js web app. This is very useful with review apps because those are scratch orgs that get created automatically by the buildpack and no one would have their credentials. The web app accomplishes this by redirecting the user to the URL retrieved from the force:org:open --urlonly command.

Since a Heroku app's URL can be public, then as a security measure the Salesforce buildpack's web app uses OAuth (with a Connected App you provide) to determine if the requestor is authorized for the buildpack to auto log them in to the Salesforce org that the Heroku app represents. This way, a Malicious User can't simply know your production Heroku app URL and simply get logged in to your production Salesforce environment.

Sequence

  1. User clicks "Open app" button of a Heroku app where the Salesforce buildpack is deployed

  2. The Node.js web app bundled with the Salesforce buildpack redirects user to OAuth authorization page of your Connected App

  3. Your Salesforce Connected App redirects the authorized user back to one of the Heroku apps in your pipeline (does not matter which one, only that it also has the Salesforce buildpack deployed)

  4. The Node.js web app uses force:org:open --urlonly CLI command to redirect user into the org that the Heroku app in step 1 represents, regardless of which Heroku app is used in step 3

Setup

  1. Create a Connected App

    • Select Enable OAuth Settings
    • Enter the Callback URL to one of your Heroku apps in the format https://yourAppName.herokuapp.com/oauth2/callback
    • Select the OAuth scope Access your basic information
    • Click Save
    • Click Manage then click Edit Policies
    • For Permitted Users field, select Admin approved users are pre-authorized then click Save
    • Scroll down to the Profiles and Permission Sets related lists and assign as appropriate to designate which users will be authorized
  2. Set the OAuth Config Vars in Heroku

    • Update the OAUTH_SALESFORCE_CLIENT_ID, OAUTH_SALESFORCE_CLIENT_SECRET, OAUTH_SALESFORCE_LOGIN_URL, and OAUTH_SALESFORCE_REDIRECT_URI config vars for each Heroku app in the development, staging, and production stages.

    Note: You could use the same Connected App oauth settings for each Heroku app, or you can use different ones to authorize different sets of users to be able to use the "Open app" button for one-click login to the different Salesforce environments. For example, one Connected App for development and staging but perhaps a different one for production, with perhaps fewer authorized users.