mirror of
https://github.com/whisperity/CodeChecker-Action.git
synced 2026-02-09 14:47:43 +00:00
Add the parse step that converts and shows analysis results
This commit is contained in:
55
.github/workflows/test.yml
vendored
55
.github/workflows/test.yml
vendored
@@ -2,10 +2,14 @@ name: 'Action test'
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
- 'releases/*'
|
- 'releases/*'
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
# Fetch tests do not produce results, but test the functionality of the
|
# 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'}}"
|
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
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
# Allow continuing the build, we check "expected failure" for misconfiguration.
|
|
||||||
continue-on-error: ${{ (matrix.logfile != '') == (matrix.build-command != '') }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: test/fix_compile_json_paths.sh
|
- run: test/fix_compile_json_paths.sh
|
||||||
- uses: ./
|
- uses: ./
|
||||||
|
id: codechecker
|
||||||
|
# Allow continuing the build, we check "expected failure" for misconfiguration.
|
||||||
|
continue-on-error: ${{ (matrix.logfile != '') == (matrix.build-command != '') }}
|
||||||
with:
|
with:
|
||||||
logfile: ${{ matrix.logfile }}
|
logfile: ${{ matrix.logfile }}
|
||||||
build-command: ${{ matrix.build-command }}
|
build-command: ${{ matrix.build-command }}
|
||||||
analyze-output: ${{ matrix.analyze-output }}
|
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:
|
analyze-cfg:
|
||||||
name: "Analysis: Custom configuration"
|
name: "Analyze: Custom configuration"
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -65,8 +75,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
config: 'test/codechecker.verbose.json'
|
config: 'test/codechecker.verbose.json'
|
||||||
logfile: 'test/simple/compile_commands.json'
|
logfile: 'test/simple/compile_commands.json'
|
||||||
analysis-ctu:
|
analyze-ctu:
|
||||||
name: "Analysis: CTU shortcut"
|
name: "Analyze: CTU shortcut"
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -75,3 +85,36 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
logfile: 'test/ctu/compile_commands.json'
|
logfile: 'test/ctu/compile_commands.json'
|
||||||
ctu: true
|
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 }}
|
||||||
|
|||||||
32
README.md
32
README.md
@@ -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.
|
1. Obtain a package of the LLVM Clang suite's analysers, and CodeChecker.
|
||||||
2. _(Optional)_ Log the build commands to prepare for analysis.
|
2. _(Optional)_ Log the build commands to prepare for analysis.
|
||||||
3. Execute the 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.
|
ℹ️ **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.
|
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
|
# Run the analysis
|
||||||
- uses: whisperity/codechecker-analysis-action
|
- uses: whisperity/codechecker-analysis-action
|
||||||
|
id: codechecker
|
||||||
with:
|
with:
|
||||||
logfile: ${{ github.workspace }}/Build/compile_commands.json
|
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
|
### Projects that need to self-creating a *JSON Compilation Database* or require generated code
|
||||||
@@ -77,8 +85,15 @@ runs:
|
|||||||
|
|
||||||
# Run the analysis
|
# Run the analysis
|
||||||
- uses: whisperity/codechecker-analysis-action
|
- uses: whisperity/codechecker-analysis-action
|
||||||
|
id: codechecker
|
||||||
with:
|
with:
|
||||||
build-command: "cd ${{ github.workspace }}/Build; cmake --build ."
|
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. |
|
| `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. |
|
| `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
|
## 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.
|
The action exposes the following outputs which may be used in a workflow's steps succeeding the analysis.
|
||||||
|
|
||||||
| Variable | Value | Description |
|
| 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. |
|
| `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. |
|
||||||
|
|||||||
32
action.yml
32
action.yml
@@ -39,6 +39,11 @@ inputs:
|
|||||||
default: 'false'
|
default: 'false'
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
|
fail-build-if-reports:
|
||||||
|
description: 'Whether to fail the build if static analysis warnings are emitted.'
|
||||||
|
default: 'false'
|
||||||
|
required: true
|
||||||
|
|
||||||
outputs:
|
outputs:
|
||||||
logfile:
|
logfile:
|
||||||
description: 'The location of the JSON Compilation Database that was used for the analysis.'
|
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.'
|
description: 'The output directory where the raw analysis output was stored to.'
|
||||||
value: ${{ steps.analyze.outputs.OUTPUT_DIR }}
|
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:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
@@ -134,3 +146,23 @@ runs:
|
|||||||
IN_OUTPUT_DIR: ${{ inputs.analyze-output }}
|
IN_OUTPUT_DIR: ${{ inputs.analyze-output }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: ${{ github.action_path }}/src/execute-analysis.sh
|
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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -ex
|
set -x
|
||||||
|
|
||||||
sudo apt-get -y --no-install-recommends install \
|
sudo apt-get -y --no-install-recommends install \
|
||||||
build-essential \
|
build-essential \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -ex
|
set -x
|
||||||
|
|
||||||
if [[ -z "$COMPILATION_DATABASE" ]]; then
|
if [[ -z "$COMPILATION_DATABASE" ]]; then
|
||||||
echo "::error title=Internal error::environment variable 'COMPILATION_DATABASE' missing!"
|
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!"
|
echo "::notice title=Cross Translation Unit analyis::CTU has been enabled, the analysis might take a long time!"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
"$CODECHECKER_PATH"/CodeChecker analyzers \
|
||||||
|
--detail \
|
||||||
|
|| true
|
||||||
|
|
||||||
# Note: Ignoring the result of the analyze command in CTU mode, as we do not
|
# Note: Ignoring the result of the analyze command in CTU mode, as we do not
|
||||||
# wish to break the build on a CTU failure.
|
# wish to break the build on a CTU failure.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -ex
|
set -x
|
||||||
|
|
||||||
if [[ ! -z "$IN_LOGFILE" && ! -z "$IN_COMMAND" ]]; then
|
if [[ ! -z "$IN_LOGFILE" && ! -z "$IN_COMMAND" ]]; then
|
||||||
echo "::error title=Configuration error::'logfile' and 'build-command' both specified!"
|
echo "::error title=Configuration error::'logfile' and 'build-command' both specified!"
|
||||||
|
|||||||
54
src/parse-results.sh
Executable file
54
src/parse-results.sh
Executable 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
|
||||||
Reference in New Issue
Block a user