DEV Community

Cover image for Continuous PHP Code Quality with SonarCloud
Jérôme Gamez
Jérôme Gamez

Posted on

Continuous PHP Code Quality with SonarCloud

Are you in a hurry or just interested in hard facts? Jump to https://git.io/fjeX1 and adapt the changes to make your PHP project ready for SonarCloud.

Also: I stole the cover image from SonarCloud's Twitter Profile 🙈.

Introduction

I had heard only good things about SonarQube before, but so far, I haven't used it myself:

  • on my local computer, I was (and still am) very happy with the PHP Inspections Extended/Ultimate plugin (by @kalessil)
  • in the cloud, I used PHPUnit and its Code Coverage on Travis CI in combination with Scrutinizer CI
  • the time last time I checked, and if I remember correctly, I would have needed a local or remote SonarQube Server to be able to use it. 1

Well, today I stumbled upon SonarCloud and SonarLint and here's what I posted on Twitter about half an hour later:

Liquid error: internal

If you want to give SonarCloud a try as well, follow along as I set it up on gamez/duration, a small library that makes it a little easier to work with durations in PHP.


What you'll need

  • A SonarCloud Account
  • A git repository hosted on GitHub, BitBucket or AzureDevOps
  • A SonarCloud Organization (this should be created automatically once you connect e.g your GitHub account)
  • A CI environment (in this example, I'm using Travis CI)

Set up a new project on SonarCloud

On https://sonarcloud.io/projects, click on the the + in the upper right corner and select "Analyze new project"

In the following screen, select the git repository you want to connect, and click on "Set up"

The next page will display some information that you will need later - write them down or keep the window open for later reference:

  • You can find the Project and Organization Keys in the right sidebar, they will be similar to <organization>_<project-slug> and <organization>_<git-service-provider>
  • The authentication token is used to identify you when an analysis is performed, click on "Generate" to generate one.

Click on "Continue" and optionally follow the instructions to download and use the sonar scanner locally for your project.


Configure Travis CI

In your project's settings on Travis CI, configure a new environment variable named SONAR_TOKEN and set its value to the token you've been given earlier. Make sure to keep the "Display value in build log" switch disabled.


Create the sonar-project.properties file

Together with the previously configured token, the following settings will make the connection between your project and SonarCloud.

sonar.projectKey=<your project key>
sonar.projectName=Your project Name

sonar.sources=src
sonar.tests=tests
sonar.language=php
sonar.sourceEncoding=UTF-8
sonar.php.coverage.reportPaths=coverage-report.clover
sonar.php.tests.reportPath=test-report.xml
Enter fullscreen mode Exit fullscreen mode
  • sonar.projectKey must be the project key that you have received earlier
  • sonar.projectName will be the title of your project on SonarCloud. When in doubt, remove the line, and it will default to <organization>/<repo>
  • sonar.sources tells SonarCloud which files to actually analyze. Don't set this value to ., otherwise all files in your project will be analyzed, including the vendors directory, in case your project is Composer based
  • sonar.php.coverage.reportPaths and sonar.php.tests.reportPath point SonarCloud to the locations of the reports that will be created on Travis CI

Create/Update the .travis.yml file

In order to use SonarCloud on Travis CI, you need to make the following additions and changes to your .travis.yml file:

Enable the SonarCloud addon

addons:
  sonarcloud:
    organization: "<your organization key>"

git:
  depth: false
Enter fullscreen mode Exit fullscreen mode

Travis CI by default makes a shallow clone of a git repository. By configuring the depth to false, we ensure that the full history is loaded, so that SonarCloud can determine which contributor made which change for the full lifetime of the project.

Let your test suite generate reports

script:
  - vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover=coverage-report.clover --log-junit=test-report.xml
Enter fullscreen mode Exit fullscreen mode

Execute sonar-scanner after running your test suite

script:
  - vendor/bin/phpunit --coverage-clover=coverage-report.clover --log-junit=test-report.xml
  - sonar-scanner
Enter fullscreen mode Exit fullscreen mode

A complete .travis.yml file could now look like this:

language: php
sudo: false

php:
  - 7.1
  - 7.2
  - 7.3

cache:
  directories:
    - $HOME/.composer/cache

addons:
  sonarcloud:
    organization: "<your organization key>"

git:
  depth: false

install: composer update --no-interaction --no-suggest --no-progress

script:
  - vendor/bin/phpunit -c phpunit.xml.dist --coverage-clover=coverage-report.clover --log-junit=test-report.xml
  - sonar-scanner
Enter fullscreen mode Exit fullscreen mode

Push your changes and enjoy

GitHub logo jeromegamez / duration-php

Working with durations made easy

Duration for PHP

Working with durations made easy.

Current version Supported PHP version Code Coverage Sponsor

Do you like to use DateInterval to compute and work with durations? Me neither, so let's fix that!


Installation

You can install the package with Composer:

composer require gamez/duration
Enter fullscreen mode Exit fullscreen mode

You can then use Duration:

<?php
use Gamez\Duration
$duration = Duration::make('13 minutes 37 seconds')
// or start with nothing
$duration = Duration::none();
Enter fullscreen mode Exit fullscreen mode

Reference

Supported input values

DateIntervals

use Gamez\Duration
Duration::make('PT13M37S');
Duration::make(new DateInterval('PT13M37S'));
Enter fullscreen mode Exit fullscreen mode

Colon notation

use Gamez\Duration;

Duration::make('13:37'); // minutes:seconds
Duration::make('13:37:37'); // hours:minutes:seconds
Enter fullscreen mode Exit fullscreen mode

Textual notation

A textual notation is any value that can be processed by DateInterval::createFromDateString()

use Gamez\Duration
Duration
Enter fullscreen mode Exit fullscreen mode

Bonus: Use SonarLint in your IDE

Visit sonarlint.org to benefit from SonarQube's/SonarCloud's inspections as you write your code 🎉


Conclusion

I ❤️ good code quality, and am willing to go to great lengths to achieve it. But I also like convenience very very much, and to me, SonarCloud provides both - for me as a Developer, today has been one of the highlights of this year so far, and if you can benefit from this post, it makes me even happier.

Happy mending!



  1. It must have been a very long time that I checked, SonarCloud is live since June 2017 😅 

Discussion (3)

Collapse
sebastianr1982 profile image
Sebastian Rapetti

Hello!
Your guide is very useful!

How did you set up github or travis for obtain this page:
github.com/jeromegamez/duration-ph...
?

Collapse
jeromegamez profile image
Jérôme Gamez Author • Edited

It happened automatically once I enabled the repo in Travis and SonarCloud.

You can check this by going into your repo‘s settings and navigating to the „Integrations and Services“ section.

You can then access the details of the checks from the "Commits" view on GitHub, in this case on github.com/jeromegamez/duration-ph... - a click on the green checkmarks (or orange bubbles) will bring you to the check details.

Collapse
sebastianr1982 profile image
Sebastian Rapetti

Thanks! I saw you are using travis-ci app and travis-ci.com, I am on travis-ci.org whiteout github app!