diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a838ad1..77a654e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -43,6 +43,7 @@ jobs: install-custom: ${{ matrix.install-custom }} version: ${{ matrix.version }} llvm-version: ${{ matrix.llvm-version }} + logfile: "test/empty/compile_commands.json" simple-analysis-tests: @@ -83,6 +84,7 @@ jobs: - uses: ./ with: config: 'test/codechecker.verbose.json' + logfile: 'test/simple/compile_commands.json' analyze-ctu: name: "Analyze: CTU shortcut" @@ -94,6 +96,7 @@ jobs: id: codechecker with: logfile: 'test/ctu/compile_commands.json' + ctu: true - name: "Reject test if previous step did not produce CTU finding" run: cat ${{ steps.codechecker.outputs.result-log }} | grep "Dereference of null pointer" @@ -108,11 +111,12 @@ jobs: id: codechecker continue-on-error: true with: - logfile: 'test/simple/compile_commands.json' # FIXME: 6.18 release on PyPI is broken when it comes to the "parse" # command. See Ericsson/CodeChecker#3515. install-custom: true version: "v6.18.0" + + logfile: 'test/simple/compile_commands.json' - name: "Reject test if output isn't as expected" if: ${{ steps.codechecker.outputs.warnings != 'true' }} run: | @@ -128,11 +132,12 @@ jobs: - uses: ./ id: codechecker with: - logfile: 'test/simple/compile_commands.json' # FIXME: 6.18 release on PyPI is broken when it comes to the "parse" # command. See Ericsson/CodeChecker#3515. install-custom: true version: "v6.18.0" + + logfile: 'test/simple/compile_commands.json' - uses: actions/upload-artifact@v2 with: name: "Parse HTML test results" @@ -187,7 +192,9 @@ jobs: continue-on-error: true with: version: "${{ env.CODECHECKER_VERSION }}" + logfile: 'test/simple/compile_commands.json' + store: true store-url: 'http://0.0.0.0:8001/Default' store-username: 'root' @@ -210,3 +217,68 @@ jobs: - name: "Fail the build if the test execution failed" if: ${{ steps.test.outcome == 'failure' || steps.codechecker.outcome == 'failure' || steps.codechecker.outputs.store-successful != 'true' }} run: exit 1 + + diff: + name: "Diff: New findings are discovered and reported" + runs-on: ubuntu-20.04 + env: + CODECHECKER_VERSION: '6.18.0' + # This time, we do not need authentication, so test with the official Docker subsystem. + services: + codechecker-server: + image: 'codechecker/codechecker-web:6.18.0' + ports: + - 8001:8001/tcp + 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: "Wait for CodeChecker server service to go live" + run: | + set -x + + sudo apt-get -y update + sudo apt-get -y install --no-install-recommends \ + netcat \ + wget + + 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" + - run: test/fix_compile_json_paths.sh + - name: "Do the first analysis that stores a result" + uses: ./ + id: codechecker-store + continue-on-error: true + with: + # FIXME: 6.18 release on PyPI is broken when it comes to the "parse" + # command. See Ericsson/CodeChecker#3515. + install-custom: true + version: "v${{ env.CODECHECKER_VERSION }}" + + logfile: 'test/simple/compile_commands.json' + + store: true + store-url: 'http://0.0.0.0:8001/Default' + store-run-name: 'test-run' + - name: "Do the second analysis that finds a new result" + uses: ./ + id: codechecker-diff + with: + # FIXME: 6.18 release on PyPI is broken when it comes to the "parse" + # command. See Ericsson/CodeChecker#3515. + install-custom: true + version: "v${{ env.CODECHECKER_VERSION }}" + + logfile: 'test/simple2/compile_commands.json' + + diff: true + diff-url: 'http://0.0.0.0:8001/Default' + diff-run-name: 'test-run' + - uses: actions/upload-artifact@v2 + if: ${{ steps.codechecker-diff.outputs.warnings-in-diff == 'true' }} + with: + name: "Diff HTML test results" + path: ${{ steps.codechecker-diff.outputs.diff-html-dir }} + if-no-files-found: error + - name: "Fail the build if the test execution failed" + if: ${{ steps.codechecker-store.outcome == 'failure' || steps.codechecker-diff.outcome == 'failure' || steps.codechecker-store.outputs.store-successful != 'true' || steps.codechecker-diff.outputs.warnings-in-diff != 'true' }} + run: exit 1 diff --git a/README.md b/README.md index a95c16a..81a475c 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ This single action composite script encompasses the following steps: 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. (Uploading is to be done by the user!) - 5. _(Optional)_ Upload the results to a running _CodeChecker server_. + 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. @@ -146,6 +147,11 @@ If your project hosts a CodeChecker server somewhere, the job can be configured to automatically create or update a run. ```yaml +# It is recommended that storing only happens for PUSH events, and preferably +# only for long-term branches. +on: + push: + runs: steps: # Check YOUR project out! @@ -168,6 +174,7 @@ runs: store-url: 'http://example.com:8001/MyProject' store-username: ${{ secrets.CODECHECKER_STORE_USER }} store-password: ${{ secrets.CODECHECKER_STORE_PASSWORD }} + # store-run-name: "custom run name to store against" # Upload the results to the CI. - uses: actions/upload-artifact@v2 @@ -176,7 +183,58 @@ runs: path: ${{ steps.codechecker.outputs.result-html-dir }} ``` +### Acting as a CI gate on pull requests +CodeChecker is capable of calculating the difference between two analyses. +If an analysis of the stable version of the project is stored (see above) to a server, a job for pull requests can be configured that automatically rejects a pull request if it tries to introduce _new_ analysis findings. + +To get the reports in a human-consumable form, they must be uploaded somewhere first, before the failure step fails the entire job! + +```yaml +on: + pull_request: + +runs: + steps: + # Check the pull request out! (In pull_request jobs, the checkout action + # automatically downloads the "after-merge" state of the pull request if + # there are no conflicts.) + - name: "Check out repository" + uses: actions/checkout@v2 + + # Prepare a build + - name: "Prepare build" + run: | + mkdir -pv Build + cd Build + cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=OFF + + # Run the analysis + - uses: whisperity/codechecker-analysis-action + id: codechecker + with: + build-command: "cd ${{ github.workspace }}/Build; cmake --build ." + diff: true + diff-url: 'http://example.com:8001/MyProject' + diff-username: ${{ secrets.CODECHECKER_DIFF_USER }} + diff-password: ${{ secrets.CODECHECKER_DIFF_PASSWORD }} + # diff-run-name: "custom run name to diff against" + + # Upload the potential new findings results to the CI. + - uses: actions/upload-artifact@v2 + if: ${{ steps.codechecker.outputs.warnings-in-diff == 'true' }} + with: + name: "New introduced results Bug Reports" + path: ${{ steps.codechecker.outputs.diff-html-dir }} + + - name: "Fail the job if new findings are introduced" + if: ${{ steps.codechecker.outputs.warnings-in-diff == 'true' }} + shell: bash + run: | + echo "::error title=New static analysis warnings::Analysed commit would introduce new static analysis warnings and potential bugs to the project" + # Fail the build, after results were collected and uploaded. + exit 1 +``` ## Action configuration @@ -215,10 +273,26 @@ runs: 🔖 Read more about [`CodeChecker parse`](http://codechecker.readthedocs.io/en/latest/analyzer/user_guide/#parse) in the official documentation. -### Store settings +### Diff configuration + +🔖 Read more about [`CodeChecker cmd diff`](http://codechecker.readthedocs.io/en/latest/analyzer/user_guide/#cmd-diff) in the official documentation. + +🔓 Checking the analysis results against the contents of a server requires the `PRODUCT_VIEW` permission, if the server is requiring authentication. + +| Variable | Default | Description | +|-----------------|---------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `diff` | `false` | If set to `true`, the job will compute a diff of the current analysis results against the results stored on a remote server. | +| `diff-url` | | The URL of the CodeChecker product to check and diff against, **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 `diff` was set to `true`. | +| `diff-username` | | If the server requires authentication to access, specify the username which the check should log in with. | +| `diff-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. | +| `diff-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. | + +### Store configuration 🔖 Read more about [`CodeChecker store`](http://codechecker.readthedocs.io/en/latest/web/user_guide/#store) in the official documentation. +🔓 Storing runs to a server requires the `PRODUCT_STORE` permission, if the server is requiring authentication. + | 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! | @@ -231,12 +305,16 @@ runs: 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. | -| `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. | -| `store-successful` | `true` or `false` | Whether storing the results succeeded. Useful for optionally breaking the build later to detect networking failures. | -| `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. | +| `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-run-name` | Auto-generated, or `diff-run-name` input | The name of the analysis run (if `diff` was enabled) against which the reports were compared. | +| `diff-result-log` | Auto-generated. | `CodeChecker cmd diff`'s output log file which contains the **new** findings dumped into it. | +| `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. | +| `store-successful` | `true` or `false` | Whether storing the results succeeded. Useful for optionally breaking the build later to detect networking failures. | +| `warnings` | `true` or `false` | Whether the static analysers reported any findings. | +| `warnings-in-diff` | `true` or `false` | If `diff` was enabled, whether there were **new** findings in the current analysis when compared against the contents of the server. | diff --git a/action.yml b/action.yml index eddc12c..00793bc 100644 --- a/action.yml +++ b/action.yml @@ -43,6 +43,24 @@ inputs: required: true default: '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 + default: 'false' + diff-url: + description: 'The CodeChecker product URL (usually in the format of http://example.com/ProductName) where the diff should connect to. Mandatory if "diff" is true.' + required: false + diff-username: + description: 'If the server requires authentication, the username to authenticate with.' + required: false + diff-password: + description: 'The password (or generated private access token) corresponding to the user.' + required: false + diff-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.' + required: true + default: '__DEFAULT__' + store: description: 'Whether to enable storing the results to a CodeChecker server. If enabled, other flags, such as "store-url" must also be set.' required: true @@ -80,6 +98,19 @@ outputs: description: 'The output directory where the user-friendly HTML reports were stored to.' value: ${{ steps.parse.outputs.HTML_DIR }} + diff-html-dir: + description: 'The output directory where the user-friendly HTML reports about the new findings (if "diff" was enabled) were stored to.' + value: ${{ steps.diff.outputs.HTML_DIR }} + diff-run-name: + description: 'The name of the analysis run against which the current reports were compared.' + value: ${{ steps.diff-pre.outputs.RUN_NAME }} + diff-result-log: + description: 'The file where the output of CodeChecker cmd diff is written to verbatim.' + value: ${{ steps.diff.outputs.OUTPUT_LOG }} + warnings-in-diff: + description: 'Whether the current analysis produced any reports that were NEW, compared to the configured analysis run on the server.' + value: ${{ steps.diff.outputs.HAS_NEW_FINDINGS }} + store-run-name: description: 'The name of the analysis run that the results were uploaded to.' value: ${{ steps.store-pre.outputs.RUN_NAME }} @@ -109,7 +140,7 @@ runs: - name: "Build and Package CodeChecker" id: codechecker env: - CODECHECKER_WILL_USE_WEB_API: ${{ inputs.store == 'true' }} + CODECHECKER_WILL_USE_WEB_API: ${{ inputs.store == 'true' || inputs.diff == 'true' }} IN_INSTALL_CUSTOM: ${{ inputs.install-custom }} IN_VERSION: ${{ inputs.version }} @@ -138,9 +169,9 @@ runs: - name: "Execute static analysis" id: analyze env: - ACTION_NAME: ${{ github.action }} CODECHECKER_PATH: ${{ steps.codechecker.outputs.PATH }} COMPILATION_DATABASE: ${{ steps.log.outputs.COMPILATION_DATABASE }} + GITHUB_ACTION_NAME: ${{ github.action }} IN_CONFIGFILE: ${{ inputs.config }} IN_CTU: ${{ inputs.ctu }} @@ -157,10 +188,40 @@ runs: RAW_RESULT_DIR: ${{ steps.analyze.outputs.OUTPUT_DIR }} IN_CONFIGFILE: ${{ inputs.config }} - IN_OUTPUT_DIR: ${{ inputs.analyze-output }} shell: bash run: ${{ github.action_path }}/src/parse-results.sh + - name: "Generate the configuration for diffing current results against previously stored" + id: diff-pre + if: ${{ inputs.diff == 'true' }} + env: + IN_DIFF_URL: ${{ inputs.diff-url }} + IN_DIFF_USERNAME: ${{ inputs.diff-username }} + IN_DIFF_PASSWORD: ${{ inputs.diff-password }} + IN_DIFF_RUN_NAME: ${{ inputs.diff-run-name }} + + GITHUB_BASE_REF: ${{ github.base_ref }} + GITHUB_EVENT_NAME: ${{ github.event_name }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_REF_NAME: ${{ github.ref_name }} + GITHUB_REF_TYPE: ${{ github.ref_type }} + shell: bash + run: ${{ github.action_path }}/src/diff-pre.sh + + - name: "Diff current results against previously stored run" + id: diff + if: ${{ steps.diff-pre.outputs.DIFF_CONFIGURED == 'true' }} + env: + 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 }} + + IN_CONFIGFILE: ${{ inputs.config }} + IN_DIFF_URL: ${{ inputs.diff-url }} + shell: bash + run: ${{ github.action_path }}/src/diff.sh + - name: "Generate the configuration for uploading results" id: store-pre if: ${{ inputs.store == 'true' }} diff --git a/src/diff-pre.sh b/src/diff-pre.sh new file mode 100755 index 0000000..9676900 --- /dev/null +++ b/src/diff-pre.sh @@ -0,0 +1,47 @@ +#!/bin/bash +set -x + +if [[ -z "$IN_DIFF_URL" ]]; then + echo "::error title=Configuration error::Diffing results against a server was enabled, but the product URL is not configured." + exit 1 +fi + +if [[ ! -z "$IN_DIFF_USERNAME" && ! -z "$IN_DIFF_PASSWORD" ]]; then + echo "Configuring credentials..." + cat < ~/.codechecker.passwords.json + { + "client_autologin": true, + "credentials": { + "$IN_DIFF_URL": "$IN_DIFF_USERNAME:$IN_DIFF_PASSWORD" + } + } +EOF + chmod 0600 ~/.codechecker.passwords.json +fi + +if [[ ! -z "$IN_DIFF_RUN_NAME" && "$IN_DIFF_RUN_NAME" != "__DEFAULT__" ]]; then + echo "Using user-requested run name." + echo "::set-output name=RUN_NAME::$IN_DIFF_RUN_NAME" + echo "::set-output name=DIFF_CONFIGURED::true" + exit 0 +fi + +if [[ "$GITHUB_EVENT_NAME" == "pull_request" ]]; then + echo "Auto-generating run name for a PULL REQUEST's target (base)." + echo "::set-output name=RUN_NAME::$GITHUB_REPOSITORY: $GITHUB_BASE_REF" + echo "::set-output name=DIFF_CONFIGURED::true" + exit 0 +elif [[ "$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=DIFF_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=DIFF_CONFIGURED::true" + exit 0 +fi + +echo "::notice title=Preparation for diff::Failed to generate a run name. Implementation error?" +echo "::set-output name=DIFF_CONFIGURED::false" diff --git a/src/diff.sh b/src/diff.sh new file mode 100755 index 0000000..5ff7d2b --- /dev/null +++ b/src/diff.sh @@ -0,0 +1,70 @@ +#!/bin/bash +set -x + +if [[ -z "$IN_DIFF_URL" ]]; then + echo "::error title=Internal error::environment variable 'IN_DIFF_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_DIFF_RUN_NAME" ]]; then + echo "::error title=Internal error::environment variable 'CODECHECKER_DIFF_RUN_NAME' missing!" + exit 1 +fi + +OUTPUT_DIR="$RAW_RESULT_DIR"_DiffHTML +OUTPUT_LOG="$(dirname "$RAW_RESULT_DIR")"/"$(basename "$RAW_RESULT_DIR")_Diff.log" +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 \ + cmd diff \ + --new \ + --url "$IN_DIFF_URL" \ + --basename "$CODECHECKER_DIFF_RUN_NAME" \ + --newname "$RAW_RESULT_DIR" \ + --output html \ + --export "$OUTPUT_DIR" \ + $CONFIG_FLAG_1 $CONFIG_FLAG_2 \ + || true +echo "::set-output name=HTML_DIR::$OUTPUT_DIR" + +"$CODECHECKER_PATH"/CodeChecker \ + cmd diff \ + --new \ + --url "$IN_DIFF_URL" \ + --basename "$CODECHECKER_DIFF_RUN_NAME" \ + --newname "$RAW_RESULT_DIR" \ + $CONFIG_FLAG_1 $CONFIG_FLAG_2 \ + > "$OUTPUT_LOG" +EXIT_CODE=$? + +cat "$OUTPUT_LOG" +echo "::set-output name=OUTPUT_LOG::$OUTPUT_LOG" + +if [[ $EXIT_CODE -eq 2 ]]; then + echo "::set-output name=HAS_NEW_FINDINGS::true" + + # Let the job continue. If there were new results, the script may be breaking + # the build in a later step. (After a potential upload to server.) + EXIT_CODE=0 +elif [[ $EXIT_CODE -eq 0 ]]; then + echo "::set-output name=HAS_NEW_FINDINGS::false" +fi + +# Exit code 1 is internal error of executing the step. +exit $EXIT_CODE diff --git a/src/execute-analysis.sh b/src/execute-analysis.sh index e48a7dc..6743a68 100755 --- a/src/execute-analysis.sh +++ b/src/execute-analysis.sh @@ -8,7 +8,7 @@ fi OUTPUT_DIR="$IN_OUTPUT_DIR" if [[ -z "$OUTPUT_DIR" ]]; then - OUTPUT_DIR=~/"$ACTION_NAME"_Results + OUTPUT_DIR=~/"$GITHUB_ACTION_NAME"_Results fi mkdir -pv "$(dirname $"OUTPUT_DIR")" diff --git a/src/parse-results.sh b/src/parse-results.sh index eda4954..1012766 100755 --- a/src/parse-results.sh +++ b/src/parse-results.sh @@ -11,13 +11,9 @@ if [[ -z "$RAW_RESULT_DIR" ]]; then 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")" - -OUTPUT_LOG="$(dirname "$IN_OUTPUT_DIR")"/"$(basename "$IN_OUTPUT_DIR")_Parse.log" +OUTPUT_DIR="$RAW_RESULT_DIR"_HTML +OUTPUT_LOG="$(dirname "$RAW_RESULT_DIR")"/"$(basename "$RAW_RESULT_DIR")_Diff.log" +mkdir -pv "$(dirname "$OUTPUT_DIR")" if [[ ! -z "$IN_CONFIGFILE" ]]; then CONFIG_FLAG_1="--config" @@ -38,16 +34,17 @@ echo "::set-output name=HTML_DIR::$OUTPUT_DIR" --trim-path-prefix "$PROJECT_PATH" \ > "$OUTPUT_LOG" EXIT_CODE=$? + +cat "$OUTPUT_LOG" echo "::set-output name=OUTPUT_LOG::$OUTPUT_LOG" - -if [[ $EXIT_CODE == "2" ]]; then +if [[ $EXIT_CODE -eq 2 ]]; then echo "::set-output name=HAS_FINDINGS::true" - # Let the jobs continue. If there were failures, the script may be breaking + # Let the jobs continue. If there were findings, the script may be breaking # the build in a later step. (After a potential upload to server.) EXIT_CODE=0 -elif [[ $EXIT_CODE == 0 ]]; then +elif [[ $EXIT_CODE -eq 0 ]]; then echo "::set-output name=HAS_FINDINGS::false" fi diff --git a/test/simple2/compile_commands.json b/test/simple2/compile_commands.json new file mode 100644 index 0000000..08cee39 --- /dev/null +++ b/test/simple2/compile_commands.json @@ -0,0 +1,7 @@ +[ + { + "directory": "__DIRECTORY__", + "command": "g++ -c main.cpp -o main.o", + "file": "main.cpp" + } +] diff --git a/test/simple2/main.cpp b/test/simple2/main.cpp new file mode 100644 index 0000000..271b438 --- /dev/null +++ b/test/simple2/main.cpp @@ -0,0 +1,3 @@ +int main(int argc, char** argv) { + return sizeof(42); +}