Skip to content

refactor(ci): enhance static code validation workflow and improve err… #71

refactor(ci): enhance static code validation workflow and improve err…

refactor(ci): enhance static code validation workflow and improve err… #71

name: Run static code validation
concurrency:
group: static-code-validation-${{ github.ref }}
cancel-in-progress: true
on:
workflow_call:
inputs:
validateEntireRepo:
description: Validate entire repo (setting to false will only validate the diff against main)
default: true
required: false
type: boolean
gitRef:
description: Which git ref to use
default: ${{ github.ref }}
required: false
type: string
secrets:
GITHUB_TOKEN:

Check failure on line 19 in .github/workflows/ciStaticCodeValidation.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/ciStaticCodeValidation.yml

Invalid workflow file

secret name `GITHUB_TOKEN` within `workflow_call` can not be used since it would collide with system reserved name
description: GitHub token for authentication
required: false
workflow_dispatch:
inputs:
validateEntireRepo:
description: Validate entire repo (unchecking will only validate the diff against main)
default: true
required: false
type: boolean
jobs:
validate:
name: Static code validation
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
pull-requests: write
defaults:
run:
shell: bash
steps:
- name: Install SF CLI
uses: navikt/sf-platform/.github/actions/installSfCli@eb5b379e3b162280de8f5b9566cb41c25f0832f5
with:
version: ${{ vars.SF_CLI_VERSION }}
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
ref: ${{ inputs.gitRef }}
fetch-depth: "0"
persist-credentials: false
- name: "Install dev dependencies"
run: |
npm ci
- name: "Set variables"
id: paths
run: |
prettierPathsToValidate='**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}'
sfCodeAnalyzerPathToValidate='src'
if [ "$VALIDATE_ENTIRE_REPO" = "false" ]; then
mapfile -t prettier_diffed_files_to_lint < <(git diff --name-only --diff-filter=d HEAD~ -- \*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml})
mapfile -t codeAnalyzer_diffed_sf_files < <(git diff --name-only --diff-filter=d HEAD~ -- src/**/*.{cls,cmp,component,css,html,js,json,page,trigger,xml})
codeAnalyzer_json=$(jq -c -n '$ARGS.positional' --args "${codeAnalyzer_diffed_sf_files[@]}")
prettierPathsToValidate="$(printf "%s\n" "${prettier_diffed_files_to_lint[@]}")"
sfCodeAnalyzerPathToValidate="$codeAnalyzer_json"
fi
echo "prettierPathsToValidate=$prettierPathsToValidate" >> "$GITHUB_OUTPUT"
echo "sfCodeAnalyzerPathToValidate=$sfCodeAnalyzerPathToValidate" >> "$GITHUB_OUTPUT"
env:
VALIDATE_ENTIRE_REPO: ${{ inputs.validateEntireRepo }}
- name: Prettier Check
if: ${{ !cancelled() && steps.paths.outcome == 'success' }}
uses: navikt/sf-platform/.github/actions/prettierCheck@eb5b379e3b162280de8f5b9566cb41c25f0832f5
with:
pathToValidate: ${{ steps.paths.outputs.prettierPathsToValidate }}
- name: Run Salesforce Code Analyzer
id: run-code-analyzer
if: ${{ !cancelled() && steps.paths.outcome == 'success' }}
uses: forcedotcom/run-code-analyzer@e88e434ef258c182fe4cb5d8f0c9f282384fd4b5
with:
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
results-artifact-name: salesforce-code-analyzer-results
github-token: ${{ github.event_name == 'pull_request' && secrets.GITHUB_TOKEN || '' }}
# Code Analyser generates an empty SARIF file if no violations are found.
# In that case this step ensures that the SARIF file is valid and contains a default structure.
# This is required for the SARIF file to be uploaded to GitHub.
- name: Check SARIF file
if: ${{ !cancelled() && steps.paths.outcome == 'success' }}
run: |
echo "::group::Print SARIF file before check"
cat code-analyzer-report.sarif
echo "::endgroup::"
echo "::group::Check SARIF file"
jq --arg wd "$GITHUB_WORKSPACE" '
if .runs == [] then
.runs = [
{
"tool": {
"driver": {
"name": "pmd",
"rules": []
}
},
"results": [],
"invocations": [
{
"executionSuccessful": true,
"workingDirectory": {
"uri": $wd
}
}
]
}
]
else
.
end
' code-analyzer-report.sarif > temp.sarif && mv temp.sarif code-analyzer-report.sarif
echo "::endgroup::"
echo "::group::Print SARIF file after check"
cat code-analyzer-report.sarif
echo "::endgroup::"
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@7e3036b9cd87fc26dd06747b7aa4b96c27aaef3a
if: ${{ !cancelled() && steps.paths.outcome == 'success' && github.ref_name == 'main' }}
with:
sarif_file: code-analyzer-report.sarif
category: salesforce-code-analyzer
- name: Check the Salesforce Code Analyzer outputs to determine whether to fail
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) }}
shell: bash
run: |
set -euo pipefail
# Normalize (default to 0 if unset/empty)
EXIT_CODE=${EXIT_CODE:-0}
NUM_SEV1_VIOLATIONS=${NUM_SEV1_VIOLATIONS:-0}
NUM_SEV2_VIOLATIONS=${NUM_SEV2_VIOLATIONS:-0}
NUM_SEV3_VIOLATIONS=${NUM_SEV3_VIOLATIONS:-0}
NUM_SEV4_VIOLATIONS=${NUM_SEV4_VIOLATIONS:-0}
NUM_SEV5_VIOLATIONS=${NUM_SEV5_VIOLATIONS:-0}
NUM_VIOLATIONS=${NUM_VIOLATIONS:-0}
# Exclude Sev5 (Info) from total count threshold
totalViolations=$(( NUM_VIOLATIONS - NUM_SEV5_VIOLATIONS ))
if (( EXIT_CODE > 0 )); then
echo "::error title=Salesforce Code Analyzer failed::Exit code: ${EXIT_CODE}"
fi
if (( NUM_SEV1_VIOLATIONS > 0 )) || (( totalViolations > MAX_ALLOWED_VIOLATIONS )); then
printf -v details \
"Number of Sev1 Critical violations: %s\n \
Number of Sev2 High violations: %s\n \
Number of Sev3 Medium violations: %s\n \
Number of Sev4 Low violations: %s\n \
Number of Sev5 Info violations: %s\n \
Total (excluding Sev5): %s (max %s)" \
"$NUM_SEV1_VIOLATIONS" "$NUM_SEV2_VIOLATIONS" "$NUM_SEV3_VIOLATIONS" "$NUM_SEV4_VIOLATIONS" "$NUM_SEV5_VIOLATIONS" "$totalViolations" "$MAX_ALLOWED_VIOLATIONS"
# GitHub command: replace literal newlines with %0A
echo "::error title=Salesforce Code Analyzer threshold exceeded::${details//$'\n'/%0A}"
fi
if (( EXIT_CODE > 0 )) || (( NUM_SEV1_VIOLATIONS > 0 )) || (( totalViolations > MAX_ALLOWED_VIOLATIONS )); then
exit 1
fi
env:
MAX_ALLOWED_VIOLATIONS: 10
EXIT_CODE: ${{ steps.run-code-analyzer.outputs.exit-code }}
NUM_SEV1_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev1-violations }}
NUM_SEV2_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev2-violations }}
NUM_SEV3_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev3-violations }}
NUM_SEV4_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev4-violations }}
NUM_SEV5_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-sev5-violations }}
NUM_VIOLATIONS: ${{ steps.run-code-analyzer.outputs.num-violations }}