Add the parse step that converts and shows analysis results

This commit is contained in:
Whisperity
2021-11-28 15:50:11 +01:00
parent 93e0b4ff7d
commit 23bc2df6a7
7 changed files with 174 additions and 13 deletions

View File

@@ -2,10 +2,14 @@ name: 'Action test'
on:
pull_request:
paths-ignore:
- '**.md'
push:
branches:
- master
- 'releases/*'
paths-ignore:
- '**.md'
jobs:
# Fetch tests do not produce results, but test the functionality of the
@@ -43,20 +47,26 @@ jobs:
name: "Simple analysis: ${{ matrix.logfile && 'logfile' || 'no logfile' }}, ${{ matrix.build-command && 'build-command' || 'no build-command' }}, ${{ matrix.analyze-output && 'analyze-output' || 'no analyze-output'}}"
runs-on: ubuntu-20.04
# Allow continuing the build, we check "expected failure" for misconfiguration.
continue-on-error: ${{ (matrix.logfile != '') == (matrix.build-command != '') }}
steps:
- uses: actions/checkout@v2
- run: test/fix_compile_json_paths.sh
- uses: ./
id: codechecker
# Allow continuing the build, we check "expected failure" for misconfiguration.
continue-on-error: ${{ (matrix.logfile != '') == (matrix.build-command != '') }}
with:
logfile: ${{ matrix.logfile }}
build-command: ${{ matrix.build-command }}
analyze-output: ${{ matrix.analyze-output }}
- name: "Reject test if previous step did not fail"
if: ${{ steps.codechecker.continue-on-error && steps.codechecker.outcome != 'failure' }}
run: |
echo "::error title=Step with expected failure passed::"
exit 1
analysis-cfg:
name: "Analysis: Custom configuration"
analyze-cfg:
name: "Analyze: Custom configuration"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
@@ -65,8 +75,8 @@ jobs:
with:
config: 'test/codechecker.verbose.json'
logfile: 'test/simple/compile_commands.json'
analysis-ctu:
name: "Analysis: CTU shortcut"
analyze-ctu:
name: "Analyze: CTU shortcut"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
@@ -75,3 +85,36 @@ jobs:
with:
logfile: 'test/ctu/compile_commands.json'
ctu: true
fail-on-error:
name: "Parse: Fail the build on error"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- run: test/fix_compile_json_paths.sh
- uses: ./
id: codechecker
continue-on-error: true
with:
logfile: 'test/simple/compile_commands.json'
fail-build-if-reports: true
- name: "Reject test if previous step did not fail"
if: ${{ steps.codechecker.outcome != 'failure' }}
run: |
echo "::error title=fail-on-error test passed::Expected the 'parse' step to breka the build."
exit 1
parse-html:
name: "Parse: Generate and upload report HTML artefact"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- run: test/fix_compile_json_paths.sh
- uses: ./
id: codechecker
with:
logfile: 'test/simple/compile_commands.json'
- uses: actions/upload-artifact@v2
with:
name: "Parse HTML test results"
path: ${{ steps.codechecker.outputs.result-html-dir }}

View File

