@salesforce/afv-skills 1.17.0 → 1.18.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.
Files changed (30) hide show
  1. package/package.json +1 -1
  2. package/skills/building-sf-integrations/SKILL.md +1 -1
  3. package/skills/configuring-code-analyzer/SKILL.md +482 -0
  4. package/skills/configuring-code-analyzer/examples/apex-project-config.yml +41 -0
  5. package/skills/configuring-code-analyzer/examples/ci-github-actions.yml +96 -0
  6. package/skills/configuring-code-analyzer/examples/fullstack-project-config.yml +46 -0
  7. package/skills/configuring-code-analyzer/examples/lwc-project-config.yml +26 -0
  8. package/skills/configuring-code-analyzer/references/ci-cd-templates.md +648 -0
  9. package/skills/configuring-code-analyzer/references/config-schema.md +257 -0
  10. package/skills/configuring-code-analyzer/references/diagnostic-flow.md +70 -0
  11. package/skills/configuring-code-analyzer/references/engine-prerequisites.md +276 -0
  12. package/skills/configuring-code-analyzer/references/rule-name-resolution.md +67 -0
  13. package/skills/configuring-code-analyzer/references/troubleshooting.md +298 -0
  14. package/skills/configuring-code-analyzer/scripts/check-prerequisites.sh +189 -0
  15. package/skills/configuring-code-analyzer/scripts/generate-config.sh +143 -0
  16. package/skills/configuring-code-analyzer/scripts/validate-config.sh +153 -0
  17. package/skills/managing-cdc-enablement/SKILL.md +164 -0
  18. package/skills/managing-cdc-enablement/assets/PlatformEventChannel-template.xml +5 -0
  19. package/skills/managing-cdc-enablement/assets/PlatformEventChannelMember-template.xml +11 -0
  20. package/skills/managing-cdc-enablement/references/deploy-troubleshooting.md +73 -0
  21. package/skills/managing-cdc-enablement/references/filter-expressions.md +93 -0
  22. package/skills/running-code-analyzer/SKILL.md +264 -267
  23. package/skills/running-code-analyzer/references/post-scan-workflows.md +286 -0
  24. package/skills/running-code-analyzer/scripts/describe-rule.js +382 -0
  25. package/skills/running-code-analyzer/scripts/list-rules.js +260 -0
  26. package/skills/running-code-analyzer/scripts/query-results.js +230 -0
  27. package/skills/using-salesforce-archive/SKILL.md +121 -0
  28. package/skills/using-salesforce-archive/examples/monitor-failed-jobs.md +47 -0
  29. package/skills/using-salesforce-archive/references/archive-activity-entity.md +59 -0
  30. package/skills/using-salesforce-archive/references/connect-api-operations.md +157 -0
