From 4b71d33a0de51611a399e61dbc590ca0980b7d96 Mon Sep 17 00:00:00 2001 From: Florent Pruvost <florent.pruvost@inria.fr> Date: Fri, 22 Sep 2023 16:51:27 +0200 Subject: [PATCH] Add macosx and windows jobs for build and test. Reorganize ci jobs for readibility. --- .gitlab-ci.yml | 222 +++++++++++++++++++---------- analysis.sh => .gitlab/analysis.sh | 49 +++---- .gitlab/build.sh | 26 ++++ .gitlab/test.sh | 27 ++++ .gitlab/validate.sh | 58 ++++++++ README.org | 2 - 6 files changed, 276 insertions(+), 108 deletions(-) rename analysis.sh => .gitlab/analysis.sh (58%) create mode 100755 .gitlab/build.sh create mode 100755 .gitlab/test.sh create mode 100755 .gitlab/validate.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a75e89e..1239392 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,108 +3,174 @@ image: registry.gitlab.inria.fr/solverstack/docker/distrib stages: - build - test - - sonar -# - deploy + - analyze + - validate before_script: - git config --global --add safe.directory $CI_PROJECT_DIR - git submodule update --init --recursive - - mkdir -p build + +.only-master-mr: + interruptible: true + rules: + - if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /^ci-.*$/) + - if: ($CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME !~ /^notest-.*$/) + +.only-mr: + interruptible: true + rules: + - if: ($CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME !~ /^notest-.*$/) hqr_build_linux: stage: build + tags: ["docker", "large"] + extends: .only-master-mr + variables: + SYSTEM: linux + script: + - bash .gitlab/build.sh | tee hqr-build-linux.log artifacts: - name: hqr_build_linux - expire_in: 42 minutes + name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" + expire_in: 180 minutes untracked: true - script: - - cd build - - cmake .. -DCMAKE_INSTALL_PREFIX=${PWD}/../install -DBUILD_SHARED_LIBS=ON -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_C_FLAGS="-O0 -g -fPIC --coverage -Wall -fdiagnostics-show-option -fno-inline" -DCMAKE_EXE_LINKER_FLAGS="--coverage" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON | tee ../hqr-build.log - - ctest --no-compress-output -V -j 5 - -D ExperimentalBuild - -D ExperimentalSubmit | tee -a hqr_build.log - - make install | tee -a ../hqr-build.log - only: - - branches - - master@solverstack/hqr -hqr_test_linux: - stage: test - dependencies: - - hqr_build_linux +hqr_build_macosx: + stage: build + tags: ['macosx'] + extends: .only-master-mr + variables: + SYSTEM: macosx + script: + - bash .gitlab/build.sh | tee hqr-build-linux.log artifacts: - name: hqr_test_linux - expire_in: 42 minutes + name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" + expire_in: 180 minutes + paths: + - hqr-build-linux.log + cache: + key: "${SYSTEM}-${VERSION}-$CI_COMMIT_REF_SLUG" untracked: true + policy: push + +hqr_build_windows: + stage: build + tags: ['windows'] + extends: .only-master-mr + variables: + SYSTEM: windows + CHERE_INVOKING: "yes" + MSYSTEM: UCRT64 script: - - source install/bin/hqr_env.sh - - (cd build && - eval "ctest -D ExperimentalTest - -D ExperimentalCoverage - -D ExperimentalSubmit | tee ../hqr-tests.log") - - lcov --directory . --capture --output-file hqr.lcov - - lcov --summary hqr.lcov | tee -a hqr-gcov.log + - bash -lc .gitlab/build.sh | tee hqr-build-linux.log + artifacts: + name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" + expire_in: 180 minutes + paths: + - hqr-build-linux.log + cache: + key: "${SYSTEM}-${VERSION}-$CI_COMMIT_REF_SLUG" + untracked: true + policy: push -hqr_sonar: - stage: sonar - dependencies: - - hqr_build_linux - - hqr_test_linux +hqr_test_linux: + stage: test + tags: ["docker", "large"] + extends: .only-master-mr + dependencies: [hqr_build_linux] + needs: [hqr_build_linux] + variables: + SYSTEM: linux + script: + - bash .gitlab/test.sh | tee hqr-test-linux.log + coverage: /^\s*lines......:\s*\d+.\d+\%/ artifacts: - name: hqr_sonar - expire_in: 1 week + name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" + expire_in: 180 minutes paths: + - hqr-test-linux.log + - junit.xml + - hqr.lcov - hqr-coverage.xml - - hqr-cppcheck.xml - - hqr-rats.xml - - sonar.log - script: - - ./analysis.sh - only: - - master@solverstack/hqr + reports: + junit: junit.xml -hqr_build_macosx: +hqr_test_macosx: + stage: test tags: ['macosx'] - stage: build + extends: .only-master-mr + dependencies: [hqr_build_macosx] + needs: [hqr_build_macosx] + variables: + SYSTEM: macosx + script: + - bash .gitlab/test.sh | tee hqr-test-macosx.log artifacts: - name: hqr_build_macosx - expire_in: 42 minutes + name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" + expire_in: 180 minutes + paths: + - hqr-test-macosx.log + reports: + junit: junit.xml + cache: + key: "${SYSTEM}-${VERSION}-$CI_COMMIT_REF_SLUG" untracked: true - script: - - cd build - - cmake .. -DCMAKE_INSTALL_PREFIX=${PWD}/../install -DBUILD_SHARED_LIBS=ON -DCMAKE_VERBOSE_MAKEFILE=ON | tee ../hqr-build.log - - ctest --no-compress-output -V -j 5 - -D ExperimentalBuild - -D ExperimentalSubmit | tee -a hqr_build.log - - make install | tee -a ../hqr-build.log - only: - - branches - - master@solverstack/hqr + policy: pull -hqr_test_macosx: - tags: ['macosx'] +hqr_test_windows: stage: test - dependencies: - - hqr_build_macosx + tags: ['windows'] + extends: .only-master-mr + dependencies: [hqr_build_windows] + needs: [hqr_build_windows] + variables: + SYSTEM: windows + CHERE_INVOKING: "yes" + MSYSTEM: UCRT64 + script: + - bash .gitlab/test.sh | tee hqr-test-windows.log artifacts: - name: hqr_test_macosx - expire_in: 42 minutes + name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" + expire_in: 180 minutes + paths: + - hqr-test-windows.log + reports: + junit: junit.xml + cache: + key: "${SYSTEM}-${VERSION}-$CI_COMMIT_REF_SLUG" untracked: true + policy: pull + +sonarqube: + stage: analyze + tags: ["docker", "large"] + extends: .only-master-mr + rules: + - if: $CI_PIPELINE_SOURCE == "merge_request_event" + when: manual + allow_failure: true + dependencies: [hqr_build_linux,hqr_test_linux] + needs: [hqr_build_linux,hqr_test_linux] script: - - source install/bin/hqr_env.sh - - (cd build && - eval "ctest -D ExperimentalTest - -D ExperimentalCoverage - -D ExperimentalSubmit | tee ../hqr-tests.log") + - ./.gitlab/analysis.sh + artifacts: + name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" + expire_in: 180 minutes + paths: + - filelist.txt + - hqr-cppcheck.xml + - hqr-rats.xml + - sonar-project.properties + - sonar.log + when: always -# pages: -# stage: deploy -# script: -# - cmake . -DBUILD_DOCUMENTATION=ON -# - make -# - mv docs/out/html ../public/ -# artifacts: -# paths: -# - public -# only: -# - master@solverstack/hqr +validate: + stage: validate + tags: ["docker", "large"] + extends: .only-mr + needs: [sonarqube] + parallel: + matrix: + - METRIC: [BUG, COVERAGE] + script: + - ./.gitlab/validate.sh $METRIC + allow_failure: true diff --git a/analysis.sh b/.gitlab/analysis.sh similarity index 58% rename from analysis.sh rename to .gitlab/analysis.sh index a98ea1d..dc20068 100755 --- a/analysis.sh +++ b/.gitlab/analysis.sh @@ -13,7 +13,7 @@ # Performs an analysis of HQR source code: # - we consider to be in HQR's source code root -# - we consider having the coverage file hqr.lcov in the root directory +# - we consider having the junit.xml file and the coverage file hqr-coverage.xml in the root directory # - we consider having cppcheck, rats, sonar-scanner programs available in the environment if [ $# -gt 0 ] @@ -26,12 +26,6 @@ BUILDDIR=${BUILDDIR:-build} rm -f filelist.txt git ls-files | grep "\.[ch]$" > filelist.txt -# Generate coverage analysis report -python3 /usr/local/lib/python3.8/dist-packages/lcov_cobertura.py hqr.lcov --output hqr-coverage.xml - -# to get it displayed and captured by gitlab to expose the badge on the main page -cat ./hqr-gcov.log - # Undefine this because not relevant in our configuration export UNDEFINITIONS="-UWIN32 -UWIN64 -U_MSC_EXTENSIONS -U_MSC_VER -U__SUNPRO_C -U__SUNPRO_CC -U__sun -Usun -U__cplusplus" @@ -41,39 +35,38 @@ cppcheck -v -f --project=build/compile_commands.json --language=c --platform=uni # run rats analysis rats -w 3 --xml `cat filelist.txt` > hqr-rats.xml -# Set the default for the project key -SONARQUBE_PROJECTKEY=${SONARQUBE_PROJECTKEY:-hiepacs:hqr:gitlab:master} - # create the sonarqube config file cat > sonar-project.properties << EOF sonar.host.url=https://sonarqube.inria.fr/sonarqube -sonar.login=$SONARQUBE_LOGIN sonar.links.homepage=$CI_PROJECT_URL sonar.links.scm=$CI_REPOSITORY_URL sonar.links.ci=$CI_PROJECT_URL/pipelines sonar.links.issue=$CI_PROJECT_URL/issues -sonar.projectKey=$SONARQUBE_PROJECTKEY +sonar.projectKey=${CI_PROJECT_NAMESPACE}:${CI_PROJECT_NAME} sonar.projectDescription=Library for hierarchical QR/LQ reduction trees -sonar.projectVersion=master +sonar.projectVersion=0.1 + +sonar.scm.disabled=false +sonar.scm.provider=git +sonar.scm.exclusions.disabled=true +sonar.sourceEncoding=UTF-8 sonar.sources=include, src, testings sonar.inclusions=`cat filelist.txt | xargs echo | sed 's/ /, /g'` -sonar.sourceEncoding=UTF-8 -sonar.c.errorRecoveryEnabled=true -sonar.c.compiler.charset=UTF-8 -sonar.c.compiler.parser=GCC -sonar.c.compiler.regex=^(.*):(\\d+):\\d+: warning: (.*)\\[(.*)\\]$ -sonar.c.compiler.reportPath=hqr-build.log -sonar.c.coverage.reportPath=hqr-coverage.xml -sonar.c.cppcheck.reportPath=hqr-cppcheck.xml -sonar.c.rats.reportPath=hqr-rats.xml -sonar.c.jsonCompilationDatabase=${BUILDDIR}/compile_commands.json -sonar.lang.patterns.c++: **/*.cxx,**/*.cpp,**/*.cc,**/*.hxx,**/*.hpp,**/*.hh -sonar.lang.patterns.c: **/*.c,**/*.h -sonar.lang.patterns.python: **/*.py + +sonar.cxx.jsonCompilationDatabase=${BUILDDIR}/compile_commands.json +sonar.cxx.file.suffixes=.h,.c +sonar.cxx.errorRecoveryEnabled=true +sonar.cxx.gcc.encoding=UTF-8 +sonar.cxx.gcc.regex=(?<file>.*):(?<line>[0-9]+):[0-9]+:\\\x20warning:\\\x20(?<message>.*)\\\x20\\\[(?<id>.*)\\\] +sonar.cxx.gcc.reportPaths=hqr-build*.log +sonar.cxx.xunit.reportPaths=junit.xml +sonar.cxx.cobertura.reportPaths=hqr-coverage.xml +sonar.cxx.cppcheck.reportPaths=hqr-cppcheck.xml +sonar.cxx.rats.reportPaths=hqr-rats.xml EOF -# run sonar analysis + publish on sonarqube-dev -sonar-scanner -X > sonar.log +# run sonar analysis + publish on sonarqube +sonar-scanner -X -Dsonar.login=$SONARQUBE_LOGIN > sonar.log diff --git a/.gitlab/build.sh b/.gitlab/build.sh new file mode 100755 index 0000000..86efc5c --- /dev/null +++ b/.gitlab/build.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +fatal() { + echo "$0: error occurred, exit" + exit 1 +} + +set -x + +if [[ "$SYSTEM" == "linux" ]]; then + + # on linux we perform a coverage analysis + cmake -B build -S . -DCMAKE_INSTALL_PREFIX=$PWD/install \ + -DBUILD_SHARED_LIBS=ON -DCMAKE_VERBOSE_MAKEFILE=ON \ + -DCMAKE_C_FLAGS="-O0 -g -fPIC --coverage -Wall -fdiagnostics-show-option -fno-inline" \ + -DCMAKE_EXE_LINKER_FLAGS="--coverage" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON || fatal + +else + + # no coverage analysis on other platforms + cmake -B build -S . -DCMAKE_INSTALL_PREFIX=$PWD/install \ + -DBUILD_SHARED_LIBS=ON -DCMAKE_VERBOSE_MAKEFILE=ON || fatal + +fi +cmake --build build -j 4 || fatal +cmake --install build || fatal diff --git a/.gitlab/test.sh b/.gitlab/test.sh new file mode 100755 index 0000000..2edbdc7 --- /dev/null +++ b/.gitlab/test.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +fatal() { + echo "$0: error occurred, exit" + exit 1 +} + +set -x + +if [[ "$SYSTEM" == "linux" ]]; then + source install/bin/hqr_env.sh || fatal +fi +cd build +if [[ "$SYSTEM" == "windows" ]]; then + # this is required with BUILD_SHARED_LIBS=ON + export PATH="/c/Windows/WinSxS/x86_microsoft-windows-m..namespace-downlevel_31bf3856ad364e35_10.0.19041.1_none_21374cb0681a6320":$PATH + export PATH=$PWD/src:$PATH +fi +ctest --output-on-failure --no-compress-output -T Test --output-junit ../junit.xml || fatal +if [[ "$SYSTEM" == "linux" ]]; then + # clang is used on macosx and it is not compatible with --coverage option + # so that we can only make the coverage report on the linux runner with gcc + cd .. + lcov --capture --directory build -q --output-file hqr.lcov + lcov --summary hqr.lcov + lcov_cobertura hqr.lcov --output hqr-coverage.xml +fi diff --git a/.gitlab/validate.sh b/.gitlab/validate.sh new file mode 100755 index 0000000..daf827c --- /dev/null +++ b/.gitlab/validate.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +### +# +# @file validate.sh +# @copyright 2023-2023 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria, +# Univ. Bordeaux. All rights reserved. +# +# @version 1.0.0 +# @author Mathieu Faverge +# @author Florent Pruvost +# @date 2023-09-22 +# +### + +# Check some metrics on sonarqube (https://sonarqube.inria.fr/sonarqube/) +# and depending on the value return 0 (success) or 1 (failure). + +if [ $# -gt 0 ]; then + METRIC=$1 +fi +METRIC=${METRIC:-BUG} + +if [[ -z $CI_MERGE_REQUEST_IID || -z $CI_PROJECT_NAMESPACE || -z $CI_PROJECT_NAME ]]; then + echo "One of the variables CI_MERGE_REQUEST_IID, CI_PROJECT_NAMESPACE, + CI_PROJECT_NAME is empty. This script must be used during a gitlab merge + request only -> Failure." + exit 1 +fi + +if [[ -z $SONARQUBE_LOGIN ]]; then + echo "SONARQUBE_LOGIN is empty, please give a valid sonarqube user's token, + with permissions set on the project -> Failure." + exit 1 +fi + +if [[ $METRIC == "BUG" ]]; then + BUG=`curl -u $TOKEN: -X GET "https://sonarqube.inria.fr/sonarqube/api/measures/component?component=${CI_PROJECT_NAMESPACE}%3A${CI_PROJECT_NAME}&pullRequest=${CI_MERGE_REQUEST_IID}&metricKeys=new_bugs" |jq '.component.measures[0].period.value' | sed -e "s#\"##g"` + if [[ $BUG > 0 ]]; then + echo "%{BUG} new bugs detected by Sonarqube -> Failure." + exit 1 + else + echo "No new bugs detected by Sonarqube -> Success." + exit 0 + fi +elif [[ $METRIC == "COVERAGE" ]]; then + COV=`curl -u $TOKEN: -X GET "https://sonarqube.inria.fr/sonarqube/api/measures/component?component=${CI_PROJECT_NAMESPACE}%3A${CI_PROJECT_NAME}&pullRequest=${CI_MERGE_REQUEST_IID}&metricKeys=new_coverage" |jq '.component.measures[0].period.value' | sed -e "s#\"##g"` + if [[ $COV == "null" || -z $COV ]]; then + echo "Coverage is empty, certainly that there are no lines of new code (considered during the analysis) to compare -> Success." + else + if [[ $COV < 80 ]]; then + echo "Coverage on new lines is ${COV}%, which is < 80% -> Failure." + exit 1 + else + echo "Coverage on new lines is ${COV}%, which is >= 80% -> Success." + exit 0 + fi + fi +fi diff --git a/README.org b/README.org index ac371c5..4780442 100644 --- a/README.org +++ b/README.org @@ -3,8 +3,6 @@ #+OPTIONS: H:3 num:t \n:nil @:t ::t |:t _:nil ^:nil -:t f:t *:t <:t #+OPTIONS: TeX:t LaTeX:t skip:nil d:nil pri:nil tags:not-in-toc html-style:nil -[[https://gitlab.inria.fr/solverstack/hqr/pipelines][https://gitlab.inria.fr/solverstack/hqr/badges/master/pipeline.svg]] [[https://gitlab.inria.fr/solverstack/hqr/commits/master][https://gitlab.inria.fr/solverstack/hqr/badges/master/coverage.svg]] - HQR is a C library providing tools to generate hierarchical trees adapted to 2D block-cyclic data distribution and algorithms based on tiled QR/algorithms. This library is used in [[https://gitlab.inria.fr/solverstack/chameleon][Chameleon]] and [[https://bitbucket.org/mfaverge/parsec][DPLASMA]]. -- GitLab