Skip to content

SFDX plugin to provide functionalities in order to improve and enhance your Development and CICD processes.

License

Notifications You must be signed in to change notification settings

Nakama-Partnering-Services/nakama-plugin-sfdx

Repository files navigation


Nakama Plugin SFDX

SFDX plugin to provide functionalities in order to improve and enhance your Development and CICD processes.

Table of Contents

TL;DR

sfdx plugins:install nakama-plugin-sfdx
sfdx force:source:deploy --wait 60 --checkonly --manifest manifest/package.xml --testlevel RunLocalTests --junit --coverageformatters cobertura --resultsdir test-results --json > test-results/results.json
sfdx nps:coverage:verify --path test-results/results.json --required-coverage 90 --classes AccountTriggerHandler,ContactTriggerHandler
sfdx nps:package:destructive:versionobsoleteflows --path deltas/destructiveChanges/destructiveChanges.xml

Getting Started

Prerequisites

Node v14.6.0 or above is required. To check if Salesforce CLI runs under a supported node version for NPS, run sfdx --version. You should see a node version above v.14.6.0. You should see a node version above v.14.6.0 to use NPS.

If you encounter this issue whereas the node version is OK on the running environment, try to install the Salesforce CLI via npm (npm install sfdx-cli --global).

Installation

Nakama plugin SFDX is a Salesforce CLI plugin. Run the following command to install it:

sfdx plugins:install nakama-plugin-sfdx

Because this plugin is not signed, you will get a warning saying that "This plugin is not digitally signed and its authenticity cannot be verified". This is expected, and you will have to answer y (yes) to proceed with the installation.

If you run your CI/CD jobs inside a Docker image, you can add the plugin to your image.

How to use it?

sfdx nps:coverage:formatters:mappaths -p <filepath> -t cobertura [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]

Map the paths in a given file to replace them with the actual project relative location for classes and triggers.

USAGE
  $ sfdx nps:coverage:formatters:mappaths -p <filepath> -t cobertura [--json] [--loglevel
    trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]

FLAGS
  -p, --path=<value>                                                                (required) project relative path to
                                                                                    the file containing the test
                                                                                    execution results
  -t, --type=(cobertura)                                                            (required) format type of the file
  --json                                                                            format output as json
  --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL)  [default: warn] logging level for
                                                                                    this command invocation

DESCRIPTION
  Map the paths in a given file to replace them with the actual project relative location for classes and triggers.

  Known Limitations: - Currently it only supports verification of coverage for apex classes, but not apex triggers nor
  flows.

EXAMPLES
  $ sfdx nps:coverage:formatters:mappaths --path test-results/coverage/cobertura.xml --type cobertura

See code: src/commands/nps/coverage/formatters/mappaths.ts

sfdx nps:coverage:verify -p <filepath> -c <array> [-r <integer>] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]

Verifies that specified apex classes have a coverage above a certain treshold

USAGE
  $ sfdx nps:coverage:verify -p <filepath> -c <array> [-r <integer>] [--json] [--loglevel
    trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]

FLAGS
  -c, --classes=<value>                                                             (required) comma separated list of
                                                                                    apex classes to verify
  -p, --path=<value>                                                                (required) project relative path to
                                                                                    the json file containing the test
                                                                                    execution results
  -r, --required-coverage=<value>                                                   [default: 75] number of the
                                                                                    percentage of coverage treshold to
                                                                                    reach
  --json                                                                            format output as json
  --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL)  [default: warn] logging level for
                                                                                    this command invocation

DESCRIPTION
  Verifies that specified apex classes have a coverage above a certain treshold

EXAMPLES
  $ sfdx nps:coverage:verify --path test-results/results.json --required-coverage 90 --classes AccountTriggerHandler,ContactTriggerHandler

See code: src/commands/nps/coverage/verify.ts

sfdx nps:package:destructive:versionobsoleteflows -p <filepath> [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]

Replace the Flow members in a XML file by all the Obsolete flow versions in the default target org

USAGE
  $ sfdx nps:package:destructive:versionobsoleteflows -p <filepath> [--json] [--loglevel
    trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]

FLAGS
  -p, --path=<value>                                                                (required) project relative path to
                                                                                    the destructiveChange.xml
  --json                                                                            format output as json
  --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL)  [default: warn] logging level for
                                                                                    this command invocation

DESCRIPTION
  Replace the Flow members in a XML file by all the Obsolete flow versions in the default target org

