Sonarcloud 显示新代码的覆盖率是 0%,并且还显示 gitlab ci 的主分支覆盖率是 0%

问题描述 投票:0回答:1

我正在使用 GitLab ci 对代码运行 SonarCloud 代码分析。

这是我的 gitlab-ci.yaml

stages:
  - test

before_script:
  - mkdir -p ~/.ssh &&
    cp $gitlab_private_key ~/.ssh/id_ed25519 &&
    chmod 600 ~/.ssh/id_ed25519 &&
    touch ~/.ssh/known_hosts &&
    ssh-keyscan gitlab.com >> ~/.ssh/``known_hosts

variables:
  SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
  GITLAB_PROJECT_ID: ${CI_PROJECT_ID} # needed to be exported to the project's environments
  FLASK_APP: manage.py

sonarcloud-check:
  image:
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""]
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script:
    - sonar-scanner
  only:
    - merge_requests
    - master

test-merge-request-changes:
  stage: test
  only:
    - merge_requests
  image:
    name: docker:19.03.13-git
  services:
    - name: docker:19.03.0-dind
      entrypoint: ["env", "-u", "DOCKER_HOST"]
      command: ["dockerd-entrypoint.sh"]
  variables:
    DOCKER_HOST: tcp://localhost:2375
    DOCKER_TLS_CERTDIR: ""
    DOCKER_DRIVER: overlay2
    ENV: test
    CI_DEBUG_TRACE: "true"
  before_script:
    - echo $CI_BUILD_TOKEN | docker login -u gitlab-ci-token --password-stdin ${CI_REGISTRY}
  script:
    - echo "Running Tests..."
    - cp ${group_shared_vars} ${CI_PROJECT_DIR}/.env
    - docker build . -f Dockerfile-testing -t test_merge_req --build-arg GITLAB_PROJECT_ID=${GITLAB_PROJECT_ID}
    - docker run --cidfile="my-package.txt" test_merge_req:latest

  after_script:
    - touch text2.txt
    - docker cp $(cat my-package.txt):/app/tests/coverage/coverage.xml coverage.xml
    - docker cp $(cat my-package.txt):/app/tests/coverage/junit.xml junit.xml
  timeout: 2h
  artifacts:
    when: always
    reports:
      cobertura:
        - coverage.xml
      junit:
        - junit.xml
  coverage: '/TOTAL.*\s+(\d+%)$/'

这是我的

sonar-project.properties

sonar.projectKey=my_app-key
sonar.organization=my_org

sonar.sources=lib
sonar.tests=tests
sonar.exclusions=tests
sonar.language=python
sonar.python.version=3.8

我想获取由 sonarcloud 在每个合并请求上分析的容器中生成的报告。

此外,当代码推送到主分支时,我想获取要更新的项目在sonarcloud上的覆盖率,但它只显示0%。

有什么方法可以在合并请求运行后,我们在 docker 容器的报告上获得 sonarcloud 分析吗?

并且还可以更新主分支覆盖率,而无需将

coverage.xml
提交到存储库?

gitlab code-coverage coverage.py sonarcloud
1个回答
3
投票

深入研究了 Gitlab CI 阶段和作业的工作方式以及此线程带来的见解后,我对上述 GitLab ci 进行了调整,以便它:

  1. 首先运行测试
  2. 然后将覆盖率输出上传到为工件指定的路径中
  3. 然后在下一阶段,它会提取这些工件
  4. path
    命令替换
    pytest-cov
    中被
    <source>...</source>
    替换的
    sed
    。 (此步骤是因为放置到源元素中的路径与 docker 容器相关,然后下载覆盖率报告后在 GitLab ci 容器内不起作用)
  5. 在覆盖率报告上运行
    sonar-scanner

GitLab ci:

stages:
  - build_test
  - analyze_test

before_script:
  - mkdir -p ~/.ssh &&
    cp $gitlab_private_key ~/.ssh/id_ed25519 &&
    chmod 600 ~/.ssh/id_ed25519 &&
    touch ~/.ssh/known_hosts &&
    ssh-keyscan gitlab.com >> ~/.ssh/``known_hosts

variables:
  SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"  # Defines the location of the analysis task cache
  GIT_DEPTH: "0"  # Tells git to fetch all the branches of the project, required by the analysis task
  GITLAB_PROJECT_ID: ${CI_PROJECT_ID} # needed to be exported to the projects environments

include:
  - template: Code-Quality.gitlab-ci.yml

test-merge-request:
  stage: build_test
  only:
    - merge_requests
    - master
  image:
    name: docker:19.03.13-git
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - build
  services:
    - name: docker:19.03.0-dind
      entrypoint: ["env", "-u", "DOCKER_HOST"]
      command: ["dockerd-entrypoint.sh"]
  variables:
    DOCKER_HOST: tcp://localhost:2375
    DOCKER_TLS_CERTDIR: ""
    DOCKER_DRIVER: overlay2
    ENV: test
    CI_DEBUG_TRACE: "true"
  before_script:
    - echo $CI_BUILD_TOKEN | docker login -u gitlab-ci-token --password-stdin ${CI_REGISTRY}
  script:
    - echo "Running Tests..."
    - cp ${group_shared_vars} ${CI_PROJECT_DIR}/.env
    - docker build . -f Dockerfile-testing -t test_merge_req --build-arg GITLAB_PROJECT_ID=${GITLAB_PROJECT_ID}
    - docker run --cidfile="my-package.txt" test_merge_req:latest
  after_script:
    - docker cp $(cat my-package.txt):/app/tests/coverage/coverage.xml build/coverage.xml
    - docker cp $(cat my-package.txt):/app/tests/coverage/junit.xml build/junit.xml
  timeout: 2h
  artifacts:
    when: always
    paths:
      - build
    reports:
      cobertura:
        - build/coverage.xml
      junit:
        - build/junit.xml
    expire_in: 30 min
  coverage: '/TOTAL.*\s+(\d+%)$/'

sonarcloud-check:
  stage: analyze_test
  image:
    name: sonarsource/sonar-scanner-cli:latest
    entrypoint: [""]
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script:
    - echo "Logging coverage..."
    - sed -i "s|<source>\/app\/my_app<\/source>|<source>$CI_PROJECT_DIR\/my_app<\/source>|g" ./build/coverage.xml
    - sonar-scanner
  only:
    - merge_requests
    - master
  dependencies:
    - test-merge-request-changes

我的问题的要点是,Gitlab 不会在一个 GitLab ci 阶段中放置的作业之间共享工件,而是在不同阶段之间共享它们。

因此,我只是创建了两个单独的阶段,一个用于构建测试 (

build_test
),一个用于分析测试 (
analyze_test
)。然后,使
sonar-cloud
作业依赖于
test-merge-request-changes
作业。这样,我们确保首先在
test-merge-request-changes
中运行测试,然后在
sonar-cloud
阶段使用上传的工件。

© www.soinside.com 2019 - 2024. All rights reserved.