mirror of
https://github.com/whisperity/CodeChecker-Action.git
synced 2026-02-09 06:37:44 +00:00
feat: Expose and wire in the store command
This commit is contained in:
72
.github/workflows/test.yml
vendored
72
.github/workflows/test.yml
vendored
@@ -121,3 +121,75 @@ jobs:
|
||||
with:
|
||||
name: "Parse HTML test results"
|
||||
path: ${{ steps.codechecker.outputs.result-html-dir }}
|
||||
|
||||
store:
|
||||
name: "Store: Authenticated local store of single result"
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
CODECHECKER_VERSION: '6.18.0'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# Need to do this manually because the server for this test has to have
|
||||
# authentication on, with a known username and password.
|
||||
- name: "Set up CodeChecker server"
|
||||
run: |
|
||||
set -x
|
||||
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install --no-install-recommends \
|
||||
netcat \
|
||||
wget
|
||||
|
||||
mkdir -pv ~/codechecker-server-data
|
||||
chmod 1777 ~/codechecker-server-data
|
||||
|
||||
cp test/codechecker.server.json ~/codechecker-server-data/server_config.json
|
||||
test/prepare-docker-server.sh
|
||||
|
||||
echo "::group::CodeChecker server configuration"
|
||||
cd ~/codechecker-server-data
|
||||
chown 950:950 server_config.json && chmod 0600 server_config.json
|
||||
chown 950:950 root.user && chmod 0600 root.user
|
||||
ls -alh
|
||||
cat docker-compose.yml
|
||||
cat root.user
|
||||
cat server_config.json
|
||||
echo "::endgroup::"
|
||||
|
||||
docker-compose up -d
|
||||
|
||||
wget -qO- http://raw.githubusercontent.com/eficode/wait-for/v2.1.3/wait-for | sh -s -- --timeout=30 http://0.0.0.0:8001/ -- echo "CodeChecker up"
|
||||
|
||||
docker ps -a
|
||||
echo "::group::CodeChecker server initial log output"
|
||||
docker logs codechecker-server
|
||||
echo "::endgroup::"
|
||||
- run: test/fix_compile_json_paths.sh
|
||||
- uses: ./
|
||||
id: codechecker
|
||||
continue-on-error: true
|
||||
with:
|
||||
version: "v${{ env.CODECHECKER_VERSION }}"
|
||||
logfile: 'test/simple/compile_commands.json'
|
||||
store: true
|
||||
store-url: 'http://0.0.0.0:8001/Default'
|
||||
store-username: 'root'
|
||||
store-password: 'root'
|
||||
- name: "Test if server logged store action"
|
||||
id: test
|
||||
continue-on-error: true
|
||||
run: docker logs codechecker-server | grep "stored results"
|
||||
- name: "Teardown CodeChecker server"
|
||||
run: |
|
||||
set -x
|
||||
|
||||
echo "::group::CodeChecker server log output"
|
||||
docker logs codechecker-server
|
||||
echo "::endgroup::"
|
||||
|
||||
cd ~/codechecker-server-data
|
||||
docker-compose down
|
||||
docker ps -a
|
||||
- name: "Fail the build if the test execution failed"
|
||||
if: ${{ steps.test.outcome == 'failure' || steps.codechecker.outcome == 'failure' }}
|
||||
run: exit 1
|
||||
|
||||
38
README.md
38
README.md
@@ -1,4 +1,4 @@
|
||||
# [CodeChecker](http://github.com/Ericsson/CodeChecker/) C++ static analysis action
|
||||
# [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
|
||||
@@ -26,7 +26,7 @@ Hence, it's recommended to configure your project in a **`Debug`** configuration
|
||||
Add the job into your CI as follows.
|
||||
The two versions are mutually exclusive — you either can give a compilation database, or you instruct CodeChecker to create one.
|
||||
|
||||
### Project can generate a [JSON Compilation Database](http://clang.llvm.org/docs/JSONCompilationDatabase.html) and build cleanly (no generated code)
|
||||
### Projects that can generate a [JSON Compilation Database](http://clang.llvm.org/docs/JSONCompilationDatabase.html) and build cleanly (no generated code)
|
||||
|
||||
Some projects are trivial enough in their build configuration that no additional steps need to be taken after executing `configure.sh`, `cmake`, or similar tools.
|
||||
If you are able to generate a _compilation database_ from your build system **without** running the build itself, you can save some time, and go to the analysis immediately.
|
||||
@@ -137,19 +137,33 @@ runs:
|
||||
ℹ️ **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. |
|
||||
| Variable | Default | Description |
|
||||
|-------------------------|---------|---------------------------------------------------------------------------------------------------|
|
||||
| `fail-build-if-reports` | `false` | If set to `true`, the build will be set to broken if the static analysers reports _any_ findings. |
|
||||
|
||||
### Store settings
|
||||
|
||||
🔖 Read more about [`CodeChecker store`](http://codechecker.readthedocs.io/en/latest/web/user_guide/#store) in the official documentation.
|
||||
|
||||
|
||||
|
||||
| Variable | Default | Description |
|
||||
|------------------|---------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `store` | `false` | If set to `true`, the script will upload the findings to a CodeChecker server. Usually, other flags need to be configured too! |
|
||||
| `store-url` | | The URL of the CodeChecker product to store to, **including** the [endpoint](http://codechecker.readthedocs.io/en/latest/web/user_guide/#product_url-format). Usually in the format of `http://example.com/ProductName`. Specifying this variable is **required** if `store` was set to `true`. |
|
||||
| `store-username` | | If the server requires authentication to access, specify the username which the upload should log in with. |
|
||||
| `store-password` | | The password or [generated access token](http://codechecker.readthedocs.io/en/latest/web/authentication/#personal-access-token) corresponding to the user. 🔐 **Note:** It is recommended that this is configured as a repository secret, and given as such: `${{ secrets.CODECHECKER_PASSWORD }}` when configuring the action. |
|
||||
| `store-run-name` | (auto-generated, in the format `user/repo: branchname`) | CodeChecker analysis executions are collected into _runs_. A run usually correlates to one configuration of the analysis. Runs can be stored incrementally, in which case CodeChecker is able to annotate that reports got fixed. |
|
||||
|
||||
## 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 |
|
||||
|-------------------|-------------------------------------------|-----------------------------------------------------------------------------------|
|
||||
| `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. |
|
||||
| `result-log` | Auto-generated. | `CodeChecker parse`'s output log file which contains the findings dumped into it. |
|
||||
| `warnings` | `true` or `false` | Whether the static analysers reported any findings. |
|
||||
| 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. |
|
||||
| `result-log` | Auto-generated. | `CodeChecker parse`'s output log file which contains the findings dumped into it. |
|
||||
| `store-run-name` | Auto-generated, or `store-run-name` input | The name of the analysis run (if `store` was enabled) to which the results were uploaded to. |
|
||||
| `warnings` | `true` or `false` | Whether the static analysers reported any findings. |
|
||||
|
||||
55
action.yml
55
action.yml
@@ -44,6 +44,24 @@ inputs:
|
||||
default: 'false'
|
||||
required: true
|
||||
|
||||
store:
|
||||
description: 'Whether to enable storing the results to a CodeChecker server. If enabled, other flags, such as `store-url` must also be set.'
|
||||
default: 'false'
|
||||
required: true
|
||||
store-url:
|
||||
description: 'The CodeChecker product URL (usually in the format of http://example.com/ProductName) where the store should connect to. Mandatory if `store` is true.'
|
||||
required: false
|
||||
store-username:
|
||||
description: 'If the server requires authentication, the username to authenticate with.'
|
||||
required: false
|
||||
store-password:
|
||||
description: 'The password (or generated private access token) corresponding to the user.'
|
||||
required: false
|
||||
store-run-name:
|
||||
description: 'An identifying name of the analysis run. A run usually correlates to a set of configuration, e.g. analysis mode, branch, etc. If left default, the name is automatically generated from the current repository and branch name.'
|
||||
default: '__DEFAULT__'
|
||||
required: true
|
||||
|
||||
outputs:
|
||||
logfile:
|
||||
description: 'The location of the JSON Compilation Database that was used for the analysis.'
|
||||
@@ -63,6 +81,10 @@ outputs:
|
||||
description: 'The output directory where the user-friendly HTML reports were stored to.'
|
||||
value: ${{ steps.parse.outputs.HTML_DIR }}
|
||||
|
||||
store-run-name:
|
||||
description: 'The name of the analysis run that the results were uploaded to.'
|
||||
value: ${{ steps.store-pre.outputs.RUN_NAME }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
@@ -92,7 +114,7 @@ runs:
|
||||
- name: "Build and Package CodeChecker"
|
||||
id: codechecker
|
||||
env:
|
||||
CODECHECKER_WILL_USE_WEB_API: "false" # TODO: Add support for this later.
|
||||
CODECHECKER_WILL_USE_WEB_API: ${{ inputs.store == 'true' }}
|
||||
shell: bash
|
||||
run: |
|
||||
set -ex
|
||||
@@ -169,3 +191,34 @@ runs:
|
||||
run: |
|
||||
echo "Static analysis reported warnings, and user requested build breaking."
|
||||
exit 1
|
||||
|
||||
- name: "Generate the configuration for uploading results"
|
||||
id: store-pre
|
||||
if: ${{ inputs.store == 'true' }}
|
||||
env:
|
||||
IN_STORE_URL: ${{ inputs.store-url }}
|
||||
IN_STORE_USERNAME: ${{ inputs.store-username }}
|
||||
IN_STORE_PASSWORD: ${{ inputs.store-password }}
|
||||
IN_STORE_RUN_NAME: ${{ inputs.store-run-name }}
|
||||
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
GITHUB_REF_NAME: ${{ github.ref_name }}
|
||||
GITHUB_REF_TYPE: ${{ github.ref_type }}
|
||||
GITHUB_SHA: ${{ github.sha }}
|
||||
shell: bash
|
||||
run: ${{ github.action_path }}/src/store-pre.sh
|
||||
|
||||
- name: "Store analysis results to server"
|
||||
id: store
|
||||
if: ${{ steps.store-pre.outputs.STORE_CONFIGURED == 'true' }}
|
||||
env:
|
||||
PROJECT_PATH: ${{ github.workspace }}
|
||||
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 }}
|
||||
|
||||
IN_CONFIGFILE: ${{ inputs.config }}
|
||||
IN_STORE_URL: ${{ inputs.store-url }}
|
||||
shell: bash
|
||||
run: ${{ github.action_path }}/src/store.sh
|
||||
|
||||
45
src/store-pre.sh
Executable file
45
src/store-pre.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
if [[ -z "$IN_STORE_URL" ]]; then
|
||||
echo "::error title=Configuration error::Uploading results to a server was enabled, but the upload URL is not configured."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -z "$IN_STORE_USERNAME" && ! -z "$IN_STORE_PASSWORD" ]]; then
|
||||
echo "Configuring credentials..."
|
||||
cat <<EOF > ~/.codechecker.passwords.json
|
||||
{
|
||||
"client_autologin": true,
|
||||
"credentials": {
|
||||
"$IN_STORE_URL": "$IN_STORE_USERNAME:$IN_STORE_PASSWORD"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
chmod 0600 ~/.codechecker.passwords.json
|
||||
fi
|
||||
|
||||
if [[ ! -z "$IN_STORE_RUN_NAME" && "$IN_STORE_RUN_NAME" != "__DEFAULT__" ]]; then
|
||||
echo "Using user-requested run name."
|
||||
echo "::set-output name=RUN_NAME::$IN_STORE_RUN_NAME"
|
||||
echo "::set-output name=RUN_TAG::"
|
||||
echo "::set-output name=STORE_CONFIGURED::true"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$GITHUB_REF_TYPE" == "branch" ]]; then
|
||||
echo "Auto-generating run name for a BRANCH."
|
||||
echo "::set-output name=RUN_NAME::$GITHUB_REPOSITORY: $GITHUB_REF_NAME"
|
||||
echo "::set-output name=RUN_TAG::$GITHUB_SHA"
|
||||
echo "::set-output name=STORE_CONFIGURED::true"
|
||||
exit 0
|
||||
elif [[ "$GITHUB_REF_TYPE" == "tag" ]]; then
|
||||
echo "Auto-generating run name for a TAG."
|
||||
echo "::set-output name=RUN_NAME::$GITHUB_REPOSITORY tags"
|
||||
echo "::set-output name=RUN_TAG::$GITHUB_REF_NAME"
|
||||
echo "::set-output name=STORE_CONFIGURED::true"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "::notice title=Preparation for store::Failed to generate a run name. Implementation error?"
|
||||
echo "::set-output name=STORE_CONFIGURED::false"
|
||||
42
src/store.sh
Executable file
42
src/store.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
if [[ -z "$IN_STORE_URL" ]]; then
|
||||
echo "::error title=Internal error::environment variable 'IN_STORE_URL' missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
if [[ -z "$CODECHECKER_STORE_RUN_NAME" ]]; then
|
||||
echo "::error title=Internal error::environment variable 'CODECHECKER_STORE_RUN_NAME' missing!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -z "$IN_CONFIGFILE" ]]; then
|
||||
CONFIG_FLAG_1="--config"
|
||||
CONFIG_FLAG_2=$IN_CONFIGFILE
|
||||
echo "Using configuration file \"$IN_CONFIGFILE\"!"
|
||||
fi
|
||||
|
||||
if [[ ! -z "$CODECHECKER_STORE_RUN_TAG" ]]; then
|
||||
RUN_TAG_FLAG_1="--tag"
|
||||
RUN_TAG_FLAG_2=$CODECHECKER_STORE_RUN_TAG
|
||||
fi
|
||||
|
||||
"$CODECHECKER_PATH"/CodeChecker \
|
||||
store \
|
||||
"$RAW_RESULT_DIR" \
|
||||
--url "$IN_STORE_URL" \
|
||||
--name "$CODECHECKER_STORE_RUN_NAME" \
|
||||
--trim-path-prefix "$PROJECT_PATH" \
|
||||
$RUN_TAG_FLAG_1 $RUN_TAG_FLAG_2 \
|
||||
$CONFIG_FLAG_1 $CONFIG_FLAG_2
|
||||
13
test/codechecker.server.json
Normal file
13
test/codechecker.server.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"authentication": {
|
||||
"enabled": true,
|
||||
"session_lifetime": 86400,
|
||||
"refresh_time": 86400,
|
||||
"logins_until_cleanup": 42,
|
||||
"method_dictionary": {
|
||||
"enabled": true,
|
||||
"auths": [],
|
||||
"groups": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
test/prepare-docker-server.sh
Executable file
33
test/prepare-docker-server.sh
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
if [[ -z "$CODECHECKER_VERSION" ]]; then
|
||||
echo "::error title=Test configuration error::Missing environment variable 'CODECHECKER_VERSION'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat <<EOF > ~/codechecker-server-data/docker-compose.yml
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
codechecker-server:
|
||||
container_name: codechecker-server
|
||||
image: "codechecker/codechecker-web:$CODECHECKER_VERSION"
|
||||
ports:
|
||||
- '8001:8001/tcp'
|
||||
networks:
|
||||
- codechecker-network
|
||||
volumes:
|
||||
- $HOME/codechecker-server-data:/workspace
|
||||
|
||||
networks:
|
||||
codechecker-network:
|
||||
driver: bridge
|
||||
EOF
|
||||
|
||||
python3 - <<- EOF
|
||||
import hashlib
|
||||
with open("$HOME/codechecker-server-data/root.user", 'w',
|
||||
encoding='utf-8', errors='ignore') as rootf:
|
||||
rootf.write(f"root:{hashlib.sha256(b'root:root').hexdigest()}")
|
||||
EOF
|
||||
Reference in New Issue
Block a user