EXAMPLES
  $ sfdx nps:package:destructive:versionobsoleteflows --path deltas/destructiveChanges/destructiveChanges.xml

See code: src/commands/nps/package/destructive/versionobsoleteflows.ts

Walkthrough

Let’s take a look at the following scenario:

Verify that each one of the non-test apex classes added or modified in a PR have a specific required coverage.

In our example, we have the following files:

  • Flow deleted: AccountFlow
  • Custom Field added: Account.NumberOfContacts__c
  • Apex Class added: ContactTriggerHandler
  • Apex Class added: ContactTriggerHandlerTest
  • Apex Class modified: AccountTriggerHandler
  • Apex Class modified: AccountTriggerHandlerTest

In this situation, we would expect the CLI plugin to:

  1. Handle the flow entries in destructiveChanges.xml for deletion: AccountFlow-1
  2. Detect the relevant apex classes in the PR to verify: ContactTriggerHandler, AccountTriggerHandler
  3. Report an error for those classes without enough test coverage: AccountTriggerHandler
  4. Optional: if using Gitlab CI, highglight coverage in MR diff changes for: ContactTriggerHandler, AccountTriggerHandler

So let’s do it!

Get a folder with all the files

From the project repo folder, the CI pipeline will run the following command:

sfdx sgd:source:delta --source sfdx-source --from origin/$GITHUB_BASE_REF --to HEAD --output deltas --ignore .forceignore --generate-delta

See sfdx-git-delta

which means:

Analyze the differences between the PR targer branch and the source branch and create a folder ´deltas´ with all the modified and added files there.

Replace Flow member entries in destructiveChanges.xml by their obsolete versions

Since flows can not be deleted with SFDX, what we actually want to delete is flow version:

sfdx nps:package:destructive:versionobsoleteflows --path deltas/destructiveChanges/destructiveChanges.xml

⚠️ This is still subjected to the restriction where a version needs to be Inactive for deletion

Deploy the delta metadata and get --json output

The simplest option to deploy the incremental changes is to use force:source:deploy command with -x parameter:

sfdx force:source:deploy --wait 60 --checkonly --manifest deltas/package/package.xml --postdestructivechanges deltas/destructiveChanges/destructiveChanges.xml --verbose --testlevel RunLocalTests --coverageformatters cobertura --resultsdir test-results --json > test-results/results.json

Optional, if using Gitlab CI: remap coverage formatter file with actual project locations paths for apex files

Due to the apex files actually belonging to an org, the coverage formatters uses apex files paths with a no-map/ default path. We can remap them properly to the real paths for the actual files location in our project with:

sfdx nps:coverage:formatters:mappaths -p test-results/cobertura.xml -t cobertura

⚠️ Currently there is a limitation where an issue will likely happen if there are .cls and .trigger files with the same name

(Bonus) Make sure that you specify the following in your deployment job:

artifacts:
    when: always
    reports:
        coverage_report:
            coverage_format: cobertura
            path: test-results/coverage/cobertura.xml

Recommended: Print deployment result

Since deployment command output is captured into a file and does not appear in the job logs, it is recommented to print it with:

cat test-results/results.json

Detect only relevant apex classes

Now, we need to generate a comma separated list of the apex classes which coverage we want to check.

NON_TEST_CLASSES=$((egrep -wrliL @IsTest deltas --include \*.cls || echo "") | xargs -rL 1 basename | sed 's/.cls//g' | paste -sd "," -)

Verify that all apex classes have an specific required coverage

Imagine that you want all of our apex classes to have at least a 90% of test coverage. After running the previous commands, the remaining thing to do is:

sfdx nps:coverage:verify -p test-results/results.json -r 90 -c $NON_TEST_CLASSES

And voilà! 🥳

We should get and output like:

List of analyzed apex classes with coverage:
ContactTriggerHandler: 92%
AccountTriggerHandler: 68%
ERROR running nps:coverage:verify:  Included apex classes should met at least the required coverage of 90%. Classes without enough coverage: AccountTriggerHandler

Besides, if using Gitlab CI and followe the optional steps, in our MR diff changes we should be able to spot the Test Coverage Visualization.

Versioning

Versioning follows SemVer specification.

Authors

  • Gabriel Serrano - Developer - jdkgabri

Contributing

Contributions are what make the trailblazer community such an amazing place. I regard this component as a way to inspire and learn from others. Any contributions you make are appreciated.

License

This project license is MIT - see the LICENSE.md file for details

About

SFDX plugin to provide functionalities in order to improve and enhance your Development and CICD processes.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •