If you’re using a service like CircleCI to deploy code to various Salesforce orgs as part of a Continuous Integration scheme, you might find the need to build your front end code as part of your CI process. Traditionally, we have built our static resources using node.js based dependency management tools like npm for our dev packages and gulp (or grunt) for front end dependencies. Our build process knows how to looks at the configuration files for these package managers to make sure we always have the proper versions and dependencies for each package we want to include.

 

Sometimes this can lead to build errors if a developer forgets to rebuild their static resource from source and it can cause what appear to be major regression bugs as a result. Features that worked earlier today seem to disappear and general havoc ensues as the team scrambles to diagnose and fix the problem. It can be hard to prevent this if devs are building their static resources on their machine, and then checking in a zip file containing the results. Code review won’t catch anything missing from that zip, since it just looks like a big binary blob when checked into your VCS.

 

A better method than checking in an opaque zip file is to let your continuous integration tool fetch your dependencies and build your static resource from the latest source code before zipping it up for you. This means that the deployed static resource is always built from the latest source code, and results in fewer errors and broken builds. In order to make this lofty goal attainable, you’ll want to add some special commands the YAML file that your CI system will read to build and deploy your app.

The image above shows the general structure of our project in our IDE. Notice that the source code of our single page apps is contained outside of the src directory that contains all of our Salesforce Metadata. In our example, we need to tell our CI system exactly how to build and package our static resource. This is the same process that the developer has to use to modify the resource, we are simple telling CircleCI how to do it on their server. circle.yml

machine:
  node:
    version: 4.1.0
  java:
    version: oraclejdk8
dependencies:
  override:
    - npm install
    - bower install
    - npm install -g gulp
    - gulp build
test:
  override:
    - ant -lib lib/ -buildfile build/build.xml Build: 
        pwd: ../../
        timeout: 600
general:
  build_dir: spa/example-spa

Besides specifying the versions of node and java we want to use to build and deploy our app, the file above sets our initial build directory to be spa/example-spa. That means that in the dependencies section, we are in that directory when we run our npm, bower and gulp commands. Running “gulp build” will do whatever your gulp files tell it to do. That might include concatenating and minifying your source files and other build tasks, and in our case it happens to zip up our app and place it in the src/staticresources/ directory. Next in the test override section, we use ant to deploy our metadata that was just built. It will run all of our Apex unit tests before deploying all of our the contents of our /src directory to our target Salesforce org. But to do that, we need to move back up to the root of our project, which is why we specify “../..” to be our present working directory when we run our ant command. Our biggest fear was that building the static resource this way would drastically increase our build time. But I am happy to say that CircleCI is smart enough to cache your npm and bower dependencies. So as long as your dependency versions are the same, it does not have to re-dowload them all every time. This again mirrors how the project behaves when being built over and over again in your local developer environment.