language: c

# Coverity Scan can be configured through Travis addons, but this allows for
# more control over the build instructions and does not require the addition
# of a coverity_scan branch in the repository. travisci_build_coverity_scan.sh
# does more checks before it decides to download Coverity (around 500M), but
# these instructions assume Coverity Scan is not installed if the directory
# does not exist and expects the download to fail if the token is incorrect.
# Coverity Scan quota are not checked as the Coverity enabled build must only
# run from cron.
install_coverity: &install_coverity
  - if [ "${COVERITY_SCAN}" = "true" ]; then
      COV_DIR="/tmp/coverity-scan-analysis";
      COV_ARC="/tmp/cov-analysis-${COV_PLATFORM}.tgz";
      test ! -d "${COV_DIR}" &&
        mkdir -p "${COV_DIR}" &&
        curl -s -S -F project="${TRAVIS_REPO_SLUG}"
                   -F token="${COVERITY_SCAN_TOKEN}"
                   -o "${COV_ARC}"
                   "https://scan.coverity.com/download/cxx/${COV_PLATFORM}" &&
        tar -xzf "${COV_ARC}" -C "${COV_DIR}";
      COV_ANALYSIS=$(find "${COV_DIR}" -type d -name "cov-analysis*");
      eval "export PATH=\"${PATH}:${COV_ANALYSIS}/bin\"";
      eval "export SCAN_BUILD=\"cov-build --dir cov-int\"";
      cov-configure --comptype ${COV_COMPTYPE} --compiler ${CC} --template;
    fi

submit_to_coverity_scan: &submit_to_coverity_scan
  - if [ "${COVERITY_SCAN}" = "true" ]; then
      tar -czf analysis-results.tgz cov-int &&
      curl -s -S -F project="${TRAVIS_REPO_SLUG}"
                 -F token="${COVERITY_SCAN_TOKEN}"
                 -F file=@analysis-results.tgz
                 -F version=$(git rev-parse --short HEAD)
                 -F description="Travis CI build"
                 -F email="${COVERITY_SCAN_EMAIL:=cyclonedds-inbox@eclipse.org}"
                 "https://scan.coverity.com/builds";
    fi

submit_to_codecov: &submit_to_codecov
  - |
    if [ "${CODECOV}" = "true" ]; then
      query=$(curl -Gso /dev/null -w "%{url_effective}" "" \
        --data-urlencode "package=cmake-codecov.io" \
        --data-urlencode "token=${CODECOV_TOKEN}" \
        --data-urlencode "branch=${TRAVIS_BRANCH}" \
        --data-urlencode "commit=${TRAVIS_PULL_REQUEST_SHA:-$TRAVIS_COMMIT}" \
        --data-urlencode "build=${TRAVIS_JOB_NUMBER}" \
        --data-urlencode "tag=${TRAVIS_TAG}" \
        --data-urlencode "slug=${TRAVIS_REPO_SLUG}" \
        --data-urlencode "service=travis" \
        --data-urlencode "flags=" \
        --data-urlencode "pr=${TRAVIS_PULL_REQUEST}" \
        --data-urlencode "job=${TRAVIS_JOB_ID}" 2>/dev/null | cut -c 3- | sed -e 's/%0A//');
      cmake --build . --target codecov &&
      curl -X POST \
        --data-binary @"codecov.tar.gz" \
        --retry 5 --retry-delay 2 --connect-timeout 2 \
        -H 'Content-Type: text/plain' \
        -H 'Content-Encoding: gzip' \
        -H 'X-Content-Encoding: gzip' \
        -H 'Accept: text/plain' \
        "https://codecov.io/upload/v2?$query";
    fi

# Coverity doesn't support gcc 10 yet
ubuntu1804_gcc7: &ubuntu1804_gcc7
  os: linux
  dist: bionic
  compiler: gcc
  before_install:
    - eval "export CC=gcc CXX=g++"
    - eval "export COV_COMPTYPE=gcc COV_PLATFORM=linux64"
    - eval "export BUILD_TOOL_OPTIONS='-j 4'"
    - eval "export GENERATOR='Unix Makefiles'"
  install:
    - *install_coverity
    - pip install conan --upgrade --user

