diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 36c3d5d90..52e438f8b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,9 +9,9 @@ jobs: name: Static analysis runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: technote-space/get-diff-action@v4 + - uses: technote-space/get-diff-action@v6 with: PATTERNS: | pkg/**/*.php @@ -25,7 +25,7 @@ jobs: - run: php ./bin/fix-symfony-version.php "5.4.*" - - uses: "ramsey/composer-install@v1" + - uses: "ramsey/composer-install@v3" - run: sed -i 's/525568/16777471/' vendor/kwn/php-rdkafka-stubs/stubs/constants.php @@ -37,9 +37,9 @@ jobs: name: Code style check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: technote-space/get-diff-action@v4 + - uses: technote-space/get-diff-action@v6 with: PATTERNS: | pkg/**/*.php @@ -49,7 +49,7 @@ jobs: run: | echo "::set-output name=dir::$(composer config cache-files-dir)" - - uses: actions/cache@v2 + - uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: composer-cs-check-${{ hashFiles('**/composer.json') }} @@ -87,14 +87,14 @@ jobs: name: PHP ${{ matrix.php }} unit tests on Sf ${{ matrix.symfony_version }}, deps=${{ matrix.dependencies }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Get Composer Cache Directory id: composer-cache run: | echo "::set-output name=dir::$(composer config cache-files-dir)" - - uses: actions/cache@v2 + - uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: composer-${{ matrix.php }}-${{ matrix.symfony_version }}-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }} @@ -131,14 +131,14 @@ jobs: name: PHP ${{ matrix.php }} functional tests on Sf ${{ matrix.symfony_version }}, deps=${{ matrix.dependencies }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Get Composer Cache Directory id: composer-cache run: | echo "::set-output name=dir::$(composer config cache-files-dir)" - - uses: actions/cache@v2 + - uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: composer-${{ matrix.php }}-${{ matrix.symfony_version }}-${{ matrix.dependencies }}-${{ hashFiles('**/composer.json') }} @@ -162,10 +162,4 @@ jobs: env: PHP_VERSION: ${{ matrix.php }} - # TODO: convert these two steps into one w/o excludes when Gearman extension gets a release for PHP 8.1 - # See https://github.com/php/pecl-networking-gearman/issues/16 - - run: bin/test.sh - if: ${{ matrix.php != '8.1' && matrix.php != '8.2' }} - - - run: bin/test.sh --exclude-group=gearman - if: ${{ matrix.php == '8.1' && matrix.php != '8.2' }} + - run: bin/test.sh --group=functional diff --git a/composer.json b/composer.json index d2258474d..7f6bc2bd5 100644 --- a/composer.json +++ b/composer.json @@ -18,30 +18,30 @@ "queue-interop/amqp-interop": "^0.8.2", "queue-interop/queue-interop": "^0.8.1", - "bunny/bunny": "^0.4|^0.5", - "php-amqplib/php-amqplib": "^3.0", - "doctrine/dbal": "^2.12|^3.1", - "ramsey/uuid": "^3.5|^4", + "bunny/bunny": "^0.5.5", + "php-amqplib/php-amqplib": "^3.1", + "doctrine/dbal": "^3.2", + "ramsey/uuid": "^4.3", "psr/log": "^1.1 || ^2.0 || ^3.0", "psr/container": "^1.1 || ^2.0", "makasim/temp-file": "^0.2", - "google/cloud-pubsub": "^1.4.3", + "google/cloud-pubsub": "^1.46", "doctrine/orm": "^2.12", "doctrine/persistence": "^2.0|^3.0", - "mongodb/mongodb": "^1.2", + "mongodb/mongodb": "^1.17", "pda/pheanstalk": "^3.1", "aws/aws-sdk-php": "^3.290", - "stomp-php/stomp-php": "^4.5|^5", + "stomp-php/stomp-php": "^5.1", "php-http/guzzle7-adapter": "^0.1.1", "php-http/client-common": "^2.2.1", "andrewmy/rabbitmq-management-api": "^2.1.2", - "predis/predis": "^1.1", + "predis/predis": "^2.1", "thruway/client": "^0.5.5", - "thruway/pawl-transport": "^0.5.1", + "thruway/pawl-transport": "^0.5.2", "influxdb/influxdb-php": "^1.14", "datadog/php-datadogstatsd": "^1.3", "guzzlehttp/guzzle": "^7.0.1", - "guzzlehttp/psr7": "^1.0", + "guzzlehttp/psr7": "^1.9.1", "php-http/discovery": "^1.13", "voryx/thruway-common": "^1.0.1", "react/dns": "^1.4", @@ -50,7 +50,7 @@ }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^9.5.28", "phpstan/phpstan": "^1.0", "queue-interop/queue-spec": "^0.6.2", "symfony/browser-kit": "^6.2|^7.0", @@ -66,8 +66,8 @@ "symfony/validator": "^6.2|^7.0", "symfony/yaml": "^6.2|^7.0", "empi89/php-amqp-stubs": "*@dev", - "doctrine/doctrine-bundle": "^2.3.2", - "doctrine/mongodb-odm-bundle": "^3.5|^4.3|^5.0", + "doctrine/doctrine-bundle": "^2.5", + "doctrine/mongodb-odm-bundle": "^4.7|^5.0", "alcaeus/mongo-php-adapter": "^1.0", "kwn/php-rdkafka-stubs": "^2.0.3", "friendsofphp/php-cs-fixer": "^3.4", diff --git a/docker-compose.yml b/docker-compose.yml index 8851efc28..b724d7881 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,11 @@ -version: '2' - services: dev: # when image publishing gets sorted: -# image: enqueue/dev:${PHP_VERSION:-7.4} + # image: enqueue/dev:${PHP_VERSION:-8.2} build: context: docker args: - PHP_VERSION: "${PHP_VERSION:-8.1}" + PHP_VERSION: "${PHP_VERSION:-8.2}" depends_on: - rabbitmq - mysql diff --git a/docker/Dockerfile b/docker/Dockerfile index b2f30c62e..c54a29866 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,71 +1,34 @@ ARG PHP_VERSION=8.2 -FROM makasim/nginx-php-fpm:${PHP_VERSION}-all-exts +FROM php:${PHP_VERSION}-alpine ARG PHP_VERSION -## libs -RUN set -x && \ - apt-get update && \ - apt-get install -y --no-install-recommends --no-install-suggests \ - wget \ - curl \ - openssl \ - ca-certificates \ - nano \ - netcat \ - php${PHP_VERSION}-dev \ - php${PHP_VERSION}-redis \ - php${PHP_VERSION}-pgsql \ - git \ - python \ - php${PHP_VERSION}-amqp \ - php${PHP_VERSION}-xml \ - php${PHP_VERSION}-mysql \ - php${PHP_VERSION}-curl \ - php${PHP_VERSION}-mongodb \ - php${PHP_VERSION}-mbstring \ - make \ - g++ \ - unzip \ - && \ - update-alternatives --install /usr/bin/php php /usr/bin/php${PHP_VERSION} 100 - -## gearman -RUN set -x && \ - apt-get install -y --no-install-recommends --no-install-suggests \ - libgearman-dev \ - && \ - mkdir -p $HOME/gearman && \ - cd $HOME/gearman && \ - git clone https://github.com/php/pecl-networking-gearman.git . && \ - git checkout gearman-2.1.0 && \ - phpize && ./configure && make && make install && \ - if [ ! -f /etc/php/${PHP_VERSION}/cli/conf.d/20-gearman.ini ]; then \ - echo "extension=gearman.so" > /etc/php/${PHP_VERSION}/cli/conf.d/20-gearman.ini && \ - echo "extension=gearman.so" > /etc/php/${PHP_VERSION}/fpm/conf.d/20-gearman.ini \ - ; \ - fi; - -## librdkafka -RUN set -x && \ - mkdir -p $HOME/librdkafka && \ - cd $HOME/librdkafka && \ - git clone https://github.com/edenhill/librdkafka.git . && \ - git checkout v1.0.0 && \ - ./configure && make && make install - -## php-rdkafka -RUN set -x && \ - mkdir -p $HOME/php-rdkafka && \ - cd $HOME/php-rdkafka && \ - git clone https://github.com/arnaud-lb/php-rdkafka.git . && \ - git checkout 5.0.1 && \ - phpize && ./configure && make all && make install && \ - echo "extension=rdkafka.so" > /etc/php/${PHP_VERSION}/cli/conf.d/10-rdkafka.ini && \ - echo "extension=rdkafka.so" > /etc/php/${PHP_VERSION}/fpm/conf.d/10-rdkafka.ini - -COPY ./php/cli.ini /etc/php/${PHP_VERSION}/cli/conf.d/1-dev_cli.ini +RUN --mount=type=cache,target=/var/cache/apk apk add --no-cache $PHPIZE_DEPS \ + libpq-dev \ + librdkafka-dev \ + rabbitmq-c-dev \ + linux-headers && \ + apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/testing \ + gearman-dev + +# Install First Party Modules +RUN docker-php-ext-install -j$(nproc) \ + pcntl \ + pdo_mysql \ + pdo_pgsql + +# Install Third Party Modules +RUN --mount=type=cache,target=/tmp/pear pecl install redis \ + mongodb-1.21.0 \ + gearman \ + rdkafka \ + xdebug && \ + pecl install --configureoptions 'with-librabbitmq-dir="autodetect"' amqp +RUN docker-php-ext-enable redis mongodb gearman rdkafka xdebug amqp + +COPY ./php/cli.ini /usr/local/etc/php/conf.d/1-dev_cli COPY ./bin/dev_entrypoiny.sh /usr/local/bin/entrypoint.sh +RUN mv /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini RUN chmod u+x /usr/local/bin/entrypoint.sh RUN mkdir -p /mqdev @@ -73,4 +36,4 @@ WORKDIR /mqdev COPY --from=composer:2 /usr/bin/composer /usr/bin/composer -CMD /usr/local/bin/entrypoint.sh +CMD ["/usr/local/bin/entrypoint.sh"] diff --git a/docker/bin/dev_entrypoiny.sh b/docker/bin/dev_entrypoiny.sh index a18b06b1e..c56e146fa 100644 --- a/docker/bin/dev_entrypoiny.sh +++ b/docker/bin/dev_entrypoiny.sh @@ -1,3 +1,3 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh while true; do sleep 1; done diff --git a/docker/bin/test.sh b/docker/bin/test.sh index b78e1c1a8..6bd094b75 100755 --- a/docker/bin/test.sh +++ b/docker/bin/test.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh # wait for service # $1 host diff --git a/pkg/dbal/DbalConsumerHelperTrait.php b/pkg/dbal/DbalConsumerHelperTrait.php index 4a3d32997..617f37ba0 100644 --- a/pkg/dbal/DbalConsumerHelperTrait.php +++ b/pkg/dbal/DbalConsumerHelperTrait.php @@ -53,7 +53,7 @@ protected function fetchMessage(array $queues, int $redeliveryDelay): ?DbalMessa while (microtime(true) < $endAt) { try { - $result = $select->execute()->fetch(); + $result = $select->execute()->fetchAssociative(); if (empty($result)) { return null; } @@ -69,7 +69,7 @@ protected function fetchMessage(array $queues, int $redeliveryDelay): ?DbalMessa ->setParameter('deliveryId', $deliveryId, DbalType::GUID) ->setMaxResults(1) ->execute() - ->fetch(); + ->fetchAssociative(); // the message has been removed by a 3rd party, such as truncate operation. if (false === $deliveredMessage) { diff --git a/pkg/enqueue/Client/DriverFactory.php b/pkg/enqueue/Client/DriverFactory.php index 1d383ac86..5c827e7e7 100644 --- a/pkg/enqueue/Client/DriverFactory.php +++ b/pkg/enqueue/Client/DriverFactory.php @@ -76,7 +76,7 @@ private function findDriverInfo(Dsn $dsn, array $factories): ?array private function createRabbitMqStompDriver(ConnectionFactory $factory, Dsn $dsn, Config $config, RouteCollection $collection): RabbitMqStompDriver { $defaultManagementHost = $dsn->getHost() ?: $config->getTransportOption('host', 'localhost'); - $managementVast = ltrim($dsn->getPath(), '/') ?: $config->getTransportOption('vhost', '/'); + $managementVast = ltrim($dsn->getPath() ?? '', '/') ?: $config->getTransportOption('vhost', '/'); $managementClient = StompManagementClient::create( urldecode($managementVast), diff --git a/pkg/enqueue/Symfony/Client/ConsumeCommand.php b/pkg/enqueue/Symfony/Client/ConsumeCommand.php index 5a0676705..94b56ad10 100644 --- a/pkg/enqueue/Symfony/Client/ConsumeCommand.php +++ b/pkg/enqueue/Symfony/Client/ConsumeCommand.php @@ -94,7 +94,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int try { $consumer = $this->getQueueConsumer($client); } catch (NotFoundExceptionInterface $e) { - throw new \LogicException(sprintf('Client "%s" is not supported.', $client), null, $e); + throw new \LogicException(sprintf('Client "%s" is not supported.', $client), previous: $e); } $driver = $this->getDriver($client); diff --git a/pkg/enqueue/Symfony/Client/ProduceCommand.php b/pkg/enqueue/Symfony/Client/ProduceCommand.php index bd23c16c3..953a76687 100644 --- a/pkg/enqueue/Symfony/Client/ProduceCommand.php +++ b/pkg/enqueue/Symfony/Client/ProduceCommand.php @@ -67,7 +67,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int try { $producer = $this->getProducer($client); } catch (NotFoundExceptionInterface $e) { - throw new \LogicException(sprintf('Client "%s" is not supported.', $client), null, $e); + throw new \LogicException(sprintf('Client "%s" is not supported.', $client), previous: $e); } if ($topic) { diff --git a/pkg/enqueue/Symfony/Client/RoutesCommand.php b/pkg/enqueue/Symfony/Client/RoutesCommand.php index 0646e37bb..04b657ef7 100644 --- a/pkg/enqueue/Symfony/Client/RoutesCommand.php +++ b/pkg/enqueue/Symfony/Client/RoutesCommand.php @@ -63,7 +63,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int try { $this->driver = $this->getDriver($input->getOption('client')); } catch (NotFoundExceptionInterface $e) { - throw new \LogicException(sprintf('Client "%s" is not supported.', $input->getOption('client')), null, $e); + throw new \LogicException(sprintf('Client "%s" is not supported.', $input->getOption('client')), previous: $e); } $routes = $this->driver->getRouteCollection()->all(); diff --git a/pkg/enqueue/Symfony/Client/SetupBrokerCommand.php b/pkg/enqueue/Symfony/Client/SetupBrokerCommand.php index b74902aa6..92d5ad022 100644 --- a/pkg/enqueue/Symfony/Client/SetupBrokerCommand.php +++ b/pkg/enqueue/Symfony/Client/SetupBrokerCommand.php @@ -55,7 +55,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int try { $this->getDriver($client)->setupBroker(new ConsoleLogger($output)); } catch (NotFoundExceptionInterface $e) { - throw new \LogicException(sprintf('Client "%s" is not supported.', $client), null, $e); + throw new \LogicException(sprintf('Client "%s" is not supported.', $client), previous: $e); } $output->writeln('Broker set up'); diff --git a/pkg/enqueue/Symfony/Consumption/ConfigurableConsumeCommand.php b/pkg/enqueue/Symfony/Consumption/ConfigurableConsumeCommand.php index 230a0dc69..34cb66d57 100644 --- a/pkg/enqueue/Symfony/Consumption/ConfigurableConsumeCommand.php +++ b/pkg/enqueue/Symfony/Consumption/ConfigurableConsumeCommand.php @@ -79,7 +79,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int try { $consumer = $this->getQueueConsumer($transport); } catch (NotFoundExceptionInterface $e) { - throw new \LogicException(sprintf('Transport "%s" is not supported.', $transport), null, $e); + throw new \LogicException(sprintf('Transport "%s" is not supported.', $transport), previous: $e); } $this->setQueueConsumerOptions($consumer, $input); diff --git a/pkg/enqueue/Symfony/Consumption/ConsumeCommand.php b/pkg/enqueue/Symfony/Consumption/ConsumeCommand.php index 1c82f3cfb..b69ae7269 100644 --- a/pkg/enqueue/Symfony/Consumption/ConsumeCommand.php +++ b/pkg/enqueue/Symfony/Consumption/ConsumeCommand.php @@ -65,7 +65,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int // QueueConsumer must be pre configured outside of the command! $consumer = $this->getQueueConsumer($transport); } catch (NotFoundExceptionInterface $e) { - throw new \LogicException(sprintf('Transport "%s" is not supported.', $transport), null, $e); + throw new \LogicException(sprintf('Transport "%s" is not supported.', $transport), previous: $e); } $this->setQueueConsumerOptions($consumer, $input); diff --git a/pkg/rdkafka/Tests/RdKafkaConsumerTest.php b/pkg/rdkafka/Tests/RdKafkaConsumerTest.php index a0544da6c..e577dfcca 100644 --- a/pkg/rdkafka/Tests/RdKafkaConsumerTest.php +++ b/pkg/rdkafka/Tests/RdKafkaConsumerTest.php @@ -190,6 +190,7 @@ public function testShouldReceiveFromQueueAndReturnMessageIfMessageInQueue() $kafkaMessage = new Message(); $kafkaMessage->err = \RD_KAFKA_RESP_ERR_NO_ERROR; $kafkaMessage->payload = 'theSerializedMessage'; + $kafkaMessage->partition = 0; $kafkaConsumer = $this->createKafkaConsumerMock(); $kafkaConsumer diff --git a/pkg/redis/PhpRedis.php b/pkg/redis/PhpRedis.php index 1a229e3c9..9e820a283 100644 --- a/pkg/redis/PhpRedis.php +++ b/pkg/redis/PhpRedis.php @@ -111,8 +111,8 @@ public function connect(): void $this->config['port'], $this->config['timeout'], $this->config['persistent'] ? ($this->config['phpredis_persistent_id'] ?? null) : null, - $this->config['phpredis_retry_interval'] ?? null, - $this->config['read_write_timeout'] + (int) ($this->config['phpredis_retry_interval'] ?? 0), + (float) $this->config['read_write_timeout'] ?? 0 ); if (false == $result) {