1# pre_check stage
2clang_tidy_check:
3  extends:
4    - .pre_check_base_template
5    - .rules:patterns:clang_tidy
6  image: ${CLANG_STATIC_ANALYSIS_IMAGE}
7  artifacts:
8    paths:
9      - $OUTPUT_DIR
10    when: always
11    expire_in: 1 day
12  variables:
13    CLANG_TIDY_RUNNER_PROJ: 2107  # idf/clang-tidy-runner
14    CLANG_TIDY_DIRS_TXT: ${CI_PROJECT_DIR}/tools/ci/clang_tidy_dirs.txt
15    RULES_FILE: ${CI_PROJECT_DIR}/tools/ci/static-analysis-rules.yml
16    OUTPUT_DIR: ${CI_PROJECT_DIR}/clang_tidy_reports
17  script:
18    - python -m pip install -U pip
19    - internal_pip_install $CLANG_TIDY_RUNNER_PROJ pyclang
20    - export PATH=$PATH:$(python -c "import sys; print(sys.executable.rsplit('/', 1)[0])")
21    - dirs=$(cat ${CLANG_TIDY_DIRS_TXT} | while read line; do echo ${CI_PROJECT_DIR}/${line}; done | xargs)
22    - run_cmd idf_clang ${dirs}
23      --output-path ${OUTPUT_DIR}
24      --limit-file ${RULES_FILE}
25      --xtensa-include-dir
26      --run-clang-tidy-py ${RUN_CLANG_TIDY_PY}
27
28check_pylint:
29  extends:
30    - .pre_check_base_template
31    - .rules:patterns:python-files
32    - .before_script_minimal
33  image: $SONARQUBE_SCANNER_IMAGE
34  artifacts:
35    when: always
36    paths:
37      - pylint-report.txt
38    expire_in: 1 week
39  script:
40    - export PYTHONPATH="$IDF_PATH/tools:$IDF_PATH/tools/ci/python_packages:$PYTHONPATH"
41    - |
42      if [ -n "$CI_MERGE_REQUEST_IID" ]; then
43        export files=$(python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py files ${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} | grep ".py");
44      else
45        export files=$(find . -iname "*.py" -print);
46      fi
47    - pylint --rcfile=.pylintrc $files -r n --output-format=parseable > pylint-report.txt || exit 0
48
49# build stage
50# Sonarqube related jobs put here for this reason:
51# Here we have two jobs. code_quality_check and code_quality_report.
52#
53# code_quality_check will analyze the code changes between your MR and
54# code repo stored in sonarqube server. The analysis result is only shown in
55# the comments under this MR and won't be transferred to the server.
56#
57# code_quality_report will analyze and transfer both of the newly added code
58# and the analysis result to the server.
59#
60# Put in the front to ensure that the newly merged code can be stored in
61# sonarqube server ASAP, in order to avoid reporting unrelated code issues
62.sonar_scan_template:
63  stage: build
64  image:
65    name: $SONARQUBE_SCANNER_IMAGE
66  before_script:
67    - source tools/ci/utils.sh
68    - export PYTHONPATH="$CI_PROJECT_DIR/tools:$CI_PROJECT_DIR/tools/ci/python_packages:$PYTHONPATH"
69    - fetch_submodules
70    # Exclude the submodules, all paths ends with /**
71    - submodules=$(get_all_submodules)
72    # get all exclude paths specified in tools/ci/sonar_exclude_list.txt | ignore lines start with # | xargs | replace all <space> to <comma>
73    - custom_excludes=$(cat $CI_PROJECT_DIR/tools/ci/sonar_exclude_list.txt | grep -v '^#' | xargs | sed -e 's/ /,/g')
74    # Exclude the report dir as well
75    - export EXCLUSIONS="$custom_excludes,$submodules"
76    - export SONAR_SCANNER_OPTS="-Xmx2048m"
77
78  variables:
79    GIT_DEPTH: 0
80    REPORT_PATTERN: clang_tidy_reports/*.txt
81  artifacts:
82    when: always
83    paths:
84      - $REPORT_PATTERN
85  tags:
86    - host_test
87  dependencies:  # Here is not a hard dependency relationship, could be skipped when only python files changed. so we do not use "needs" here.
88    - clang_tidy_check
89    - check_pylint
90
91code_quality_check:
92  extends:
93    - .sonar_scan_template
94    - .rules:patterns:static-code-analysis-preview
95  allow_failure: true  # since now it's using exit code to indicate the code analysis result,
96                       # we don't want to block ci when critical issues founded
97  script:
98    - export CI_MERGE_REQUEST_COMMITS=$(python ${CI_PROJECT_DIR}/tools/ci/ci_get_mr_info.py commits ${CI_COMMIT_REF_NAME} | tr '\n' ',')
99    # test if this branch have merge request, if not, exit 0
100    - test -n "$CI_MERGE_REQUEST_IID" || exit 0
101    - test -n "$CI_MERGE_REQUEST_COMMITS" || exit 0
102    - sonar-scanner
103      -Dsonar.analysis.mode=preview
104      -Dsonar.branch.name=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
105      -Dsonar.cxx.clangtidy.reportPath=$REPORT_PATTERN
106      -Dsonar.exclusions=$EXCLUSIONS
107      -Dsonar.gitlab.ci_merge_request_iid=$CI_MERGE_REQUEST_IID
108      -Dsonar.gitlab.commit_sha=$CI_MERGE_REQUEST_COMMITS
109      -Dsonar.gitlab.merge_request_discussion=true
110      -Dsonar.gitlab.ref_name=$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME
111      -Dsonar.host.url=$SONAR_HOST_URL
112      -Dsonar.login=$SONAR_LOGIN
113      -Dsonar.python.pylint.reportPath=pylint-report.txt
114
115code_quality_report:
116  extends:
117    - .sonar_scan_template
118    - .rules:protected
119  allow_failure: true  # since now it's using exit code to indicate the code analysis result,
120                       # we don't want to block ci when critical issues founded
121  script:
122    - sonar-scanner
123      -Dsonar.branch.name=$CI_COMMIT_REF_NAME
124      -Dsonar.cxx.clangtidy.reportPath=$REPORT_PATTERN
125      -Dsonar.exclusions=$EXCLUSIONS
126      -Dsonar.gitlab.commit_sha=$PIPELINE_COMMIT_SHA
127      -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
128      -Dsonar.host.url=$SONAR_HOST_URL
129      -Dsonar.login=$SONAR_LOGIN
130      -Dsonar.python.pylint.reportPath=pylint-report.txt
131