|
1 | 1 | name: Run static code validation |
| 2 | +concurrency: |
| 3 | + group: static-code-validation-${{ github.ref }} |
| 4 | + cancel-in-progress: true |
2 | 5 | on: |
3 | 6 | workflow_call: |
4 | 7 | inputs: |
|
12 | 15 | default: ${{ github.ref }} |
13 | 16 | required: false |
14 | 17 | type: string |
| 18 | + secrets: |
| 19 | + GITHUB_TOKEN: |
| 20 | + description: GitHub token for authentication |
| 21 | + required: false |
15 | 22 | workflow_dispatch: |
16 | 23 | inputs: |
17 | 24 | validateEntireRepo: |
|
26 | 33 | permissions: |
27 | 34 | contents: read |
28 | 35 | security-events: write |
| 36 | + pull-requests: write |
29 | 37 | defaults: |
30 | 38 | run: |
31 | 39 | shell: bash |
|
35 | 43 | with: |
36 | 44 | version: ${{ vars.SF_CLI_VERSION }} |
37 | 45 |
|
38 | | - - name: "Install Salesforce Code Analyzer" |
39 | | - run: | |
40 | | - echo "::group::Install Salesforce Code Analyzer Plugin" |
41 | | - sf plugins install code-analyzer@"$SF_SCANNER_VERSION" |
42 | | - sf plugins --core |
43 | | - echo "::endgroup::" |
44 | | - env: |
45 | | - SF_SCANNER_VERSION: ${{ vars.SF_SCANNER_VERSION }} |
46 | | - |
47 | 46 | - name: Checkout |
48 | 47 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 |
49 | 48 | with: |
|
73 | 72 | echo "prettierPathsToValidate=$prettierPathsToValidate" >> "$GITHUB_OUTPUT" |
74 | 73 | echo "sfCodeAnalyzerPathToValidate=$sfCodeAnalyzerPathToValidate" >> "$GITHUB_OUTPUT" |
75 | 74 | env: |
76 | | - VALIDATE_ENTIRE_REPO: ${{ inputs.validateEntireRepo != '' && inputs.validateEntireRepo || true }} |
| 75 | + VALIDATE_ENTIRE_REPO: ${{ inputs.validateEntireRepo }} |
77 | 76 |
|
78 | 77 | - name: Prettier Check |
79 | 78 | if: ${{ !cancelled() && steps.paths.outcome == 'success' }} |
|
88 | 87 | with: |
89 | 88 | run-arguments: --workspace ${{ steps.paths.outputs.sfCodeAnalyzerPathToValidate }} --view detail --output-file sfca_results.html --output-file sfca_results.json --output-file code-analyzer-report.sarif |
90 | 89 | results-artifact-name: salesforce-code-analyzer-results |
| 90 | + github-token: ${{ github.event_name == 'pull_request' && secrets.GITHUB_TOKEN || '' }} |
91 | 91 |
|
92 | 92 | # Code Analyser generates an empty SARIF file if no violations are found. |
93 | 93 | # In that case this step ensures that the SARIF file is valid and contains a default structure. |
@@ -137,12 +137,51 @@ jobs: |
137 | 137 | category: salesforce-code-analyzer |
138 | 138 |
|
139 | 139 | - name: Check the Salesforce Code Analyzer outputs to determine whether to fail |
140 | | - if: ${{ !cancelled() && steps.paths.outcome == 'success' && ( steps.run-code-analyzer.outputs.exit-code > 0 || steps.run-code-analyzer.outputs.num-sev1-violations > 0 || steps.run-code-analyzer.outputs.num-violations > 10 ) }} |
| 140 | + if: ${{ !cancelled() && steps.paths.outcome == 'success' && ( steps.run-code-analyzer.outputs.exit-code > 0 || steps.run-code-analyzer.outputs.num-sev1-violations > 0 || steps.run-code-analyzer.outputs.num-violations > 10) }} |
141 | 141 | shell: bash |
142 | 142 | run: | |
143 | | - echo "::error title=Code Analyzer failed with exit code: ${EXIT_CODE}::Number of Sev1 violations: ${NUM_SEV1_VIOLATIONS} (max 0). Number of violations: ${NUM_VIOLATIONS} (max 10)." |
144 | | - exit 1 |
| 143 | + set -euo pipefail |
| 144 | +
|
| 145 | + # Normalize (default to 0 if unset/empty) |
| 146 | + EXIT_CODE=${EXIT_CODE:-0} |
| 147 | + NUM_SEV1_VIOLATIONS=${NUM_SEV1_VIOLATIONS:-0} |
| 148 | + NUM_SEV2_VIOLATIONS=${NUM_SEV2_VIOLATIONS:-0} |
| 149 | + NUM_SEV3_VIOLATIONS=${NUM_SEV3_VIOLATIONS:-0} |
| 150 | + NUM_SEV4_VIOLATIONS=${NUM_SEV4_VIOLATIONS:-0} |
| 151 | + NUM_SEV5_VIOLATIONS=${NUM_SEV5_VIOLATIONS:-0} |
| 152 | + NUM_VIOLATIONS=${NUM_VIOLATIONS:-0} |
| 153 | +
|
| 154 | + # Exclude Sev5 (Info) from total count threshold |
| 155 | + totalViolations=$(( NUM_VIOLATIONS - NUM_SEV5_VIOLATIONS )) |
| 156 | +
|
| 157 | + if (( EXIT_CODE > 0 )); then |
| 158 | + echo "::error title=Salesforce Code Analyzer failed::Exit code: ${EXIT_CODE}" |
| 159 | + fi |
| 160 | +
|
| 161 | + if (( NUM_SEV1_VIOLATIONS > 0 )) || (( totalViolations > MAX_ALLOWED_VIOLATIONS )); then |
| 162 | + |
| 163 | + printf -v details \ |
| 164 | + "Number of Sev1 Critical violations: %s\n \ |
| 165 | + Number of Sev2 High violations: %s\n \ |
| 166 | + Number of Sev3 Medium violations: %s\n \ |
| 167 | + Number of Sev4 Low violations: %s\n \ |
| 168 | + Number of Sev5 Info violations: %s\n \ |
| 169 | + Total (excluding Sev5): %s (max %s)" \ |
| 170 | + "$NUM_SEV1_VIOLATIONS" "$NUM_SEV2_VIOLATIONS" "$NUM_SEV3_VIOLATIONS" "$NUM_SEV4_VIOLATIONS" "$NUM_SEV5_VIOLATIONS" "$totalViolations" "$MAX_ALLOWED_VIOLATIONS" |
| 171 | + |
| 172 | + # GitHub command: replace literal newlines with %0A |
| 173 | + echo "::error title=Salesforce Code Analyzer threshold exceeded::${details//$'\n'/%0A}" |
| 174 | + fi |
| 175 | +
|
| 176 | + if (( EXIT_CODE > 0 )) || (( NUM_SEV1_VIOLATIONS > 0 )) || (( totalViolations > MAX_ALLOWED_VIOLATIONS )); then |
| 177 | + exit 1 |
| 178 | + fi |
145 | 179 | env: |
| 180 | + MAX_ALLOWED_VIOLATIONS: 10 |
146 | 181 | EXIT_CODE: ${{ steps.run-code-analyzer.outputs.exit-code }} |
147 | 182 | NUM_SEV1_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev1-violations }} |
| 183 | + NUM_SEV2_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev2-violations }} |
| 184 | + NUM_SEV3_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev3-violations }} |
| 185 | + NUM_SEV4_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev4-violations }} |
| 186 | + NUM_SEV5_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev5-violations }} |
148 | 187 | NUM_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-violations }} |
0 commit comments