@@ -13,6 +13,7 @@ This single action composite script encompasses the following steps:
1. Obtain a package of the LLVM Clang suite's analysers, and CodeChecker.
2. _(Optional)_ Log the build commands to prepare for analysis.
3. Execute the analysis.
4. Show the analysis results in the CI log, and create HTML reports that can be uploaded as an artefact.
**Note:** Static analysis can be a time-consuming process.
It's recommended that the static analysis step is not sequential with the rest of a CI execution, but either runs as its own job in a workflow, or a completely distinct workflow altogether.
@@ -48,8 +49,15 @@ runs:
# Run the analysis
- uses: whisperity/codechecker-analysis-action
id: codechecker
with:
logfile: ${{ github.workspace }}/Build/compile_commands.json
# Upload the results to the CI.
- uses: actions/upload-artifact@v2
with:
name: "CodeChecker Bug Reports"
path: ${{ steps.codechecker.outputs.result-html-dir }}
```
### Projects that need to self-creating a *JSON Compilation Database* or require generated code
@@ -77,8 +85,15 @@ runs:
# Run the analysis
- uses: whisperity/codechecker-analysis-action
id: codechecker
with:
build-command: "cd ${{ github.workspace }}/Build; cmake --build ."
# Upload the results to the CI.
- uses: actions/upload-artifact@v2
with:
name: "CodeChecker Bug Reports"
path: ${{ steps.codechecker.outputs.result-html-dir }}
```
@@ -115,12 +130,25 @@ runs:
| `analyze-output` | (auto-generated) | The directory where the **raw** analysis output should be stored. |
| `ctu` | `false` | Enable [Cross Translation Unit analysis](http://clang.llvm.org/docs/analyzer/user-docs/CrossTranslationUnit.html) in the _Clang Static Analyzer_. ⚠️ **CAUTION!** _CTU_ analysis might take a very long time, and CTU is officially regarded as experimental. |
### Report configuration
🔖 Read more about [`CodeChecker parse`](http://codechecker.readthedocs.io/en/latest/analyzer/user_guide/#parse) in the official documentation.
**Note:** Due to static analysis being potentially noisy and the reports being unwieldy to fix, the default behaviour is to only report the findings but do not break the CI.
| Variable | Default | Description |
|-------------------------|---------|-----------------------------------------------------------------------------------|
| `fail-build-if-reports` | `false` | If set to `true`, the build will be set to broken if the static analysers report. |
## Action *`outputs`* to use in further steps
The action exposes the following outputs which may be used in a workflow's steps succeeding the analysis.
| Variable | Value | Description |
|------------------|-------------------------------------------|----------------------------------------------------------------------|
| `logfile` | Auto-generated, or `logfile` input | The JSON Compilation Database of the analysis that was executed. |
| `analyze-output` | Auto-generated, or `analyze-output` input | The directory where the **raw** analysis output files are available. |
| Variable | Value | Description |
|-------------------|-------------------------------------------|-------------------------------------------------------------------------------|
| `analyze-output` | Auto-generated, or `analyze-output` input | The directory where the **raw** analysis output files are available. |
| `logfile` | Auto-generated, or `logfile` input | The JSON Compilation Database of the analysis that was executed. |
| `result-html-dir` | Auto-generated. | The directory where the **user-friendly HTML** bug reports were generated to. |
| `warnings` | `true` or `false` | Whether the static analysers reported any findings. |

View File

@@ -39,6 +39,11 @@ inputs:
default: 'false'
required: true
fail-build-if-reports:
description: 'Whether to fail the build if static analysis warnings are emitted.'
default: 'false'
required: true
outputs:
logfile:
description: 'The location of the JSON Compilation Database that was used for the analysis.'
@@ -48,6 +53,13 @@ outputs:
description: 'The output directory where the raw analysis output was stored to.'
value: ${{ steps.analyze.outputs.OUTPUT_DIR }}
warnings:
description: 'Whether the static analyser(s) reported any findings.'
value: ${{ steps.parse.outputs.HAS_FINDINGS }}
result-html-dir:
description: 'The output directory where the user-friendly HTML reports were stored to.'
value: ${{ steps.parse.outputs.HTML_DIR }}
runs:
using: "composite"
steps:
@@ -134,3 +146,23 @@ runs:
IN_OUTPUT_DIR: ${{ inputs.analyze-output }}
shell: bash
run: ${{ github.action_path }}/src/execute-analysis.sh
- name: "Parse and convert results"
id: parse
env:
PROJECT_PATH: ${{ github.workspace }}
CODECHECKER_PATH: ${{ steps.codechecker.outputs.PATH }}
RAW_RESULT_DIR: ${{ steps.analyze.outputs.OUTPUT_DIR }}
IN_CONFIGFILE: ${{ inputs.config }}
IN_FAIL_IF_REPORTS: ${{ inputs.fail-build-if-reports }}
IN_OUTPUT_DIR: ${{ inputs.analyze-output }}
shell: bash
run: ${{ github.action_path }}/src/parse-results.sh
- name: "Fail the build if requested and warnings detected"
if: ${{ steps.parse.outputs.HAS_FINDINGS == 'true' && inputs.fail-build-if-reports == 'true' }}
shell: bash
run: |
echo "Static analysis reported warnings, and user requested build breaking."
exit 1

View File

@@ -1,5 +1,5 @@
#!/bin/bash
set -ex
set -x
sudo apt-get -y --no-install-recommends install \
build-essential \

View File

@@ -1,5 +1,5 @@
#!/bin/bash
set -ex
set -x
if [[ -z "$COMPILATION_DATABASE" ]]; then
echo "::error title=Internal error::environment variable 'COMPILATION_DATABASE' missing!"
@@ -25,6 +25,10 @@ if [[ "$IN_CTU" == "true" ]]; then
echo "::notice title=Cross Translation Unit analyis::CTU has been enabled, the analysis might take a long time!"
fi
"$CODECHECKER_PATH"/CodeChecker analyzers \
--detail \
|| true
# Note: Ignoring the result of the analyze command in CTU mode, as we do not
# wish to break the build on a CTU failure.

View File

@@ -1,5 +1,5 @@
#!/bin/bash
set -ex
set -x
if [[ ! -z "$IN_LOGFILE" && ! -z "$IN_COMMAND" ]]; then
echo "::error title=Configuration error::'logfile' and 'build-command' both specified!"

54
src/parse-results.sh Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/bash
set -x
if [[ -z "$PROJECT_PATH" ]]; then
echo "::error title=Internal error::environment variable 'PROJECT_PATH' missing!"
exit 1
fi
if [[ -z "$RAW_RESULT_DIR" ]]; then
echo "::error title=Internal error::environment variable 'RAW_RESULT_DIR' missing!"
exit 1
fi
OUTPUT_DIR="$IN_OUTPUT_DIR"
if [[ -z "$OUTPUT_DIR" ]]; then
OUTPUT_DIR=~/"$ACTION_NAME"_Results-HTML
fi
mkdir -pv "$(dirname $"OUTPUT_DIR")"
if [[ ! -z "$IN_CONFIGFILE" ]]; then
CONFIG_FLAG_1="--config"
CONFIG_FLAG_2=$IN_CONFIGFILE
echo "Using configuration file \"$IN_CONFIGFILE\"!"
fi
"$CODECHECKER_PATH"/CodeChecker parse \
"$RAW_RESULT_DIR" \
--export "html" \
--output "$OUTPUT_DIR" \
--trim-path-prefix "$PROJECT_PATH" \
|| true
echo "::set-output name=HTML_DIR::$OUTPUT_DIR"
"$CODECHECKER_PATH"/CodeChecker parse \
"$RAW_RESULT_DIR" \
--trim-path-prefix "$PROJECT_PATH"
EXIT_CODE=$?
if [[ "$EXIT_CODE" == "2" ]]; then
echo "::set-output name=HAS_FINDINGS::true"
if [[ "$IN_FAIL_IF_REPORTS" == "true" ]]; then
echo "::notice title=Static analysis suppressed::CodeChecker static analyser found bug reports, but the build job is configured to suppress it."
fi
# Let the jobs continue. If there were failures, the action script will break
# the build in a later step. (After a potential upload to server.)
EXIT_CODE=0
else
echo "::set-output name=HAS_FINDINGS::false"
fi
exit $EXIT_CODE