rubysonarqubecode-coverage

SonarCloud CI can't find source files for Ruby / SimpleCov coverage


tl;dr - SonarCloud CI on GitHub actions warns that it can't find any of the source files with coverage reported, despite confirming that the files are in the docker filesystem at the path reported.

I have a Ruby / Rails app with rspec specs which produce coverage stats using SimpleCov and its JSON formatter (so my rails_helper.rb starts:

require 'simplecov'
require "simplecov_json_formatter"
SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter
SimpleCov.start('rails') do
  add_filter ['/channels/', '/jobs/', '/mailers/']
end

I have SonarCloud CI set up to scan using GitHub Actions, with the following sonar-project.properties in the root:

sonar.projectKey=asilano_my-app
sonar.organization=asilano

sonar.ruby.coverage.reportPaths=coverage/coverage.json

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
sonar.sources=app,lib
sonar.tests=spec

and the following GitHub workflow:

name: Test and Deploy

on:
  pull_request:
    types: [opened, synchronize, reopened]
    branches:
      - 'main'
      - 'staging'
  push:
    branches:
      - 'main'
      - 'staging'

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          - 5432:5432

    steps:
    - uses: actions/checkout@v2
    - uses: ruby/setup-ruby@v1
      with:
        bundler-cache: true
    - name: Install PostgreSQL client
      run: |
        sudo apt-get -yqq install libpq-dev
    - name: Build App
      env:
        PGHOST: localhost
        PGUSER: postgres
        PGPASSWORD: postgres
        RAILS_ENV: test
        RAILS_MASTER_KEY: ${{ secrets.TEST_MASTER_KEY }}
      run: |
        bin/rails db:setup
        yarn install
    - name: Run Tests
      env:
        PGHOST: localhost
        PGUSER: postgres
        PGPASSWORD: postgres
        RAILS_ENV: test
        RAILS_MASTER_KEY: ${{ secrets.TEST_MASTER_KEY }}
      run: |
        bundle exec rspec
    - name: Where Am I?
      run: |
        head coverage/coverage.json
        ls -l /home/runner/work/my-app/my-app/app/lib/some_file.rb
    - name: SonarCloud Scan
      uses: SonarSource/sonarcloud-github-action@master
      env:
        GITHUB_TOKEN: ${{ secrets.SONAR_GITHUB_TOKEN }}  # Needed to get PR information, if any
        SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

(main and staging are both long-lasting branches in SonarCloud)

The Where Am I? step is to try and debug the problems I'm having. It shows that the top of coverage.json reads:

{
  "meta": {
    "simplecov_version": "0.21.2"
  },
  "coverage": {
    "/home/runner/work/my-app/my-app/app/lib/some_file.rb": {
      "lines": [
        1,
        1,
        1,

and confirms via ls that the mentioned path exists:

-rw-r--r-- 1 runner docker 1729 Oct 24 08:15 /home/runner/work/my-app/my-app/app/lib/some_file.rb

However, the SonarCloud scan step warns that the coverage file mentions some_file.rb, but can't find it in the filesytem:

INFO: Sensor SimpleCov Sensor for Ruby coverage [ruby]
WARN: File '/home/runner/work/my-app/my-app/app/lib/some_file.rb' is present in coverage report but cannot be found in filesystem

...and then repeating for every file in the app.

Why not? Why can't the SonarCloud scanner find some_file.rb on the path reported in the coverage file, even though I've confirmed it's where it should be?


Solution

  • I had the same issue with GitHub actions, rails, and simplecov. You need to replace the paths generated by simplecov on coverage/coverage.json. To do this run this step before your sonarcloud scan. Also, you could check this post https://community.sonarsource.com/t/code-coverage-doesnt-work-with-github-action/16747

      - name: Running rails tests
        run: bundle exec rspec
      - name: fix code coverage paths
        working-directory: ./coverage
        run: |
          sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' coverage.json
      - name: SonarCloud Scan
        uses: SonarSource/sonarcloud-github-action@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}