{"id":21722476,"url":"https://github.com/end-of-game/php-code-quality-testing-sonar-gitlab-ci","last_synced_at":"2025-04-12T21:43:18.453Z","repository":{"id":72480954,"uuid":"347029815","full_name":"end-of-game/php-code-quality-testing-sonar-gitlab-ci","owner":"end-of-game","description":"During the life-cycle of an application in continuous integration and continuous delivery   pipelines, we need to build, test, and deliver. The testing phase is the most important and each kind of tests has its specificity. In this article, we deal with code quality tests, such as static code analysis and code coverage, for PHP applications using SonarQube and Gitlab CI.","archived":false,"fork":false,"pushed_at":"2021-03-22T10:28:44.000Z","size":1436,"stargazers_count":10,"open_issues_count":0,"forks_count":14,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-12T21:42:39.477Z","etag":null,"topics":["docker","gitlab","php","sonarqube","testing"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/end-of-game.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-12T10:38:08.000Z","updated_at":"2024-01-12T06:35:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"eec98fcc-3998-46ff-90ea-56355dc8596b","html_url":"https://github.com/end-of-game/php-code-quality-testing-sonar-gitlab-ci","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/end-of-game%2Fphp-code-quality-testing-sonar-gitlab-ci","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/end-of-game%2Fphp-code-quality-testing-sonar-gitlab-ci/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/end-of-game%2Fphp-code-quality-testing-sonar-gitlab-ci/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/end-of-game%2Fphp-code-quality-testing-sonar-gitlab-ci/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/end-of-game","download_url":"https://codeload.github.com/end-of-game/php-code-quality-testing-sonar-gitlab-ci/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248637833,"owners_count":21137538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","gitlab","php","sonarqube","testing"],"created_at":"2024-11-26T02:29:23.906Z","updated_at":"2025-04-12T21:43:18.443Z","avatar_url":"https://github.com/end-of-game.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [Code quality testing with SonarQube and Gitlab CI for PHP applications](https://medium.com/@nicolastournier/code-quality-testing-with-sonarqube-and-gitlab-ci-for-php-applications-f0c953f4133d)\n\nDuring the lifecycle of an application in continuous integration and continuous delivery   pipelines, we need to build, test, and deliver. The testing phase is the most important and each kind of tests has its specificity. In this article, we deal with code quality tests, such as static code analysis and code coverage, for PHP applications using SonarQube and Gitlab CI.\n\n![Gitlab CI pipeline goal](./img/pipelines.png \"Gitlab CI pipeline goal\")\n\nFirst, we take our time to create the building stage of the application in Gitlab CI. Then, we focus on the testing stage and code coverage. Furthermore, we are looking how to deploy SonarQube using Docker. And finally, showing in SonarQube the kind of useful information you can collect.\n\nCode sources are available [here](https://github.com/Treeptik/php-code-quality-testing-sonar-gitlab-ci).\n\n## Building PHP applications in Gitlab with Composer\n\n[Gitlab](https://www.gitlab.com) is a SaaS to collaborate on code and embed some tools in order to be considered as a DevOps platform. In this section, step by step, we deal with the CI of the build of PHP applications.\n\nEven if we want to focus on quality testing, beginning the project from scratch can be interesting. You can skip this section if you want to get into the main issue.\n\n### Requirements for building PHP application in Gitlab\n\n- Git\n- Composer\n- [Gitlab](https://www.gitlab.com) account\n\n\u003e For those who are not PHP developers, Composer is the PHP dependency manager binary tool ; such as Maven or Gradle for Java, NPM or Yarn for JavaScript, Cargo for Rust, etc. The composer.json file describes the dependencies.\n\n### Gitlab CI pipeline for PHP applications\n\nTo begin our pipeline, we choose the official PHP Docker image on Docker hub. Before scripting, we need to install composer in order to download the PHP dependencies. Moreover, to be installed, some packages need `git` or `unzip` packages.\n\nThe simplest way to write this step for Gitlab CI may seem like this:\n\n```yml\nphp:\n  stage: build\n  image:\n    name: php:8.0\n  before_script:\n    - apt-get update -yqq\n    - apt-get install git unzip -yqq\n    - php -r \"copy('https://getcomposer.org/installer', 'composer-setup.php');\"\n    - php composer-setup.php --install-dir=/usr/bin --filename=composer --version=2.0.9\n    - php -r \"unlink('composer-setup.php');\"\n  script:\n    - composer install\n```\n\n[https://gist.github.com/n1c0l4stournier/be0fe41ee74b3628ae9d656a5ab0deb8](https://gist.github.com/n1c0l4stournier/be0fe41ee74b3628ae9d656a5ab0deb8)\n\n\u003e For every tools you use, it is important to set the version in order to expect the same behavior on your local machine and in Gitlab CI. As you can see (cf. line 9), when this article is written, the latest version for composer is the `2.0.11`.\n\nFor more information of the Composer installation, you can see the [documentation](https://getcomposer.org/download/).\n\nTo be more effective, you can add some cache for the downloaded libraries and some conditions to trigger the pipeline only on merge requests or on the master/main branch.\n\n```yml\nphp:\n  stage: build\n  image:\n    name: php:8.0\n  before_script:\n    - apt-get update -yqq\n    - apt-get install git unzip -yqq\n    - php -r \"copy('https://getcomposer.org/installer', 'composer-setup.php');\"\n    - php composer-setup.php --install-dir=/usr/bin --filename=composer --version=2.0.9\n    - php -r \"unlink('composer-setup.php');\"\n  script:\n    - composer install\n  cache:\n    key: \"${CI_JOB_NAME}-build\"\n    paths:\n      - vendor\n  only:\n    - merge_requests\n    - master\n```\n\n[https://gist.github.com/n1c0l4stournier/83cb035cf6ab2381c2efa64dc449d0b4](https://gist.github.com/n1c0l4stournier/83cb035cf6ab2381c2efa64dc449d0b4)\n\n\u003e You can use a trusted Docker image or build yours, that includes the tools you need. It will simplify the description of the pipeline in .`gitlab-ci.yml` file and can reduce the pipeline execution time. Nevertheless, it will be an other project you will have to maintain.\n\n## Testing and code coverage for PHP applications\n\nOur pipeline download the libraries that the application needs. The aim is to generate report in SonarQube, on static code analysis and code coverage. In order to generate code coverage report, we also need to test the application.\n\n### PHPUnit in Gitlab CI\n\nPHPUnit is the most used library for unit testing in PHP. Furthermore, we need Xdebug, a module for debugging and profiling PHP application. It is also used for code coverage analysis. It is available using `pecl` the binary for PHP extension installation from its repository, and in a Docker container context, you have to enable the extension using `docker-php-ext-enable`.\n\nAdding the installation before scripting and the pipeline becomes:\n\n```yml\nphp:\n  stage: build\n  image:\n    name: php:8.0\n  before_script:\n    - apt-get update -yqq\n    - apt-get install git unzip -yqq\n    - php -r \"copy('https://getcomposer.org/installer', 'composer-setup.php');\"\n    - php composer-setup.php --install-dir=/usr/bin --filename=composer --version=2.0.11\n    - php -r \"unlink('composer-setup.php');\"\n    - pecl install xdebug-3.0.0\n    - docker-php-ext-enable xdebug\n  script:\n    - composer install\n  cache:\n    key: \"${CI_JOB_NAME}-build\"\n    paths:\n      - vendor\n  only:\n    - merge_requests\n    - master\n```\n\n[https://gist.github.com/n1c0l4stournier/ac9f34c90eb683569697fd8958203ccb](https://gist.github.com/n1c0l4stournier/ac9f34c90eb683569697fd8958203ccb)\n\nThe `composer.json` file describe the dependencies. As we can see bellow, PHPUnit is a development dependency downloaded during the build step. PHPUnit executable is available in the directory `vendor/bin/`.\n\n```json\n{\n    \"name\": \"linkbynet/demo-php-code-quality-testing-sonar-gitlab-ci\",\n    \"description\": \"Code quality testing with SonarQube and Gitlab CI for PHP applications\",\n    \"authors\": [\n        {\n            \"name\": \"Nicolas Tournier\",\n            \"email\": \"n.tournier@linkbynet.com\"\n        }\n    ],\n    \"require\": {\n        \"php\": \"\u003e=7.3\"  \n    },\n    \"require-dev\": {\n        \"phpunit/phpunit\": \"^9.5\"\n    },\n    \"autoload\": {\n        \"psr-4\": {\n            \"LBN\\\\Demo\\\\\": \"src/\"\n        }\n    },\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"LBN\\\\Tests\\\\\": \"tests/\"\n        }\n    }\n}\n```\n\n[https://gist.github.com/n1c0l4stournier/5ce42323b4a6cea0e60a28faab89b297](https://gist.github.com/n1c0l4stournier/5ce42323b4a6cea0e60a28faab89b297)\n\nConsidering, `tests` is the name of the directory where the unit tests are stored ; to launch tests, you have only to execute:\n\n```bash\n./vendor/bin/phpunit tests\n```\n\nYou can configure PHPUnit thanks to a XML configuration file or/and in command line. For this simple demonstration, command line is enough.\n\nWith Xdebug activated in coverage mode, for testing and some integration in Gitlab interface (cf. next subsection), this is the minimal command we need to execute. If you need more details, you can read this part of [documentation](https://phpunit.readthedocs.io/fr/latest/textui.html).\n\n```bash\n./vendor/bin/phpunit \\\n  --coverage-text \\\n  --log-junit build/phpunit/phpunit.xml \\\n  --whitelist src \\\n  --colors=never \\\n  tests\n```\n\nThe activation of Xdebug in coverage mode is mage by setting the environment variable `XDEBUG_MODE=coverage`.\n\nSo, the Gitlab pipelines becomes:\n\n```yml\nphpunit:\n  stage: build\n  image:\n    name: php:8.0\n  before_script:\n    - apt-get update -yqq\n    - apt-get install git unzip -yqq\n    - php -r \"copy('https://getcomposer.org/installer', 'composer-setup.php');\"\n    - php composer-setup.php --install-dir=/usr/bin --filename=composer --version=2.0.9\n    - php -r \"unlink('composer-setup.php');\"\n    - pecl install xdebug-3.0.0\n    - docker-php-ext-enable xdebug\n  variables:\n    XDEBUG_MODE: \"coverage\"\n  script:\n    - composer install\n    - |\n      ./vendor/bin/phpunit \\\n        --coverage-text \\\n        --log-junit build/phpunit.xml \\\n        --whitelist src \\\n        --colors=never \\\n          tests\n  cache:\n    key: \"${CI_JOB_NAME}-build\"\n    paths:\n      - vendor\n  artifacts:\n    reports:\n      junit: build/phpunit.xml\n    expire_in: 30 min\n  only:\n    - merge_requests\n    - master\n```\n\n[https://gist.github.com/n1c0l4stournier/d4290059a9c74cbf7f87b654447bf92c](https://gist.github.com/n1c0l4stournier/d4290059a9c74cbf7f87b654447bf92c)\n\nAs you can see, we choose some options for PHPUnit that can be discussed.\n\nFirst, we choose to export the unit tests logs with the JUnit format. Because you can integrate the results in the Gitlab interface. And this is some examples.\n\nThen, the following three other options are for code covering. The white list directory stands for the source code directory to analyze. We choose to print the report in the console, because Gitlab can parse the result and embed it in the interface or generate a badge. And, in order to avoid parsing errors, the syntax color printing is disabled.\n\n### Integration of results in Gitlab interface\n\n#### Coverage integration\n\nTn order to have coverage metric integration, you have to follow these steps.\n\n![CI/CD Settings menu in Gitlab](./img/gitlab_01_edit.png \"CI/CD Settings menu in Gitlab\")\n\nIn **Settings \u003e CI/CD**, expend **General pipelines**:\n\n![General pipelines in Gitlab CI/CD Settings](./img/gitlab_general_pipeline.png \"General pipelines in Gitlab CI/CD Settings\")\n\nAnd look for **Test coverage parsing**:\n\n![Test coverage parsing in General pipelines settings](./img/gitlab_coverage_parsing.png \"Test coverage parsing in General pipelines settings\")\n\nLike on the screenshot, you have to type:\n\n```bash\n^\\s*Lines:\\s*\\d+.\\d+\\%\n```\n\nThen, just bellow, you have two sections **Pipeline status** and **Coverage report**, that generate an icon that you can paste in the `README.md` file to know at a look the status of the repository.\n\nThen, in the merge request, the first information appeared is the coverage rate and the evolution compared with the previous build. As you can see on the following screenshot, tests cover 86.36% of the code and before it was at 100%.\n\n![Coverage report in Gitlab merge request](./img/report_gitlab_01.png \"Coverage report in Gitlab merge request\")\n\n#### PHPUnit tests integration\n\nBelow few blocks, the is as summary of the PHPUnit report and a link to see the details. This is possible only if you export unit tests logs as JUnit format, in the PHPUnit options.\n\n![Test report in Gitlab merge request](./img/report_gitlab_02.png \"Test report in Gitlab merge request\")\n\nWhen you look at the details, there is the name of the Gitlab CI job associated to the PHPUnit tests. And, if you click on the job name, here phpunit, you have the detail for each test functions.\n\n![PHPUnit report embed in Gitlab](./img/report_gitlab_03.png \"PHPUnit report embed in Gitlab\")\n\n![PHPUnit detailed report in Gitlab](./img/report_gitlab_04.png \"PHPUnit detailed report in Gitlab\")\n\nThis is quite interesting to have these general metrics directly in Gitlab ; but to have more details, it is more comfortable to use complementary tools such as SonarQube.\n\n## SonarQube with Docker\n\nSonarQube is an automatic code review tool to detect bugs, vulnerabilities, and code smells in your code. There are three editions available for SonarQube, you can compare these in the official website. We choose the community edition, because it is free and open source. And, the features are enough to show the potential of the tool.\n\nFor the deployment, SonarQube needs a database. It is compatible with Microsoft SQL Server, Oracle and PostgreSQL. For the example, we choose SonarQube community edition and PostgreSQL.\n\n### Requirements for SonarQube with Docker\n\n- Docker\n\n### SonarQube deployment\n\nFor the deployment, we are using Docker. As following, the docker-compose file describe the two services we use: SonarQube community edition and PostgreSQL. The environment variables for SonarQube and PostgreSQL are the credentials to the database.\n\n```yml\nversion: \"3.8\"\nservices:\n  sonar:\n    image: sonarqube:8.7.0-community\n    environment:\n      SONARQUBE_JDBC_URL: jdbc:postgresql://db:5432/sonarDbName\n      SONARQUBE_JDBC_USERNAME: sonarDbUsername\n      SONARQUBE_JDBC_PASSWORD: sonarDbPassword\n    ports:\n      - 9000:9000\n    volumes:\n      - sonarqube_conf:/opt/sonarqube/conf\n      - sonarqube_data:/opt/sonarqube/data\n      - sonarqube_extensions:/opt/sonarqube/extensions\n      - sonarqube_bundled-plugins:/opt/sonarqube/lib/bundled-plugins\n  db:\n    image: postgres:13.2\n    environment:\n      POSTGRES_USER: sonarDbUsername\n      POSTGRES_PASSWORD: sonarDbPassword\n      POSTGRES_DB: sonarDbName\n    ports:\n      - 5432:5432\n    volumes:\n      - postgresql:/var/lib/postgresql\n      - postgresql_data:/var/lib/postgresql/data\nvolumes:\n  sonarqube_conf:\n  sonarqube_data:\n  sonarqube_extensions:\n  sonarqube_bundled-plugins:\n  postgresql:\n  postgresql_data:\n```\n\n[https://gist.github.com/n1c0l4stournier/19baa24c7047e276be650921d365ebf0](https://gist.github.com/n1c0l4stournier/19baa24c7047e276be650921d365ebf0)\n\n\u003e Today, the release version is `8.7.0-community`, do not hesitate to update your file by consulting the Docker Hub page. You have to avoid to use the latest version in your `docker-compose.yml` file. Keep the best practice and fix the version to avoid bad surprises.\n\nFrom the docker-compose file, the best way to deploy the stack is the use Docker with the [Swarm](https://docs.docker.com/engine/swarm/) mode, even if you only have one node.\n\n\u003e If you prefer using Kubernetes cluster for tooling, SonarQube can also be deployed on this platform.\n\n```bash\ndocker stack deploy -c docker-compose.yml sonar\n```\n\nIn order to check if the deployment is successful you can list the stack and the services, you will have two services running.\n\n```bash\ndocker stack ls\n```\n\n![Docker sonar stack capture](./img/docker_01.png \"Docker sonar stack capture\")\n\n```bash\ndocker stack services sonar\n```\n\n![Docker sonar services capture](./img/docker_02.png \"Docker sonar services capture\")\n\n![SonarQube is installing](./img/sonar_01.png \"SonarQube is installing\")\n\n![SonarQube is installed](./img/sonar_02.png \"SonarQube is installed\")\n\n![SonarQube home page after the installation](./img/sonar_03.png \"SonarQube home page after the installation\")\n\nSonarQube is exposed on the port 9000, so the URL `http://{IP_ADDR}:9000` will display the login form. The default value are admin/admin as login/password entries. Then, SonarQube ask you changing this password.\n\n![Update SonarQube password at the first login](./img/sonar_04.png \"Update SonarQube password at the first login\")\n\nThe SonarQube instance is ready, now we can set up the Gitlab CI pipeline.\n\n![SonarQube homepage](./img/sonar_05.png \"SonarQube homepage\")\n\n### New project on SonarQube\n\nSonarQube is ready, you have to create your first project. From scratch, only the manual option is active. You can activate Azure DevOps, Bitbucket, Github, Gitlab in **Administration** menu and choose the **ALM integration** tab.\n\n![Choose the type of project](./img/sonar_project_01.png \"Choose the type of project\")\n\nThen, you have to give a name of the project. For consistency, I choose the same name in composer project name. The display name can be change.\n\n![Name your project](./img/sonar_project_02.png \"Name your project\")\n\nAnd, you have to generate a key, by naming the token and clicking on generate. With the project name it permits to authenticate your request when you have to upload your PHPUnit reports.\n\n![Generate a token for SonarQube](./img/sonar_project_04.png \"Generate a token for SonarQube\")\n\nFinally, you can chose what king of technology you use for your project and some solution are proposed to execute sonar analysis and upload the reports. We will come back on this topic when we build our sonar step in Gitlab CI.\n\n![Select your technical stack](./img/sonar_project_05.png \"Select your technical stack\")\n\nIt's done ! Your project appears in the home page. On the left, when you will have lots of project, they can be filtered by Sonar criteria, such as: quality gate, reliability, security, coverage rate, maintainability, language, etc.\n\n![SonarQube homepage after adding your first project](./img/sonar_project_06.png \"SonarQube homepage after adding your first project\")\n\nFor the next step, two values are important:\n\n- the name of the sonar project (not the display name)\n- the generated key for this project\n\n## Adding SonarQube in the Gitlab pipeline\n\nFor the SonarQube job, we are using the sonar-scanner CLI Docker image in our Gitlab pipeline.\n\n### PHPUnit job adjustments\n\nFirst, we add some clarity with two stages to be executed in this order. The order is important, because PHPUnit produces the unit tests report and the coverage report, that we need in SonarQube job.\n\nThen, we need to produce a coverage report, we have to choose the Clover report format to be compatible with SonarQube. And, we create it in the same directory than the unit test report.\n\nTo make this files available in the next job, we have to use artifacts in Gitlab CI. Remember, we had use this to embed unit test result in Gitlab CI. In this part, we add the path where the reports are produce.\n\n```yml\nstages:\n  - phpunit\n  - sonarqube\n\nphpunit:\n  stage: phpunit\n  image:\n    name: php:8.0\n  before_script:\n    - apt-get update -yqq\n    - apt-get install git unzip -yqq\n    - php -r \"copy('https://getcomposer.org/installer', 'composer-setup.php');\"\n    - php composer-setup.php --install-dir=/usr/bin --filename=composer --version=2.0.11\n    - php -r \"unlink('composer-setup.php');\"\n    - pecl install xdebug-3.0.0\n    - docker-php-ext-enable xdebug\n  cache:\n    key: ${CI_JOB_NAME}\n    paths:\n      - vendor\n  variables:\n    XDEBUG_MODE: \"coverage\"\n  script:\n    - composer install\n    - |\n      ./vendor/bin/phpunit \\\n        --whitelist src/Domain \\\n        --log-junit build/phpunit.xml \\\n        --coverage-text \\\n        --coverage-clover build/coverage.xml \\\n        --colors=never \\\n          tests\n  artifacts:\n    paths:\n      - build\n    reports:\n      junit: build/phpunit.xml\n    expire_in: 30 min\n  only:\n    - merge_requests\n    - master\n\nsonarqube:\n  stage: sonarqube\n  image:\n    name: sonarsource/sonar-scanner-cli:4.6\n    entrypoint: [\"\"]\n  variables:\n    IP_SONAR_MACHINE: \"10.1.1.1\"\n  cache:\n    key: \"${CI_JOB_NAME}\"\n    paths:\n      - .sonar/cache\n      - .scannerwork\n  script:\n    - |\n      sonar-scanner \\\n        -Dsonar.language=php \\\n        -Dsonar.qualitygate.wait=true \\\n        -Dsonar.sources=src/Domain \\\n        -Dsonar.host.url=http://${IP_SONAR_MACHINE}:9000 \\\n        -Dsonar.php.tests.reportPath=build/phpunit.xml \\\n        -Dsonar.php.coverage.reportPaths=build/coverage.xml \\\n        -Dsonar.projectKey=demo-php-code-quality-testing-sonar-gitlab-ci \\\n        -Dsonar.login=227f5c5b4f4e11e587b9b2e93f2a9f14c1fa71df\n  only:\n    - merge_requests\n    - master\n```\n\n[https://gist.github.com/n1c0l4stournier/74d5ff2595f4c8abf501eb4f9df186b3](https://gist.github.com/n1c0l4stournier/74d5ff2595f4c8abf501eb4f9df186b3)\n\n### SonarQube job\n\n`sonar-scanner` is the binary used to make the job, it is included in the sonar-scanner Docker image. It needs some mandatory arguments, those that were create in SonarQube interface:\n\n- **sonar.projectKey**, the name of the sonar project;\n- **sonar.login**, the generated key for this project;\n- and **sonar.host.url**, the URL where the sonar instance is reachable. In this pipeline, we create a variable in the job and we suppose the port is set to 9000.\n\n```bash\nsonar-scanner \\ \n  -Dsonar.language=php \\ \n  -Dsonar.qualitygate.wait=true \\ \n  -Dsonar.sources=src/Domain \\ \n  -Dsonar.host.url=http://${IP_SONAR_MACHINE}:9000 \\ \n  -Dsonar.php.tests.reportPath=build/phpunit.xml \\ \n  -Dsonar.php.coverage.reportPaths=build/coverage.xml \\ \n  -Dsonar.projectKey=demo-php-code-quality-testing-sonar-gitlab-ci \\ \n  -Dsonar.login=227f5c5b4f4e11e587b9b2e93f2a9f14c1fa71df\n```\n\nThen, we give to sonar-scanner the path to test report and coverage report for our PHP application:\n\n- **sonar.php.tests.reportPath**, with JUnit format (such as Gitlab requires to embed the results in its interface);\n- **sonar.php.coverage.reportPath**, in Clover format.\n\nAnd, with:\n\n- **sonar.language**, we precises the project language (it is optional);\n- **sonar.sources**, we declare the directory of the sources that need to be analyse;\n- **sonar.qualitygate.wait**, will fail the job if the project does not verify the quality conditions. We will see which possible criteria in the following section.\n\nSuch as for the PHPUnit job, sonar-scanner produces cache files. We can add these files in the Gitlab CI job cache.\n\nThe CI is completed. You have to test and analyze your application, and look at your quality code. In the next section, we will see how to create custom threshold to validate the quality of your code.\n\n### SonqarQube Quality Gate\n\nBy default, SonarQube has a default Quality Gate. You can show it, by clicking on Quality Gate on the navigation bar.\n\n![Default quality gate in SonarQube](./img/quality_gate_01.png \"Default quality gate in SonarQube\")\n\nDefault quality gate in SonarQubeBut, you can add yours. If you click on Create button, name the new quality gate and you can add your conditions on criteria computed by SonarQube.\n\n![Create custom quality gate](./img/quality_gate_02.png \"Create custom quality gate\")\n\nCreate custom quality gateThen, in your project, you can select the quality gate you just created. In your Project Settings \u003e Quality Gate and choose yours as specific Quality Gate.\n\n![Choose specific quality gate](./img/quality_gate_03.png \"Choose specific quality gate\")\n\nAfter saving, if you come back to the Quality Gate section, you can see your project will use your custom quality gate during the next analyze.\n\n![Projects linked to a specific quality gate](./img/quality_gate_04.png \"Projects linked to a specific quality gate\")\n\nThen, I analyze my demonstration application thanks to the CI we built.\n\n![Gitlab CI results when SonarQube job failed](./img/quality_gate_06.png \"Gitlab CI results when SonarQube job failed\")\n\nAnd... The CI tells us, we failed and it is about quality tests.\n\n![Gitlab CI logs when quality gate conditions are not verified](./img/quality_gate_07.png \"Gitlab CI logs when quality gate conditions are not verified\")\n\nIn SonarQube under the red block, SonarQube explains why.\n\n\u003e In the example, we set on overall code, the code coverage rate must be greater than 80%. Our score is at 75.8%, so the conditions are not verified. The quality analysis failed.\n\n![SonarQube interface when quality gate conditions are not verified](./img/quality_gate_05.png \"SonarQube interface when quality gate conditions are not verified\")\n\nMoreover, SonarQube warn us there are some code smells.\n\n![SonarQube code smells report](./img/quality_gate_08.png \"SonarQube code smells report\")\n\nBy clicking on one of them, SonarQube shows your code.\n\n![SonarQube code smell in your code](./img/quality_gate_09.png \"SonarQube code smell in your code\")\n\nAnd, it gives you the reason of the issue. In this example, it is very simple to see the issue and to fix it. Everyone makes mistakes, but with this kind of tools, you make your code cleaner.\n\nMoreover, you can improve yourself, by understanding why there are code smells in the code you push in your branch.\n\n![Code smell explanation](./img/quality_gate_10.png \"Code smell explanation\")\n\n## Conclusion\n\nIn this article, we saw how to:\n\n- create a CI in Gitlab for PHP applications using Composer and PHPUnit;\n- embed test unit report and coverage rate in Gitlab interface;\n- deploy a SonarQube instance using Docker;\n- add SonarQube analysis in our previous CI;\n- create quality gate in SonarQube and fail the pipeline if constraints are not satisfied.\n\nCode sources are available [here](https://github.com/Treeptik/php-code-quality-testing-sonar-gitlab-ci).\n\nThanks for reading.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fend-of-game%2Fphp-code-quality-testing-sonar-gitlab-ci","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fend-of-game%2Fphp-code-quality-testing-sonar-gitlab-ci","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fend-of-game%2Fphp-code-quality-testing-sonar-gitlab-ci/lists"}