mirror of
https://github.com/whisperity/CodeChecker-Action.git
synced 2026-02-09 06:37:44 +00:00
feat: Add support for executing the report-converter tool
This commit is contained in:
30
.github/workflows/test.yml
vendored
30
.github/workflows/test.yml
vendored
@@ -61,7 +61,6 @@ 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
|
||||
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: test/fix_compile_json_paths.sh
|
||||
@@ -105,6 +104,29 @@ jobs:
|
||||
- name: "Reject test if previous step did not produce CTU finding"
|
||||
run: cat ${{ steps.codechecker.outputs.result-log }} | grep "Dereference of null pointer"
|
||||
|
||||
report-converter:
|
||||
name: "Report converter: PyLint"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: "Install PyLint"
|
||||
run: |
|
||||
sudo apt-get install -y pylint
|
||||
- name: "Perform static analysis explicitly with PyLint"
|
||||
run: |
|
||||
pylint test/report-converter/testpylint.py \
|
||||
-f json \
|
||||
--exit-zero \
|
||||
> ./pylint_reports.json
|
||||
- uses: ./
|
||||
id: codechecker
|
||||
with:
|
||||
report-converter: true
|
||||
original-analyser: 'pylint'
|
||||
original-analysis-output: './pylint_reports.json'
|
||||
- name: "Reject test if previous step did not produce findings"
|
||||
run: cat ${{ steps.codechecker.outputs.result-log }} | grep "Explicit return in __init__"
|
||||
|
||||
reports-errors:
|
||||
name: "Parse: Findings are reported"
|
||||
runs-on: ubuntu-20.04
|
||||
@@ -219,7 +241,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
env:
|
||||
CODECHECKER_VERSION: '6.18.1'
|
||||
CODECHECKER_VERSION: '6.19.1'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: test/fix_compile_json_paths.sh
|
||||
@@ -240,11 +262,11 @@ jobs:
|
||||
name: "Diff: New findings are discovered and reported"
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
CODECHECKER_VERSION: '6.18.1'
|
||||
CODECHECKER_VERSION: '6.19.1'
|
||||
# This time, we do not need authentication, so test with the official Docker subsystem.
|
||||
services:
|
||||
codechecker-server:
|
||||
image: 'codechecker/codechecker-web:6.18.1'
|
||||
image: 'codechecker/codechecker-web:6.19.1'
|
||||
ports:
|
||||
- 8001:8001/tcp
|
||||
steps:
|
||||
|
||||
74
README.md
74
README.md
@@ -1,10 +1,10 @@
|
||||
# [CodeChecker](http://github.com/Ericsson/CodeChecker/) C++ Static Analysis action
|
||||
|
||||
GitHub Action to execute static analysis over C-family projects (C, C++,
|
||||
Objective-C) using the [Clang](http://clang.llvm.org/) infrastructure and
|
||||
[CodeChecker](http://github.com/Ericsson/CodeChecker/) as its driver.
|
||||
GitHub Action to execute static analysis over using [CodeChecker](http://github.com/Ericsson/CodeChecker/) as its driver.
|
||||
For C-family projects (C, C++, Objective-C, CUDA, etc.), CodeChecker supports driving the static analysis programs of [Clang](http://clang.llvm.org).
|
||||
Several other static analysers' output can be integrated into CodeChecker through the [report converter](http://codechecker.readthedocs.io/en/latest/tools/report-converter/).
|
||||
|
||||
## Overview
|
||||
## Overview (for C-family projects)
|
||||
|
||||
⚠️ **CAUTION! This action has been written with commands that target Ubuntu-based distributions!**
|
||||
|
||||
@@ -238,6 +238,60 @@ runs:
|
||||
exit 1
|
||||
```
|
||||
|
||||
## Overview (for other analyses through the _report-converter_)
|
||||
|
||||
⚠️ **CAUTION! This action has been written with commands that target Ubuntu-based distributions!**
|
||||
|
||||
This single action composite script encompasses the following steps:
|
||||
|
||||
1. Obtain a package of CodeChecker.
|
||||
3. Use the `report-converter` to convert other analysers' reports to CodeChecker's format.
|
||||
4. Show the analysis results in the CI log, and create HTML reports that can be uploaded as an artefact. (Uploading is to be done by the user!)
|
||||
5. _(Optional)_ Check for the current commit introducing new bug reports against a known state. (Good for pull requests!)
|
||||
6. _(Optional)_ Upload the results to a running _CodeChecker server_. (Good for the main project!)
|
||||
|
||||
|
||||
ℹ️ **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.
|
||||
|
||||
Please refer to the documentation of the analyser of your choice for this.
|
||||
CodeChecker does **NOT** support driving the analysis through external tools, but if a successful analysis had been done, it can convert and store the results.
|
||||
|
||||
```yaml
|
||||
job:
|
||||
steps:
|
||||
# Check YOUR project out!
|
||||
- name: "Check out repository"
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Perform the analysis. Details vary between analysers!
|
||||
# Example for "PyLint" added below!
|
||||
- name: "Analyse with PyLint"
|
||||
run: |
|
||||
sudo apt-get -y install pylint
|
||||
pylint -f json --exit-zero myproject > pylint_reports.json
|
||||
|
||||
# Run the conversion
|
||||
- uses: whisperity/codechecker-analysis-action@v1
|
||||
id: codechecker
|
||||
with:
|
||||
report-converter: true
|
||||
original-analyser: "pylint"
|
||||
original-analysis-output: "pylint_reports.json"
|
||||
|
||||
# Upload the results (after conversion by CodeChecker) to the CI.
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: "CodeChecker Bug Reports"
|
||||
path: ${{ steps.codechecker.outputs.result-html-dir }}
|
||||
```
|
||||
|
||||
### Uploading results and acting as a CI gate
|
||||
|
||||
The _report-converter_ tool converts the output of various analysers to the common format used by CodeChecker.
|
||||
Once the conversion is done, the rest of the action's features can execute in the same fashion as for C/C++ projects.
|
||||
Please refer to earlier parts of the documentation for the configuration of these features.
|
||||
|
||||
## Action configuration
|
||||
|
||||
| Variable | Default | Description |
|
||||
@@ -276,6 +330,16 @@ runs:
|
||||
|
||||
🔖 Read more about [`CodeChecker parse`](http://codechecker.readthedocs.io/en/latest/analyzer/user_guide/#parse) in the official documentation.
|
||||
|
||||
### Report conversion configuration
|
||||
|
||||
🔖 Read more about the [`report-converter`](http://codechecker.readthedocs.io/en/latest/tools/report-converter/) in the official documentation.
|
||||
|
||||
| Variable | Default | Description |
|
||||
|----------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `report-converter` | `false` | If set to `true`, the job will execute _report conversion_ from other analysers instead of driving the static analysis by itself. |
|
||||
| `original-analyser` | | The "type" of the analysis that **had been performed** earlier. Passed as mandatory input to the `report-converter` executable. |
|
||||
| `original-analysis-output` | | The file or directory where the results of the third-party analyser are available. Passed as mandatory input to the `report-converter` executable. |
|
||||
|
||||
### Diff configuration
|
||||
|
||||
🔖 Read more about [`CodeChecker cmd diff`](http://codechecker.readthedocs.io/en/latest/analyzer/web_guide/#cmd-diff) in the official documentation.
|
||||
@@ -310,7 +374,7 @@ The action exposes the following outputs which may be used in a workflow's steps
|
||||
|
||||
| Variable | Value | Description |
|
||||
|--------------------|-------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `analyze-output` | Auto-generated, or `analyze-output` input | The directory where the **raw** analysis output files are available. |
|
||||
| `analyze-output` | Auto-generated, or `analyze-output` input | The directory where the **raw** analysis output files (either created by the analysers, or by the converter) are available. |
|
||||
| `logfile` | Auto-generated, or `logfile` input | The JSON Compilation Database of the analysis that was executed. |
|
||||
| `diff-html-dir` | Auto-generated. | The directory where the **user-friendly HTML** bug reports were generated to about the **new** findings (if `diff` was enabled). |
|
||||
| `diff-result-log` | Auto-generated. | `CodeChecker cmd diff`'s output log file which contains the **new** findings dumped into it. |
|
||||
|
||||
61
action.yml
61
action.yml
@@ -47,6 +47,17 @@ inputs:
|
||||
required: true
|
||||
default: 'true'
|
||||
|
||||
report-converter:
|
||||
description: 'Whether to perform report conversion from analyses executed by third-party analysers instead of driving the analysis via CodeChecker directly.'
|
||||
required: true
|
||||
default: 'false'
|
||||
original-analyser:
|
||||
description: 'The type of the third-party analyser which performed the analysis. Passed to the report converter executable, as a mandatory input parameter.'
|
||||
required: false
|
||||
original-analysis-output:
|
||||
description: 'The location of the analysis data emitted by the third-party analyser. Passed to the report converter executable, as a mandatory input parameter.'
|
||||
required: false
|
||||
|
||||
diff:
|
||||
description: 'Whether to enable calculating the different of the current analysis results against a run stored on a CodeChecker server. If enabled, other flags, such as "diff-url" must also be set.'
|
||||
required: true
|
||||
@@ -89,8 +100,8 @@ outputs:
|
||||
value: ${{ steps.log.outputs.COMPILATION_DATABASE }}
|
||||
|
||||
analyze-output:
|
||||
description: 'The output directory where the raw analysis output was stored to.'
|
||||
value: ${{ steps.analyze.outputs.OUTPUT_DIR }}
|
||||
description: 'The output directory where the raw analysis or converted output was stored to.'
|
||||
value: ${{ steps.analyze-or-report.outputs.OUTPUT_DIR }}
|
||||
|
||||
warnings:
|
||||
description: 'Whether the static analyser(s) reported any findings.'
|
||||
@@ -135,7 +146,7 @@ runs:
|
||||
|
||||
- name: "Install LLVM (${{ inputs.llvm-version }})"
|
||||
id: llvm
|
||||
if: ${{ inputs.llvm-version != 'ignore' }}
|
||||
if: ${{ inputs.llvm-version != 'ignore' && inputs.report-converter != 'true' }}
|
||||
env:
|
||||
IN_LLVM_VERSION: ${{ inputs.llvm-version }}
|
||||
shell: bash
|
||||
@@ -159,6 +170,7 @@ runs:
|
||||
|
||||
- name: "Prepare JSON Compilation Database"
|
||||
id: log
|
||||
if: ${{ inputs.report-converter != 'true' }}
|
||||
env:
|
||||
ACTION_NAME: ${{ github.action }}
|
||||
CODECHECKER_PATH: ${{ steps.codechecker.outputs.PATH }}
|
||||
@@ -170,8 +182,9 @@ runs:
|
||||
shell: bash
|
||||
run: ${{ github.action_path }}/src/get-or-create-build-json.sh
|
||||
|
||||
- name: "Execute static analysis"
|
||||
- name: "Execute static analysis for C/C++"
|
||||
id: analyze
|
||||
if: ${{ inputs.report-converter != 'true' }}
|
||||
env:
|
||||
CODECHECKER_PATH: ${{ steps.codechecker.outputs.PATH }}
|
||||
COMPILATION_DATABASE: ${{ steps.log.outputs.COMPILATION_DATABASE }}
|
||||
@@ -179,18 +192,48 @@ runs:
|
||||
|
||||
IN_CONFIGFILE: ${{ inputs.config }}
|
||||
IN_CTU: ${{ inputs.ctu }}
|
||||
IN_FLAGS: ${{ inputs.analyze-options }}
|
||||
IN_IGNORE_CRASHES: ${{ inputs.ignore-analyze-crashes }}
|
||||
IN_OUTPUT_DIR: ${{ inputs.analyze-output }}
|
||||
shell: bash
|
||||
run: ${{ github.action_path }}/src/execute-analysis.sh
|
||||
|
||||
- name: "Parse and convert results"
|
||||
- name: "Perform report-converter"
|
||||
id: report-convert
|
||||
if: ${{ inputs.report-converter == 'true' }}
|
||||
env:
|
||||
CODECHECKER_PATH: ${{ steps.codechecker.outputs.PATH }}
|
||||
GITHUB_ACTION_NAME: ${{ github.action }}
|
||||
|
||||
IN_ORIGINAL_ANALYSER: ${{ inputs.original-analyser }}
|
||||
IN_ORIGINAL_ANALYSIS_OUTPUT: ${{ inputs.original-analysis-output }}
|
||||
IN_IGNORE_CRASHES: ${{ inputs.ignore-analyze-crashes }}
|
||||
IN_OUTPUT_DIR: ${{ inputs.analyze-output }}
|
||||
shell: bash
|
||||
run: ${{ github.action_path }}/src/report-converter.sh
|
||||
|
||||
# This step is needed because it is forbidden to reuse the 'id' of a step,
|
||||
# even if the two steps taking the same 'id' are mutually exclusive.
|
||||
- name: "(Internal: set output variables for steps after analyze/convert)"
|
||||
id: analyze-or-report
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ ! -z "$CODECHECKER_ACTION_DEBUG" ]]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
if [[ "${{ inputs.report-converter }}" != "true" ]]
|
||||
then
|
||||
echo "::set-output name=OUTPUT_DIR::${{ steps.analyze.outputs.OUTPUT_DIR }}"
|
||||
else
|
||||
echo "::set-output name=OUTPUT_DIR::${{ steps.report-convert.outputs.OUTPUT_DIR }}"
|
||||
fi
|
||||
|
||||
- name: "Parse and convert results to HTML"
|
||||
id: parse
|
||||
env:
|
||||
PROJECT_PATH: ${{ github.workspace }}
|
||||
CODECHECKER_PATH: ${{ steps.codechecker.outputs.PATH }}
|
||||
RAW_RESULT_DIR: ${{ steps.analyze.outputs.OUTPUT_DIR }}
|
||||
RAW_RESULT_DIR: ${{ steps.analyze-or-report.outputs.OUTPUT_DIR }}
|
||||
|
||||
IN_CONFIGFILE: ${{ inputs.config }}
|
||||
shell: bash
|
||||
@@ -220,7 +263,7 @@ runs:
|
||||
PROJECT_PATH: ${{ github.workspace }}
|
||||
CODECHECKER_PATH: ${{ steps.codechecker.outputs.PATH }}
|
||||
CODECHECKER_DIFF_RUN_NAME: ${{ steps.diff-pre.outputs.RUN_NAME }}
|
||||
RAW_RESULT_DIR: ${{ steps.analyze.outputs.OUTPUT_DIR }}
|
||||
RAW_RESULT_DIR: ${{ steps.analyze-or-report.outputs.OUTPUT_DIR }}
|
||||
|
||||
IN_CONFIGFILE: ${{ inputs.config }}
|
||||
IN_DIFF_URL: ${{ inputs.diff-url }}
|
||||
@@ -251,7 +294,7 @@ runs:
|
||||
CODECHECKER_PATH: ${{ steps.codechecker.outputs.PATH }}
|
||||
CODECHECKER_STORE_RUN_NAME: ${{ steps.store-pre.outputs.RUN_NAME }}
|
||||
CODECHECKER_STORE_RUN_TAG: ${{ steps.store-pre.outputs.RUN_TAG }}
|
||||
RAW_RESULT_DIR: ${{ steps.analyze.outputs.OUTPUT_DIR }}
|
||||
RAW_RESULT_DIR: ${{ steps.analyze-or-report.outputs.OUTPUT_DIR }}
|
||||
|
||||
IN_CONFIGFILE: ${{ inputs.config }}
|
||||
IN_STORE_URL: ${{ inputs.store-url }}
|
||||
|
||||
48
src/report-converter.sh
Executable file
48
src/report-converter.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
if [[ ! -z "$CODECHECKER_ACTION_DEBUG" ]]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
echo "::group::Preparing for conversion"
|
||||
if [[ -z "$IN_ORIGINAL_ANALYSER" ]]; then
|
||||
echo "::error title=Internal error::environment variable 'IN_ORIGINAL_ANALYSER' missing!"
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z "$IN_ORIGINAL_ANALYSIS_OUTPUT" ]]; then
|
||||
echo "::error title=Internal error::environment variable 'IN_ORIGINAL_ANALYSIS_OUTPUT' missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
OUTPUT_DIR="$IN_OUTPUT_DIR"
|
||||
if [[ -z "$OUTPUT_DIR" ]]; then
|
||||
OUTPUT_DIR=~/"$GITHUB_ACTION_NAME"_Results
|
||||
fi
|
||||
|
||||
mkdir -pv "$(dirname $"OUTPUT_DIR")"
|
||||
|
||||
# Report-Converter does not support a config file. :(
|
||||
# if [[ ! -z "$IN_CONFIGFILE" ]]; then
|
||||
# CONFIG_FLAG_1="--config"
|
||||
# CONFIG_FLAG_2=$IN_CONFIGFILE
|
||||
# echo "Using configuration file \"$IN_CONFIGFILE\"!"
|
||||
# fi
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Performing conversion"
|
||||
"$CODECHECKER_PATH"/report-converter \
|
||||
"$IN_ORIGINAL_ANALYSIS_OUTPUT" \
|
||||
--type "$IN_ORIGINAL_ANALYSER" \
|
||||
--output "$OUTPUT_DIR" \
|
||||
--export plist
|
||||
EXIT_CODE=$?
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ $EXIT_CODE -ne 0 && "$IN_IGNORE_CRASHES" == "true" ]]; then
|
||||
# In general it is a good idea not to destroy the entire job just because a
|
||||
# few translation units failed. Crashes are, unfortunately, usual.
|
||||
echo "::warning title=Report Converter crashed on some inputs::Some of the analysis results failed to convert due to internal error."
|
||||
EXIT_CODE=0
|
||||
fi
|
||||
|
||||
echo "::set-output name=OUTPUT_DIR::$OUTPUT_DIR"
|
||||
exit $EXIT_CODE
|
||||
4
test/report-converter/testpylint.py
Normal file
4
test/report-converter/testpylint.py
Normal file
@@ -0,0 +1,4 @@
|
||||
class ReturnInInitE0101:
|
||||
def __init__(self, value):
|
||||
# Should trigger "return-in-init"
|
||||
return value
|
||||
Reference in New Issue
Block a user