From 7e08d92e770057790d7554694c4f7bfa5945c701 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Wed, 2 Nov 2022 15:02:13 -0400 Subject: [PATCH] Fix #607, rework static-analysis workflow Updates the static analysis workflow: - Make it work with the latest Ubuntu and Cppcheck - Allow callers to pass in a project configuration to get "real" macro definitions and include paths - Streamlined - only generate XML outputs, then use XSLT to convert that to text, rather than running the tool twice. - Streamlined - merge the two XML outputs into one, before converting to sarif and uploading - Streamlined - Call the sarif conversion tool directly, rather than going through a 3rd party action. --- .github/scripts/cppcheck-merge.xslt | 25 +++++ .github/scripts/cppcheck-xml2text.xslt | 17 ++++ .github/workflows/static-analysis-reuse.yml | 7 +- .github/workflows/static-analysis.yml | 100 ++++++++++++++------ 4 files changed, 115 insertions(+), 34 deletions(-) create mode 100644 .github/scripts/cppcheck-merge.xslt create mode 100644 .github/scripts/cppcheck-xml2text.xslt diff --git a/.github/scripts/cppcheck-merge.xslt b/.github/scripts/cppcheck-merge.xslt new file mode 100644 index 000000000..b6d8fcfe6 --- /dev/null +++ b/.github/scripts/cppcheck-merge.xslt @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/.github/scripts/cppcheck-xml2text.xslt b/.github/scripts/cppcheck-xml2text.xslt new file mode 100644 index 000000000..032bb8226 --- /dev/null +++ b/.github/scripts/cppcheck-xml2text.xslt @@ -0,0 +1,17 @@ + + + +## CppCheck Summary + +| error | warning | style | performance | portability | information | +| --- | --- | --- | --- | --- | --- | +| | | | | | | + +| severity | file | line | issue | +| --- | --- | --- | --- | +| | | | | + + +** error(s) reported** + + diff --git a/.github/workflows/static-analysis-reuse.yml b/.github/workflows/static-analysis-reuse.yml index 44688b621..225b4a249 100644 --- a/.github/workflows/static-analysis-reuse.yml +++ b/.github/workflows/static-analysis-reuse.yml @@ -1,10 +1,9 @@ -name: Reuse Static Analysis +name: Bundle Static Analysis on: - push: - pull_request: + workflow_dispatch: jobs: static-analysis: name: Static Analysis - uses: nasa/cFS/.github/workflows/static-analysis.yml@main \ No newline at end of file + uses: nasa/cFS/.github/workflows/static-analysis.yml@main diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index decb2fda6..ae18c926c 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -7,6 +7,14 @@ on: description: 'Directory List' type: string default: '' + cmake-project-options: + description: 'Command line options to pass to CMake' + type: string + default: '' + cppcheck-xslt-path: + description: 'Path to XSLT file for translating cppcheck XML output' + type: string + default: 'nasa/cFS/main/.github/scripts' # Force bash to apply pipefail option so pipeline failures aren't masked defaults: @@ -14,8 +22,9 @@ defaults: shell: bash jobs: - #Checks for duplicate actions. Skips push actions if there is a matching or duplicate pull-request action. + #Checks for duplicate actions. Skips push actions if there is a matching or duplicate pull-request action. check-for-duplicates: + name: Check for Duplicates runs-on: ubuntu-latest # Map a step output to a job output outputs: @@ -33,48 +42,79 @@ jobs: needs: check-for-duplicates if: ${{ needs.check-for-duplicates.outputs.should_skip != 'true' }} name: Run cppcheck - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false - steps: + steps: - name: Install cppcheck - run: sudo apt-get install cppcheck -y + run: sudo apt-get install cppcheck xsltproc -y + + - name: Install sarif tool + run: npm install @microsoft/sarif-multitool - # Checks out a copy of the cfs bundle - - name: Checkout code - uses: actions/checkout@v2 + - name: Fetch conversion XSLT + run: | + wget -O cppcheck-xml2text.xslt https://raw.githubusercontent.com/${{ inputs.cppcheck-xslt-path }}/cppcheck-xml2text.xslt + wget -O cppcheck-merge.xslt https://raw.githubusercontent.com/${{ inputs.cppcheck-xslt-path }}/cppcheck-merge.xslt + + # Checks out a copy of the reference repository + - name: Checkout subject repository + uses: actions/checkout@v3 with: + path: source submodules: true - - name: Run general cppcheck - run: cppcheck --force --inline-suppr . 2> general_cppcheck_err.txt - - - name: Check for general errors + # For a CMake-based project, get the list of files by setting up a build with CMAKE_EXPORT_COMPILE_COMMANDS=ON and + # referencing the compile_commands.json file produced by the tool. This will capture the correct include paths and + # compile definitions based on how the source is actually compiled. + - name: CMake Setup + if: ${{ inputs.cmake-project-options != '' }} + run: | + cmake -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/staging -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=debug ${{ inputs.cmake-project-options }} -S source -B build + echo CPPCHECK_OPTS=--project="$GITHUB_WORKSPACE/build/compile_commands.json" >> $GITHUB_ENV + + # For a Non-CMake project, just pass the base source directory of the repo. This will examine all .c files in the repo, + # but it will not see the macro definitions, and thus may not correctly interpret macro usage. + - name: Non-CMake Setup + if: ${{ inputs.cmake-project-options == '' }} run: | - if [[ -s general_cppcheck_err.txt ]]; - then - cat general_cppcheck_err.txt - exit -1 - fi - - # Run strict static analysis for embedded portions of cfe, osal, and psp - - name: Strict cppcheck + echo CPPCHECK_OPTS="$GITHUB_WORKSPACE/source" >> $GITHUB_ENV + + - name: Run general cppcheck + run: cppcheck --force --inline-suppr --xml $CPPCHECK_OPTS 2> cppcheck_err.xml + + # Run strict static analysis for selected portions of source code + - name: Run Strict cppcheck if: ${{ inputs.strict-dir-list !='' }} - run: cppcheck --force --inline-suppr --std=c99 --language=c --enable=warning,performance,portability,style --suppress=variableScope --inconclusive ${{ inputs.strict-dir-list }} 2> strict_cppcheck_err.txt + working-directory: ${{ github.workspace }}/source + run: cppcheck --force --inline-suppr --std=c99 --language=c --enable=warning,performance,portability,style --suppress=variableScope --inconclusive --xml ${{ inputs.strict-dir-list }} 2> ../strict_cppcheck_err.xml - - name: Check for strict errors + - name: Merge cppcheck results if: ${{ inputs.strict-dir-list !='' }} run: | - if [[ -s strict_cppcheck_err.txt ]]; - then - cat strict_cppcheck_err.txt - exit -1 - fi - - - name: Archive Static Analysis Artifacts - uses: actions/upload-artifact@v2 + mv cppcheck_err.xml general_cppcheck_err.xml + xsltproc --stringparam merge_file strict_cppcheck_err.xml cppcheck-merge.xslt general_cppcheck_err.xml > cppcheck_err.xml + + - name: Convert cppcheck results to SARIF + run: npx "@microsoft/sarif-multitool" convert "cppcheck_err.xml" --tool "CppCheck" --output "cppcheck_err.sarif" --force + + - name: Convert cppcheck results to Markdown + run: xsltproc cppcheck-xml2text.xslt cppcheck_err.xml | tee $GITHUB_STEP_SUMMARY cppcheck_err.txt + + - name: Upload SARIF results + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: ${{ github.workspace }}/cppcheck_err.sarif + checkout_path: ${{ github.workspace }}/source + category: 'cppcheck' + + - name: Archive static analysis artifacts + uses: actions/upload-artifact@v3 with: name: cppcheck-errors - path: ./*cppcheck_err.txt + path: ./*cppcheck_err.* + + - name: Check for reported errors + run: tail -n 1 cppcheck_err.txt | grep -q '^\*\*0 error(s) reported\*\*$'