ubuntu1804_gcc10: &ubuntu1804_gcc10
  os: linux
  dist: bionic
  compiler: gcc
  addons:
    apt:
      update: true
      sources:
        - sourceline: 'ppa:ubuntu-toolchain-r/test'
      packages: [ gcc-10 g++-10 ]
  before_install:
    - eval "export CC=gcc-10 CXX=g++-10"
    - eval "export COV_COMPTYPE=gcc COV_PLATFORM=linux64"
    - eval "export BUILD_TOOL_OPTIONS='-j 4'"
    - eval "export GENERATOR='Unix Makefiles'"
  install:
    - pip install conan --upgrade --user

ubuntu1804_clang10: &ubuntu1804_clang10
  os: linux
  dist: bionic
  compiler: clang
  addons:
    apt:
      update: true
      sources:
        - sourceline: 'deb https://apt.llvm.org/bionic llvm-toolchain-bionic-10 main'
          key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
      packages: [ clang-10 clang++-10 ]
  before_install:
    - eval "export CC=clang-10 CXX=clang++-10"
    - eval "export COV_COMPTYPE=clang COV_PLATFORM=linux64"
    - eval "export BUILD_TOOL_OPTIONS='-j 4'"
    - eval "export GENERATOR='Unix Makefiles'"
  install:
    - pip install conan --upgrade --user

macos1015_xcode11_5: &macos1015_xcode11_5
  os: osx
  osx_image: xcode11.5
  compiler: clang
  addons:
    homebrew:
      packages: [ python3, bison, flex ]
  before_install:
    - eval "export CC=clang CXX=clang++"
    - eval "export COV_COMPTYPE=clang COV_PLATFORM=macOSX"
    - eval "export BUILD_TOOL_OPTIONS='-j 4'"
    - eval "export GENERATOR='Unix Makefiles'"
    - eval "export PATH=\"${PATH}:$(python3 -m site --user-base)/bin\""
    - eval "export PATH=\"/usr/local/opt/flex/bin:/usr/local/opt/bison/bin:${PATH}\""
  install:
    - python3 -m pip install conan --upgrade --user

freebsd12_clang8: &freebsd12_clang8
  os: freebsd
  compiler: clang
  addons:
    pkg:
      packages: [ py37-pip ]
  before_install:
    - eval "export BUILD_TOOL_OPTIONS='-j 4'"
    - eval "export GENERATOR='Unix Makefiles'"
  install:
    - pip install conan --upgrade --user

windows1809_vs2017: &windows1809_vs2017
  os: windows
  # Conan will automatically determine the best compiler for a given platform
  # based on educated guesses. The first check is based on the CC and CXX
  # environment variables, the second (on Windows) is to check if Microsoft
  # Visual Studio is installed. On Travis CC and CXX are set to gcc on
  # Microsoft Windows targets as well, this has the undesired effect that MSVC
  # is not detected, unsetting CC and CXX solves that problem.
  #
  #
  # !!! IMPORTANT !!!
  #
  # Microsoft Windows instances freeze at "install:" if secure environment
  # variables are used. There is no option to export secrets only for
  # specified platforms. The "filter_secrets: false" option is used to disable
  # the filter for Microsoft Windows instances. This is not an issue if the
  # secret is removed from the environment at the earliest opportunity, before
  # risk of exposure, as secrets are always removed from the environment for
  # pull requests and are still filtered when exported to the environment. The
  # secret of course will not be available for Microsoft Windows builds, but
  # for Coverity Scan, that is fine.
  filter_secrets: false
  before_install:
    - eval "unset COVERITY_SCAN_TOKEN"
    - eval "unset COVERITY_SCAN_EMAIL"
    - eval "unset CC CXX"
    - eval "export COV_COMPTYPE=msvc COV_PLATFORM=win64"
    - eval "export BUILD_TOOL_OPTIONS='-nologo -verbosity:minimal -maxcpucount -p:CL_MPCount=2'"
    - |
      if [ "${ARCH}" = "x86_64" ]; then
        eval "export GENERATOR='Visual Studio 15 2017 Win64'"
      else
        eval "export GENERATOR='Visual Studio 15 2017'"
      fi
  # Windows targets in Travis are still very much in beta and Python is not yet
  # available and installation of Python through Chocolaty does not work well.
  # The real fix is to wait until Python and pip are both available on the
  # target. Until then download Conan from the official website and simply add
  # the extracted folder to the path.
  install:
    - choco install innoextract
    - choco install winflexbison3
    - wget -q https://dl.bintray.com/conan/installers/conan-win-64_1_34_0.exe
    - innoextract conan-win-64_1_34_0.exe
    - eval "export PATH=\"$(pwd)/app/conan:${PATH}\""

