diff --git a/README.md b/README.md index 1232e383544ae22d5a395cf37069c32c67a5fe3d..f821363166f10e45f29e2dba01b2d88ba9a3395e 100644 --- a/README.md +++ b/README.md @@ -67,13 +67,15 @@ It is bound to the `build` stage, and uses the following variables: | Name | description | default value | | ------------------------ | ---------------------------------- | ----------------- | -| `PYLINT_ARGS` | Additional [pylint CLI options](http://pylint.pycqa.org/en/latest/user_guide/run.html#command-line-options) | _none_ | +| `PYLINT_ARGS` | Additional [pylint CLI options](http://pylint.pycqa.org/en/latest/user_guide/run.html#command-line-options) | _none_ | | `PYLINT_FILES` | Files or directories to analyse | _none_ (by default analyses all found python source files) | -This job produces the following artifacts, kept for one day: +In addition to a textual report in the console, this job produces the following reports, kept for one day: -* Code quality json report in code climate format. -* Pylint report for SonarQube (if `SONAR_URL` is defined). +| Report | Format | Usage | +| -------------- | ---------------------------------------------------------------------------- | ----------------- | +| `$PYTHON_PROJECT_DIR/reports/py-lint.codeclimate.json` | [Code Climate](https://docs.codeclimate.com/docs/pylint) | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscodequality) | +| `$PYTHON_PROJECT_DIR/reports/py-lint.parseable.txt` | [parseable](https://pylint.pycqa.org/en/latest/user_guide/usage/output.html) | [SonarQube integration](https://docs.sonarqube.org/latest/analysis/external-issues/) | ### Test jobs @@ -97,14 +99,7 @@ It is bound to the `build` stage, and uses the following variables: | ------------------------ | -------------------------------------------------------------------- | ----------------------- | | `UNITTEST_ARGS` | Additional xmlrunner/unittest CLI options | _none_ | -This job produces the following artifacts, kept for one day: - -* JUnit test report (using the [xmlrunner](https://github.com/xmlrunner/unittest-xml-reporting) module) -* code coverage report (cobertura xml format). - -:warning: code coverage report artifact is disabled, due to a deprecated syntax, see [Activate code coverage report artifact](#activate-code-coverage-report-artifact) - -:warning: create a `.coveragerc` file at the root of your Python project to control the coverage settings. +:information_source: use a `.coveragerc` file at the root of your Python project to control the coverage settings. Example: @@ -118,6 +113,13 @@ source = module_2 ``` +In addition to a textual report in the console, this job produces the following reports, kept for one day: + +| Report | Format | Usage | +| -------------- | ---------------------------------------------------------------------------- | ----------------- | +| `$PYTHON_PROJECT_DIR/reports/TEST-*.xml` | [xUnit](https://en.wikipedia.org/wiki/XUnit) test report(s) | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportsjunit) & [SonarQube integration](https://docs.sonarqube.org/latest/analysis/test-coverage/test-execution-parameters/#header-8) | +| `$PYTHON_PROJECT_DIR/reports/py-coverage.cobertura.xml` | [Cobertura XML](https://gcovr.com/en/stable/output/cobertura.html) coverage report | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscoverage_report) & [SonarQube integration](https://docs.sonarqube.org/latest/analysis/test-coverage/python-test-coverage/) | + #### `py-pytest` job This job is **disabled by default** and performs tests based on [pytest](https://docs.pytest.org/en/latest/) Python lib. @@ -129,14 +131,7 @@ It is bound to the `build` stage, and uses the following variables: | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | | `PYTEST_ARGS` | Additional [pytest](https://docs.pytest.org/en/stable/usage.html) or [pytest-cov](https://github.com/pytest-dev/pytest-cov#usage) CLI options | _none_ | -This job produces the following artifacts, kept for one day: - -* JUnit test report (with the [`--junit-xml`](http://doc.pytest.org/en/latest/usage.html#creating-junitxml-format-files) argument) -* code coverage report (cobertura xml format). - -:warning: code coverage report artifact is disabled, due to a deprecated syntax, see [Activate code coverage report artifact](#activate-code-coverage-report-artifact) - -:warning: create a `.coveragerc` file at the root of your Python project to control the coverage settings. +:information_source: use a `.coveragerc` file at the root of your Python project to control the coverage settings. Example: @@ -150,6 +145,13 @@ source = module_2 ``` +In addition to a textual report in the console, this job produces the following reports, kept for one day: + +| Report | Format | Usage | +| -------------- | ---------------------------------------------------------------------------- | ----------------- | +| `$PYTHON_PROJECT_DIR/reports/TEST-*.xml` | [xUnit](https://en.wikipedia.org/wiki/XUnit) test report(s) | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportsjunit) & [SonarQube integration](https://docs.sonarqube.org/latest/analysis/test-coverage/test-execution-parameters/#header-8) | +| `$PYTHON_PROJECT_DIR/reports/py-coverage.cobertura.xml` | [Cobertura XML](https://gcovr.com/en/stable/output/cobertura.html) coverage report | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscoverage_report) & [SonarQube integration](https://docs.sonarqube.org/latest/analysis/test-coverage/python-test-coverage/) | + #### `py-nosetest` job This job is **disabled by default** and performs tests based on [nose](https://nose.readthedocs.io/en/latest/) Python lib. @@ -161,17 +163,17 @@ It is bound to the `build` stage, and uses the following variables: | ------------------------ | --------------------------------------------------------------------------------------- | ----------------------- | | `NOSETESTS_ARGS` | Additional [nose CLI options](https://nose.readthedocs.io/en/latest/usage.html#options) | _none_ | -By default coverage will be run on all the directory. You can restrict it to your packages by setting NOSE_COVER_PACKAGE variable. +By default coverage will be run on all the project directories. You can restrict it to your packages by setting the `$NOSE_COVER_PACKAGE` variable. More [info](https://nose.readthedocs.io/en/latest/plugins/cover.html) -This job produces the following artifacts, kept for one day: - -* JUnit test report (with the [`--with-xunit`](https://nose.readthedocs.io/en/latest/plugins/xunit.html) argument) -* code coverage report (cobertura xml format + html report). +:information_source: use a `.coveragerc` file at the root of your Python project to control the coverage settings. -:warning: code coverage report artifact is disabled, due to a deprecated syntax, see [Activate code coverage report artifact](#activate-code-coverage-report-artifact) +In addition to a textual report in the console, this job produces the following reports, kept for one day: -:warning: create a `.coveragerc` file at the root of your Python project or use [nose CLI options](https://nose.readthedocs.io/en/latest/plugins/cover.html#options) to control the coverage settings. +| Report | Format | Usage | +| -------------- | ---------------------------------------------------------------------------- | ----------------- | +| `$PYTHON_PROJECT_DIR/reports/TEST-*.xml` | [xUnit](https://en.wikipedia.org/wiki/XUnit) test report(s) | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportsjunit) & [SonarQube integration](https://docs.sonarqube.org/latest/analysis/test-coverage/test-execution-parameters/#header-8) | +| `$PYTHON_PROJECT_DIR/reports/py-coverage.cobertura.xml` | [Cobertura XML](https://gcovr.com/en/stable/output/cobertura.html) coverage report | [GitLab integration](https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscoverage_report) & [SonarQube integration](https://docs.sonarqube.org/latest/analysis/test-coverage/python-test-coverage/) | #### `py-compile` job @@ -184,58 +186,6 @@ It is bound to the `build` stage, and uses the following variables: | --------------------- | ----------------------------------------------------------------------------- | ------------- | | `PYTHON_COMPILE_ARGS` | [`compileall` CLI options](https://docs.python.org/3/library/compileall.html) | `*` | -#### Activate code coverage report artifact - -Code coverage report artifact is disabled, due to a [deprecated syntax](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78132). - -In order to activate code coverage report artifact, you need to override your actual unit test job depending on our GitLab version. - -Here is an example with `py-pytest` job (change to `py-unittest` or `py-nosetests` depending on your unit tests library): - -* for GitLab < 14.10: -```yaml -py-pytest: - artifacts: - reports: - cobertura: $PYTHON_PROJECT_DIR/reports/coverage.xml -``` -* for GitLab >= 14.10: -```yaml -py-pytest: - artifacts: - reports: - coverage_report: - ​coverage_format: cobertura - path: ​$PYTHON_PROJECT_DIR/reports/coverage.xml -``` - -### SonarQube analysis - -If you're using the SonarQube template to analyse your Python code, here is a sample `sonar-project.properties` file: - -```properties -# see: https://docs.sonarqube.org/latest/analysis/languages/python/ -# set your source directory(ies) here (relative to the sonar-project.properties file) -sonar.sources=. -# exclude unwanted directories and files from being analysed -sonar.exclusions=**/test_*.py - -# set your tests directory(ies) here (relative to the sonar-project.properties file) -sonar.tests=. -sonar.test.inclusions=**/test_*.py - -# tests report: generic format -sonar.python.xunit.reportPath=reports/unittest/TEST-*.xml -# coverage report: XUnit format -sonar.python.coverage.reportPaths=reports/coverage.xml -``` - -More info: - -* [Python language support](https://docs.sonarqube.org/latest/analysis/languages/python/) -* [test coverage & execution parameters](https://docs.sonarqube.org/latest/analysis/coverage/) -* [third-party issues](https://docs.sonarqube.org/latest/analysis/external-issues/) - ### `py-bandit` job (SAST) This job is **disabled by default** and performs a [Bandit](https://pypi.org/project/bandit/) analysis. @@ -247,8 +197,12 @@ It is bound to the `test` stage, and uses the following variables: | `BANDIT_ENABLED` | Set to `true` to enable Bandit analysis | _none_ (disabled) | | `BANDIT_ARGS` | Additional [Bandit CLI options](https://github.com/PyCQA/bandit#usage) | `--recursive .` | -This job outputs a **textual report** in the console, and in case of failure also exports a JSON report in the `reports/` -directory _(relative to project root dir)_. +In addition to a textual report in the console, this job produces the following reports, kept for one day: + +| Report | Format | Usage | +| -------------- | ---------------------------------------------------------------------------- | ----------------- | +| `$PYTHON_PROJECT_DIR/reports/py-bandit.bandit.csv` | [CSV](https://bandit.readthedocs.io/en/latest/formatters/csv.html) | [SonarQube integration](https://docs.sonarqube.org/latest/analysis/external-issues/)<br/>_This report is generated only if SonarQube template is detected_ | +| `$PYTHON_PROJECT_DIR/reports/py-bandit.bandit.json` | [JSON](https://bandit.readthedocs.io/en/latest/formatters/json.html) | [DefectDojo integration](https://defectdojo.github.io/django-DefectDojo/integrations/parsers/#bandit)<br/>_This report is generated only if DefectDojo template is detected_ | ### `py-safety` job (dependency check) @@ -261,9 +215,6 @@ It is bound to the `test` stage, and uses the following variables: | `SAFETY_ENABLED` | Set to `true` to enable Safety job | _none_ (disabled) | | `SAFETY_ARGS` | Additional [Safety CLI options](https://github.com/pyupio/safety#usage) | `--full-report` | -This job outputs a **textual report** in the console, and in case of failure also exports a JSON report in the `reports/` -directory _(relative to project root dir)_. - ### `py-trivy` job (dependency check) This job is **disabled by default** and performs a dependency check analysis using [Trivy](https://github.com/aquasecurity/trivy/). @@ -275,8 +226,42 @@ It is bound to the `test` stage, and uses the following variables: | `PYTHON_TRIVY_ENABLED` | Set to `true` to enable Trivy job | _none_ (disabled) | | `PYTHON_TRIVY_ARGS` | Additional [Trivy CLI options](https://aquasecurity.github.io/trivy/v0.21.1/getting-started/cli/fs/) | `--vuln-type library` | -This job outputs a **textual report** in the console, and in case of failure also exports a JSON report in the `reports/` -directory _(relative to project root dir)_. +In addition to a textual report in the console, this job produces the following reports, kept for one day: + +| Report | Format | Usage | +| -------------- | ---------------------------------------------------------------------------- | ----------------- | +| `$PYTHON_PROJECT_DIR/reports/py-trivy.trivy.json` | [JSON](https://aquasecurity.github.io/trivy/latest/docs/vulnerability/examples/report/#json) | [DefectDojo integration](https://defectdojo.github.io/django-DefectDojo/integrations/parsers/#trivy)<br/>_This report is generated only if DefectDojo template is detected_ | + +### SonarQube analysis + +If you're using the SonarQube template to analyse your Python code, here is a sample `sonar-project.properties` file: + +```properties +# see: https://docs.sonarqube.org/latest/analysis/languages/python/ +# set your source directory(ies) here (relative to the sonar-project.properties file) +sonar.sources=. +# exclude unwanted directories and files from being analysed +sonar.exclusions=**/test_*.py + +# set your tests directory(ies) here (relative to the sonar-project.properties file) +sonar.tests=. +sonar.test.inclusions=**/test_*.py + +# tests report: xUnit format +sonar.python.xunit.reportPath=reports/unittest/TEST-*.xml +# coverage report: Cobertura format +sonar.python.coverage.reportPaths=reports/py-coverage.cobertura.xml +# pylint: parseable format (if enabled) +sonar.python.pylint.reportPaths=reports/py-lint.parseable.txt +# Bandit: CSV format (if enabled) +sonar.python.bandit.reportPaths=reports/py-bandit.bandit.csv +``` + +More info: + +* [Python language support](https://docs.sonarqube.org/latest/analysis/languages/python/) +* [test coverage & execution parameters](https://docs.sonarqube.org/latest/analysis/coverage/) +* [third-party issues](https://docs.sonarqube.org/latest/analysis/external-issues/) ### `py-release` job diff --git a/templates/gitlab-ci-python.yml b/templates/gitlab-ci-python.yml index 706f58942f0bea5f24ac0d45e4e156def8c48cf3..7f34610dd41ba47230d0a96f0375693c9d3fe4db 100644 --- a/templates/gitlab-ci-python.yml +++ b/templates/gitlab-ci-python.yml @@ -604,34 +604,19 @@ py-lint: extends: .python-base stage: build script: - - mkdir -p reports - - chmod o+rwx reports + - mkdir -p -m 777 reports - install_requirements - - _pip install pylint_gitlab - - | - if ! _run pylint --ignore=.cache --output-format=text ${PYLINT_ARGS} ${PYLINT_FILES:-$(find -type f -name "*.py")} - then - # failed: also generate codeclimate report - _run pylint --ignore=.cache --output-format=pylint_gitlab.GitlabCodeClimateReporter ${PYLINT_ARGS} ${PYLINT_FILES:-$(find -type f -name "*.py")} > reports/pylint-codeclimate.json - exit 1 - else - # success: generate empty codeclimate report (required by GitLab :( ) - echo "[]" > reports/pylint-codeclimate.json - fi - - | - if [ -n "$SONAR_URL" ] - then - # SonarQube is configured, export analysis report - _run pylint --ignore=.cache --output-format=parseable ${PYLINT_ARGS} ${PYLINT_FILES:-$(find -type f -name "*.py")} > reports/pylint.txt - fi + - _pip install pylint_gitlab # codeclimate reports + # run pylint and generate reports all at once + - _run pylint --ignore=.cache --output-format=colorized,pylint_gitlab.GitlabCodeClimateReporter:reports/py-lint.codeclimate.json,parseable:reports/py-lint.parseable.txt ${PYLINT_ARGS} ${PYLINT_FILES:-$(find -type f -name "*.py")} artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" expire_in: 1 day when: always reports: - codequality: $PYTHON_PROJECT_DIR/reports/pylint-codeclimate.json + codequality: $PYTHON_PROJECT_DIR/reports/py-lint.codeclimate.json paths: - - $PYTHON_PROJECT_DIR/reports/ + - "$PYTHON_PROJECT_DIR/reports/py-lint.*" rules: # exclude if $PYLINT_ENABLED not set - if: '$PYLINT_ENABLED != "true"' @@ -657,8 +642,7 @@ py-unittest: extends: .python-base stage: build script: - - mkdir -p reports - - chmod o+rwx reports + - mkdir -p -m 777 reports - install_requirements # code coverage - _pip install coverage @@ -666,7 +650,7 @@ py-unittest: - _pip install unittest-xml-reporting - _run coverage run -m xmlrunner discover -o "reports/" $UNITTEST_ARGS - _run coverage report -m - - _run coverage xml -o "reports/coverage.xml" + - _run coverage xml -o "reports/py-coverage.cobertura.xml" coverage: /^TOTAL.+?(\d+\%)$/ artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" @@ -674,16 +658,13 @@ py-unittest: when: always reports: junit: - - $PYTHON_PROJECT_DIR/reports/TEST-*.xml - # declaring the Cobertura report depends on the GitLab version :( - # GitLab < 14.10 - # cobertura: $PYTHON_PROJECT_DIR/reports/coverage.xml - # GitLab >= 14.10 - # coverage_report: - # ​coverage_format: cobertura - # path: ​$PYTHON_PROJECT_DIR/reports/coverage.xml + - "$PYTHON_PROJECT_DIR/reports/TEST-*.xml" + coverage_report: + coverage_format: cobertura + path: "$PYTHON_PROJECT_DIR/reports/py-coverage.cobertura.xml" paths: - - $PYTHON_PROJECT_DIR/reports/ + - "$PYTHON_PROJECT_DIR/reports/TEST-*.xml" + - "$PYTHON_PROJECT_DIR/reports/py-coverage.*" rules: # skip if $UNITTEST_ENABLED not set - if: '$UNITTEST_ENABLED != "true"' @@ -694,11 +675,10 @@ py-pytest: extends: .python-base stage: build script: - - mkdir -p reports - - chmod o+rwx reports + - mkdir -p -m 777 reports - install_requirements - _pip install pytest pytest-cov coverage - - _python -m pytest --junit-xml=reports/TEST-pytests.xml --cov --cov-report term --cov-report xml:reports/coverage.xml ${PYTEST_ARGS} + - _python -m pytest --junit-xml=reports/TEST-pytests.xml --cov --cov-report term --cov-report xml:reports/py-coverage.cobertura.xml ${PYTEST_ARGS} coverage: /^TOTAL.+?(\d+\%)$/ artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" @@ -706,16 +686,13 @@ py-pytest: when: always reports: junit: - - $PYTHON_PROJECT_DIR/reports/TEST-*.xml - # declaring the Cobertura report depends on the GitLab version :( - # GitLab < 14.10 - # cobertura: $PYTHON_PROJECT_DIR/reports/coverage.xml - # GitLab >= 14.10 - # coverage_report: - # ​coverage_format: cobertura - # path: ​$PYTHON_PROJECT_DIR/reports/coverage.xml + - "$PYTHON_PROJECT_DIR/reports/TEST-*.xml" + coverage_report: + coverage_format: cobertura + path: "$PYTHON_PROJECT_DIR/reports/py-coverage.cobertura.xml" paths: - - $PYTHON_PROJECT_DIR/reports/ + - "$PYTHON_PROJECT_DIR/reports/TEST-*.xml" + - "$PYTHON_PROJECT_DIR/reports/py-coverage.*" rules: # skip if $PYTEST_ENABLED not set - if: '$PYTEST_ENABLED != "true"' @@ -726,10 +703,9 @@ py-nosetests: extends: .python-base stage: build script: - - mkdir -p reports - - chmod o+rwx reports + - mkdir -p -m 777 reports - install_requirements - - _run nosetests --with-xunit --xunit-file=reports/TEST-nosetests.xml --with-coverage --cover-erase --cover-xml --cover-xml-file=reports/coverage.xml --cover-html --cover-html-dir=reports/coverage ${NOSETESTS_ARGS} + - _run nosetests --with-xunit --xunit-file=reports/TEST-nosetests.xml --with-coverage --cover-erase --cover-xml --cover-xml-file=reports/py-coverage.cobertura.xml ${NOSETESTS_ARGS} coverage: /^TOTAL.+?(\d+\%)$/ artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" @@ -737,16 +713,13 @@ py-nosetests: when: always reports: junit: - - $PYTHON_PROJECT_DIR/reports/TEST-*.xml - # declaring the Cobertura report depends on the GitLab version :( - # GitLab < 14.10 - # cobertura: $PYTHON_PROJECT_DIR/reports/coverage.xml - # GitLab >= 14.10 - # coverage_report: - # coverage_format: cobertura - # path: ​$PYTHON_PROJECT_DIR/reports/coverage.xml + - "$PYTHON_PROJECT_DIR/reports/TEST-*.xml" + coverage_report: + coverage_format: cobertura + path: "$PYTHON_PROJECT_DIR/reports/py-coverage.cobertura.xml" paths: - - $PYTHON_PROJECT_DIR/reports/ + - "$PYTHON_PROJECT_DIR/reports/TEST-*.xml" + - "$PYTHON_PROJECT_DIR/reports/py-coverage.*" rules: # skip if $NOSETESTS_ENABLED not set - if: '$NOSETESTS_ENABLED != "true"' @@ -760,23 +733,28 @@ py-bandit: # force no dependencies dependencies: [] script: - - mkdir -p reports - - chmod o+rwx reports + - mkdir -p -m 777 reports - install_requirements - _pip install bandit + # CSV (for SonarQube) - | - if ! _run bandit ${TRACE+--verbose} ${BANDIT_ARGS} + if [[ "$SONAR_HOST_URL"]] then - # failed: also generate JSON report - _run bandit ${TRACE+--verbose} --format json --output reports/bandit.json ${BANDIT_ARGS} - exit 1 + _run bandit ${TRACE+--verbose} --exit-zero --format csv --output reports/py-bandit.bandit.csv ${BANDIT_ARGS} + fi + # JSON (for DefectDojo) + - | + if [[ "$DEFECTDOJO_BANDIT_REPORTS"]] + then + _run bandit ${TRACE+--verbose} --exit-zero --format json --output reports/py-bandit.bandit.json ${BANDIT_ARGS} fi + - _run bandit ${TRACE+--verbose} ${BANDIT_ARGS} artifacts: when: always name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" expire_in: 1 day paths: - - $PYTHON_PROJECT_DIR/reports/ + - "$PYTHON_PROJECT_DIR/reports/py-bandit.*" rules: # exclude if $BANDIT_ENABLED not set - if: '$BANDIT_ENABLED != "true"' @@ -790,24 +768,10 @@ py-safety: # force no dependencies dependencies: [] script: - - mkdir -p reports - - chmod o+rwx reports + - mkdir -p -m 777 reports - install_requirements - _pip install safety - - | - if ! _pip freeze | _run safety check --stdin ${SAFETY_ARGS} - then - # failed: also generate JSON report - - _pip freeze | _run safety check --stdin --json --output reports/safety.json ${SAFETY_ARGS} - exit 1 - fi - artifacts: - name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" - expire_in: 1 day - when: always - paths: - - $PYTHON_PROJECT_DIR/reports/ + - _pip freeze | _run safety check --stdin ${SAFETY_ARGS} rules: # exclude if $SAFETY_ENABLED not set - if: '$SAFETY_ENABLED != "true"' @@ -821,8 +785,7 @@ py-trivy: # force no dependencies dependencies: [] script: - - mkdir -p reports - - chmod o+rwx reports + - mkdir -p -m 777 reports - install_requirements - apt-get update - apt-get install -y wget apt-transport-https gnupg lsb-release @@ -853,15 +816,18 @@ py-trivy: log_error "Could not find a file listing all dependencies with their versions." exit 1 fi - trivy fs ${PYTHON_TRIVY_ARGS} --format table --exit-code 0 ./reports/ - trivy fs ${PYTHON_TRIVY_ARGS} --format cyclonedx --output ./reports/sbom_cyclonedx.json --exit-code 0 ./reports/ - trivy fs ${PYTHON_TRIVY_ARGS} --format json --output reports/trivy-python.json --list-all-pkgs --exit-code 1 ./reports/ + if [[ "$DEFECTDOJO_TRIVY_REPORTS" ]] + then + trivy fs ${PYTHON_TRIVY_ARGS} --exit-code 0 --list-all-pkgs --format json --output reports/py-trivy.trivy.json ./reports/ + fi + trivy fs ${PYTHON_TRIVY_ARGS} --format table ./reports/ artifacts: name: "$CI_JOB_NAME artifacts from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG" expire_in: 1 day when: always paths: - - $PYTHON_PROJECT_DIR/reports/ + - "$PYTHON_PROJECT_DIR/reports/py-trivy.*" + - "$PYTHON_PROJECT_DIR/reports/requirements.txt" rules: # exclude if $PYTHON_TRIVY_ENABLED not set - if: '$PYTHON_TRIVY_ENABLED != "true"'