diff --git a/.dockerignore b/.dockerignore index 8ce5ee95a..b86d58efc 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,7 +7,6 @@ /.github /.gitignore /.php_cs.cache -/.travis.yml /composer.lock /tests/runtime/* /vendor diff --git a/.gitattributes b/.gitattributes index 8cdf150ae..257176809 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,15 +1,9 @@ # Ignore all test and documentation for archive -/.github export-ignore +.* export-ignore +*.dist export-ignore +*.xml export-ignore /docs export-ignore /tests export-ignore -/.dockerignore export-ignore -/.editorconfig export-ignore -/.env.example export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore -/.php_cs export-ignore /Makefile export-ignore -/phpunit.xml.dist export-ignore /support export-ignore -/psalm.xml export-ignore /stubs export-ignore diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9f2e1b2c8..a0c1a0f68 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,3 +1,4 @@ +--- name: build on: @@ -30,7 +31,7 @@ jobs: strategy: fail-fast: false matrix: - php: [ '8.2', '8.3' ] + php: [ '8.3', '8.4', '8.5' ] steps: - name: Checkout. uses: actions/checkout@v2 @@ -39,6 +40,7 @@ jobs: run: make test v=${{ matrix.php }} - name: Upload coverage to Codecov. - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v5 with: files: ./coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 5126dc889..9e5e160bb 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -1,3 +1,4 @@ +--- on: pull_request: paths-ignore: @@ -32,7 +33,7 @@ jobs: strategy: fail-fast: false matrix: - php: [ '8.2', '8.3', '8.4' ] + php: [ '8.3', '8.4', '8.5' ] steps: - name: Checkout. uses: actions/checkout@v2 diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 6e1c230a1..000000000 --- a/.php_cs +++ /dev/null @@ -1,124 +0,0 @@ -in(__DIR__ . '/src') -; - -return PhpCsFixer\Config::create() - ->setRiskyAllowed(true) - ->setRules([ - '@PSR2' => true, - 'array_syntax' => [ - 'syntax' => 'short', - ], - 'binary_operator_spaces' => [ - 'align_double_arrow' => false, - 'align_equals' => false, - ], - 'blank_line_after_opening_tag' => true, - 'cast_spaces' => true, - 'concat_space' => [ - 'spacing' => 'one', - ], - 'dir_constant' => true, - 'ereg_to_preg' => true, - 'function_typehint_space' => true, - 'hash_to_slash_comment' => true, - 'include' => true, - 'heredoc_to_nowdoc' => true, - 'is_null' => [ - 'use_yoda_style' => false, - ], - 'linebreak_after_opening_tag' => true, - 'lowercase_cast' => true, - 'magic_constant_casing' => true, - 'modernize_types_casting' => true, - 'native_function_casing' => true, - 'new_with_braces' => true, - 'no_alias_functions' => true, - 'no_blank_lines_after_class_opening' => true, - 'no_blank_lines_after_phpdoc' => true, - 'no_empty_comment' => true, - 'no_empty_phpdoc' => true, - 'no_empty_statement' => true, - 'no_extra_consecutive_blank_lines' => [ - 'tokens' => [ - 'break', - 'continue', - 'return', - 'throw', - 'use', - 'use_trait', - 'parenthesis_brace_block', - 'square_brace_block', - ], - ], - 'no_leading_import_slash' => true, - 'no_leading_namespace_whitespace' => true, - 'no_mixed_echo_print' => true, - 'no_multiline_whitespace_around_double_arrow' => true, - 'no_multiline_whitespace_before_semicolons' => true, - 'no_php4_constructor' => true, - 'no_short_bool_cast' => true, - 'no_singleline_whitespace_before_semicolons' => true, - 'no_spaces_around_offset' => true, - 'no_trailing_comma_in_list_call' => true, - 'no_trailing_comma_in_singleline_array' => true, - 'no_unneeded_control_parentheses' => true, - 'no_unused_imports' => true, - 'no_useless_else' => true, - 'no_useless_return' => true, - 'no_whitespace_before_comma_in_array' => true, - 'no_whitespace_in_blank_line' => true, - 'non_printable_character' => true, - 'normalize_index_brace' => true, - 'object_operator_without_whitespace' => true, - 'ordered_imports' => [ - 'sortAlgorithm' => 'alpha', - 'importsOrder' => [ - 'const', - 'function', - 'class', - ], - ], - 'php_unit_construct' => true, - 'php_unit_dedicate_assert' => true, - 'php_unit_fqcn_annotation' => true, - 'phpdoc_add_missing_param_annotation' => true, - 'phpdoc_indent' => true, - 'phpdoc_no_access' => true, - 'phpdoc_no_empty_return' => true, - 'phpdoc_no_package' => true, - 'phpdoc_no_useless_inheritdoc' => true, - 'phpdoc_return_self_reference' => true, - 'phpdoc_scalar' => true, - 'phpdoc_single_line_var_spacing' => true, - 'phpdoc_summary' => true, - 'phpdoc_trim' => true, - 'phpdoc_types' => true, - 'phpdoc_var_without_name' => false, - 'protected_to_private' => true, - 'psr4' => true, - 'self_accessor' => true, - 'short_scalar_cast' => true, - 'single_blank_line_before_namespace' => true, - 'single_quote' => true, - 'standardize_not_equals' => true, - 'ternary_operator_spaces' => true, - 'trailing_comma_in_multiline_array' => true, - 'trim_array_spaces' => true, - 'unary_operator_spaces' => true, - 'whitespace_after_comma_in_array' => true, - 'header_comment' => [ - 'header' => $header, - 'commentType' => 'PHPDoc', - 'separate' => 'bottom', - ], - ]) - ->setFinder($finder) -; diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e7f2e2cd..aacfa9296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,22 +3,26 @@ Yii2 Queue Extension Change Log 3.0.0 under development --- -- The minimum supported PHP version is 8.2 -- Added PSALM for static code analysis. Error level set to 1 -- Added strict typing -- The `pda/pheanstalk` package of the Beanstalk driver has been updated to version 5.* -- Removed deprecated interfaces `RetryableJob`, `Job`, `Serializer` -- Removed deprecated classes `Signal`, `Verbose` -- Deprecated driver amqp has been removed -- Returned tests for the SQS driver -- All dependent packages for supported drivers have been updated to the latest versions -- The `opis/closure` package did not support PHP 8.1 and was replaced by the `laravel/serializable-closure` package - -2.3.8 under development ------------------------ -- Enh #516: Ensure Redis driver messages are consumed at least once (soul11201) +- The minimum supported PHP version is 8.3 (@s1lver) +- Added PSALM for static code analysis. Error level set to 1 (@s1lver) +- Added strict typing (@s1lver) +- The `pda/pheanstalk` package of the Beanstalk driver has been updated to version 8.* (@s1lver) +- Removed deprecated interfaces `RetryableJob`, `Job`, `Serializer` (@s1lver) +- Removed deprecated classes `Signal`, `Verbose` (@s1lver) +- Deprecated driver amqp has been removed (@s1lver) +- Returned tests for the SQS driver (@s1lver) +- All dependent packages for supported drivers have been updated to the latest versions (@s1lver) +- The `opis/closure` package did not support PHP 8.1 and was replaced by the `laravel/serializable-closure` package (@s1lver) + +2.3.8 January 08, 2026 +---------------------- + - Bug #522: Fix SQS driver type error with custom value passed to `queue/listen` (flaviovs) - Bug #528: Prevent multiple execution of aborted jobs (luke-) +- Bug #538: Fix type hint for previous parameter in `InvalidJobException` class constructor in PHP `8.4` (implicitly marking parameter nullable) (terabytesoftw) +- Enh #493: Pass environment variables to sub-processes (mgrechanik) +- Enh #516: Ensure Redis driver messages are consumed at least once (soul11201) + 2.3.7 April 29, 2024 -------------------- diff --git a/Makefile b/Makefile index c01e40b11..1cd5ce583 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,18 @@ help: ## Display help information @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' -build: ## Build an image from a docker-compose file. Params: {{ v=8.2 }}. Default latest PHP 8.2 - @cp -n .env.example .env +build: ## Build an image from a docker-compose file. Params: {{ v=8.3 }}. Default latest PHP 8.3 + @if [ ! -f .env ]; then \ + cp .env.example .env; \ + echo "Created .env file from .env.example"; \ + else \ + echo ".env file already exists, skipping creation"; \ + fi PHP_VERSION=$(filter-out $@,$(v)) docker compose up -d --build make create-sqs-queue make create-sqs-fifo-queue -test: ## Run tests. Params: {{ v=8.2 }}. Default latest PHP 8.2 +test: ## Run tests. Params: {{ v=8.3 }}. Default latest PHP 8.3 make build PHP_VERSION=$(filter-out $@,$(v)) docker compose run yii2-queue-php vendor/bin/phpunit --coverage-clover coverage.xml make down @@ -15,7 +20,7 @@ test: ## Run tests. Params: {{ v=8.2 }}. Default latest PHP 8.2 down: ## Stop and remove containers, networks docker compose down -benchmark: ## Run benchmark. Params: {{ v=8.2 }}. Default latest PHP 8.2 +benchmark: ## Run benchmark. Params: {{ v=8.3 }}. Default latest PHP 8.3 PHP_VERSION=$(filter-out $@,$(v)) docker compose build --pull yii2-queue-php PHP_VERSION=$(filter-out $@,$(v)) docker compose run yii2-queue-php tests/yii benchmark/waiting make down @@ -23,7 +28,7 @@ benchmark: ## Run benchmark. Params: {{ v=8.2 }}. Default latest PHP 8.2 sh: ## Enter the container with the application docker exec -it yii2-queue-php sh -static-analyze: ## Run code static analyze. Params: {{ v=8.2 }}. Default latest PHP 8.2 +static-analyze: ## Run code static analyze. Params: {{ v=8.3 }}. Default latest PHP 8.3 PHP_VERSION=$(filter-out $@,$(v)) docker compose build --pull yii2-queue-php PHP_VERSION=$(filter-out $@,$(v)) docker compose run yii2-queue-php vendor/bin/psalm --config=psalm.xml --shepherd --stats --php-version=$(v) make down diff --git a/README.md b/README.md index e336b02c2..7fc02a8fd 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,15 @@ Documentation is at [docs/guide/README.md](docs/guide/README.md). [![Latest Stable Version](https://poser.pugx.org/yiisoft/yii2-queue/v/stable.svg)](https://packagist.org/packages/yiisoft/yii2-queue) [![Total Downloads](https://poser.pugx.org/yiisoft/yii2-queue/downloads.svg)](https://packagist.org/packages/yiisoft/yii2-queue) [![Build Status](https://github.com/yiisoft/yii2-queue/workflows/build/badge.svg)](https://github.com/yiisoft/yii2-queue/actions) - -## Requirements - -- PHP 8.2 or higher. +[![Static status](https://github.com/yiisoft/yii2-queue/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/yii2-queue/actions?query=workflow%3A%22static+analysis%22) +[![codecov](https://codecov.io/gh/yiisoft/yii2-queue/graph/badge.svg)](https://codecov.io/gh/yiisoft/yii2-queue) Installation ------------ +> [!IMPORTANT] +> - The minimum required [PHP](https://www.php.net/) version is PHP `8.3`. + The preferred way to install this extension is through [composer](https://getcomposer.org/download/): ``` diff --git a/composer.json b/composer.json index be729e785..602789f7c 100644 --- a/composer.json +++ b/composer.json @@ -16,14 +16,14 @@ "docs": "https://github.com/yiisoft/yii2-queue/blob/master/docs/guide" }, "require": { - "php": ">=8.2", - "yiisoft/yii2": "~2.0.50", + "php": ">=8.3", + "yiisoft/yii2": "~2.0.54", "symfony/process": "^7.0", - "laravel/serializable-closure": "^v1.3.0" + "laravel/serializable-closure": "^v2.0.0" }, "require-dev": { "phpunit/phpunit": "^10.3.0", - "yiisoft/yii2-redis": "~2.0.0", + "yiisoft/yii2-redis": "~2.1.0", "yiisoft/yii2-debug": "~2.1.0", "yiisoft/yii2-gii": "~2.2.0", "php-amqplib/php-amqplib": "^3.0.0", @@ -31,8 +31,8 @@ "enqueue/amqp-bunny": "^0.10.0", "enqueue/amqp-ext": "^0.10.8", "enqueue/stomp": "^0.10.0", - "pda/pheanstalk": "^5.0.0", - "aws/aws-sdk-php": "3.285.0", + "pda/pheanstalk": "^8.0.0", + "aws/aws-sdk-php": "^3.369.0", "vimeo/psalm": "^6.0.0" }, "suggest": { diff --git a/docs/guide-ja/driver-sqs.md b/docs/guide-ja/driver-sqs.md index 0e98206ec..70ef53407 100644 --- a/docs/guide-ja/driver-sqs.md +++ b/docs/guide-ja/driver-sqs.md @@ -19,6 +19,7 @@ return [ 'key' => '', 'secret' => '', 'region' => '', + 'endpoint' => '', // https://docs.aws.amazon.com/general/latest/gr/sqs-service.html#sqs_region ], ], ]; @@ -39,6 +40,7 @@ return [ 'secret' => '', 'region' => '', 'messageGroupId' => '', + 'endpoint' => '', // https://docs.aws.amazon.com/general/latest/gr/sqs-service.html#sqs_region ], ], ]; diff --git a/docs/guide-ru/driver-sqs.md b/docs/guide-ru/driver-sqs.md index f99aa818d..ddfeca112 100644 --- a/docs/guide-ru/driver-sqs.md +++ b/docs/guide-ru/driver-sqs.md @@ -19,6 +19,7 @@ return [ 'key' => '', 'secret' => '', 'region' => '', + 'endpoint' => '', // https://docs.aws.amazon.com/general/latest/gr/sqs-service.html#sqs_region ], ], ]; @@ -39,6 +40,7 @@ return [ 'secret' => '', 'region' => '', 'messageGroupId' => '', + 'endpoint' => '', // https://docs.aws.amazon.com/general/latest/gr/sqs-service.html#sqs_region ], ], ]; diff --git a/docs/guide-zh-CN/driver-sqs.md b/docs/guide-zh-CN/driver-sqs.md index 504050415..dd2dd5633 100644 --- a/docs/guide-zh-CN/driver-sqs.md +++ b/docs/guide-zh-CN/driver-sqs.md @@ -19,6 +19,7 @@ return [ 'key' => '', 'secret' => '', 'region' => '', + 'endpoint' => '', // https://docs.aws.amazon.com/general/latest/gr/sqs-service.html#sqs_region ], ], ]; @@ -39,6 +40,7 @@ return [ 'secret' => '', 'region' => '', 'messageGroupId' => '', + 'endpoint' => '', // https://docs.aws.amazon.com/general/latest/gr/sqs-service.html#sqs_region ], ], ]; diff --git a/docs/guide/driver-sqs.md b/docs/guide/driver-sqs.md index 504050415..dd2dd5633 100644 --- a/docs/guide/driver-sqs.md +++ b/docs/guide/driver-sqs.md @@ -19,6 +19,7 @@ return [ 'key' => '', 'secret' => '', 'region' => '', + 'endpoint' => '', // https://docs.aws.amazon.com/general/latest/gr/sqs-service.html#sqs_region ], ], ]; @@ -39,6 +40,7 @@ return [ 'secret' => '', 'region' => '', 'messageGroupId' => '', + 'endpoint' => '', // https://docs.aws.amazon.com/general/latest/gr/sqs-service.html#sqs_region ], ], ]; diff --git a/psalm-baseline.xml b/psalm-baseline.xml new file mode 100644 index 000000000..880903735 --- /dev/null +++ b/psalm-baseline.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + loopConfig]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/psalm.xml b/psalm.xml index ec0f9676e..454e3efe5 100644 --- a/psalm.xml +++ b/psalm.xml @@ -7,6 +7,7 @@ xmlns="https://getpsalm.org/schema/config" xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd" cacheDirectory="vendor/.psalm-cache" + errorBaseline="psalm-baseline.xml" > diff --git a/src/cli/Command.php b/src/cli/Command.php index af7cd5e75..ab27b0d2e 100644 --- a/src/cli/Command.php +++ b/src/cli/Command.php @@ -189,8 +189,8 @@ protected function handleMessage(int|string|null $id, string $message, ?int $ttr if (!in_array('color', $this->getPassedOptions(), true)) { $cmd[] = '--color=' . $this->isColorEnabled(); } - - $process = new Process($cmd, null, null, $message, $ttr); + $env = isset($_ENV) ? $_ENV : null; + $process = new Process($cmd, null, $env, $message, $ttr); try { $result = $process->run(function (string $type, string $buffer) { if ($type === Process::ERR) { diff --git a/src/cli/Queue.php b/src/cli/Queue.php index c041dfff1..2422d75a6 100644 --- a/src/cli/Queue.php +++ b/src/cli/Queue.php @@ -20,6 +20,8 @@ /** * Queue with CLI. * + * @property-read int|null $workerPid + * * @author Roman Zhuravlev */ abstract class Queue extends BaseQueue implements BootstrapInterface diff --git a/src/drivers/sqs/Queue.php b/src/drivers/sqs/Queue.php index 47dbe4b81..c2e6c0aa7 100644 --- a/src/drivers/sqs/Queue.php +++ b/src/drivers/sqs/Queue.php @@ -30,6 +30,11 @@ class Queue extends CliQueue * @var string */ public string $url = 'localhost'; + /** + * Custom endpoint for SQS + * @var string|null + */ + public ?string $endpoint = null; /** * aws access key. * @var string|null @@ -233,11 +238,18 @@ protected function getClient(): SqsClient $credentials = CredentialProvider::defaultProvider(); } - $this->client = new SqsClient([ + $config = [ 'credentials' => $credentials, 'region' => $this->region, 'version' => $this->version, - ]); + ]; + + if (null !== $this->endpoint) { + $config['endpoint'] = $this->endpoint; + $config['use_path_style_endpoint'] = true; + } + + $this->client = new SqsClient($config); return $this->client; } } diff --git a/src/serializers/IgbinarySerializer.php b/src/serializers/IgbinarySerializer.php index 98cb58bc3..ba78b8485 100644 --- a/src/serializers/IgbinarySerializer.php +++ b/src/serializers/IgbinarySerializer.php @@ -27,7 +27,9 @@ class IgbinarySerializer extends BaseObject implements SerializerInterface */ public function serialize($job): string { - return igbinary_serialize($job); + /** @var string|null|false $serialize */ + $serialize = igbinary_serialize($job); + return is_string($serialize) ? $serialize : ''; } /** diff --git a/tests/app/config/main.php b/tests/app/config/main.php index 66f104ed0..c3198fb25 100644 --- a/tests/app/config/main.php +++ b/tests/app/config/main.php @@ -17,6 +17,16 @@ use yii\queue\sync\Queue as SyncQueue; use yii\redis\Connection as RedisConnection; +if (version_compare(PHP_VERSION, '8.5.0') >= 0) { + $mysqlAttributes = [ + Pdo\Mysql::ATTR_INIT_COMMAND => 'SET sql_mode = "STRICT_ALL_TABLES"', + ]; +} else { + $mysqlAttributes = [ + PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode = "STRICT_ALL_TABLES"', + ]; +} + $config = [ 'id' => 'yii2-queue-app', 'basePath' => dirname(__DIR__), @@ -51,9 +61,7 @@ 'username' => getenv('MYSQL_USER') ?: 'root', 'password' => getenv('MYSQL_PASSWORD') ?: '', 'charset' => 'utf8', - 'attributes' => [ - PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode = "STRICT_ALL_TABLES"', - ], + 'attributes' => $mysqlAttributes, ], 'mysqlQueue' => [ 'class' => DbQueue::class, @@ -130,6 +138,7 @@ 'key' => getenv('AWS_KEY'), 'secret' => getenv('AWS_SECRET'), 'region' => getenv('AWS_REGION'), + 'endpoint' => getenv('AWS_SQS_ENDPOINT'), ], 'sqsFifoQueue' => [ 'class' => SqsQueue::class, @@ -138,6 +147,7 @@ 'secret' => getenv('AWS_SECRET'), 'region' => getenv('AWS_REGION'), 'messageGroupId' => getenv('AWS_SQS_FIFO_MESSAGE_GROUP_ID'), + 'endpoint' => getenv('AWS_SQS_ENDPOINT'), ], ], ]; diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index 0efa42219..ec7f284da 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -7,7 +7,7 @@ services: context: .. dockerfile: tests/docker/php/Dockerfile args: - PHP_VERSION: ${PHP_VERSION:-8.2} + PHP_VERSION: ${PHP_VERSION:-8.3} volumes: - ./runtime/.composer:/root/.composer - ..:/code @@ -42,6 +42,7 @@ services: AWS_KEY: ${AWS_KEY:-admin} AWS_SECRET: ${AWS_SECRET:-admin} AWS_REGION: ${AWS_REGION:-us-east-1} + AWS_SQS_ENDPOINT: ${AWS_SQS_ENDPOINT:-http://localstack:4566} AWS_SQS_URL: ${AWS_SQS_URL:-http://localstack:4566/000000000000/yii2-queue} AWS_SQS_FIFO_URL: ${AWS_SQS_FIFO_URL:-http://localstack:4566/000000000000/yii2-queue.fifo} AWS_SQS_FIFO_MESSAGE_GROUP_ID: ${AWS_SQS_FIFO_MESSAGE_GROUP_ID:-default} @@ -61,7 +62,8 @@ services: # https://hub.docker.com/_/mysql/ mysql: - image: mysql:5.7 + image: mysql:5.7.44 + platform: linux/amd64 ports: - "3307:3306" environment: diff --git a/tests/docker/php/Dockerfile b/tests/docker/php/Dockerfile index c76d6726d..c9cee6526 100644 --- a/tests/docker/php/Dockerfile +++ b/tests/docker/php/Dockerfile @@ -10,11 +10,11 @@ RUN echo https://dl-cdn.alpinelinux.org/alpine/edge/main >> /etc/apk/repositorie RUN apk add git icu-dev libpq-dev gearman-dev libcrypto3 openssl-dev autoconf g++ make linux-headers rabbitmq-c-dev -RUN docker-php-ext-install pcntl bcmath pdo_mysql intl pdo_pgsql sockets opcache -RUN pecl install igbinary pcov amqp-1.11.0 xdebug +RUN docker-php-ext-install pcntl bcmath pdo_mysql intl pdo_pgsql sockets +RUN pecl install igbinary pcov amqp xdebug RUN docker-php-ext-enable igbinary pcov amqp xdebug -# Official gearman package not supported PHP 8.1 now +# Official gearman package not supported PHP 8.5 now RUN TMPDIR=$(mktemp -d) \ && cd $TMPDIR \ && git clone https://github.com/php/pecl-networking-gearman gearman \