jobs:
  include:
    - <<: *ubuntu1804_gcc7
      env: [ ARCH=x86_64, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES, COVERITY_SCAN=true ]
      if: type = cron
    - <<: *ubuntu1804_gcc7
      env: [ ARCH=x86_64, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES, CODECOV=true ]
      if: type = cron
    - <<: *ubuntu1804_gcc10
      env: [ ARCH=x86_64, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]
    - <<: *ubuntu1804_gcc7
      env: [ ARCH=x86_64, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=NO, CONANFILE=conanfile102.txt ]
    - <<: *ubuntu1804_gcc10
      env: [ ARCH=x86_64, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]
    - <<: *ubuntu1804_gcc10
      env: [ ARCH=x86_64, BUILD_TYPE=Debug, SSL=NO, SECURITY=YES, LIFESPAN=NO, DEADLINE=NO, TYPE_DISCOVERY=NO, TOPIC_DISCOVERY=NO ]
    - <<: *ubuntu1804_clang10
      env: [ ARCH=x86_64, SANITIZER=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]
    - <<: *ubuntu1804_clang10
      env: [ ARCH=x86_64, SANITIZER=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=NO, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]
    - <<: *ubuntu1804_clang10
      env: [ ARCH=x86_64, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]
    - <<: *macos1015_xcode11_5
      env: [ ARCH=x86_64, BUILD_TYPE=Release, SSL=NO, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES, MACOSX_DEPLOYMENT_TARGET=10.12 ]
    - <<: *macos1015_xcode11_5
      env: [ ARCH=x86_64, SANITIZER=address, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]
    - <<: *macos1015_xcode11_5
      env: [ ARCH=x86_64, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]
    # CUnit package in ConanCenter does not build on 32-bit Windows
    #- <<: *windows1809_vs2017
    #  env: [ ARCH=x86, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES, CONANFILE=conanfile102.txt ]
    - <<: *windows1809_vs2017
      env: [ ARCH=x86_64, BUILD_TYPE=Debug, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]
    - <<: *windows1809_vs2017
      env: [ ARCH=x86_64, BUILD_TYPE=Release, SSL=YES, SECURITY=YES, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]
    # CUnit package in ConanCenter does not build on FreeBSD
    #- <<: *freebsd12_clang8
    #  env: [ ARCH=x86_64, BUILD_TYPE=Debug, SSL=NO, SECURITY=NO, LIFESPAN=YES, DEADLINE=YES, TYPE_DISCOVERY=YES, TOPIC_DISCOVERY=YES ]

before_script:
  - conan profile new default --detect
  - conan remote add bincrafters https://api.bintray.com/conan/bincrafters/public-conan

