From 5257d7a41370fb4c8573e2e77391a3c69adc4e44 Mon Sep 17 00:00:00 2001
From: Gilbertsoft <25326036+gilbertsoft@users.noreply.github.com>
Date: Sat, 2 Apr 2022 15:47:23 +0200
Subject: [PATCH] [TASK] Optimize Github workflows (#311)
---
.github/workflows/continuous-integration.yml | 548 +++++++++++++++++++
.github/workflows/deployment.yml | 67 ++-
.github/workflows/integration.yml | 78 ---
.github/workflows/manual-deployment.yml | 27 +
.gitignore | 6 +-
composer.json | 66 +--
composer.lock | 413 +++-----------
phpstan.neon | 12 +-
rector.php | 2 +-
symfony.lock | 21 -
tests/Functional/DatabasePrimer.php | 1 +
tests/Functional/phpunit.xml | 42 ++
tests/Unit/phpunit.xml | 35 ++
tools/phpunit/composer.json | 7 +
14 files changed, 822 insertions(+), 503 deletions(-)
create mode 100644 .github/workflows/continuous-integration.yml
delete mode 100644 .github/workflows/integration.yml
create mode 100644 .github/workflows/manual-deployment.yml
create mode 100644 tests/Functional/phpunit.xml
create mode 100644 tests/Unit/phpunit.xml
create mode 100644 tools/phpunit/composer.json
diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
new file mode 100644
index 00000000..27b44cdb
--- /dev/null
+++ b/.github/workflows/continuous-integration.yml
@@ -0,0 +1,548 @@
+name: Continuous Integration (CI)
+
+on:
+ push:
+ branches:
+ - develop
+ - production
+ - stage
+ pull_request:
+ schedule:
+ - cron: '33 3 * * *'
+
+env:
+ COMPOSER_FLAGS: --ansi --no-interaction --no-progress
+ COMPOSER_INSTALL_FLAGS: --prefer-dist
+ COMPOSER_UPDATE_FLAGS: ''
+
+jobs:
+ validation:
+ name: Composer validation
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: none
+ extensions: zip, zlib
+ ini-values: memory_limit=-1, error_reporting=E_ALL, display_errors=On
+ php-version: latest
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-latest-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-latest-
+ ${{ runner.os }}-composer-
+
+ - name: Setup authentication for Composer
+ run: composer config github-oauth.github.com ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Install dependencies
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Validate composer.json
+ run: composer ci:composer:validate
+
+ - name: Normalize composer.json
+ run: composer ci:composer:normalize
+
+ - name: Check dependencies
+ run: composer ci:composer:require-checker
+
+ json_lint:
+ name: JSON Lint
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: none
+ extensions: ctype, iconv, json, sqlit3, tokenizer, zip, zlib
+ ini-values: memory_limit=-1, error_reporting=E_ALL, display_errors=On
+ php-version: latest
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-latest-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-latest-
+ ${{ runner.os }}-composer-
+
+ - name: Install dependencies
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Lint YAML files
+ run: composer ci:json:lint
+
+ yaml_lint:
+ name: YAML Lint
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: none
+ extensions: ctype, iconv, json, sqlit3, tokenizer, zip, zlib
+ ini-values: memory_limit=-1, error_reporting=E_ALL, display_errors=On
+ php-version: latest
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-latest-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-latest-
+ ${{ runner.os }}-composer-
+
+ - name: Install dependencies
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Lint YAML files
+ run: composer ci:yaml:lint
+
+ php_lint:
+ name: PHP Lint
+ runs-on: ubuntu-latest
+ continue-on-error: ${{ matrix.experimental }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ php-version:
+ - '8.1'
+ - 'latest'
+ experimental: [false]
+ include:
+ - php-version: 'nightly'
+ experimental: true
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: none
+ extensions: ctype, iconv, json, sqlit3, tokenizer, zip, zlib
+ ini-values: memory_limit=-1, error_reporting=E_ALL, display_errors=On
+ php-version: ${{ matrix.php-version }}
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-${{ matrix.php-version }}-
+ ${{ runner.os }}-composer-
+
+ - name: Set platform.php for nightly
+ if: ${{ matrix.php-version == 'nightly' }}
+ run: |
+ composer install --no-scripts ${{ env.COMPOSER_FLAGS }}
+ composer bin phpunit config platform.php 8.1.99
+
+ - name: Install dependencies
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Lint PHP files
+ run: composer ci:php:lint
+
+ php_rector:
+ name: PHP Rector
+ needs:
+ - php_lint
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: none
+ extensions: ctype, iconv, json, sqlit3, tokenizer, zip, zlib
+ ini-values: memory_limit=-1, error_reporting=E_ALL, display_errors=On
+ php-version: latest
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-latest-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-latest-
+ ${{ runner.os }}-composer-
+
+ - name: Install dependencies
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Validation of Rector rules for PHP files
+ run: composer ci:php:rector
+
+ php_coding_standards:
+ name: PHP Coding Standards
+ needs:
+ - php_rector
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: none
+ extensions: ctype, iconv, json, sqlit3, tokenizer, zip, zlib
+ ini-values: memory_limit=-1, error_reporting=E_ALL, display_errors=On
+ php-version: latest
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-latest-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-latest-
+ ${{ runner.os }}-composer-
+
+ - name: Install dependencies
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Validation of coding standards for PHP files
+ run: composer ci:php:cs
+
+ php_sniff:
+ name: PHP Code Sniffer
+ needs:
+ - php_rector
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: none
+ extensions: ctype, iconv, json, sqlit3, tokenizer, zip, zlib
+ ini-values: memory_limit=-1, error_reporting=E_ALL, display_errors=On
+ php-version: latest
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-latest-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-latest-
+ ${{ runner.os }}-composer-
+
+ - name: Install dependencies
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Validation of coding standards
+ run: composer ci:php:sniff
+
+ php_copypaste_detector:
+ name: PHP Copy/Paste Detector
+ needs:
+ - php_rector
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: none
+ extensions: ctype, iconv, json, sqlit3, tokenizer, zip, zlib
+ ini-values: memory_limit=-1, error_reporting=E_ALL, display_errors=On
+ php-version: latest
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-latest-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-latest-
+ ${{ runner.os }}-composer-
+
+ - name: Install dependencies
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Detection of copy/paste code in PHP files
+ run: composer ci:php:copypaste
+
+ php_stan:
+ name: PHP Stan
+ needs:
+ - validation
+ - php_coding_standards
+ - php_sniff
+ - php_copypaste_detector
+ runs-on: ubuntu-latest
+ continue-on-error: ${{ matrix.experimental }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ php-version: ['8.1']
+ dependencies: ['lock']
+ experimental: [false]
+ include:
+ - php-version: 'latest'
+ dependencies: 'lock'
+ experimental: true
+ - php-version: 'latest'
+ dependencies: 'highest'
+ experimental: true
+ - php-version: 'nightly'
+ dependencies: 'lock'
+ experimental: true
+ - php-version: 'nightly'
+ dependencies: 'highest'
+ experimental: true
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: none
+ extensions: ctype, iconv, json, sqlit3, tokenizer, zip, zlib
+ ini-values: memory_limit=-1
+ php-version: ${{ matrix.php-version }}
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ matrix.php-version }}-${{ matrix.dependencies }}-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-${{ matrix.php-version }}-${{ matrix.dependencies }}-
+ ${{ runner.os }}-composer-${{ matrix.php-version }}-
+ ${{ runner.os }}-composer-
+
+ - name: Setup authentication for Composer
+ run: composer config github-oauth.github.com ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Handle lowest dependencies update
+ if: contains(matrix.dependencies, 'lowest')
+ run: echo "COMPOSER_UPDATE_FLAGS=$COMPOSER_UPDATE_FLAGS --prefer-lowest" >> $GITHUB_ENV
+
+ - name: Allow alpha releases for latest-deps builds to catch problems earlier
+ if: contains(matrix.dependencies, 'highest')
+ run: composer config minimum-stability alpha
+
+ - name: Set platform.php for nightly
+ if: ${{ matrix.php-version == 'nightly' }}
+ run: |
+ composer install --no-scripts ${{ env.COMPOSER_FLAGS }}
+ composer bin phpunit config platform.php 8.1.99
+
+ - name: Install dependencies
+ if: ${{ matrix.dependencies == 'lock' }}
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Update dependencies
+ if: ${{ matrix.dependencies != 'lock' }}
+ run: composer update ${{ env.COMPOSER_UPDATE_FLAGS }} ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Run PHPStan
+ run: composer ci:php:stan
+
+ tests:
+ name: Tests
+ needs:
+ - php_stan
+ runs-on: ubuntu-latest
+ continue-on-error: ${{ matrix.experimental }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ php-version: ['8.1']
+ dependencies: ['lock']
+ experimental: [false]
+ include:
+ - php-version: '8.1'
+ dependencies: 'highest'
+ experimental: true
+ - php-version: 'latest'
+ dependencies: 'lock'
+ experimental: true
+ - php-version: 'latest'
+ dependencies: 'highest'
+ experimental: true
+ - php-version: 'nightly'
+ dependencies: 'lock'
+ experimental: true
+ - php-version: 'nightly'
+ dependencies: 'highest'
+ experimental: true
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ submodules: 'recursive'
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ coverage: xdebug
+ extensions: ctype, iconv, json, sqlit3, tokenizer, zip, zlib
+ ini-values: memory_limit=-1, error_reporting=E_ALL, display_errors=On
+ php-version: ${{ matrix.php-version }}
+ tools: composer:2
+
+ - name: Get Composer Cache Directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache Composer dependencies
+ uses: actions/cache@v3
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ matrix.php-version }}-${{ matrix.dependencies }}-${{ hashFiles('**/composer.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-composer-${{ matrix.php-version }}-${{ matrix.dependencies }}-
+ ${{ runner.os }}-composer-${{ matrix.php-version }}-
+ ${{ runner.os }}-composer-
+
+ - name: Setup authentication for Composer
+ run: composer config github-oauth.github.com ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Allow alpha releases for latest-deps builds to catch problems earlier
+ if: ${{ matrix.dependencies == 'highest' }}
+ run: composer config minimum-stability alpha
+
+ - name: Set platform.php for nightly
+ if: ${{ matrix.php-version == 'nightly' }}
+ run: |
+ composer install --no-scripts ${{ env.COMPOSER_FLAGS }}
+ composer bin phpunit config platform.php 8.1.99
+
+ - name: Install dependencies
+ if: ${{ matrix.dependencies == 'lock' }}
+ run: composer install ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Update dependencies
+ if: ${{ matrix.dependencies != 'lock' }}
+ run: composer update ${{ env.COMPOSER_UPDATE_FLAGS }} ${{ env.COMPOSER_INSTALL_FLAGS }} ${{ env.COMPOSER_FLAGS }}
+
+ - name: Unit Tests
+ continue-on-error: ${{ matrix.experimental }}
+ if: always()
+ run: composer ci:tests:php:unit
+
+ - name: Functional Tests
+ continue-on-error: ${{ matrix.experimental }}
+ if: always()
+ run: composer ci:tests:php:functional
+
+ - name: Upload Logs
+ uses: actions/upload-artifact@v3
+ if: always()
+ with:
+ name: logs-${{ matrix.php-version }}-${{ matrix.dependencies }}
+ path: var/log
+ retention-days: 7
+
+ deployment:
+ name: Deployment
+ needs:
+ - tests
+ if: startsWith(github.event.workflow_run.event, 'push')
+ uses: ./.github/workflows/deployment.yml
diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml
index 863056e0..532e62a1 100644
--- a/.github/workflows/deployment.yml
+++ b/.github/workflows/deployment.yml
@@ -1,14 +1,36 @@
-name: Deployment (CD)
+name: Deployment Template
+
on:
- push:
- branches:
- - production
- - develop
- - stage
+ workflow_call:
+ inputs:
+ php_version:
+ description: 'PHP version to be used for the deployment.'
+ default: '8.1'
+ required: false
+ type: string
+ composer_version:
+ description: 'Composer version to be used for the deployment.'
+ default: '2'
+ required: false
+ type: string
+
jobs:
- deployment:
- name: Deployment
+ print_inputs:
+ name: Print Inputs
runs-on: ubuntu-latest
+
+ steps:
+ - name: Print the inputs
+ run: |
+ echo PHP version: ${{ inputs.php_version }}
+ echo Composer version: ${{ inputs.composer_version }}
+
+ deploy:
+ name: Deploy
+ needs:
+ - print_inputs
+ runs-on: ubuntu-latest
+
steps:
- name: Setup SSH Key
env:
@@ -20,33 +42,34 @@ jobs:
ssh-keygen -p -P "${{ secrets.SSH_PASSPHRASE }}" -N "" -f ~/.ssh/deploy_key
ssh-agent -a $SSH_AUTH_SOCK > /dev/null
ssh-add ~/.ssh/deploy_key
- - uses: actions/checkout@v2
- - name: Checkout submodules
- shell: bash
- run: |
- # If your submodules are configured to use SSH instead of HTTPS please uncomment the following line
- # git config --global url."https://github.com/".insteadOf "git@github.com:"
- auth_header="$(git config --local --get http.https://github.com/.extraheader)"
- git submodule sync --recursive
- git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
+
+ - uses: actions/checkout@v3
+ name: Checkout
+ with:
+ submodules: 'recursive'
+
- name: Set up PHP Version
uses: shivammathur/setup-php@v2
with:
- php-version: '8.1'
- tools: composer:v2, andres-montanez/magallanes
+ php-version: ${{ inputs.php_version }}
+ tools: composer:${{ inputs.composer_version }}, andres-montanez/magallanes
+
- name: Get Environment
id: environment
run: |
echo ::set-output name=target::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//-/g')
+
- name: Deployment
env:
SSH_AUTH_SOCK: /tmp/ssh-auth.sock
run: |
mkdir -p ./.mage/logs
composer global exec mage deploy ${{ steps.environment.outputs.target }}
- - name: Archive Logs
- uses: actions/upload-artifact@v1
+
+ - name: Upload Logs
+ uses: actions/upload-artifact@v3
if: always()
with:
- name: logs
+ name: deployment
path: .mage/logs
+ retention-days: 7
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
deleted file mode 100644
index 65fde26c..00000000
--- a/.github/workflows/integration.yml
+++ /dev/null
@@ -1,78 +0,0 @@
-name: Integration (CI)
-
-on: [push, pull_request]
-
-jobs:
- build:
- name: Build
- runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- php: ['8.1']
- steps:
- - uses: actions/checkout@v2
- - name: Checkout submodules
- shell: bash
- run: |
- # If your submodules are configured to use SSH instead of HTTPS please uncomment the following line
- # git config --global url."https://github.com/".insteadOf "git@github.com:"
- auth_header="$(git config --local --get http.https://github.com/.extraheader)"
- git submodule sync --recursive
- git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
- - name: Set up PHP Version
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php }}
- - name: Update Composer
- run: |
- sudo composer self-update
- composer --version
- - name: Get Composer Cache Directory
- id: composer-cache
- run: |
- echo "::set-output name=dir::$(composer config cache-files-dir)"
- - uses: actions/cache@v1
- with:
- path: ${{ steps.composer-cache.outputs.dir }}
- key: ${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
- restore-keys: |
- ${{ matrix.php }}-composer-
- - name: Composer validate
- if: always()
- run: |
- composer ci:composer:validate
- - name: Install
- run: |
- composer install --no-progress
- - name: Composer normalize
- if: always()
- run: |
- composer ci:composer:normalize
- - name: Lint
- if: always()
- run: |
- composer ci:php:lint
- - name: PHPStan
- if: always()
- run: |
- composer ci:php:stan
- - name: CGL
- if: always()
- run: |
- composer ci:php:cs-fixer
- - name: Unit Tests
- if: always()
- run: |
- composer ci:tests:php:unit
- - name: Functional Tests
- if: always()
- run: |
- composer ci:tests:php:functional
- - name: Archive Logs
- uses: actions/upload-artifact@v1
- if: always()
- with:
- name: logs
- path: var/log
-
diff --git a/.github/workflows/manual-deployment.yml b/.github/workflows/manual-deployment.yml
new file mode 100644
index 00000000..8c866625
--- /dev/null
+++ b/.github/workflows/manual-deployment.yml
@@ -0,0 +1,27 @@
+name: Manual Deployment
+
+on:
+ workflow_dispatch:
+ inputs:
+ php_version:
+ description: 'PHP version to be used for the deployment.'
+ default: '8.1'
+ required: true
+ type: choice
+ options:
+ - '8.1'
+ - 'latest'
+ - 'nightly'
+ composer_version:
+ description: 'Composer version to be used for the deployment.'
+ default: '2'
+ required: true
+ type: string
+
+jobs:
+ deployment:
+ name: Deployment
+ uses: ./.github/workflows/deployment.yml
+ with:
+ php_version: ${{ github.event.inputs.php_version }}
+ composer_version: ${{ github.event.inputs.composer_version }}
diff --git a/.gitignore b/.gitignore
index c84d821e..b1a4da62 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@
/.php-cs-fixer.cache
/.phplint-cache
/missing-downloads.yaml
+.phpunit.result.cache
###> symfony/framework-bundle ###
/.env.local
@@ -23,8 +24,3 @@
/var/
/vendor/
###< symfony/framework-bundle ###
-###> symfony/phpunit-bridge ###
-.phpunit
-.phpunit.result.cache
-/phpunit.xml
-###< symfony/phpunit-bridge ###
diff --git a/composer.json b/composer.json
index dfcc2adc..88fc81c0 100644
--- a/composer.json
+++ b/composer.json
@@ -29,7 +29,7 @@
"source": "https://github.com/TYPO3/get.typo3.org"
},
"require": {
- "php": ">=7.4.25",
+ "php": ">=8.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"ext-json": "*",
@@ -97,7 +97,6 @@
"symfony/debug-bundle": "5.4.*",
"symfony/maker-bundle": "^1.0",
"symfony/panther": "^1.1.1",
- "symfony/phpunit-bridge": "5.4.*",
"symfony/stopwatch": "5.4.*",
"symfony/var-dumper": "5.4.*",
"symfony/web-profiler-bundle": "5.4.*"
@@ -116,19 +115,14 @@
"symfony/polyfill-php71": "*",
"symfony/polyfill-php72": "*",
"symfony/polyfill-php73": "*",
- "symfony/polyfill-php74": "*"
+ "symfony/polyfill-php74": "*",
+ "symfony/polyfill-php80": "*",
+ "symfony/polyfill-php81": "*"
},
"conflict": {
"symfony/symfony": "*"
},
"repositories": {
- "local": {
- "type": "path",
- "url": "packages/*",
- "exclude": [
- "t3g/symfony-template-bundle"
- ]
- },
"template-bundle": {
"type": "vcs",
"url": "https://github.com/gilbertsoft/symfony-template-bundle"
@@ -188,7 +182,8 @@
},
"bin": "echo 'bin not installed.'",
"ci": [
- "@ci:static"
+ "@ci:static",
+ "@ci:dynamic"
],
"ci:composer": [
"@ci:composer:validate",
@@ -209,31 +204,26 @@
"ci:dynamic": [
"@ci:tests"
],
- "ci:json:lint": "jsonlint -q composer.json",
+ "ci:json:lint": "@php jsonlint -q composer.json",
"ci:php": [
- "@ci:php:copypaste",
"@ci:php:lint",
+ "@ci:php:rector",
+ "@ci:php:cs-fixer",
"@ci:php:sniff",
- "@ci:php:stan",
- "@ci:php:cs-fixer"
- ],
- "ci:php:copypaste": "phpcpd src tests",
- "ci:php:cs-fixer": "php-cs-fixer fix -v --dry-run --diff",
- "ci:php:lint": "phplint --no-progress",
- "ci:php:rector": [
- "@php simple-phpunit install -c phpunit.xml.dist",
- "@php rector process --dry-run --no-progress-bar --no-diffs"
- ],
- "ci:php:sniff": "phpcs --standard=PSR12 src tests",
- "ci:php:stan": [
- "@php simple-phpunit install -c phpunit.xml.dist",
- "@php phpstan analyse --no-progress"
+ "@ci:php:copypaste",
+ "@ci:php:stan"
],
+ "ci:php:copypaste": "@php phpcpd src tests",
+ "ci:php:cs-fixer": "@php php-cs-fixer fix -v --dry-run --diff",
+ "ci:php:lint": "@php phplint --no-progress",
+ "ci:php:rector": "@php rector process --dry-run --no-progress-bar || true",
+ "ci:php:sniff": "@php phpcs --standard=PSR12 src tests || true",
+ "ci:php:stan": "@php phpstan analyse --no-progress",
"ci:static": [
"@ci:composer",
"@ci:json:lint",
- "@ci:php",
- "@ci:yaml:lint"
+ "@ci:yaml:lint",
+ "@ci:php"
],
"ci:tests": [
"@ci:tests:php"
@@ -242,9 +232,9 @@
"@ci:tests:php:unit",
"@ci:tests:php:functional"
],
- "ci:tests:php:functional": "simple-phpunit -c phpunit.xml.dist --log-junit var/log/phpunit-functional.xml --testsuite \"Functional Test Suite\"",
- "ci:tests:php:unit": "simple-phpunit -c phpunit.xml.dist --log-junit var/log/phpunit-unit.xml --testsuite \"Unit Test Suite\"",
- "ci:yaml:lint": "yaml-lint .ddev config",
+ "ci:tests:php:functional": "@php phpunit -c tests/Functional/phpunit.xml",
+ "ci:tests:php:unit": "@php phpunit -c tests/Unit/phpunit.xml",
+ "ci:yaml:lint": "@php yaml-lint .ddev config",
"fix": [
"@fix:composer",
"@fix:php"
@@ -257,16 +247,10 @@
"@fix:php:rector",
"@fix:php:cs-fixer"
],
- "fix:php:cs-fixer": "php-cs-fixer fix",
- "fix:php:rector": [
- "@php simple-phpunit install -c phpunit.xml.dist",
- "@php rector process --no-diffs"
- ],
+ "fix:php:cs-fixer": "@php php-cs-fixer fix",
+ "fix:php:rector": "@php rector process --no-diffs",
"fix:php:sniff": "phpcbf src",
- "tools:php:rector": [
- "@php simple-phpunit install -c phpunit.xml.dist",
- "@php rector process --dry-run"
- ],
+ "tools:php:rector": "@php rector process --dry-run",
"tools:setup:clean": "rm -r tools/**/composer.lock tools/**/vendor",
"tools:setup:install": "@composer bin all install --ansi",
"tools:setup:update": "@composer bin all update --ansi"
diff --git a/composer.lock b/composer.lock
index 85ecca9b..2479c95d 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "9c3b998df17eeaa7d36fcb6fee993fdc",
+ "content-hash": "8f5dea6f855258d52cab103f055eb95d",
"packages": [
{
"name": "composer/ca-bundle",
@@ -412,6 +412,88 @@
],
"time": "2022-02-02T09:15:57+00:00"
},
+ {
+ "name": "doctrine/data-fixtures",
+ "version": "1.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/data-fixtures.git",
+ "reference": "51c1890e8c5467c421c7cab4579f059ebf720278"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/51c1890e8c5467c421c7cab4579f059ebf720278",
+ "reference": "51c1890e8c5467c421c7cab4579f059ebf720278",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/common": "^2.13|^3.0",
+ "doctrine/persistence": "^1.3.3|^2.0",
+ "php": "^7.2 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/dbal": "<2.13",
+ "doctrine/phpcr-odm": "<1.3.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9.0",
+ "doctrine/dbal": "^2.13 || ^3.0",
+ "doctrine/mongodb-odm": "^1.3.0 || ^2.0.0",
+ "doctrine/orm": "^2.7.0",
+ "ext-sqlite3": "*",
+ "jangregor/phpstan-prophecy": "^0.8.1",
+ "phpstan/phpstan": "^0.12.99",
+ "phpunit/phpunit": "^8.0",
+ "symfony/cache": "^5.0 || ^6.0",
+ "vimeo/psalm": "^4.10"
+ },
+ "suggest": {
+ "alcaeus/mongo-php-adapter": "For using MongoDB ODM 1.3 with PHP 7 (deprecated)",
+ "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures",
+ "doctrine/orm": "For loading ORM fixtures",
+ "doctrine/phpcr-odm": "For loading PHPCR ODM fixtures"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\DataFixtures\\": "lib/Doctrine/Common/DataFixtures"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ }
+ ],
+ "description": "Data Fixtures for all Doctrine Object Managers",
+ "homepage": "https://www.doctrine-project.org",
+ "keywords": [
+ "database"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/data-fixtures/issues",
+ "source": "https://github.com/doctrine/data-fixtures/tree/1.5.2"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdata-fixtures",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-01-20T17:10:56+00:00"
+ },
{
"name": "doctrine/dbal",
"version": "3.3.4",
@@ -6259,168 +6341,6 @@
],
"time": "2022-01-02T09:53:40+00:00"
},
- {
- "name": "symfony/polyfill-php80",
- "version": "v1.25.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c",
- "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.23-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Php80\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Ion Bazan",
- "email": "ion.bazan@gmail.com"
- },
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2022-03-04T08:16:47+00:00"
- },
- {
- "name": "symfony/polyfill-php81",
- "version": "v1.25.0",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/polyfill-php81.git",
- "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
- "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.23-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Polyfill\\Php81\\": ""
- },
- "classmap": [
- "Resources/stubs"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "polyfill",
- "portable",
- "shim"
- ],
- "support": {
- "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2021-09-13T13:58:11+00:00"
- },
{
"name": "symfony/process",
"version": "v5.4.5",
@@ -9019,88 +8939,6 @@
},
"time": "2022-02-22T21:01:25+00:00"
},
- {
- "name": "doctrine/data-fixtures",
- "version": "1.5.2",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/data-fixtures.git",
- "reference": "51c1890e8c5467c421c7cab4579f059ebf720278"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/51c1890e8c5467c421c7cab4579f059ebf720278",
- "reference": "51c1890e8c5467c421c7cab4579f059ebf720278",
- "shasum": ""
- },
- "require": {
- "doctrine/common": "^2.13|^3.0",
- "doctrine/persistence": "^1.3.3|^2.0",
- "php": "^7.2 || ^8.0"
- },
- "conflict": {
- "doctrine/dbal": "<2.13",
- "doctrine/phpcr-odm": "<1.3.0"
- },
- "require-dev": {
- "doctrine/coding-standard": "^9.0",
- "doctrine/dbal": "^2.13 || ^3.0",
- "doctrine/mongodb-odm": "^1.3.0 || ^2.0.0",
- "doctrine/orm": "^2.7.0",
- "ext-sqlite3": "*",
- "jangregor/phpstan-prophecy": "^0.8.1",
- "phpstan/phpstan": "^0.12.99",
- "phpunit/phpunit": "^8.0",
- "symfony/cache": "^5.0 || ^6.0",
- "vimeo/psalm": "^4.10"
- },
- "suggest": {
- "alcaeus/mongo-php-adapter": "For using MongoDB ODM 1.3 with PHP 7 (deprecated)",
- "doctrine/mongodb-odm": "For loading MongoDB ODM fixtures",
- "doctrine/orm": "For loading ORM fixtures",
- "doctrine/phpcr-odm": "For loading PHPCR ODM fixtures"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "Doctrine\\Common\\DataFixtures\\": "lib/Doctrine/Common/DataFixtures"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com"
- }
- ],
- "description": "Data Fixtures for all Doctrine Object Managers",
- "homepage": "https://www.doctrine-project.org",
- "keywords": [
- "database"
- ],
- "support": {
- "issues": "https://github.com/doctrine/data-fixtures/issues",
- "source": "https://github.com/doctrine/data-fixtures/tree/1.5.2"
- },
- "funding": [
- {
- "url": "https://www.doctrine-project.org/sponsorship.html",
- "type": "custom"
- },
- {
- "url": "https://www.patreon.com/phpdoctrine",
- "type": "patreon"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdata-fixtures",
- "type": "tidelift"
- }
- ],
- "time": "2022-01-20T17:10:56+00:00"
- },
{
"name": "doctrine/doctrine-fixtures-bundle",
"version": "3.4.1",
@@ -10717,89 +10555,6 @@
],
"time": "2021-11-30T15:51:25+00:00"
},
- {
- "name": "symfony/phpunit-bridge",
- "version": "v5.4.3",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/phpunit-bridge.git",
- "reference": "216b07b05644607c81afd89a208e52641c1ce6b8"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/216b07b05644607c81afd89a208e52641c1ce6b8",
- "reference": "216b07b05644607c81afd89a208e52641c1ce6b8",
- "shasum": ""
- },
- "require": {
- "php": ">=7.1.3",
- "symfony/deprecation-contracts": "^2.1|^3"
- },
- "conflict": {
- "phpunit/phpunit": "<7.5|9.1.2"
- },
- "require-dev": {
- "symfony/error-handler": "^4.4|^5.0|^6.0"
- },
- "suggest": {
- "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader"
- },
- "bin": [
- "bin/simple-phpunit"
- ],
- "type": "symfony-bridge",
- "extra": {
- "thanks": {
- "name": "phpunit/phpunit",
- "url": "https://github.com/sebastianbergmann/phpunit"
- }
- },
- "autoload": {
- "files": [
- "bootstrap.php"
- ],
- "psr-4": {
- "Symfony\\Bridge\\PhpUnit\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Provides utilities for PHPUnit, especially user deprecation notices management",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/phpunit-bridge/tree/v5.4.3"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2022-01-26T16:28:35+00:00"
- },
{
"name": "symfony/web-profiler-bundle",
"version": "v5.4.6",
@@ -10890,7 +10645,7 @@
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
- "php": ">=7.4.25",
+ "php": ">=8.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"ext-json": "*",
diff --git a/phpstan.neon b/phpstan.neon
index d141e439..5b2830e8 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -3,14 +3,14 @@ parameters:
treatPhpDocTypesAsCertain: false
bootstrapFiles:
- - %currentWorkingDirectory%/vendor/bin/.phpunit/phpunit/vendor/autoload.php
+ - tools/phpunit/vendor/autoload.php
paths:
- - %currentWorkingDirectory%/config/
- - %currentWorkingDirectory%/migrations/
- - %currentWorkingDirectory%/public/
- - %currentWorkingDirectory%/src/
- - %currentWorkingDirectory%/tests/
+ - config/
+ - migrations/
+ - public/
+ - src/
+ - tests/
stubFiles:
- stubs/MenuBuilder.stub
diff --git a/rector.php b/rector.php
index 7a51582a..ff249db8 100644
--- a/rector.php
+++ b/rector.php
@@ -47,7 +47,7 @@
$parameters->set(Option::BOOTSTRAP_FILES, [
__DIR__ . '/vendor/autoload.php',
- __DIR__ . '/vendor/bin/.phpunit/phpunit/vendor/autoload.php',
+ __DIR__ . '/tools/phpunit/vendor/autoload.php',
]);
// Path to phpstan with extensions, that PHPStan in Rector uses to determine types
diff --git a/symfony.lock b/symfony.lock
index 6c6c9684..af91477d 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -464,27 +464,6 @@
"symfony/password-hasher": {
"version": "v5.3.4"
},
- "symfony/phpunit-bridge": {
- "version": "4.3",
- "recipe": {
- "repo": "github.com/symfony/recipes",
- "branch": "master",
- "version": "4.3",
- "ref": "6d0e35f749d5f4bfe1f011762875275cd3f9874f"
- },
- "files": [
- ".env.test",
- "bin/phpunit",
- "phpunit.xml.dist",
- "tests/bootstrap.php"
- ]
- },
- "symfony/polyfill-php80": {
- "version": "v1.20.0"
- },
- "symfony/polyfill-php81": {
- "version": "v1.23.0"
- },
"symfony/process": {
"version": "v5.1.9"
},
diff --git a/tests/Functional/DatabasePrimer.php b/tests/Functional/DatabasePrimer.php
index bfc1b084..3ea703da 100644
--- a/tests/Functional/DatabasePrimer.php
+++ b/tests/Functional/DatabasePrimer.php
@@ -42,6 +42,7 @@ public static function prime(KernelInterface $kernel): void
}
// Get the entity manager from the service container
+ /** @noRector */
$entityManager = $kernel->getContainer()->get('doctrine.orm.entity_manager');
if (!$entityManager instanceof EntityManagerInterface) {
throw new \LogicException('EntityManager could not be retrieved');
diff --git a/tests/Functional/phpunit.xml b/tests/Functional/phpunit.xml
new file mode 100644
index 00000000..7bd6d7f2
--- /dev/null
+++ b/tests/Functional/phpunit.xml
@@ -0,0 +1,42 @@
+
+
+
+
+ ../../src/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ./
+
+
+
+
+
+
+
diff --git a/tests/Unit/phpunit.xml b/tests/Unit/phpunit.xml
new file mode 100644
index 00000000..a9db86b1
--- /dev/null
+++ b/tests/Unit/phpunit.xml
@@ -0,0 +1,35 @@
+
+
+
+
+ ../../src/
+
+
+
+
+
+
+
+
+ ./
+
+
+
+
+
+
+
diff --git a/tools/phpunit/composer.json b/tools/phpunit/composer.json
new file mode 100644
index 00000000..11e241e5
--- /dev/null
+++ b/tools/phpunit/composer.json
@@ -0,0 +1,7 @@
+{
+ "require": {
+ "phpspec/prophecy-phpunit": "^1.1.0 || ^2.0.1",
+ "phpunit/phpunit": "^9.5",
+ "phpunit/phpcov": ">=6.0.1"
+ }
+}