How Many Days of Technical Debt Has your PHP Project

Every project has technical dept. But how would you measure it? With cognitive complexity? The age of the framework? Any other guess?

This year I've started to use CI service, which tells you the number in days. And it works pretty well... how many days Rector has? Keep on learning.

How Reliable is Technical Dept Metric?

When I first analyzed Rector, top 5 worst classes had these in common:

As the first experiment, I picked a class that had 5 hours and 40 minutes of technical debt, and I gradually converted it to collector pattern.

Do you want to see real code? Look at this PR with NodeTypeResolver decoupling to 10 new classes.

I Thought Removing Legacy Would be Fun...

...but removing my legacy code was rather painful. I had to load huge methods to my working memory, think about relations of huge monolithic class and try to split into the smallest standalone pieces.

After 3 hours of work, I was exhausted, but CI was passing, and the god class was gone. I pushed my work, merged the PR to the master, and waited for SonarCloud analysis... from 5:40 I got into 2:40. What?

After all this work, only such a small improvement? Don't take me wrong; the code was much improved, I'm just used to work more effectively with Rector-wave refactoring approach... no more from months to days?

This process taught me a lesson:

The legacy code will always be there. Observe it, measure it and remove it.
The later you start, the more it hurts. No matter what.

Since then, I'm adding SonarCube on every project I work on, so I know (not just feel):

...to keep code base fit for years


Do you wonder how many days you have on your back? 10, 50 or over 100? Add your first SonarCube check into the CI and share with us in comments ↓

How to add SonarCube to your Github Project in 6 Steps?

SonarCube is free for open-source and has a 1-week trial for private projects. I tried the 1-week trial on one private project, and then I saw the debt... 365, hours days... you have to love it :D.

1. Add Project on SonarCloud

2. Authorize Your Github Project

Add the file and commit to master.

3. Add Github Action

We need to have a way to tell the Sonar that new code was pushed. That's what Github Actions are for.

Add new workflow:

# .github/workflows/sonarcube.yaml
name: Sonar

on: push

jobs:
    sonar_cloud:
        runs-on: ubuntu-latest
        steps:
            -   uses: actions/[email protected]
                with:
                    # sonar needs non-shallow clone
                    fetch-depth: 10000

            -   uses: sonarsource/[email protected]
                env:
                    ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
                    SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

As you can see, there are 2 tokens to authorize.

How to get Tokens?

Where to place Them?

Add both tokens to your secrets sections in your repository: https://github.com/TomasVotruba/tomasvotruba.com/settings/secrets

What is analysis good for if you can't reach it from your README? Be sure to add it there, so you can enter it quickly and share your excellent results with others.

[![SonarCube](https://img.shields.io/badge/SonarCube_Debt-%3C2-brightgreen.svg?style=flat-square)](https://sonarcloud.io/dashboard?id=TomasVotruba_tomasvotruba.com)

SonarCube

Almost done...

5. Where is the Code?

We still have to tell SonarCube where to look for the src code. To do this, we need to add sonar-project.properties.

# sonar-project.properties
# see https://sonarcloud.io/documentation/project-administration/narrowing-the-focus/
sonar.organization=TomasVotruba
sonar.projectKey=tomasvotruba.com

# relative paths to the source, wildcards don't work
sonar.sources=src

To get organization and and projectKey, just split the key (TomasVotruba_tomasvotruba.com) by _.

6. Remove Spam Bot

Do this AFTER the first analysis of master branch is completed. If you do it earlier, the Github Action will not work.


There is a price for all the excellent features... you need to tolerate SonarCube spam bot on every commit.

I hated it and wanted to delete all this Sonar-spam from my repositories, but there is one solution out of it.

Go to Github installations:

And remove it:

We only need it for the first contact. Instead of it, you can authorize with Github Actions.


And that should be it! (If not, let me know in comments.)


Trouble Shooting

"Please add the secret GITHUB_TOKEN to the GitHub action for SonarCloud"

If you see this message, don'T try to add GITHUB_TOKEN to your Secrets in GitHub repository. It won't let you. Instead, re-use already existing secret in your .github/workflows/sonarcube.yaml:

# .github/workflows/sonarcube.yaml
# ...
             -   uses: sonarsource/[email protected]
                 env:
                     ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
                     SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+                    GITHUB_TOKEN: ${{ secrets.SONAR_TOKEN }}


Dual Analysis?

When CI fails for having both automatic and Github Action analysis, go to your project on SonarCube and disable it:


"Project was never analyzed. A regular analysis is required before a branch analysis."

I tried many paths, but I'm not aware of any specific solution for this. Delete project on Sonarcloud, hide local GitHub Action workflow and star over.


Now you see your weakest points and Fight the Hydra with courage!


Happy coding!