# Notes on test settings:
# - CYCLONEDDS_URI:
#   - EnableExpensiveChecks: for the few horrendously expensive (but pretty thorough)
#     integrity checks, in particular on the WHC and the RHC, but there may be more
#   - config to stderr: gives the configuration used when running the test in conjunction
#     with "--output-on-failure" (sadly that still doesn't output the failed
#     assertions ...)
# - -j 4: run 4 tests in parallel, this saves quite a bit of time because the VMs are
#   all dual-core
# - --output-on-failed: print whatever output the test generated when it failed, which
#   can obviously be quite helpful for debugging
# - -E ...: regex of tests to exclude:
#     CUnit_ddsrt_random_default_random: performs a Chi-square test on the output of
#     the random generator, but this does produce the odd failure (it should!).  The
#     code has been vetted, the test has been run a great many times (with the odd
#     failure), and so we now simply skip the test to avoid the spurious failures.
script:
  - INSTALLPREFIX="$(pwd)/install"
  - mkdir build
  - cd build
  - conan install -b missing -s arch=${ARCH} -s build_type=${BUILD_TYPE} ../${CONANFILE:-conanfile.txt}
  - cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
          -DCMAKE_INSTALL_PREFIX=${INSTALLPREFIX}
          -DSANITIZER=${SANITIZER}
          -DENABLE_SSL=${SSL}
          -DENABLE_SECURITY=${SECURITY}
          -DENABLE_LIFESPAN=${LIFESPAN}
          -DENABLE_DEADLINE_MISSED=${DEADLINE}
          -DENABLE_TYPE_DISCOVERY=${TYPE_DISCOVERY}
          -DENABLE_TOPIC_DISCOVERY=${TOPIC_DISCOVERY}
          -DENABLE_COVERAGE=${CODECOV}
          -DBUILD_TESTING=on
          -DBUILD_IDLC_TESTING=on
          -DBUILD_EXAMPLES=on
          -DWERROR=on
          -G "${GENERATOR}" ..
  - ${SCAN_BUILD} cmake --build . --config ${BUILD_TYPE} --target install -- ${BUILD_TOOL_OPTIONS}
  - CYCLONEDDS_URI='<CycloneDDS><Domain><Internal><EnableExpensiveChecks>rhc,whc</EnableExpensiveChecks><LivelinessMonitoring>true</LivelinessMonitoring></Internal><Tracing><Verbosity>config</Verbosity><OutputFile>stderr</OutputFile></Tracing></Domain></CycloneDDS>' ctest -j 4 --output-on-failure -T test -E '^CUnit_ddsrt_random_default_random$' -C ${BUILD_TYPE}
  - |
    if [ -z "${SANITIZER}" ]; then
      ${SHELL} ../src/tools/ddsperf/sanity.bash;
    fi
  - |
    if [ -n "${SANITIZER}" ]; then
      CMAKE_LINKER_FLAGS="-DCMAKE_LINKER_FLAGS=-fsanitize=${SANITIZER}";
      CMAKE_C_FLAGS="-DCMAKE_C_FLAGS=-fsanitize=${SANITIZER}";
    fi
  - |
    if [ "${SSL}" = "YES" ] && [ "${SECURITY}" = "YES" ]; then
      diff --strip-trailing-cr ../etc/cyclonedds.rnc docs/cyclonedds.rnc && \
      diff --strip-trailing-cr ../etc/cyclonedds.xsd docs/cyclonedds.xsd && \
      diff --strip-trailing-cr ../docs/manual/options.md docs/manual/options.md
    fi
  - cd ..
  - mkdir helloworld_build
  - cd helloworld_build
  - cmake -DCMAKE_PREFIX_PATH=${INSTALLPREFIX}
          -DCMAKE_BUILD_TYPE=${BUILD_TYPE}
          ${CMAKE_C_FLAGS}
          ${CMAKE_LINKER_FLAGS}
          -G "${GENERATOR}"
          ${INSTALLPREFIX}/share/CycloneDDS/examples/helloworld
  - cmake --build . --config ${BUILD_TYPE}
  - cd "${TRAVIS_BUILD_DIR}/build"

after_success:
  - *submit_to_coverity_scan
  - *submit_to_codecov
