diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index bdc7455..b1dbae1 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @kununu/rosa-mota-backend
+* @kununu/backend-libraries
diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml
deleted file mode 100644
index bed9754..0000000
--- a/.github/workflows/code_quality.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: Qodana
-on:
- workflow_dispatch:
- pull_request:
- push:
- branches: # Specify your branches here
- - main # The 'main' branch
- - 'releases/*' # The release branches
-
-jobs:
- qodana:
- runs-on: ubuntu-latest
- permissions:
- contents: write
- pull-requests: write
- checks: write
- steps:
- - uses: actions/checkout@v4
- with:
- ref: ${{ github.event.pull_request.head.sha }}
- fetch-depth: 0
- - name: 'Install composer dependencies'
- uses: php-actions/composer@v6
- with:
- php_version: '8.3'
- version: 2
- ssh_key: ${{ secrets.CLONE_SSH_KEY }}
- ssh_key_pub: ${{ secrets.CLONE_SSH_KEY_PUB }}
- - name: 'Qodana Scan'
- uses: JetBrains/qodana-action@v2025.2
- env:
- QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
new file mode 100644
index 0000000..de9023b
--- /dev/null
+++ b/.github/workflows/continuous-integration.yml
@@ -0,0 +1,123 @@
+name: Continuous Integration
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ types: [ opened, synchronize, reopened ]
+
+env:
+ fail-fast: true
+
+jobs:
+ checks:
+ name: Code Checks
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Code
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 8.4
+ coverage: none
+ tools: composer-dependency-analyser, composer-normalize, composer-require-checker
+
+ - name: Install Composer Dependencies
+ uses: ramsey/composer-install@v3
+ with:
+ dependency-versions: "highest"
+ composer-options: "--prefer-stable --optimize-autoloader --no-progress --no-interaction"
+
+ - name: Run Composer Dependency Analyser
+ run: composer-dependency-analyser
+
+ - name: Run Composer Require Checker
+ run: composer-require-checker
+
+ - name: Run Composer Normalize
+ run: composer-normalize --dry-run --indent-size 2 --indent-style space --no-check-lock --no-update-lock
+
+ - name: Run code style sniffer
+ run: vendor/bin/phpcs --standard=phpcs.xml Kununu/ tests/
+
+ - name: Run PHP CS Fixer
+ run: vendor/bin/php-cs-fixer check --using-cache=no --config php-cs-fixer.php
+
+ - name: Run PHPStan
+ run: vendor/bin/phpstan analyse
+
+ - name: Run Rector
+ run: vendor/bin/rector process --ansi --dry-run --config rector.php Kununu/ tests/
+
+ build:
+ needs: checks
+ name: PHPUnit
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ dependencies:
+ - lowest
+ - highest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 8.4
+ coverage: pcov
+
+ - name: Install Composer Dependencies
+ uses: ramsey/composer-install@v3
+ with:
+ dependency-versions: ${{ matrix.dependencies }}
+ composer-options: "--prefer-stable --optimize-autoloader --no-progress --no-interaction"
+
+ - name: Run PHPUnit
+ run: |
+ vendor/bin/phpunit --colors=always --testdox \
+ --log-junit tests/.results/tests-junit.xml \
+ --coverage-clover tests/.results/tests-clover.xml
+
+ - name: Upload coverage files
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ github.job }}-8.4-${{ matrix.dependencies }}-coverage
+ include-hidden-files: true
+ path: tests/.results/
+
+ sonarcloud:
+ needs: build
+ name: SonarCloud Checks
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - uses: actions/download-artifact@v4
+ with:
+ name: build-8.4-highest-coverage
+ path: tests/.results/
+
+ - name: Fix Code Coverage Paths
+ working-directory: tests/.results/
+ run: |
+ sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' tests-clover.xml
+ sed -i 's@'$GITHUB_WORKSPACE'@/github/workspace/@g' tests-junit.xml
+
+ - name: SonarCloud Scan
+ uses: SonarSource/sonarqube-scan-action@v7.0.0
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
diff --git a/.github/workflows/cs_sniff.yml b/.github/workflows/cs_sniff.yml
deleted file mode 100644
index 3de262e..0000000
--- a/.github/workflows/cs_sniff.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-name: CI
-on:
- pull_request:
-
-jobs:
- cs:
- name: cs
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: '8.3'
- coverage: none
-
- - name: Cache Composer dependencies
- uses: actions/cache@v4
- with:
- path: /tmp/composer-cache
- key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: ${{ runner.os }}-composer
-
- - name: Install composer dependencies
- uses: php-actions/composer@v6
- with:
- php_version: '8.3'
- version: 2
- args: --optimize-autoloader --no-progress --no-interaction
- ssh_key: ${{ secrets.CLONE_SSH_KEY }}
- ssh_key_pub: ${{ secrets.CLONE_SSH_KEY_PUB }}
-
- - name: Run code style sniffer
- run: vendor/bin/phpcs --standard=phpcs.xml Kununu/ tests/
-
- - name: Run PHP CS Fixer
- run: vendor/bin/php-cs-fixer check --using-cache=no --config php-cs-fixer.php
-
- - name: Run PHPStan
- run: vendor/bin/phpstan analyse
-
- - name: Run Rector
- run: vendor/bin/rector process --ansi --dry-run --config rector.php Kununu/ tests/
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
deleted file mode 100644
index 002c718..0000000
--- a/.github/workflows/testing.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-name: CI
-on:
- pull_request:
-
-jobs:
- tests:
- name: tests
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: '8.3'
- coverage: none
-
- - name: Cache Composer dependencies
- uses: actions/cache@v4
- with:
- path: /tmp/composer-cache
- key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: ${{ runner.os }}-composer
-
- - name: Install composer dependencies
- uses: php-actions/composer@v6
- with:
- php_version: '8.3'
- version: 2
- args: --optimize-autoloader --no-progress --no-interaction
- ssh_key: ${{ secrets.CLONE_SSH_KEY }}
- ssh_key_pub: ${{ secrets.CLONE_SSH_KEY_PUB }}
-
- - name: Run tests
- run: vendor/bin/phpunit
\ No newline at end of file
diff --git a/README.md b/README.md
index 51b8790..ae313ee 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-[](https://github.com/kununu/code-tools/actions/workflows/code_quality.yml)
-
+
+[](https://sonarcloud.io/dashboard?id=kununu_code-tools)
diff --git a/composer-dependency-analyser.php b/composer-dependency-analyser.php
new file mode 100644
index 0000000..236115a
--- /dev/null
+++ b/composer-dependency-analyser.php
@@ -0,0 +1,27 @@
+addPathToExclude(__DIR__ . '/tests')
+ ->ignoreErrorsOnPath(__DIR__ . '/Kununu/Sniffs/', [ErrorType::UNKNOWN_CLASS])
+ ->ignoreErrorsOnExtensions(
+ [
+ 'ext-mbstring',
+ 'ext-tokenizer',
+ ],
+ [ErrorType::SHADOW_DEPENDENCY]
+ )
+ ->ignoreErrorsOnPackages(
+ [
+ 'friendsofphp/php-cs-fixer',
+ 'phpstan/phpstan',
+ 'rector/rector',
+ 'squizlabs/php_codesniffer',
+ ],
+ [ErrorType::UNUSED_DEPENDENCY]
+ );
diff --git a/composer-require-checker.json b/composer-require-checker.json
new file mode 100644
index 0000000..36cdc19
--- /dev/null
+++ b/composer-require-checker.json
@@ -0,0 +1,27 @@
+{
+ "symbol-whitelist": [
+ "mb_strlen",
+ "PHP_CodeSniffer\\Exceptions\\DeepExitException",
+ "PHP_CodeSniffer\\Files\\File",
+ "PHP_CodeSniffer\\Sniffs\\Sniff",
+ "PHP_CodeSniffer\\Standards\\Generic\\Sniffs\\Files\\LineLengthSniff",
+ "T_CLASS",
+ "T_FUNCTION",
+ "T_CLOSE_CURLY_BRACKET",
+ "T_COMMA",
+ "T_NULLABLE",
+ "T_OPEN_TAG",
+ "T_PRIVATE",
+ "T_PROTECTED",
+ "T_PUBLIC",
+ "T_READONLY",
+ "T_SEMICOLON",
+ "T_STRING",
+ "T_USE",
+ "T_VAR",
+ "T_VARIABLE",
+ "T_WHITESPACE",
+ "T_CONST",
+ "T_DECLARE"
+ ]
+}
diff --git a/composer.json b/composer.json
index 41d4625..94c5298 100644
--- a/composer.json
+++ b/composer.json
@@ -1,64 +1,71 @@
{
- "name": "kununu/code-tools",
- "description": "Code Tools",
- "type": "composer-plugin",
- "license": "MIT",
- "authors": [
- {
- "name": "Team Rosa Mota",
- "email": "rosamota-dev@kununu.com"
- }
- ],
- "require": {
- "php": ">=8.3",
- "phpat/phpat": "^0.11.4",
- "phpstan/phpstan": "^2.1",
- "composer-plugin-api": "^2.0",
- "composer/composer": "^2.8",
- "friendsofphp/php-cs-fixer": "^3.75",
- "rector/rector": "^2.0",
- "squizlabs/php_codesniffer": "^3.10",
- "symfony/yaml": "^6.4 || ^7.4"
- },
- "require-dev": {
- "phpunit/phpunit": "^11.5"
- },
- "autoload": {
- "psr-4": {
- "Kununu\\": "Kununu/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Tests\\": "tests/"
- }
+ "name": "kununu/code-tools",
+ "description": "Code Tools",
+ "license": "MIT",
+ "type": "composer-plugin",
+ "authors": [
+ {
+ "name": "Team Rosa Mota",
+ "email": "rosamota-dev@kununu.com"
+ }
+ ],
+ "require": {
+ "php": ">=8.4",
+ "composer-plugin-api": "^2.0",
+ "composer/composer": "^2.8",
+ "friendsofphp/php-cs-fixer": "^3.93",
+ "phpat/phpat": "^0.11.4",
+ "phpstan/phpstan": "^2.1",
+ "rector/rector": "^2.0",
+ "squizlabs/php_codesniffer": "^3.10",
+ "symfony/console": "^6.4 || ^7.4",
+ "symfony/process": "^6.4 || ^7.4",
+ "symfony/yaml": "^6.4 || ^7.4"
+ },
+ "require-dev": {
+ "ergebnis/composer-normalize": "^2.50",
+ "phpunit/phpunit": "^11.5",
+ "shipmonk/composer-dependency-analyser": "^1.8"
+ },
+ "autoload": {
+ "psr-4": {
+ "Kununu\\": "Kununu/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/"
+ }
+ },
+ "bin": [
+ "bin/code-tools",
+ "bin/php-in-k8s"
+ ],
+ "config": {
+ "allow-plugins": {
+ "ergebnis/composer-normalize": true
},
- "bin": [
- "bin/code-tools",
- "bin/php-in-k8s"
+ "process-timeout": 900,
+ "sort-packages": true
+ },
+ "extra": {
+ "class": "Kununu\\CsFixer\\CsFixerPlugin"
+ },
+ "scripts": {
+ "ci-checks": [
+ "@cs-fixer-check",
+ "@cs-check",
+ "@stan",
+ "@rector",
+ "@test-unit"
],
- "config": {
- "sort-packages": true,
- "process-timeout": 900
- },
- "extra": {
- "class": "Kununu\\CsFixer\\CsFixerPlugin"
- },
- "scripts": {
- "test-unit": "phpunit",
- "cs-fixer-check": "php-cs-fixer check --config=php-cs-fixer.php",
- "cs-fixer-fix": "php-cs-fixer fix --config=php-cs-fixer.php",
- "cs-check": "phpcs --standard=phpcs.xml Kununu/ tests/",
- "cs-fix": "phpcbf --standard=phpcs.xml Kununu/ tests/",
- "stan": "phpstan analyze",
- "rector": "rector process --dry-run Kununu/ tests/ -vvv",
- "rector-fix": "rector process Kununu/ tests/",
- "ci-checks": [
- "@cs-fixer-check",
- "@cs-check",
- "@stan",
- "@rector",
- "@test-unit"
- ]
- }
+ "cs-check": "phpcs --standard=phpcs.xml Kununu/ tests/",
+ "cs-fix": "phpcbf --standard=phpcs.xml Kununu/ tests/",
+ "cs-fixer-check": "php-cs-fixer check --config=php-cs-fixer.php",
+ "cs-fixer-fix": "php-cs-fixer fix --config=php-cs-fixer.php",
+ "rector": "rector process --dry-run Kununu/ tests/ -vvv",
+ "rector-fix": "rector process Kununu/ tests/",
+ "stan": "phpstan analyze",
+ "test-unit": "phpunit"
+ }
}
diff --git a/qodana.yaml b/qodana.yaml
deleted file mode 100644
index b78eaf2..0000000
--- a/qodana.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-version: "1.0"
-linter: jetbrains/qodana-php:2025.2
-profile:
- name: qodana.recommended
-exclude:
- - name: All
- paths:
- - rector.php
- - name: PhpDisabledQualityToolComposerInspection
- - name: DuplicatedCode
- paths:
- - Kununu/Sniffs
-failureConditions:
- severityThresholds:
- critical: 0
- high: 0
- moderate: 0
diff --git a/sonar-project.properties b/sonar-project.properties
new file mode 100644
index 0000000..b17bf22
--- /dev/null
+++ b/sonar-project.properties
@@ -0,0 +1,28 @@
+# ######################################################################################################################
+# Project configuration
+# ######################################################################################################################
+sonar.projectKey=kununu_code-tools
+sonar.organization=kununu
+sonar.projectName=code-tools
+sonar.projectVersion=1.0
+sonar.sourceEncoding=UTF-8
+
+# ######################################################################################################################
+# Directories
+# ######################################################################################################################
+sonar.sources=Kununu
+sonar.tests=tests
+sonar.php.coverage.reportPaths=tests/.results/tests-clover.xml
+sonar.php.tests.reportPath=tests/.results/tests-junit.xml
+
+# ######################################################################################################################
+# Code coverage exclusions
+# ######################################################################################################################
+sonar.coverage.exclusions=\
+ tests/**,\
+
+# ######################################################################################################################
+# Code duplication detections exclusions
+# ######################################################################################################################
+sonar.cpd.exclusions=\
+ tests/**,\
diff --git a/tests/Unit/Kununu/CsFixer/Command/CsFixerCommandTest.php b/tests/Unit/Kununu/CsFixer/Command/CsFixerCommandTest.php
index 0c6ef34..f883037 100644
--- a/tests/Unit/Kununu/CsFixer/Command/CsFixerCommandTest.php
+++ b/tests/Unit/Kununu/CsFixer/Command/CsFixerCommandTest.php
@@ -22,7 +22,10 @@ public function testCsFixerCommand(string $before, string $after): void
}
$application = new Application();
- $application->add(new CsFixerCommand());
+ $command = new CsFixerCommand();
+ method_exists($application, 'addCommand')
+ ? $application->addCommand($command)
+ : $application->add($command);
$command = $application->find('kununu:cs-fixer');
$tester = new CommandTester($command);
diff --git a/tests/Unit/Kununu/CsFixer/Command/CsFixerGitHookCommandTest.php b/tests/Unit/Kununu/CsFixer/Command/CsFixerGitHookCommandTest.php
index aa6f179..9a2b069 100644
--- a/tests/Unit/Kununu/CsFixer/Command/CsFixerGitHookCommandTest.php
+++ b/tests/Unit/Kununu/CsFixer/Command/CsFixerGitHookCommandTest.php
@@ -17,7 +17,10 @@ final class CsFixerGitHookCommandTest extends TestCase
public function testFailsWhenNotAGitRepo(): void
{
$app = new Application();
- $app->add(new CsFixerGitHookCommand());
+ $command = new CsFixerGitHookCommand();
+ method_exists($app, 'addCommand')
+ ? $app->addCommand($command)
+ : $app->add($command);
$command = $app->find('kununu:cs-fixer-git-hook');
$tester = new CommandTester($command);
@@ -51,7 +54,10 @@ public function testInstallsHookSuccessfully(): void
@chmod($binDir . '/php-cs-fixer', 0755);
$app = new Application();
- $app->add(new CsFixerGitHookCommand());
+ $command = new CsFixerGitHookCommand();
+ method_exists($app, 'addCommand')
+ ? $app->addCommand($command)
+ : $app->add($command);
$command = $app->find('kununu:cs-fixer-git-hook');
$tester = new CommandTester($command);