Symfony Logo

How to use Gitlab CI and PHPStan to improve code quality in your Symfony project

published at Oct 21, 2020
#Symfony

This blog post installs a brand new Symfony project, configure PHPStan and Gitlab CI on it, improving code quality by monitoring your code. If you don't know much about PHP Stan or Gitlab CI, it could be your getting starting point.

First, I assume you already have installed Symfony CLI on your machine. If not, then, you can download it by following the installation guide..

I will use PHP 7.4 for this post but it does not make any difference if you use an other PHP 7 version. Obviously, I also have Composer installed on my machine.

Create a new Symfony 5 project

symfony new my_symfony_project
symfony server:start -d
symfony open:local

The first command creates a minimal Symfony project.
Then the server is started. The -d option means "start a server in detached mode".
Finally, the last command launches your default browser and opens the project.

Quick and easy step. Very straightforward. That's what I like the most with Symfony.

Configure PHPStan

PHPStan is a static analysis tool. It's a tool that find bugs, inconsistencies in your code. It can't replace functional or unit tests but it's a first and very useful testing layer, I could say. The thing I liked the most when I first came to it is the easy configuration process. You can progressively adopt it and harden checking rules by passing a level configuration option.

First install it with a Symfony extension

composer require --dev phpstan/phpstan phpstan/phpstan-symfony

The Symfony extension is not mandatory, just recommended to improve the integration with the framework. Essentially, it provides correct return types for some Symfony methods.

Launch your first test to check PHPStan is working correctly:

php vendor/bin/phpstan analyse src/ --level=5

You will probably see a screen like this one:
Img

So far so good. But passing arguments on the command line is not very practical. I prefer using a configuration file. PHPStan can parse neon file to know how you want to configure the test suite.

Let's create it at the root of your project

touch phpstan.neon
includes:
    - vendor/phpstan/phpstan-symfony/extension.neon
parameters:
    level: max #  you can currently choose from 9 levels (0 is the loosest and 8 is the strictest). 
    # Often I use the level 5 because the level 6 checks that every method returns type. 
    # As Symfony code generator commands does not fill those return types, it's quite inconvenient to set a level greater than 5. 
    # Feel free to use the one you prefer. You could even set it to 0 to start slowly 
    symfony:
        # or with Symfony 4.2+
        # container_xml_path: var/cache/dev/srcApp_KernelDevDebugContainer.xml
        # or with Symfony 5+
        container_xml_path: var/cache/dev/App_KernelDevDebugContainer.xml
    paths:
        - src
        # if you have tests and want to analyze this folder, uncomment the line below
        # - tests

Then, if you want to use this configuration file, you have to launch the tests by typing:

php vendor/bin/phpstan analyse -c phpstan.neon

Congrats ! You have successfully setup PHPStan. Now let's take it a step further, by configuring continuous integration with Gitlab CI

Setup Gitlab CI to automate the tests

Obviously, if you want to use Github instead, the rest of this post is not very useful. If this is your case, you have to use Github Actions. I use Gitlab at work, so I will stick with it for this post.

Gitlab CI is a tool that let you configure CI/CD. Configure CI is a big improvement in a team workflow because it allows you to catch bugs and errors earlier, ensuring that all the code pushed to the git repo complies with the code standards you established.

Gitlab CI is a very large topic. For the sake of clarity and simplicity, we will just automate the execution of the previously configured PHPStan tests. I want you to be able to get started quickly and have a nice and working setup.

So, create a new project on Gitlab and add the remote origin:

git remote add origin git@gitlab.com:your_username/your_project.git

GitLab CI pipelines are configured using a YAML file called .gitlab-ci.yml.

touch .gitlab-ci.yml
default:
  image: php:7.4-fpm

before_script:
  - apt-get update && apt-get install -y zip libzip-dev unzip git libfreetype6-dev libjpeg62-turbo-dev libxslt-dev libpng-dev && docker-php-ext-install -j$(nproc) gd xsl intl zip
  - curl --silent --show-error https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
  - composer install

static_analysis:
  script:
    - php --version && php -d memory_limit=512M vendor/bin/phpstan analyse -c phpstan.neon

This file could be reduced because, right now, our project is very small. But as it will grow, you'll probably need to install some php extensions or composer. That's the main purpose of the before_script part.

With this config, every time you will push on your Gitlab repo, a new pipeline will be created and the static_analysis job will start. Lets's test it by typing:

git add .
git commit -m "initial commit. configure phpstan and gitlab ci"
git push -u origin master

Go to your Gitlab dashboard and browse the CI/CD section to check the pipeline is running fine.

Img

If the job succeeds, then the pipeline is marked as passed.

Img

Congrats ! Gitlab CI is now correctly setup. PHPStan tests are automated.

It's a minimal setup, but a working one. And I hope you found this post a good starting point. Feel free to contact me if you have any question or suggestion.