apex-code-coverage-transformer 4.3.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,17 @@
5
5
 
6
6
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
7
7
 
8
+ ## [5.0.0](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v4.3.0...v5.0.0) (2026-11-14)
9
+
10
+
11
+ ### ⚠ BREAKING CHANGES
12
+
13
+ * handle sfdx-hardis coverage through plugin events ([#443](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/443))
14
+
15
+ ### Features
16
+
17
+ * handle sfdx-hardis coverage through plugin events ([#443](https://github.com/mcarvin8/apex-code-coverage-transformer/issues/443)) ([807f1f1](https://github.com/mcarvin8/apex-code-coverage-transformer/commit/807f1f1edcdce8e53b2522826ae7469c739e2575))
18
+
8
19
  ## [4.3.0](https://github.com/mcarvin8/apex-code-coverage-transformer/compare/v4.2.0...v4.3.0) (2026-11-09)
9
20
 
10
21
 
package/README.md CHANGED
@@ -12,6 +12,9 @@ Transforms (and optionally merges) Apex code coverage JSON from Salesforce deplo
12
12
  > [!WARNING]
13
13
  > **v4 breaking change:** v3 and earlier automatically re-numbered deploy command coverage lines that Salesforce reported beyond the end of a file. Salesforce fixed this bug server-side in Winter '27 (API v68.0), regardless of the `--api-version` used on the deploy, so v4 removes the re-numbering and passes deploy coverage lines through exactly as reported. Test-command coverage is unaffected. See [Troubleshooting](#troubleshooting) for details.
14
14
 
15
+ > [!WARNING]
16
+ > **v5 breaking change:** Only affects users using this plugin's automated hooks with sfdx-hardis. The `finally` hook no longer runs after `sf hardis project deploy smart` or `sf hardis org test apex`, or after the `sf` commands sfdx-hardis runs under the hood, so coverage is no longer transformed twice. sfdx-hardis coverage now goes through [sfdx-hardis events](#sfdx-hardis-events), which require sfdx-hardis 8.24.1 or later with plugin events enabled. With an older sfdx-hardis, upgrade it or run `sf acc-transformer transform` after the sfdx-hardis command. The `deployCoverageJsonPath` and `testCoverageJsonPath` config keys are no longer needed for sfdx-hardis.
17
+
15
18
  <details>
16
19
  <summary>Table of Contents</summary>
17
20
 
@@ -34,7 +37,7 @@ Transforms (and optionally merges) Apex code coverage JSON from Salesforce deplo
34
37
  ## Prerequisites
35
38
 
36
39
  - [Salesforce CLI](https://developer.salesforce.com/tools/sfdxcli) (`sf`) installed
37
- - Node.js 22.19 or later
40
+ - Node.js 22.22.2 or later (`apex-code-coverage-transformer-core` alone needs 22.19 or later)
38
41
  - A Salesforce DX project with `sfdx-project.json` and package directories
39
42
  - Use only the **json** coverage formatter from the Salesforce CLI; other formatters are not supported
40
43
 
@@ -122,9 +125,9 @@ sf apex get test --test-run-id <id> --code-coverage --output-dir "coverage"
122
125
 
123
126
  **SFDX Hardis** — coverage path: `hardis-report/apex-coverage-results.json`
124
127
 
125
- Works with [sfdx-hardis](https://github.com/hardisgroupcom/sfdx-hardis):
128
+ Works with [sfdx-hardis](https://github.com/hardisgroupcom/sfdx-hardis) 8.24.1 or later: the plugin picks up the coverage automatically through [sfdx-hardis events](#sfdx-hardis-events) and posts a coverage summary on the Pull Request.
126
129
 
127
- - `sf hardis project deploy smart` (requires `COVERAGE_FORMATTER_JSON=true`)
130
+ - `sf hardis project deploy smart|start|validate|quick`
128
131
  - `sf hardis org test apex`
129
132
 
130
133
  ## Command Reference
@@ -196,7 +199,7 @@ EXAMPLES
196
199
  `sf acc-transformer transform -j "coverage1.json" -j "coverage2.json" -r "coverage.xml" -f "sonar"`
197
200
  ```
198
201
 
199
- _See code: [src/commands/acc-transformer/transform.ts](https://github.com/mcarvin8/apex-code-coverage-transformer/blob/v4.3.0/src/commands/acc-transformer/transform.ts)_
202
+ _See code: [src/commands/acc-transformer/transform.ts](https://github.com/mcarvin8/apex-code-coverage-transformer/blob/v5.0.0/src/commands/acc-transformer/transform.ts)_
200
203
  <!-- commandsstop -->
201
204
 
202
205
  ## Coverage Report Formats
@@ -527,8 +530,7 @@ Create `.apexcodecovtransformer.config.json` in the project root to transform co
527
530
  - `sf project deploy [start|validate|report|resume]`
528
531
  - `sf apex run test`
529
532
  - `sf apex get test`
530
- - `sf hardis project deploy smart` (if sfdx-hardis installed and `COVERAGE_FORMATTER_JSON=true`)
531
- - `sf hardis org test apex` (if sfdx-hardis installed)
533
+ - `sf hardis project deploy [smart|start|validate|quick]` and `sf hardis org test apex` (see [sfdx-hardis events](#sfdx-hardis-events))
532
534
 
533
535
  > **Note:** The hook fires once per command and always processes a single coverage JSON. It cannot merge multiple inputs. If you need to merge coverage from multiple runs (e.g. split test batches), run the `sf acc-transformer transform` command manually with multiple `-j` flags after all runs complete.
534
536
 
@@ -544,6 +546,31 @@ Sample configs: [Salesforce CLI](https://raw.githubusercontent.com/mcarvin8/apex
544
546
  | `minCoverage` | No | Minimum required line coverage percentage (0–100). Exits with an error if overall coverage is below this threshold. |
545
547
  | `maxAnnotations` | No | Maximum `::warning` annotations emitted when `format` includes `github-actions` (default: `50`). |
546
548
  | `excludePatterns` | No | Comma-separated glob patterns for file paths to exclude (e.g. `**/*Test*,**/mock/**`). Matched against the relative path from the repo root. |
549
+ | `pullRequestComment` | No | sfdx-hardis events only: post the coverage summary as a Pull Request comment (default: `true`). |
550
+
551
+ ### sfdx-hardis events
552
+
553
+ sfdx-hardis 8.24.1 and later send an event as soon as Salesforce returns the result of a validation, a deployment or an Apex test run. The plugin listens to these events, so with sfdx-hardis you don't need `deployCoverageJsonPath` or `testCoverageJsonPath`: the event gives the path of `hardis-report/apex-coverage-results.json`.
554
+
555
+ The coverage of sfdx-hardis commands only goes through these events. The `sf project deploy` and `sf apex run test` commands that sfdx-hardis starts under the hood are skipped by the hook, so the coverage is transformed once per run.
556
+
557
+ | Event | Sent by |
558
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------- |
559
+ | `sfdx-hardis:validation-done` | `sf hardis project deploy smart` in check mode, `sf hardis project deploy validate`, `deploy start --dry-run` |
560
+ | `sfdx-hardis:deployment-done` | `sf hardis project deploy smart`, `sf hardis project deploy start`, `sf hardis project deploy quick` |
561
+ | `sfdx-hardis:apex-tests-done` | `sf hardis org test apex` |
562
+
563
+ On each event, when `.apexcodecovtransformer.config.json` exists, the plugin:
564
+
565
+ 1. Writes the reports set by `format` and `outputReportPath`.
566
+ 2. Posts a markdown coverage summary (files sorted with the lowest coverage first) as a Pull Request comment, through the git provider sfdx-hardis is set up with (GitHub, GitLab, Azure DevOps, Bitbucket). There is one comment for validations, one for deployments and one for Apex test runs, and each later run updates its comment. The sfdx-hardis comments are left as they are. Set `pullRequestComment` to `false` to only write the reports.
567
+
568
+ Notes:
569
+
570
+ - The summary only counts Apex in the project's package directories, so it can differ from the org-wide coverage sfdx-hardis checks.
571
+ - `minCoverage` marks the comment as failing but does not fail the sfdx-hardis command. Use the sfdx-hardis coverage threshold (`apexTestsMinCoverageOrgWide`) to fail the job.
572
+ - A `deploy smart` run with several packages sends one event per package; each one overwrites the reports and the comment, so the last package wins.
573
+ - Turning the sfdx-hardis events off (`disablePluginEvents: true` in `.sfdx-hardis.yml` or `SFDX_HARDIS_DISABLE_PLUGIN_EVENTS=true`) also turns off this plugin in sfdx-hardis commands.
547
574
 
548
575
  ## Programmatic Usage
549
576
 
@@ -1,70 +1,51 @@
1
1
  'use strict';
2
2
  import { existsSync } from 'node:fs';
3
- import { readFile } from 'node:fs/promises';
4
3
  import { resolve } from 'node:path';
5
4
  import TransformerTransform from '../commands/acc-transformer/transform.js';
6
- import { getRepoRoot } from '../utils/getRepoRoot.js';
7
- function buildCommandArgs(coverageJsonPath, outputReportPath, configFile) {
8
- const args = ['--coverage-json', coverageJsonPath, '--output-report', outputReportPath];
9
- const coverageFormat = configFile.format || 'sonar';
10
- if (coverageFormat.trim() !== '') {
11
- for (const format of coverageFormat.split(',')) {
12
- args.push('--format', format.replace(/,/g, ''));
13
- }
14
- }
15
- const ignorePackageDirs = configFile.ignorePackageDirectories || '';
16
- if (ignorePackageDirs.trim() !== '') {
17
- for (const dir of ignorePackageDirs.split(',')) {
18
- args.push('--ignore-package-directory', dir.replace(/,/g, ''));
19
- }
20
- }
21
- if (configFile.minCoverage !== undefined) {
22
- args.push('--min-coverage', String(configFile.minCoverage));
23
- }
24
- if (configFile.maxAnnotations !== undefined) {
25
- args.push('--max-annotations', String(configFile.maxAnnotations));
26
- }
27
- const excludePatterns = configFile.excludePatterns ?? '';
28
- if (excludePatterns.trim() !== '') {
29
- for (const pattern of excludePatterns.split(',')) {
30
- args.push('--exclude-pattern', pattern.trim());
31
- }
32
- }
5
+ import { getHookTransformOptions, isRunningUnderSfdxHardis, loadHookConfig, } from '../utils/hookConfig.js';
6
+ const DEPLOY_COMMANDS = [
7
+ 'project:deploy:validate',
8
+ 'project:deploy:start',
9
+ 'project:deploy:report',
10
+ 'project:deploy:resume',
11
+ ];
12
+ const TEST_COMMANDS = ['apex:run:test', 'apex:get:test'];
13
+ function buildCommandArgs(coverageJsonPath, options) {
14
+ const args = ['--coverage-json', coverageJsonPath, '--output-report', resolve(options.outputReport)];
15
+ for (const format of options.formats)
16
+ args.push('--format', format);
17
+ for (const dir of options.ignorePackageDirectories)
18
+ args.push('--ignore-package-directory', dir);
19
+ if (options.minCoverage !== undefined)
20
+ args.push('--min-coverage', String(options.minCoverage));
21
+ if (options.maxAnnotations !== undefined)
22
+ args.push('--max-annotations', String(options.maxAnnotations));
23
+ for (const pattern of options.excludePatterns)
24
+ args.push('--exclude-pattern', pattern);
33
25
  return args;
34
26
  }
35
27
  export const hook = async function (options) {
36
28
  const commandId = options?.Command?.id ?? '';
37
29
  let commandType;
38
- if ([
39
- 'project:deploy:validate',
40
- 'project:deploy:start',
41
- 'project:deploy:report',
42
- 'project:deploy:resume',
43
- 'hardis:project:deploy:smart',
44
- ].includes(commandId)) {
30
+ if (DEPLOY_COMMANDS.includes(commandId)) {
45
31
  commandType = 'deploy';
46
32
  }
47
- else if (['apex:run:test', 'apex:get:test', 'hardis:org:test:apex'].includes(commandId)) {
33
+ else if (TEST_COMMANDS.includes(commandId)) {
48
34
  commandType = 'test';
49
35
  }
50
36
  else {
51
37
  return;
52
38
  }
53
- const { repoRoot } = await getRepoRoot();
54
- if (!repoRoot) {
39
+ // An sf command started by sfdx-hardis: the sfdxHardisRunDone hook handles its coverage.
40
+ if (isRunningUnderSfdxHardis()) {
55
41
  return;
56
42
  }
57
- let configFile;
58
- const configPath = resolve(repoRoot, '.apexcodecovtransformer.config.json');
59
- try {
60
- const jsonString = await readFile(configPath, 'utf-8');
61
- configFile = JSON.parse(jsonString);
62
- }
63
- catch {
43
+ const loaded = await loadHookConfig();
44
+ if (!loaded) {
64
45
  return;
65
46
  }
66
- const outputReport = configFile.outputReportPath || 'coverage.xml';
67
- const coverageJson = commandType === 'deploy' ? configFile.deployCoverageJsonPath || '.' : configFile.testCoverageJsonPath || '.';
47
+ const { config } = loaded;
48
+ const coverageJson = (commandType === 'deploy' ? config.deployCoverageJsonPath : config.testCoverageJsonPath) || '.';
68
49
  if (coverageJson.trim() === '.') {
69
50
  return;
70
51
  }
@@ -72,7 +53,6 @@ export const hook = async function (options) {
72
53
  if (!existsSync(coverageJsonPath)) {
73
54
  return;
74
55
  }
75
- const commandArgs = buildCommandArgs(coverageJsonPath, resolve(outputReport), configFile);
76
- await TransformerTransform.run(commandArgs);
56
+ await TransformerTransform.run(buildCommandArgs(coverageJsonPath, getHookTransformOptions(config)));
77
57
  };
78
58
  //# sourceMappingURL=finally.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"finally.js","sourceRoot":"","sources":["../../src/hooks/finally.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"finally.js","sourceRoot":"","sources":["../../src/hooks/finally.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,oBAAoB,MAAM,0CAA0C,CAAC;AAC5E,OAAO,EACL,uBAAuB,EAEvB,wBAAwB,EACxB,cAAc,GACf,MAAM,wBAAwB,CAAC;AAEhC,MAAM,eAAe,GAAG;IACtB,yBAAyB;IACzB,sBAAsB;IACtB,uBAAuB;IACvB,uBAAuB;CACxB,CAAC;AACF,MAAM,aAAa,GAAG,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;AAEzD,SAAS,gBAAgB,CAAC,gBAAwB,EAAE,OAA6B;IAC/E,MAAM,IAAI,GAAa,CAAC,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/G,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO;QAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACpE,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,wBAAwB;QAAE,IAAI,CAAC,IAAI,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;IACjG,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IAChG,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IACzG,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,eAAe;QAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACvF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,IAAI,GAAoB,KAAK,WAAW,OAAO;IAC1D,MAAM,SAAS,GAAG,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC;IAC7C,IAAI,WAA8B,CAAC;IACnC,IAAI,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACxC,WAAW,GAAG,QAAQ,CAAC;IACzB,CAAC;SAAM,IAAI,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7C,WAAW,GAAG,MAAM,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,OAAO;IACT,CAAC;IAED,yFAAyF;IACzF,IAAI,wBAAwB,EAAE,EAAE,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAE1B,MAAM,YAAY,GAAG,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,GAAG,CAAC;IACrH,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;QAChC,OAAO;IACT,CAAC;IAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,MAAM,oBAAoB,CAAC,GAAG,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtG,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Hook } from '@oclif/core';
2
+ export declare const hook: Hook<'prerun'>;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+ import { markSfdxHardisParent } from '../utils/hookConfig.js';
3
+ // Flag sfdx-hardis commands so the `sf` commands they start skip the `finally` hook.
4
+ export const hook = async function (options) {
5
+ markSfdxHardisParent(options?.Command?.id ?? '');
6
+ };
7
+ //# sourceMappingURL=prerun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../src/hooks/prerun.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAIb,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,qFAAqF;AACrF,MAAM,CAAC,MAAM,IAAI,GAAmB,KAAK,WAAW,OAAO;IACzD,oBAAoB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AACnD,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type SfdxHardisEventHookOptions, type SfdxHardisRunEvent } from 'sfdx-hardis/plugin-api';
2
+ declare const hook: (options: SfdxHardisEventHookOptions<SfdxHardisRunEvent>) => Promise<void>;
3
+ export default hook;
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+ // Listens to the events sfdx-hardis sends as soon as Salesforce returns the result of a validation,
3
+ // a deployment or an Apex test run (declared under oclif.hooks in package.json). oclif only loads
4
+ // this file when sfdx-hardis fires one of them.
5
+ import { postPullRequestComment, uxLog, } from 'sfdx-hardis/plugin-api';
6
+ import { handleSfdxHardisRunEvent, PLUGIN_NAME } from '../utils/sfdxHardisRunEvent.js';
7
+ const hook = async function (options) {
8
+ // A failing hook is only a warning for sfdx-hardis, but it must never break the run.
9
+ try {
10
+ const outcome = await handleSfdxHardisRunEvent(options, {
11
+ postPullRequestComment,
12
+ log: (message) => uxLog('log', null, `[${PLUGIN_NAME}] ${message}`),
13
+ warn: (message) => uxLog('warning', null, `[${PLUGIN_NAME}] ${message}`),
14
+ });
15
+ if (!outcome.handled) {
16
+ uxLog('log', null, `[${PLUGIN_NAME}] Skipped ${options.event}: ${outcome.reason}`);
17
+ }
18
+ else if (!outcome.comment.posted) {
19
+ uxLog('log', null, `[${PLUGIN_NAME}] No Pull Request comment posted (${outcome.comment.reason ?? 'unknown'})`);
20
+ }
21
+ }
22
+ catch (error) {
23
+ uxLog('warning', null, `[${PLUGIN_NAME}] ${error.message}`);
24
+ }
25
+ };
26
+ export default hook;
27
+ //# sourceMappingURL=sfdxHardisRunDone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sfdxHardisRunDone.js","sourceRoot":"","sources":["../../src/hooks/sfdxHardisRunDone.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,oGAAoG;AACpG,kGAAkG;AAClG,gDAAgD;AAChD,OAAO,EACL,sBAAsB,EAGtB,KAAK,GACN,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAEvF,MAAM,IAAI,GAAG,KAAK,WAAW,OAAuD;IAClF,qFAAqF;IACrF,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,OAAO,EAAE;YACtD,sBAAsB;YACtB,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;YACnE,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;SACzE,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,WAAW,aAAa,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACrF,CAAC;aAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,WAAW,qCAAqC,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,SAAS,GAAG,CAAC,CAAC;QACjH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,WAAW,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;AACH,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -1,5 +1,4 @@
1
1
  import { TransformCoverageOptions, TransformCoverageResult, TransformOptions } from '../utils/types.js';
2
- export { TransformOptions };
3
2
  /**
4
3
  * Transform Salesforce CLI Apex coverage JSON into one or more report formats.
5
4
  *
@@ -1 +1 @@
1
- {"version":3,"file":"coverageTransformer.js","sourceRoot":"","sources":["../../src/transformers/coverageTransformer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"coverageTransformer.js","sourceRoot":"","sources":["../../src/transformers/coverageTransformer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { CoverageFormat } from './types.js';
2
+ export declare const HOOK_CONFIG_FILE_NAME = ".apexcodecovtransformer.config.json";
3
+ /** Contents of `.apexcodecovtransformer.config.json`. */
4
+ export type HookFile = {
5
+ deployCoverageJsonPath?: string;
6
+ testCoverageJsonPath?: string;
7
+ outputReportPath?: string;
8
+ format?: string;
9
+ ignorePackageDirectories?: string;
10
+ minCoverage?: number;
11
+ maxAnnotations?: number;
12
+ excludePatterns?: string;
13
+ /** sfdx-hardis events only: post the coverage summary as a Pull Request comment. Defaults to true. */
14
+ pullRequestComment?: boolean;
15
+ };
16
+ /**
17
+ * Set by the prerun hook while an sfdx-hardis command runs. sfdx-hardis passes its environment to the
18
+ * `sf` commands it starts (`sf project deploy start`, `sf apex run test`...), so the `finally` hook of
19
+ * those child commands can leave the coverage to the sfdx-hardis events instead of running twice.
20
+ */
21
+ export declare const SFDX_HARDIS_PARENT_ENV = "APEX_CODE_COVERAGE_TRANSFORMER_IN_SFDX_HARDIS";
22
+ export declare function markSfdxHardisParent(commandId: string, env?: NodeJS.ProcessEnv): void;
23
+ export declare function isRunningUnderSfdxHardis(env?: NodeJS.ProcessEnv): boolean;
24
+ /** Options shared by every hook, parsed from the comma-separated values of the config file. */
25
+ export type HookTransformOptions = {
26
+ outputReport: string;
27
+ formats: CoverageFormat[];
28
+ ignorePackageDirectories: string[];
29
+ excludePatterns: string[];
30
+ minCoverage?: number;
31
+ maxAnnotations?: number;
32
+ };
33
+ /** Split a comma-separated config value into trimmed, non-empty entries. */
34
+ export declare function splitList(value: string | undefined): string[];
35
+ /**
36
+ * Load `.apexcodecovtransformer.config.json` from the root of the Salesforce DX project.
37
+ * Returns undefined when there is no project or no readable config: the hooks are opt-in.
38
+ */
39
+ export declare function loadHookConfig(cwd?: string): Promise<{
40
+ repoRoot: string;
41
+ config: HookFile;
42
+ } | undefined>;
43
+ export declare function getHookTransformOptions(config: HookFile): HookTransformOptions;
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { resolve } from 'node:path';
4
+ import { getRepoRoot } from './getRepoRoot.js';
5
+ export const HOOK_CONFIG_FILE_NAME = '.apexcodecovtransformer.config.json';
6
+ /**
7
+ * Set by the prerun hook while an sfdx-hardis command runs. sfdx-hardis passes its environment to the
8
+ * `sf` commands it starts (`sf project deploy start`, `sf apex run test`...), so the `finally` hook of
9
+ * those child commands can leave the coverage to the sfdx-hardis events instead of running twice.
10
+ */
11
+ export const SFDX_HARDIS_PARENT_ENV = 'APEX_CODE_COVERAGE_TRANSFORMER_IN_SFDX_HARDIS';
12
+ export function markSfdxHardisParent(commandId, env = process.env) {
13
+ if (commandId.startsWith('hardis:'))
14
+ env[SFDX_HARDIS_PARENT_ENV] = 'true';
15
+ }
16
+ export function isRunningUnderSfdxHardis(env = process.env) {
17
+ return env[SFDX_HARDIS_PARENT_ENV] === 'true';
18
+ }
19
+ /** Split a comma-separated config value into trimmed, non-empty entries. */
20
+ export function splitList(value) {
21
+ return (value ?? '')
22
+ .split(',')
23
+ .map((entry) => entry.trim())
24
+ .filter((entry) => entry !== '');
25
+ }
26
+ /**
27
+ * Load `.apexcodecovtransformer.config.json` from the root of the Salesforce DX project.
28
+ * Returns undefined when there is no project or no readable config: the hooks are opt-in.
29
+ */
30
+ export async function loadHookConfig(cwd) {
31
+ let repoRoot;
32
+ try {
33
+ // getRepoRoot throws when no sfdx-project.json is found, so repoRoot is always set here.
34
+ repoRoot = (await getRepoRoot(cwd)).repoRoot;
35
+ }
36
+ catch {
37
+ return undefined;
38
+ }
39
+ try {
40
+ const config = JSON.parse(await readFile(resolve(repoRoot, HOOK_CONFIG_FILE_NAME), 'utf-8'));
41
+ return { repoRoot, config };
42
+ }
43
+ catch {
44
+ return undefined;
45
+ }
46
+ }
47
+ export function getHookTransformOptions(config) {
48
+ const formats = splitList(config.format);
49
+ return {
50
+ outputReport: config.outputReportPath || 'coverage.xml',
51
+ formats: (formats.length > 0 ? formats : ['sonar']),
52
+ ignorePackageDirectories: splitList(config.ignorePackageDirectories),
53
+ excludePatterns: splitList(config.excludePatterns),
54
+ minCoverage: config.minCoverage,
55
+ maxAnnotations: config.maxAnnotations,
56
+ };
57
+ }
58
+ //# sourceMappingURL=hookConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hookConfig.js","sourceRoot":"","sources":["../../src/utils/hookConfig.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,MAAM,CAAC,MAAM,qBAAqB,GAAG,qCAAqC,CAAC;AAgB3E;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,+CAA+C,CAAC;AAEtF,MAAM,UAAU,oBAAoB,CAAC,SAAiB,EAAE,GAAG,GAAsB,OAAO,CAAC,GAAG;IAC1F,IAAI,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,GAAG,CAAC,sBAAsB,CAAC,GAAG,MAAM,CAAC;AAC5E,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IAC3E,OAAO,GAAG,CAAC,sBAAsB,CAAC,KAAK,MAAM,CAAC;AAChD,CAAC;AAYD,4EAA4E;AAC5E,MAAM,UAAU,SAAS,CAAC,KAAyB;IACjD,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;SACjB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;SAC5B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAY;IAC/C,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,yFAAyF;QACzF,QAAQ,GAAG,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,QAAkB,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,qBAAqB,CAAC,EAAE,OAAO,CAAC,CAAa,CAAC;QACzG,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAgB;IACtD,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO;QACL,YAAY,EAAE,MAAM,CAAC,gBAAgB,IAAI,cAAc;QACvD,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAqB;QACvE,wBAAwB,EAAE,SAAS,CAAC,MAAM,CAAC,wBAAwB,CAAC;QACpE,eAAe,EAAE,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC;QAClD,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { PluginPullRequestCommentRequest, PluginPullRequestCommentResult, SfdxHardisRunEvent } from 'sfdx-hardis/plugin-api';
2
+ import { TransformCoverageResult } from './types.js';
3
+ export declare const PLUGIN_NAME = "apex-code-coverage-transformer";
4
+ export declare const PULL_REQUEST_COMMENT_TITLE = "Apex code coverage";
5
+ /** GitHub rejects comments over 65536 characters; keep room for the sfdx-hardis wrapper. */
6
+ export declare const MAX_COMMENT_LENGTH = 60000;
7
+ /** One Pull Request comment per kind of run; the next run of the same kind updates it. */
8
+ export declare function getCommentKey(event: Pick<SfdxHardisRunEvent, 'event' | 'data'>): string;
9
+ /** Build the comment body from the markdown report, with the minimum coverage verdict on top. */
10
+ export declare function buildCommentMarkdown(markdownReport: string, result: TransformCoverageResult, minCoverage?: number): string;
11
+ /** Cut at the last full line under the limit, with a note pointing to the full reports. */
12
+ export declare function truncateMarkdown(markdown: string, maxLength: number): string;
13
+ export type SfdxHardisRunEventDeps = {
14
+ postPullRequestComment: (request: PluginPullRequestCommentRequest) => Promise<PluginPullRequestCommentResult>;
15
+ log: (message: string) => void;
16
+ warn: (message: string) => void;
17
+ /** Directory to search upward from for `sfdx-project.json`. Defaults to `process.cwd()`. */
18
+ cwd?: string;
19
+ };
20
+ export type SfdxHardisRunEventOutcome = {
21
+ handled: false;
22
+ reason: 'no-coverage-file' | 'no-config';
23
+ } | {
24
+ handled: true;
25
+ reportPaths: string[];
26
+ passed: boolean;
27
+ comment: PluginPullRequestCommentResult | {
28
+ posted: false;
29
+ reason: 'disabled';
30
+ };
31
+ };
32
+ /**
33
+ * Transform the coverage file sent by an sfdx-hardis run event into the reports set in
34
+ * `.apexcodecovtransformer.config.json`, then post the coverage summary as a Pull Request comment.
35
+ */
36
+ export declare function handleSfdxHardisRunEvent(event: Pick<SfdxHardisRunEvent, 'event' | 'data'>, deps: SfdxHardisRunEventDeps): Promise<SfdxHardisRunEventOutcome>;
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+ import { resolve } from 'node:path';
3
+ import { transformCoverage } from '../transformers/coverageTransformer.js';
4
+ import { getHookTransformOptions, loadHookConfig } from './hookConfig.js';
5
+ export const PLUGIN_NAME = 'apex-code-coverage-transformer';
6
+ export const PULL_REQUEST_COMMENT_TITLE = 'Apex code coverage';
7
+ /** GitHub rejects comments over 65536 characters; keep room for the sfdx-hardis wrapper. */
8
+ export const MAX_COMMENT_LENGTH = 60_000;
9
+ /** One Pull Request comment per kind of run; the next run of the same kind updates it. */
10
+ export function getCommentKey(event) {
11
+ if (event.event === 'sfdx-hardis:apex-tests-done')
12
+ return 'apex-tests';
13
+ return event.data.checkOnly ? 'validation' : 'deployment';
14
+ }
15
+ /** Build the comment body from the markdown report, with the minimum coverage verdict on top. */
16
+ export function buildCommentMarkdown(markdownReport, result, minCoverage) {
17
+ // sfdx-hardis renders the comment title, so drop the report's own H1.
18
+ const report = markdownReport.replace(/^# .*\n+/, '').trim();
19
+ const percent = (result.summary.lineRate * 100).toFixed(2);
20
+ const lines = [];
21
+ if (minCoverage !== undefined) {
22
+ lines.push(result.passed
23
+ ? `✅ Coverage of ${percent}% meets the minimum of ${minCoverage}%.`
24
+ : `❌ Coverage of ${percent}% is below the minimum of ${minCoverage}%.`, '');
25
+ }
26
+ lines.push(report, '');
27
+ lines.push("_Only Apex in this repository's package directories is counted, so this can differ from the org-wide coverage reported by sfdx-hardis._");
28
+ return truncateMarkdown(lines.join('\n'), MAX_COMMENT_LENGTH);
29
+ }
30
+ /** Cut at the last full line under the limit, with a note pointing to the full reports. */
31
+ export function truncateMarkdown(markdown, maxLength) {
32
+ if (markdown.length <= maxLength)
33
+ return markdown;
34
+ const note = '\n\n_Truncated: see the coverage reports of the job for every file._';
35
+ const cut = markdown.lastIndexOf('\n', maxLength - note.length);
36
+ return `${markdown.slice(0, cut > 0 ? cut : maxLength - note.length)}${note}`;
37
+ }
38
+ /**
39
+ * Transform the coverage file sent by an sfdx-hardis run event into the reports set in
40
+ * `.apexcodecovtransformer.config.json`, then post the coverage summary as a Pull Request comment.
41
+ */
42
+ export async function handleSfdxHardisRunEvent(event, deps) {
43
+ const { coverageFile } = event.data;
44
+ if (!coverageFile)
45
+ return { handled: false, reason: 'no-coverage-file' };
46
+ const loaded = await loadHookConfig(deps.cwd);
47
+ if (!loaded)
48
+ return { handled: false, reason: 'no-config' };
49
+ const options = getHookTransformOptions(loaded.config);
50
+ const base = {
51
+ inputs: [coverageFile],
52
+ cwd: deps.cwd,
53
+ ignorePackageDirectories: options.ignorePackageDirectories,
54
+ excludePatterns: options.excludePatterns,
55
+ minCoverage: options.minCoverage,
56
+ maxAnnotations: options.maxAnnotations,
57
+ };
58
+ const result = await transformCoverage({
59
+ ...base,
60
+ formats: options.formats,
61
+ outputReport: resolve(deps.cwd ?? process.cwd(), options.outputReport),
62
+ });
63
+ const reportPaths = result.reports.map((report) => report.path);
64
+ deps.log(`The coverage report has been written to: ${reportPaths.join(', ')}`);
65
+ for (const warning of result.warnings)
66
+ deps.warn(warning);
67
+ if (loaded.config.pullRequestComment === false) {
68
+ return { handled: true, reportPaths, passed: result.passed, comment: { posted: false, reason: 'disabled' } };
69
+ }
70
+ const markdownReport = result.reports.find((report) => report.format === 'markdown')?.content ??
71
+ (await transformCoverage({ ...base, formats: ['markdown'], write: false })).reports[0].content;
72
+ const comment = await deps.postPullRequestComment({
73
+ pluginName: PLUGIN_NAME,
74
+ messageKey: getCommentKey(event),
75
+ title: PULL_REQUEST_COMMENT_TITLE,
76
+ markdown: buildCommentMarkdown(markdownReport, result, options.minCoverage),
77
+ status: result.passed ? 'valid' : 'invalid',
78
+ });
79
+ return { handled: true, reportPaths, passed: result.passed, comment };
80
+ }
81
+ //# sourceMappingURL=sfdxHardisRunEvent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sfdxHardisRunEvent.js","sourceRoot":"","sources":["../../src/utils/sfdxHardisRunEvent.ts"],"names":[],"mappings":"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"}
@@ -137,16 +137,6 @@ export type SonarCoverageObject = {
137
137
  '@version': string;
138
138
  };
139
139
  };
140
- export type HookFile = {
141
- deployCoverageJsonPath: string;
142
- testCoverageJsonPath: string;
143
- outputReportPath: string;
144
- format: string;
145
- ignorePackageDirectories: string;
146
- minCoverage?: number;
147
- maxAnnotations?: number;
148
- excludePatterns?: string;
149
- };
150
140
  export type CoberturaLine = {
151
141
  '@number': number;
152
142
  '@hits': number;
@@ -130,5 +130,5 @@
130
130
  ]
131
131
  }
132
132
  },
133
- "version": "4.3.0"
133
+ "version": "5.0.0"
134
134
  }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "apex-code-coverage-transformer",
3
3
  "description": "Transform Salesforce Apex code coverage JSON for SonarQube, SonarCloud, GitHub, GitLab, Azure, and Bitbucket",
4
- "version": "4.3.0",
4
+ "version": "5.0.0",
5
5
  "dependencies": {
6
6
  "@oclif/core": "5.1.11",
7
7
  "@salesforce/core": "9.4.4",
8
- "@salesforce/sf-plugins-core": "13.0.8"
8
+ "@salesforce/sf-plugins-core": "13.0.8",
9
+ "sfdx-hardis": "8.24.1-beta202611122321.0"
9
10
  },
10
11
  "devDependencies": {
11
12
  "@actions/core": "3.0.1",
@@ -31,7 +32,7 @@
31
32
  "wireit": "0.15.0"
32
33
  },
33
34
  "engines": {
34
- "node": ">=22.19.0"
35
+ "node": ">=22.22.2"
35
36
  },
36
37
  "files": [
37
38
  "/lib",
@@ -78,7 +79,11 @@
78
79
  }
79
80
  },
80
81
  "hooks": {
81
- "finally": "./lib/hooks/finally"
82
+ "prerun": "./lib/hooks/prerun",
83
+ "finally": "./lib/hooks/finally",
84
+ "sfdx-hardis:validation-done": "./lib/hooks/sfdxHardisRunDone",
85
+ "sfdx-hardis:deployment-done": "./lib/hooks/sfdxHardisRunDone",
86
+ "sfdx-hardis:apex-tests-done": "./lib/hooks/sfdxHardisRunDone"
82
87
  },
83
88
  "devPlugins": [
84
89
  "@oclif/plugin-help"