@@ -0,0 +1,26 @@
1
+ # Code Analyzer Configuration — LWC-focused Project
2
+ #
3
+ # This file contains ONLY overrides. Code Analyzer's built-in defaults
4
+ # handle everything else. Only add entries here that intentionally
5
+ # change behavior for your project.
6
+ #
7
+ # Usage:
8
+ # Place at project root as code-analyzer.yml
9
+ # Validate: sf code-analyzer config --config-file code-analyzer.yml
10
+
11
+ # Exclude non-project files and test infrastructure
12
+ ignores:
13
+ files:
14
+ - "**/node_modules/**"
15
+ - "**/.sfdx/**"
16
+ - "**/.sf/**"
17
+ - "**/jest-mocks/**"
18
+ - "**/__tests__/**"
19
+ - "**/*.min.js"
20
+
21
+ # Engine tuning
22
+ engines:
23
+ # ESLint: opt-in to use project's existing ESLint config
24
+ # (built-in default is false — Code Analyzer uses its own base configs)
25
+ eslint:
26
+ auto_discover_eslint_config: true
@@ -0,0 +1,648 @@
1
+ # CI/CD Pipeline Templates
2
+
3
+ Ready-to-use templates for integrating Code Analyzer into CI/CD pipelines.
4
+
5
+ ## GitHub Actions (using `forcedotcom/run-code-analyzer@v2`)
6
+
7
+ The official GitHub Action for Code Analyzer. It orchestrates the run, uploads artifacts, and optionally creates PR reviews with violation counts.
8
+
9
+ **Action inputs:**
10
+ | Input | Required | Default | Description |
11
+ |-------|----------|---------|-------------|
12
+ | `run-arguments` | No | `--view detail --output-file sfca_results.json` | Flags passed to `sf code-analyzer run` |
13
+ | `results-artifact-name` | No | `salesforce-code-analyzer-results` | Name of the uploaded ZIP artifact |
14
+ | `github-token` | No | *(none)* | Enables PR reviews + `*-in-changed-files` outputs |
15
+
16
+ **Action outputs:** `exit-code`, `num-violations`, `num-sev1-violations` through `num-sev5-violations`, `num-violations-in-changed-files`, `num-sev1-violations-in-changed-files` through `num-sev5-violations-in-changed-files`, `review-id`.
17
+
18
+ **Key `run-arguments` flags:**
19
+ | Flag | Purpose | Example |
20
+ |------|---------|---------|
21
+ | `--workspace` | Root directory to scan (scans all eligible files recursively) | `--workspace .` |
22
+ | `--target` | Specific files/directories to scan (comma-separated or repeated) | `--target force-app/main/default/classes --target force-app/main/default/triggers` |
23
+ | `--rule-selector` | Which rules to run | `Recommended`, `all`, `all:Security`, `pmd`, `"Severity:1,2"` |
24
+ | `--config-file` | Path to `code-analyzer.yml` — **omit if no config file exists** | `--config-file code-analyzer.yml` |
25
+ | `--output-file` | Output file (repeat for multiple formats; format inferred from extension) | `--output-file results.html --output-file results.sarif` |
26
+ | `--view` | Output verbosity | `detail` or `summary` |
27
+
28
+ **`--workspace` vs `--target`:**
29
+ - Use `--workspace .` for full-repo scans (most common in CI)
30
+ - Use `--target <path>` to scan specific directories (monorepos, scoped scans, faster feedback)
31
+ - If both are omitted, defaults to current working directory
32
+ - You can combine: `--workspace . --target force-app/` scans only `force-app/` within the workspace
33
+
34
+ ### Basic Quality Gate (Pull Requests)
35
+
36
+ ```yaml
37
+ # .github/workflows/code-analyzer.yml
38
+ name: Salesforce Code Analyzer
39
+
40
+ on:
41
+ pull_request:
42
+ branches: [main, develop]
43
+
44
+ jobs:
45
+ code-analysis:
46
+ permissions:
47
+ pull-requests: write
48
+ contents: read
49
+ actions: read
50
+ runs-on: ubuntu-latest
51
+ steps:
52
+ - name: Check out files
53
+ uses: actions/checkout@v4
54
+
55
+ - name: Setup Node
56
+ uses: actions/setup-node@v4
57
+ with:
58
+ node-version: '>=20.9.0'
59
+
60
+ - name: Setup Java
61
+ uses: actions/setup-java@v4
62
+ with:
63
+ distribution: 'temurin'
64
+ java-version: '>=11'
65
+
66
+ - name: Install Salesforce CLI
67
+ run: npm install -g @salesforce/cli@latest
68
+
69
+ - name: Install Code Analyzer Plugin
70
+ run: sf plugins install code-analyzer@latest
71
+
72
+ - name: Run Salesforce Code Analyzer
73
+ id: run-code-analyzer
74
+ uses: forcedotcom/run-code-analyzer@v2
75
+ with:
76
+ run-arguments: --workspace . --rule-selector Recommended --output-file sfca_results.html --output-file sfca_results.json
77
+ results-artifact-name: code-analyzer-results
78
+ github-token: ${{ github.token }}
79
+
80
+ - name: Check Quality Gate (Changed Files Only)
81
+ if: |
82
+ steps.run-code-analyzer.outputs.num-sev1-violations-in-changed-files > 0 ||
83
+ steps.run-code-analyzer.outputs.num-sev2-violations-in-changed-files > 0
84
+ run: |
85
+ echo "Critical/High violations found in changed files!"
86
+ echo "Sev1: ${{ steps.run-code-analyzer.outputs.num-sev1-violations-in-changed-files }}"
87
+ echo "Sev2: ${{ steps.run-code-analyzer.outputs.num-sev2-violations-in-changed-files }}"
88
+ exit 1
89
+ ```
90
+
91
+ ### Strict Quality Gate (All Files + SARIF)
92
+
93
+ ```yaml
94
+ # .github/workflows/code-analyzer-strict.yml
95
+ name: Salesforce Code Analyzer (Strict)
96
+
97
+ on:
98
+ pull_request:
99
+ branches: [main]
100
+ push:
101
+ branches: [main]
102
+
103
+ jobs:
104
+ code-analysis:
105
+ permissions:
106
+ pull-requests: write
107
+ contents: read
108
+ actions: read
109
+ security-events: write
110
+ runs-on: ubuntu-latest
111
+ steps:
112
+ - name: Check out files
113
+ uses: actions/checkout@v4
114
+
115
+ - name: Setup Node
116
+ uses: actions/setup-node@v4
117
+ with:
118
+ node-version: '>=20.9.0'
119
+
120
+ - name: Setup Java
121
+ uses: actions/setup-java@v4
122
+ with:
123
+ distribution: 'temurin'
124
+ java-version: '>=11'
125
+
126
+ - name: Install Salesforce CLI
127
+ run: npm install -g @salesforce/cli@latest
128
+
129
+ - name: Install Code Analyzer Plugin
130
+ run: sf plugins install code-analyzer@latest
131
+
132
+ - name: Run Salesforce Code Analyzer
133
+ id: run-code-analyzer
134
+ uses: forcedotcom/run-code-analyzer@v2
135
+ with:
136
+ run-arguments: --workspace . --rule-selector Recommended --output-file sfca_results.html --output-file sfca_results.json --output-file sfca_results.sarif --config-file code-analyzer.yml
137
+ results-artifact-name: code-analyzer-results
138
+ github-token: ${{ github.token }}
139
+
140
+ - name: Upload SARIF to GitHub Security
141
+ if: always()
142
+ uses: github/codeql-action/upload-sarif@v3
143
+ with:
144
+ sarif_file: sfca_results.sarif
145
+
146
+ - name: Check Quality Gate (All Files)
147
+ if: |
148
+ steps.run-code-analyzer.outputs.exit-code > 0 ||
149
+ steps.run-code-analyzer.outputs.num-sev1-violations > 0 ||
150
+ steps.run-code-analyzer.outputs.num-sev2-violations > 0
151
+ run: |
152
+ echo "Quality gate failed!"
153
+ echo "Total violations: ${{ steps.run-code-analyzer.outputs.num-violations }}"
154
+ echo "Sev1: ${{ steps.run-code-analyzer.outputs.num-sev1-violations }}"
155
+ echo "Sev2: ${{ steps.run-code-analyzer.outputs.num-sev2-violations }}"
156
+ exit 1
157
+ ```
158
+
159
+ ### Security-Focused (AppExchange Prep)
160
+
161
+ ```yaml
162
+ # .github/workflows/code-analyzer-security.yml
163
+ name: Security Analysis
164
+
165
+ on:
166
+ pull_request:
167
+ branches: [main]
168
+ schedule:
169
+ - cron: '0 6 * * 1' # Weekly Monday 6am
170
+
171
+ jobs:
172
+ security-scan:
173
+ permissions:
174
+ pull-requests: write
175
+ contents: read
176
+ actions: read
177
+ security-events: write
178
+ runs-on: ubuntu-latest
179
+ steps:
180
+ - name: Check out files
181
+ uses: actions/checkout@v4
182
+
183
+ - name: Setup Node
184
+ uses: actions/setup-node@v4
185
+ with:
186
+ node-version: '>=20.9.0'
187
+
188
+ - name: Setup Java
189
+ uses: actions/setup-java@v4
190
+ with:
191
+ distribution: 'temurin'
192
+ java-version: '>=11'
193
+
194
+ - name: Install Salesforce CLI
195
+ run: npm install -g @salesforce/cli@latest
196
+
197
+ - name: Install Code Analyzer Plugin
198
+ run: sf plugins install code-analyzer@latest
199
+
200
+ - name: Run Security Scan
201
+ id: run-code-analyzer
202
+ uses: forcedotcom/run-code-analyzer@v2
203
+ with:
204
+ run-arguments: --workspace . --rule-selector "all:Security" --output-file security-results.html --output-file security-results.json --output-file security-results.sarif --config-file code-analyzer.yml
205
+ results-artifact-name: security-scan-results
206
+ github-token: ${{ github.token }}
207
+
208
+ - name: Upload SARIF to GitHub Security
209
+ if: always()
210
+ uses: github/codeql-action/upload-sarif@v3
211
+ with:
212
+ sarif_file: security-results.sarif
213
+
214
+ - name: Fail on Any Security Violations
215
+ if: steps.run-code-analyzer.outputs.num-sev1-violations > 0
216
+ run: |
217
+ echo "Critical security violations found!"
218
+ echo "Sev1: ${{ steps.run-code-analyzer.outputs.num-sev1-violations }}"
219
+ exit 1
220
+ ```
221
+
222
+ ### With Path Filters (Faster Feedback)
223
+
224
+ Use `paths:` to only trigger the workflow when relevant source files change. This avoids running scans on README edits, CI config changes, etc.
225
+
226
+ ```yaml
227
+ # .github/workflows/code-analyzer-filtered.yml
228
+ name: Salesforce Code Analyzer
229
+
230
+ on:
231
+ pull_request:
232
+ branches: [main, develop]
233
+ paths:
234
+ - 'force-app/**'
235
+ - '**/*.cls'
236
+ - '**/*.trigger'
237
+ - '**/*.js'
238
+ - '**/*.ts'
239
+ - '**/*.html'
240
+ - '**/*.flow-meta.xml'
241
+ - 'code-analyzer.yml'
242
+
243
+ jobs:
244
+ code-analysis:
245
+ permissions:
246
+ pull-requests: write
247
+ contents: read
248
+ actions: read
249
+ runs-on: ubuntu-latest
250
+ steps:
251
+ - name: Check out files
252
+ uses: actions/checkout@v4
253
+
254
+ - name: Setup Node
255
+ uses: actions/setup-node@v4
256
+ with:
257
+ node-version: '>=20.9.0'
258
+
259
+ - name: Setup Java
260
+ uses: actions/setup-java@v4
261
+ with:
262
+ distribution: 'temurin'
263
+ java-version: '>=11'
264
+
265
+ - name: Install Salesforce CLI
266
+ run: npm install -g @salesforce/cli@latest
267
+
268
+ - name: Install Code Analyzer Plugin
269
+ run: sf plugins install code-analyzer@latest
270
+
271
+ - name: Run Salesforce Code Analyzer
272
+ id: run-code-analyzer
273
+ uses: forcedotcom/run-code-analyzer@v2
274
+ with:
275
+ run-arguments: --workspace . --rule-selector Recommended --output-file sfca_results.html --output-file sfca_results.json
276
+ results-artifact-name: code-analyzer-results
277
+ github-token: ${{ github.token }}
278
+
279
+ - name: Check Quality Gate
280
+ if: |
281
+ steps.run-code-analyzer.outputs.num-sev1-violations-in-changed-files > 0 ||
282
+ steps.run-code-analyzer.outputs.num-sev2-violations-in-changed-files > 0
283
+ run: exit 1
284
+ ```
285
+
286
+ **When to use path filters:**
287
+ - Use when the repo contains non-Salesforce code (docs, scripts, infra) that shouldn't trigger scans
288
+ - Always include `code-analyzer.yml` in paths so config changes trigger a validation run
289
+ - Don't use if you want every PR to get a scan regardless of what changed
290
+
291
+ ### With Flow Engine (Python Required)
292
+
293
+ If the project contains `.flow-meta.xml` files and uses the Flow engine, Python 3.10+ must be installed:
294
+
295
+ ```yaml
296
+ - name: Setup Python (required for Flow engine)
297
+ uses: actions/setup-python@v5
298
+ with:
299
+ python-version: '>=3.10'
300
+ ```
301
+
302
+ Insert this step after the Java setup step. If you're unsure whether the project uses Flows, include it — it adds ~5s and avoids a partial scan failure.
303
+
304
+ ### Monorepo / Scoped Scan
305
+
306
+ For monorepos where Salesforce code lives in a subdirectory, use `--target` to scope the scan:
307
+
308
+ ```yaml
309
+ - name: Run Salesforce Code Analyzer
310
+ id: run-code-analyzer
311
+ uses: forcedotcom/run-code-analyzer@v2
312
+ with:
313
+ run-arguments: --workspace . --target packages/salesforce-app/force-app --rule-selector Recommended --output-file sfca_results.html --output-file sfca_results.json
314
+ results-artifact-name: code-analyzer-results
315
+ github-token: ${{ github.token }}
316
+ ```
317
+
318
+ For multiple packages:
319
+ ```
320
+ --target packages/app-a/force-app --target packages/app-b/force-app
321
+ ```
322
+
323
+ ### Without a Config File
324
+
325
+ If the project has no `code-analyzer.yml`, simply omit `--config-file`. Code Analyzer uses built-in defaults:
326
+
327
+ ```yaml
328
+ - name: Run Salesforce Code Analyzer
329
+ id: run-code-analyzer
330
+ uses: forcedotcom/run-code-analyzer@v2
331
+ with:
332
+ run-arguments: --workspace . --rule-selector Recommended --output-file sfca_results.html --output-file sfca_results.json
333
+ results-artifact-name: code-analyzer-results
334
+ github-token: ${{ github.token }}
335
+ ```
336
+
337
+ To conditionally use a config file if it exists:
338
+ ```yaml
339
+ - name: Check for config file
340
+ id: config-check
341
+ run: |
342
+ if [ -f "code-analyzer.yml" ]; then
343
+ echo "config-flag=--config-file code-analyzer.yml" >> $GITHUB_OUTPUT
344
+ else
345
+ echo "config-flag=" >> $GITHUB_OUTPUT
346
+ fi
347
+
348
+ - name: Run Salesforce Code Analyzer
349
+ id: run-code-analyzer
350
+ uses: forcedotcom/run-code-analyzer@v2
351
+ with:
352
+ run-arguments: --workspace . --rule-selector Recommended --output-file sfca_results.html --output-file sfca_results.json ${{ steps.config-check.outputs.config-flag }}
353
+ results-artifact-name: code-analyzer-results
354
+ github-token: ${{ github.token }}
355
+ ```
356
+
357
+ ## Jenkins
358
+
359
+ ### Jenkinsfile (Declarative Pipeline)
360
+
361
+ ```groovy
362
+ // Jenkinsfile
363
+ pipeline {
364
+ agent {
365
+ docker {
366
+ image 'node:20'
367
+ args '-v /usr/local/share/java:/usr/local/share/java'
368
+ }
369
+ }
370
+
371
+ environment {
372
+ JAVA_HOME = '/usr/lib/jvm/java-11-openjdk-amd64'
373
+ }
374
+
375
+ stages {
376
+ stage('Setup') {
377
+ steps {
378
+ sh 'npm install -g @salesforce/cli@latest'
379
+ sh 'sf plugins install code-analyzer@latest'
380
+ }
381
+ }
382
+
383
+ stage('Code Analysis') {
384
+ steps {
385
+ sh '''
386
+ sf code-analyzer run \
387
+ --workspace . \
388
+ --rule-selector Recommended \
389
+ --output-file results.json \
390
+ --output-file results.html \
391
+ --config-file code-analyzer.yml 2>&1 | tee sfca_output.txt
392
+ '''
393
+ script {
394
+ def output = readFile('results.json')
395
+ def json = new groovy.json.JsonSlurper().parseText(output)
396
+ def sev1Count = json.violations?.count { it.severity == 1 } ?: 0
397
+ def sev2Count = json.violations?.count { it.severity == 2 } ?: 0
398
+ if (sev1Count > 0 || sev2Count > 0) {
399
+ error("Quality gate failed! Sev1: ${sev1Count}, Sev2: ${sev2Count}")
400
+ }
401
+ }
402
+ }
403
+ post {
404
+ always {
405
+ archiveArtifacts artifacts: 'results.*', allowEmptyArchive: true
406
+ publishHTML(target: [
407
+ reportName: 'Code Analyzer Report',
408
+ reportDir: '.',
409
+ reportFiles: 'results.html'
410
+ ])
411
+ }
412
+ }
413
+ }
414
+ }
415
+
416
+ post {
417
+ failure {
418
+ echo 'Code analysis found violations above severity threshold!'
419
+ }
420
+ }
421
+ }
422
+ ```
423
+
424
+ ## GitLab CI
425
+
426
+ ```yaml
427
+ # .gitlab-ci.yml
428
+ code-analysis:
429
+ image: node:20
430
+ stage: test
431
+ before_script:
432
+ - apt-get update && apt-get install -y openjdk-11-jdk python3
433
+ - export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
434
+ - npm install -g @salesforce/cli@latest
435
+ - sf plugins install code-analyzer@latest
436
+ script:
437
+ - |
438
+ sf code-analyzer run \
439
+ --workspace . \
440
+ --rule-selector Recommended \
441
+ --output-file results.json \
442
+ --output-file results.html \
443
+ --config-file code-analyzer.yml
444
+ - |
445
+ # Quality gate: fail on sev1 or sev2 violations
446
+ SEV1=$(cat results.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(sum(1 for v in d.get('violations',[]) if v.get('severity')==1))")
447
+ SEV2=$(cat results.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(sum(1 for v in d.get('violations',[]) if v.get('severity')==2))")
448
+ echo "Sev1: $SEV1, Sev2: $SEV2"
449
+ if [ "$SEV1" -gt 0 ] || [ "$SEV2" -gt 0 ]; then
450
+ echo "Quality gate failed!"
451
+ exit 1
452
+ fi
453
+ artifacts:
454
+ paths:
455
+ - results.json
456
+ - results.html
457
+ reports:
458
+ codequality: results.json
459
+ rules:
460
+ - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
461
+ - if: '$CI_COMMIT_BRANCH == "main"'
462
+ ```
463
+
464
+ ## Bitbucket Pipelines
465
+
466
+ ```yaml
467
+ # bitbucket-pipelines.yml
468
+ pipelines:
469
+ pull-requests:
470
+ '**':
471
+ - step:
472
+ name: Code Analysis
473
+ image: node:20
474
+ script:
475
+ - apt-get update && apt-get install -y openjdk-11-jdk
476
+ - export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
477
+ - npm install -g @salesforce/cli@latest
478
+ - sf plugins install code-analyzer@latest
479
+ - |
480
+ sf code-analyzer run \
481
+ --workspace . \
482
+ --rule-selector Recommended \
483
+ --output-file results.json \
484
+ --output-file results.html \
485
+ --config-file code-analyzer.yml
486
+ - |
487
+ # Quality gate: fail on sev1 or sev2 violations
488
+ SEV1=$(cat results.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(sum(1 for v in d.get('violations',[]) if v.get('severity')==1))")
489
+ SEV2=$(cat results.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(sum(1 for v in d.get('violations',[]) if v.get('severity')==2))")
490
+ echo "Sev1: $SEV1, Sev2: $SEV2"
491
+ if [ "$SEV1" -gt 0 ] || [ "$SEV2" -gt 0 ]; then
492
+ echo "Quality gate failed!"
493
+ exit 1
494
+ fi
495
+ artifacts:
496
+ - results.json
497
+ - results.html
498
+ ```
499
+
500
+ ## Configuration Tips for CI/CD
501
+
502
+ ### Quality Gating Strategy
503
+
504
+ With `forcedotcom/run-code-analyzer@v2`, you control the quality gate via output checks:
505
+
506
+ | Strategy | Condition | Use Case |
507
+ |----------|-----------|----------|
508
+ | Block on critical only | `num-sev1-violations > 0` | Permissive — only block security vulnerabilities |
509
+ | Block on critical + high | `num-sev1-violations > 0 \|\| num-sev2-violations > 0` | Recommended for most teams |
510
+ | Block on changed files only | `num-sev1-violations-in-changed-files > 0` | Great for legacy codebases — don't block on pre-existing issues |
511
+ | Block on total count | `num-violations > 10` | Budget approach — allow some violations but cap total |
512
+ | Zero tolerance | `num-violations > 0` | For new greenfield projects only |
513
+
514
+ For non-GitHub platforms (Jenkins, GitLab, Bitbucket), parse `results.json` to count violations by severity and fail the pipeline accordingly.
515
+
516
+ ### Output Formats
517
+
518
+ Specify multiple `--output-file` flags (format inferred from extension):
519
+
520
+ | Format | Extension | Best For |
521
+ |--------|-----------|----------|
522
+ | SARIF | `.sarif` | GitHub Code Scanning integration (requires `security-events: write` permission) |
523
+ | JSON | `.json` | Programmatic processing, quality gating scripts, custom dashboards |
524
+ | HTML | `.html` | Human-readable reports in artifacts |
525
+ | CSV | `.csv` | Spreadsheet analysis |
526
+ | XML | `.xml` | Legacy tool integration |
527
+
528
+ ### Caching for Faster CI
529
+
530
+ ```yaml
531
+ # GitHub Actions: Cache sf CLI plugins
532
+ - uses: actions/cache@v4
533
+ with:
534
+ path: ~/.local/share/sf/
535
+ key: sf-plugins-${{ hashFiles('**/code-analyzer.yml') }}
536
+ restore-keys: sf-plugins-
537
+ ```
538
+
539
+ ### Recommended PR Workflow
540
+
541
+ 1. **On PR open/update:** Use `forcedotcom/run-code-analyzer@v2` with `github-token` — gate on changed-files outputs only
542
+ 2. **On merge to main:** Full scan with SARIF upload to GitHub Security tab
543
+ 3. **Weekly schedule:** Full security scan with `--rule-selector "all:Security"`
544
+
545
+ ### When to Use Path Filters
546
+
547
+ | Situation | Use Path Filters? | Reasoning |
548
+ |-----------|-------------------|-----------|
549
+ | Mixed repo (docs, infra, salesforce code) | Yes | Avoid wasting CI minutes on non-code PRs |
550
+ | Pure Salesforce project | Optional | Every PR likely touches scannable files anyway |
551
+ | You want config changes to trigger a scan | Yes, include `code-analyzer.yml` | Validates config changes don't break the scan |
552
+ | Monorepo with multiple apps | Yes, scope to your package path | Avoid scanning unrelated packages |
553
+
554
+ ---
555
+
556
+ ## Composition & Adaptation Guide
557
+
558
+ When a user's request doesn't match an existing template exactly, compose from these building blocks:
559
+
560
+ ### Prerequisites Block (always required)
561
+ ```yaml
562
+ # ALWAYS include these — the action does NOT install them
563
+ - uses: actions/setup-node@v4 # Node >= 20.9.0
564
+ - uses: actions/setup-java@v4 # Java >= 11 (for PMD/CPD/SFGE)
565
+ - uses: actions/setup-python@v5 # Python >= 3.10 (ONLY if project has .flow-meta.xml files)
566
+ - run: npm install -g @salesforce/cli@latest
567
+ - run: sf plugins install code-analyzer@latest
568
+ ```
569
+
570
+ ### Composing `run-arguments`
571
+
572
+ Build the `run-arguments` string by combining these independent flags as needed:
573
+
574
+ | Need | Flag to Add |
575
+ |------|-------------|
576
+ | Scan the whole repo | `--workspace .` |
577
+ | Scan specific directory | `--target force-app/main/default/classes` |
578
+ | Scan multiple directories | `--target dir1 --target dir2` |
579
+ | Use recommended rules | `--rule-selector Recommended` |
580
+ | Use all rules | `--rule-selector all` |
581
+ | Security rules only | `--rule-selector "all:Security"` |
582
+ | Specific engine only | `--rule-selector pmd` or `--rule-selector eslint` |
583
+ | Specific severity filter | `--rule-selector "Severity:1,2"` |
584
+ | Combined selector | `--rule-selector "pmd:Security:(1,2)"` |
585
+ | Apply custom config | `--config-file code-analyzer.yml` |
586
+ | No custom config | *(omit --config-file entirely)* |
587
+ | HTML output | `--output-file results.html` |
588
+ | JSON output | `--output-file results.json` |
589
+ | SARIF for GitHub Security | `--output-file results.sarif` |
590
+ | Multiple formats | `--output-file a.html --output-file b.json --output-file c.sarif` |
591
+ | Verbose output | `--view detail` |
592
+
593
+ ### Permissions Required
594
+
595
+ | Feature | Permission Needed |
596
+ |---------|------------------|
597
+ | PR review comments | `pull-requests: write` |
598
+ | Upload SARIF to Security tab | `security-events: write` |
599
+ | Private repo checkout | `contents: read` |
600
+ | Download artifacts | `actions: read` |
601
+
602
+ ### Decision Tree for Template Selection
603
+
604
+ ```
605
+ User wants CI/CD for Code Analyzer
606
+ ├── Platform?
607
+ │ ├── GitHub Actions → Use forcedotcom/run-code-analyzer@v2
608
+ │ ├── Jenkins → Use Jenkinsfile template + JSON parsing for quality gate
609
+ │ ├── GitLab → Use .gitlab-ci.yml template + script-based quality gate
610
+ │ └── Bitbucket → Use bitbucket-pipelines.yml template + script-based quality gate
611
+ ├── Scope?
612
+ │ ├── Full repo → --workspace .
613
+ │ ├── Specific folder → --target <path>
614
+ │ └── Changed files only → use github-token + *-in-changed-files outputs (GitHub only)
615
+ ├── Strictness?
616
+ │ ├── Block on sev1 only → check num-sev1-violations
617
+ │ ├── Block on sev1+sev2 → check both (RECOMMENDED DEFAULT)
618
+ │ ├── Block on any violation → check num-violations
619
+ │ └── Legacy codebase → use *-in-changed-files to avoid blocking on old debt
620
+ ├── Has config file?
621
+ │ ├── Yes → add --config-file code-analyzer.yml
622
+ │ ├── No → omit --config-file
623
+ │ └── Maybe → use conditional check pattern
624
+ ├── Has Flow files?
625
+ │ ├── Yes → add actions/setup-python step
626
+ │ └── No → skip Python setup
627
+ └── Wants GitHub Security integration?
628
+ ├── Yes → add --output-file *.sarif + upload-sarif step + security-events: write
629
+ └── No → skip SARIF
630
+ ```
631
+
632
+ ### Common User Requests → Modifications
633
+
634
+ | User Says | What to Change |
635
+ |-----------|---------------|
636
+ | "Only scan on PRs to main" | Set `on: pull_request: branches: [main]` |
637
+ | "Scan only Apex classes" | Use `--target force-app/main/default/classes` |
638
+ | "Don't fail on existing violations" | Use `*-in-changed-files` outputs for quality gate |
639
+ | "I want to see results in GitHub Security tab" | Add `--output-file *.sarif` + `upload-sarif` step + `security-events: write` |
640
+ | "Run a nightly full scan" | Add `schedule: - cron: '0 0 * * *'` trigger |
641
+ | "We don't have a config file" | Remove `--config-file` from run-arguments |
642
+ | "Only run security rules" | Change `--rule-selector` to `"all:Security"` |
643
+ | "Block the PR if there are more than 5 violations" | Change gate to `num-violations > 5` |
644
+ | "We have Flows in our project" | Add `actions/setup-python@v5` with `python-version: '>=3.10'` |
645
+ | "Scan only what changed in the PR" | Use `github-token` + gate on `*-in-changed-files` outputs |
646
+ | "We're a monorepo" | Use `--target packages/my-sf-app/force-app` instead of `--workspace .` |
647
+ | "Cache the plugin install" | Add `actions/cache@v4` step for `~/.local/share/sf/` |
648
+ | "I want an HTML report I can download" | Add `--output-file results.html` (auto-uploaded via results-artifact-name) |