diff --git a/ci/README.md b/ci/README.md index b131d1a034ef..b7dcb774aba9 100644 --- a/ci/README.md +++ b/ci/README.md @@ -78,6 +78,7 @@ The `./ci/run_envoy_docker.sh './ci/do_ci.sh '` targets are: * `bazel.release` — build Envoy static binary and run tests under `-c opt` with gcc. * `bazel.release.server_only` — build Envoy static binary under `-c opt` with gcc. * `bazel.coverage` — build and run tests under `-c dbg` with gcc, generating coverage information in `$ENVOY_DOCKER_BUILD_DIR/envoy/generated/coverage/coverage.html`. +* `bazel.coverity` — build Envoy static binary and run Coverity Scan static analysis. * `bazel.tsan` — build and run tests under `-c dbg --config=clang-tsan` with clang-5.0. * `check_format`— run `clang-format` 5.0 and `buildifier` on entire source tree. * `fix_format`— run and enforce `clang-format` 5.0 and `buildifier` on entire source tree. @@ -107,3 +108,20 @@ Dependencies are installed by the `ci/mac_ci_setup.sh` script, via [Homebrew](ht which is pre-installed on the CircleCI MacOS image. The dependencies are cached are re-installed on every build. The `ci/mac_ci_steps.sh` script executes the specific commands that build and test Envoy. + +# Coverity Scan Build Flow + +[Coverity Scan Envoy Project](https://scan.coverity.com/projects/envoy-proxy) + +Coverity Scan static analysis is not run within Envoy CI. However, Envoy can be locally built and +submitted for analysis. A Coverity Scan Envoy project token must be generated from the +[Coverity Project Settings](https://scan.coverity.com/projects/envoy-proxy?tab=pro). +With this token, running `ci/do_coverity_local.sh` will use the Ubuntu based +`lyft/envoy-build-ubuntu` image to build the Envoy static binary with the Coverity Scan tool chain. +This process generates an artifact, envoy-coverity-output.tgz, that is uploaded to Coverity for +static analysis. + +To build and submit for analysis: +```bash +COVERITY_TOKEN={generated Coverity project token} ./ci/do_coverity_local.sh +``` diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 140db233dae2..6fccb09b6ab8 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -120,6 +120,24 @@ elif [[ "$1" == "bazel.coverage" ]]; then SRCDIR="${GCOVR_DIR}" "${ENVOY_SRCDIR}"/test/run_envoy_bazel_coverage.sh rsync -av "${ENVOY_BUILD_DIR}"/bazel-envoy/generated/coverage/ "${ENVOY_COVERAGE_DIR}" exit 0 +elif [[ "$1" == "bazel.coverity" ]]; then + # Coverity Scan version 2017.07 fails to analyze the entirely of the Envoy + # build when compiled with Clang 5. Revisit when Coverity Scan explicitly + # supports Clang 5. Until this issue is resolved, run Coverity Scan with + # the GCC toolchain. + setup_gcc_toolchain + echo "bazel Coverity Scan build" + echo "Building..." + cd "${ENVOY_CI_DIR}" + /build/cov-analysis/bin/cov-build --dir "${ENVOY_BUILD_DIR}"/cov-int bazel --batch build --action_env=LD_PRELOAD ${BAZEL_BUILD_OPTIONS} \ + -c opt //source/exe:envoy-static.stamped + # tar up the coverity results + tar czvf "${ENVOY_BUILD_DIR}"/envoy-coverity-output.tgz "${ENVOY_BUILD_DIR}"/cov-int + # Copy the Coverity results somewhere that we can access outside of the container. + cp -f \ + "${ENVOY_BUILD_DIR}"/envoy-coverity-output.tgz \ + "${ENVOY_DELIVERY_DIR}"/envoy-coverity-output.tgz + exit 0 elif [[ "$1" == "fix_format" ]]; then echo "fix_format..." cd "${ENVOY_SRCDIR}" diff --git a/ci/do_coverity_local.sh b/ci/do_coverity_local.sh new file mode 100755 index 000000000000..a7a7776c7e0c --- /dev/null +++ b/ci/do_coverity_local.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# +# do_coverity_local.sh +# +# This script builds Envoy with the Coverity Scan Built Tool. +# +# It expects the following environment variables to be set: +# COVERITY_TOKEN - set to the user's Coverity Scan project token. +# COVERITY_USER_EMAIL - set to the email address used with the Coverity account. +# defaults to the local git config user.email. + + +set -e + +. ./ci/envoy_build_sha.sh + +[[ -z "${ENVOY_DOCKER_BUILD_DIR}" ]] && ENVOY_DOCKER_BUILD_DIR=/tmp/envoy-docker-build +mkdir -p "${ENVOY_DOCKER_BUILD_DIR}" + +TEST_TYPE="bazel.coverity" +COVERITY_USER_EMAIL="${COVERITY_USER_EMAIL:-$(git config user.email)}" +COVERITY_OUTPUT_FILE="${ENVOY_DOCKER_BUILD_DIR}"/envoy/source/exe/envoy-coverity-output.tgz + +if [ -n "${COVERITY_TOKEN}" ] +then + pushd "${ENVOY_DOCKER_BUILD_DIR}" + rm -rf cov-analysis + wget https://scan.coverity.com/download/linux64 --post-data "token=${COVERITY_TOKEN}&project=Envoy+Proxy" -O coverity_tool.tgz + tar xvf coverity_tool.tgz + mv cov-analysis-linux* cov-analysis + popd +else + echo "ERROR: COVERITY_TOKEN is required to download and run Coverity Scan." + exit 1 +fi + +ci/run_envoy_docker.sh "ci/do_ci.sh ${TEST_TYPE}" + +# Check the artifact size as an approximation for determining if the scan tool was successful. +if [[ $(find "${COVERITY_OUTPUT_FILE}" -type f -size +256M 2>/dev/null) ]] +then + echo "Uploading Coverity Scan build" + curl \ + --form token="${COVERITY_TOKEN}" \ + --form email="${COVERITY_USER_EMAIL}" \ + --form file=@"${COVERITY_OUTPUT_FILE}" \ + --form version="${ENVOY_BUILD_SHA}" \ + --form description="Envoy Proxy Build ${ENVOY_BUILD_SHA}" \ + https://scan.coverity.com/builds?project=Envoy+Proxy +else + echo "Coverity Scan output file appears to be too small." + echo "Not submitting build for analysis." + exit 1 +fi