I am a big fan of Prettier and we have been using it for almost 6 months now in all our SFDX projects. A local install of Prettier is great, but the real magic happens when you integrate it into a CI job. This post shows how to integrate Prettier into CircleCI (but the instructions should work for any CI vendor).

Integrate Prettier In Your CI Manually

Adding Prettier to your pipeline is pretty straightforward (pun intended). Essentially, here is what you should consider:

  • You need Node.js and Java (the apex-prettier-plugin relies on Java for the Apex Language Server)
  • Call Prettier from an npm script (do not call the CLI directly) and always execute with the local configuration
  • Do not use your CI job to format files (use pre-commit hooks instead), only check for faulty formatting

Following these guidelines, it should be very easy to integrate Prettier into TravisCI, Github Actions, Gitlab Pipelines, or other CI vendors that support docker containers as job runners.

Add Prettier To Your SFDX Project

Adding Prettier for continuous integration is nothing different than adding it for local use. If you followed my instructions in this post, you only need to add one more script to your package.json: prettier:check:ci.

{
  "name": "your-package-name",
  "description": "Your package description",
  "scripts": {
    "prettier:check:ci": "./node_modules/.bin/prettier --check .",
    "prettier:format": "./node_modules/.bin/prettier --write .",
    ...
   },
   ...
}

It is important to rely on a single entry point for all scripts in your SFDX project. It doesn’t matter if you run UI tests with sfdx-lwc-jest, API E2E tests with newman, or format your code with Prettier. Always invoke those tools consistently with the same parameters and configuration from an npm script.

This way, your CI output is consistent with the results of a local execution. As a side effect, developers do not have to memorize the exact parameters that the CI job will use to reproduce the results locally. This will make the whole experience more consistent and reproducible. In the end, this will also improve adoption and acceptance among your team.

Run Prettier From Your CI

As mentioned, Prettier depends on Node.js and Java to be able to check your files. CircleCI makes all this incredibly easy with the cimg/openjdk convenience image. This image has Node.js, npm and Java installed and can be used right off the bat. All you need to do is add it to your jobs stanza (or your executor):

docker:
  - image: cimg/openjdk:17.0-node

steps:
  - run:
      name: Install NPM dependencies
      command: |
        npm ci
  - run:
      name: "Run Prettier with project configuration"
      command: |
        npm run prettier:check:ci

And that’s it. Prettier now wards your project, checking for those lazy colleagues of yours that never bother to oblige to your formatting guidelines.

This is what a failed job/step looks like when Prettier finds a culprit.

Prettier

On a side note: I strongly advise you to only check for the formatting of your files! Do not format them once they have reached your pipeline. Formatting should be done before the commit with husky or directly in the vscode.formatOnSave setting.

Use the jsc/salesforce Orb To Run Prettier Automatically

Instead of adding Prettier manually, you can also use the jsc/salesforce orb. The scratch_org_test job supports a convenience flag to run prettier. When configuring the job In your workflow, simply use the runPrettier parameter. The job runs Prettier before scratch org validation, so your team gets the earliest possible feedback if files do not comply.

workflows:
  package_build:
    jobs:
      - jsc-sfdx/scratch_org_test:
          devhubUsername: << pipeline.parameters.devhubUsername >>
          devhubInstanceUrl: << pipeline.parameters.devhubInstanceUrl >>
          jwtKey: SFDX_JWT_KEY
          consumerKey: SFDX_CONSUMER_KEY
          setupScript: scripts/shell/setup.sh
          runPrettier: true
          runLwcTests: false

Summary

Prettier is an insanely useful tool when it comes to settling the code formatting debate. Running it in your CI is your last defense against anyone who does not know about your project’s formatting guidelines. Adding it was much easier than I expected.