diff --git a/.docker/php81.Dockerfile b/.docker/php81.Dockerfile deleted file mode 100644 index 899dcf0..0000000 --- a/.docker/php81.Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM php:8.1-cli - -RUN apt-get update && \ - apt-get install -y libpq-dev unzip && \ - docker-php-ext-install pdo_mysql pdo_pgsql - -RUN apt-get -y install gpg && \ - curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg && \ - curl https://packages.microsoft.com/config/debian/12/prod.list | tee /etc/apt/sources.list.d/mssql-release.list && \ - apt-get update && \ - ACCEPT_EULA=Y apt-get -y install msodbcsql18 unixodbc-dev && \ - pecl install sqlsrv pdo_sqlsrv && \ - docker-php-ext-enable sqlsrv pdo_sqlsrv - -COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer diff --git a/.docker/php82.Dockerfile b/.docker/php82.Dockerfile deleted file mode 100644 index 738d7b1..0000000 --- a/.docker/php82.Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM php:8.2-cli - -RUN apt-get update && \ - apt-get install -y libpq-dev unzip && \ - docker-php-ext-install pdo_mysql pdo_pgsql - -RUN apt-get -y install gpg && \ - curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg && \ - curl https://packages.microsoft.com/config/debian/12/prod.list | tee /etc/apt/sources.list.d/mssql-release.list && \ - apt-get update && \ - ACCEPT_EULA=Y apt-get -y install msodbcsql18 unixodbc-dev && \ - pecl install sqlsrv pdo_sqlsrv && \ - docker-php-ext-enable sqlsrv pdo_sqlsrv - -COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer diff --git a/.docker/php83.Dockerfile b/.docker/php83.Dockerfile deleted file mode 100644 index 374c468..0000000 --- a/.docker/php83.Dockerfile +++ /dev/null @@ -1,15 +0,0 @@ -FROM php:8.3-cli - -RUN apt-get update && \ - apt-get install -y libpq-dev unzip && \ - docker-php-ext-install pdo_mysql pdo_pgsql - -RUN apt-get -y install gpg && \ - curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg && \ - curl https://packages.microsoft.com/config/debian/12/prod.list | tee /etc/apt/sources.list.d/mssql-release.list && \ - apt-get update && \ - ACCEPT_EULA=Y apt-get -y install msodbcsql18 unixodbc-dev && \ - pecl install sqlsrv pdo_sqlsrv && \ - docker-php-ext-enable sqlsrv pdo_sqlsrv - -COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer diff --git a/.docker/xdebug.ci.ini b/.docker/xdebug.ci.ini new file mode 100644 index 0000000..56b3946 --- /dev/null +++ b/.docker/xdebug.ci.ini @@ -0,0 +1,4 @@ +zend_extension=xdebug + +[xdebug] +xdebug.mode=coverage diff --git a/.docker/xdebug.ini b/.docker/xdebug.ini new file mode 100644 index 0000000..d191809 --- /dev/null +++ b/.docker/xdebug.ini @@ -0,0 +1,5 @@ +zend_extension=xdebug + +[xdebug] +xdebug.mode=coverage,debug,develop +xdebug.client_host=host.docker.internal diff --git a/.gitattributes b/.gitattributes index 90c7705..169a96a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,9 +1,10 @@ -/.docker export-ignore -/.github export-ignore -/tests export-ignore -.gitattributes export-ignore -.gitignore export-ignore -.scrutinizer.yml export-ignore -docker-compose.yml export-ignore -phpstan.neon.dist export-ignore -phpunit.xml.dist export-ignore +/.docker export-ignore +/.github export-ignore +/tests export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.scrutinizer.yml export-ignore +docker-compose.ci.yml export-ignore +docker-compose.yml export-ignore +phpstan.neon.dist export-ignore +phpunit.xml.dist export-ignore diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 64a890e..9abf936 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -23,5 +23,6 @@ We accept contributions via Pull Requests on [GitHub](https://github.com/stauden ## Running Tests ``` -vendor/bin/phpunit +docker compose run --rm php8.3 composer install +docker compose run --rm php8.3 vendor/bin/phpunit ``` diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eaf2496..41369b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,82 +12,37 @@ jobs: database: [ mysql, mariadb, pgsql, sqlite, sqlsrv ] release: [ stable, lowest ] include: - - database: mysql - pdo: mysql - - database: mariadb - pdo: mysql - - database: pgsql - pdo: pgsql - - database: sqlite - pdo: sqlite - - database: sqlsrv - pdo: sqlsrv - php: 8.3 release: stable - coverage: xdebug - - services: - mysql: - image: mysql:latest - env: - MYSQL_ROOT_PASSWORD: password - MYSQL_DATABASE: test - ports: - - 3306 - mariadb: - image: mariadb:latest - env: - MYSQL_ROOT_PASSWORD: password - MYSQL_DATABASE: test - ports: - - 3306 - pgsql: - image: postgres:latest - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: password - POSTGRES_DB: test - ports: - - 5432/tcp - sqlsrv: - image: mcr.microsoft.com/mssql/server:2019-latest - env: - ACCEPT_EULA: Y - SA_PASSWORD: Password! - options: >- - --name sqlsrv - --health-cmd "echo quit | /opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -l 1 -U sa -P Password!" - ports: - - 1433 + coverage: true steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 2 - - uses: actions/cache@v3 + - name: Check out code + uses: actions/checkout@v4 + - name: Cache Composer dependencies + uses: actions/cache@v4 with: path: ~/.cache/composer/files - key: php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }} - - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - tools: pecl - extensions: bcmath, ctype, json, mbstring, openssl, pdo, pdo_${{ matrix.pdo }}, tokenizer, xml - coverage: ${{ matrix.coverage }} - - run: docker exec sqlsrv /opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U sa -P Password! -Q "create database [test]" + key: php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} + - name: Start database container + run: docker compose -f docker-compose.yml -f docker-compose.ci.yml up --wait ${{ matrix.database }} + if: matrix.database != 'sqlite' + - name: Create SQL Server database + run: docker compose exec sqlsrv /opt/mssql-tools/bin/sqlcmd -S 127.0.0.1 -U sa -P Password! -Q 'create database [test]' if: matrix.database == 'sqlsrv' - - run: composer update --no-interaction --no-progress --prefer-dist --prefer-${{ matrix.release }} - - run: cp tests/config/database.ci.php tests/config/database.php - - run: | - PHPUNIT_FLAGS=$([ "${{ matrix.coverage }}" == "xdebug" ] && echo "--coverage-clover=coverage.xml" || echo "") - vendor/bin/phpunit $PHPUNIT_FLAGS + - name: Install dependencies + run: | + docker compose -f docker-compose.yml -f docker-compose.ci.yml run --rm php${{ matrix.php }} \ + composer update --no-interaction --no-progress --prefer-dist --prefer-${{ matrix.release }} + - name: Run tests + run: | + docker compose -f docker-compose.yml -f docker-compose.ci.yml run -e DB_CONNECTION=${{ matrix.database }} \ + --rm php${{ matrix.php }}${{ env.XDEBUG }} vendor/bin/phpunit ${{ env.COVERAGE }} env: - DB_CONNECTION: ${{ matrix.database }} - MYSQL_PORT: ${{ job.services.mysql.ports[3306] }} - MARIADB_PORT: ${{ job.services.mariadb.ports[3306] }} - PGSQL_PORT: ${{ job.services.pgsql.ports[5432] }} - SQLSRV_PORT: ${{ job.services.sqlsrv.ports[1433] }} - - uses: codecov/codecov-action@v3 + COVERAGE: ${{ matrix.coverage && '--coverage-clover=coverage.xml' || '' }} + XDEBUG: ${{ matrix.coverage && '-xdebug' || '' }} + - name: Upload code coverage + uses: codecov/codecov-action@v3 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - if: matrix.coverage == 'xdebug' && env.CODECOV_TOKEN + if: matrix.coverage && env.CODECOV_TOKEN diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index de43a9f..56f2939 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -6,14 +6,24 @@ jobs: phpstan: runs-on: ubuntu-latest + strategy: + matrix: + php: [ 8.3 ] + release: [ stable ] + steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - name: Check out code + uses: actions/checkout@v4 + - name: Cache Composer dependencies + uses: actions/cache@v4 with: path: ~/.cache/composer/files - key: php-8.3-composer-${{ hashFiles('**/composer.json') }} - - uses: shivammathur/setup-php@v2 - with: - php-version: 8.3 - - run: composer update --no-interaction --no-progress --prefer-dist - - run: vendor/bin/phpstan analyse --error-format=github + key: php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }} + - name: Install dependencies + run: | + docker compose -f docker-compose.yml -f docker-compose.ci.yml run --rm php${{ matrix.php }} \ + composer update --no-interaction --no-progress --prefer-dist --prefer-${{ matrix.release }} + - name: Analyse code + run: | + docker compose -f docker-compose.yml -f docker-compose.ci.yml run --rm php${{ matrix.php }} \ + vendor/bin/phpstan analyse --error-format=github --memory-limit=-1 diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml new file mode 100644 index 0000000..2fdbe12 --- /dev/null +++ b/docker-compose.ci.yml @@ -0,0 +1,36 @@ +version: '3.8' + +services: + php8.1: + image: ghcr.io/staudenmeir/php:8.1 + working_dir: /var/www/html + networks: + - test + volumes: + - .:/var/www/html:delegated + - ~/.cache/composer/files:/root/.composer/cache/files + php8.2: + image: ghcr.io/staudenmeir/php:8.2 + working_dir: /var/www/html + networks: + - test + volumes: + - .:/var/www/html:delegated + - ~/.cache/composer/files:/root/.composer/cache/files + php8.3: + image: ghcr.io/staudenmeir/php:8.3 + working_dir: /var/www/html + networks: + - test + volumes: + - .:/var/www/html:delegated + - ~/.cache/composer/files:/root/.composer/cache/files + php8.3-xdebug: + image: ghcr.io/staudenmeir/php:8.3 + working_dir: /var/www/html + networks: + - test + volumes: + - .:/var/www/html:delegated + - .docker/xdebug.ci.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini + - ~/.cache/composer/files:/root/.composer/cache/files diff --git a/docker-compose.yml b/docker-compose.yml index dfff94c..e666c64 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,46 +1,44 @@ version: '3.8' services: - php81: - build: - context: . - dockerfile: .docker/php81.Dockerfile + php8.1: + image: ghcr.io/staudenmeir/php:8.1 working_dir: /var/www/html networks: - test volumes: - .:/var/www/html:delegated - php82: - build: - context: . - dockerfile: .docker/php82.Dockerfile + - .docker/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini + php8.2: + image: ghcr.io/staudenmeir/php:8.2 working_dir: /var/www/html networks: - test volumes: - .:/var/www/html:delegated - php83: - build: - context: . - dockerfile: .docker/php83.Dockerfile + - .docker/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini + php8.3: + image: ghcr.io/staudenmeir/php:8.3 working_dir: /var/www/html networks: - test volumes: - .:/var/www/html:delegated + - .docker/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini mysql: image: 'mysql:latest' - ports: - - '3306:3306' environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: test + healthcheck: + test: mysqladmin ping --silent + interval: 5s + timeout: 3s + retries: 10 networks: - test mariadb: image: 'mariadb:latest' - ports: - - '33060:3306' environment: MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: test @@ -48,8 +46,6 @@ services: - test pgsql: image: 'postgres:latest' - ports: - - '5432:5432' environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: password @@ -58,20 +54,17 @@ services: - test sqlsrv: image: 'mcr.microsoft.com/mssql/server:2019-latest' - ports: - - '1433:1433' environment: ACCEPT_EULA: Y SA_PASSWORD: Password! healthcheck: test: /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$${SA_PASSWORD}" -Q "SELECT 1" -b -o /dev/null - interval: 10s + interval: 5s timeout: 3s retries: 10 - start_period: 10s networks: - test networks: - test: - driver: bridge + test: + driver: bridge diff --git a/tests/config/database.ci.php b/tests/config/database.ci.php deleted file mode 100644 index 5b45761..0000000 --- a/tests/config/database.ci.php +++ /dev/null @@ -1,60 +0,0 @@ - [ - 'driver' => 'mysql', - 'host' => '127.0.0.1', - 'port' => getenv('MYSQL_PORT'), - 'database' => 'test', - 'username' => 'root', - 'password' => 'password', - 'unix_socket' => '', - 'charset' => 'utf8mb4', - 'collation' => 'utf8mb4_0900_ai_ci', - 'prefix' => '', - 'strict' => true, - 'engine' => null, - ], - 'mariadb' => [ - 'driver' => 'mysql', - 'host' => '127.0.0.1', - 'port' => getenv('MARIADB_PORT'), - 'database' => 'test', - 'username' => 'root', - 'password' => 'password', - 'unix_socket' => '', - 'charset' => 'utf8mb4', - 'collation' => 'utf8mb4_uca1400_ai_ci', - 'prefix' => '', - 'strict' => true, - 'engine' => null, - ], - 'pgsql' => [ - 'driver' => 'pgsql', - 'host' => '127.0.0.1', - 'port' => getenv('PGSQL_PORT'), - 'database' => 'test', - 'username' => 'postgres', - 'password' => 'password', - 'charset' => 'utf8', - 'prefix' => '', - 'search_path' => 'public', - 'sslmode' => 'prefer', - ], - 'sqlite' => [ - 'driver' => 'sqlite', - 'database' => ':memory:', - 'prefix' => '', - ], - 'sqlsrv' => [ - 'driver' => 'sqlsrv', - 'host' => '127.0.0.1', - 'port' => getenv('SQLSRV_PORT'), - 'database' => 'test', - 'username' => 'sa', - 'password' => 'Password!', - 'charset' => 'utf8', - 'prefix' => '', - 'prefix_indexes' => true, - ], -];