Configurar o SonarCloud para um projeto usando Pytest - fga-eps-mds/A-Disciplina-MDS-EPS GitHub Wiki

Como configurar o SonarCloud para um projeto usando Pytest

Histórico de Revisão

Data Versão Descrição Revisor
17/11/2021 1.0 Versão Inicial Henrique Martins de Messias
19/11/2021 1.1 Adição do parser Henrique Martins de Messias
24/03/2022 2.0 Colhe outras métricas de teste e adiciona o arquivo de métricas no asset da Release automaticamente Igor Batista Paiva, Renan Cristyan Araujo Pinheiro, Rhuan Carlos Pereira de Queiroz e Thiago Aparecido Lopes Santos
24/03/2021 2.1 Adiciona tratamento dos arquivos de saída Rhuan Carlos Pereira de Queiroz

O que será usado

  • Github Actions
  • Python
  • SonarCloud
  • Pytest
  • Pytest JSON Report
  • Pytest-cov

Passo 1 - Criar arquivo de propriedades do SonarCloud

Na raíz do projeto, crie um arquivo chamado sonar-project.properties com o seguinte conteúdo:

sonar.organization=fga-eps-mds-1
sonar.projectKey=fga-eps-mds_<nome_do_repositorio>

sonar.sources=./src
sonar.tests=./tests
sonar.python.coverage.reportPaths=*coverage*.xml
sonar.python.xunit.reportPath=junittest.xml

Os valores de sonar.organization e sonar.projectKey podem ser encontrados ao acessar o SonarCloud e acessar a área de informação do projeto.

Os valores de sonar.sources e sonar.tests podem variar dependendo do seu projeto.

Os valores para *.reportPath são necessários para que o SonarCloud saiba onde encontrar o resultado dos testes para obter as métricas posteriormente.

Passo 2 - Adicionar Secret no repositório

Independentemente da linguagem usada no projeto, é necessário adicionar uma secret chamada SONAR_TOKEN.

Para adicionar a secret no repositório:

  1. Vá para a página do seu projeto no SonarCloud;
  2. Na aba Administration, clique em Analysis Method; Default user
  3. Na seção Supported analysis methods, logo abaixo de GitHub Actions, clique em Follow the tutorial; Default user
  4. Copie o código que é mostrado no campo 2 (o que vem após Value field); Default user
  5. Vá para a página do seu projeto no GitHub e clique em Settings;
  6. Clique em Secrets; Default user
  7. Clique em New repository secret; Default user
  8. Na parte Name coloque: SONAR_TOKEN; Default user
  9. Na parte Value cole o código copiado no passo 4; Default user
  10. Clique em Add secret. Default user

Passo 3 - Configurar workflow no GitHub Actions

Crie um arquivo chamado .github/workflows/<nome_do_arquivo>.yml com o seguinte conteúdo:

on:
  push:
    branches:
      - main

name: SonarCloud
jobs:
  sonarcloud:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - name: Get main
        run: git fetch origin main
      - name: Instalar pip
        run: python -m pip install --upgrade pip
      - name: Instalar Pytest
        run: pip install pytest
      - name: Instalar Pytest-cov
        run: pip install pytest-cov
      - name: Executar testes
        run: pytest --cov=src --cov-report=xml --junitxml=junittest.xml
      - name: fix code coverage paths
        run: |
          sed -i 's/\/home\/runner\/work\/<nome_do_repo>\/<nome_do_repo>\//\/github\/workspace\//g' coverage.x
      - name: SonarCloud Scan
        uses: sonarsource/sonarcloud-github-action@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

Obs: o secrets.GITHUB_TOKEN é disponibilizado automaticamente pelo GitHub.

Obs2: no lugar de <nome_do_repo> deve ser colocado o nome do repo em questão sem os parênteses angulares.

Os passos importantes desse pipeline são Executar testes e SonarCloud Scan. O seu projeto pode configurar o pipeline de maneiras diferentes, mas certifique-se que esses dois passos estejam presentes.

Atente-se para o caminho do parâmetro cov, pois ele deve ser o mesmo que foi definido no arquivo de propriedades do SonarCloud.

Passo 4 - Criar parser de métricas

Na raíz do repositório, crie um arquivo chamado parser.py com o seguinte conteúdo:

import json
import requests
import sys
import re
from datetime import datetime

TODAY = datetime.now()

METRICS_SONAR = [
    # lista de métricas do SonarCloud
]

BASE_URL = "https://sonarcloud.io/api/measures/component_tree?component=fga-eps-mds_"

if __name__ == "__main__":

    REPO = sys.argv[1]
    RELEASE_VERSION = sys.argv[2]


    # Get Metrics for Sonar Cloud
    response = requests.get(
        f'{BASE_URL}{REPO}&metricKeys={",".join(METRICS_SONAR)}&ps=500'
    )
    j = json.loads(response.text)

    file_path = f'./analytics-raw-data/fga-eps-mds-{REPO}-{TODAY.strftime("%m-%d-%Y-%H-%M-%S")}-{RELEASE_VERSION}.json'

    with open(file_path, "w") as fp:
        fp.write(json.dumps(j))
        fp.close()

Passo 5 - Extrair métricas

Crie um arquivo chamado .github/workflows/<nome_do_arquivo>.yml com o seguinte conteúdo:

on:
  push:
    tags:
      - "v*"

jobs:
  release:
    runs-on: "ubuntu-latest"
    steps:
      - uses: actions/checkout@v2
        with:
          # Disabling shallow clone is recommended for improving relevancy of reporting
          fetch-depth: 0

      - name: Criar diretório
        run: mkdir analytics-raw-data

      - name: Coletar métricas
        run: python parser.py ${{ github.event.repository.name }} ${{ github.ref_name }}

      - name: Faz upload das métricas como asset da release
        uses: AButler/[email protected]
        with:
          files: 'analytics-raw-data/*'
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          release-tag: ${{ github.ref_name }}

      # Aqui fica a critério do grupo como enviar os arquivos para o
      # repositório de documentação

Extra - Resolvendo Erro de Automatic Analysis

Caso você receba o seguinte erro:

You are running CI analysis while Automatic Analysis is enabled. Please consider disabling one or the other

É necessário desabilitar o scan automático do repositório no SonarCloud. Para isso:

  1. Vá para a página do seu projeto no SonarCloud;
  2. Na aba Administration, clique em Analysis Method;
  3. Na seção SonarCloud Automatic Analysis, clique no botão para desabilitar.
⚠️ **GitHub.com Fallback** ⚠️