From c7ad6f67eb21ae2c50e14823c923911bed6957d0 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 8 Jun 2023 10:18:44 +0200 Subject: [PATCH 1/7] Require PHPStan 1.11 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 22501953..14ab0970 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "require": { "php": "^7.2 || ^8.0", "ext-simplexml": "*", - "phpstan/phpstan": "^1.9.18" + "phpstan/phpstan": "^1.11" }, "conflict": { "symfony/framework-bundle": "<3.0" From 30915c323c793b3440d5953de9b5ea5165d99a8e Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 8 Jun 2023 10:18:51 +0200 Subject: [PATCH 2/7] Modernize rules with RuleErrorBuilder --- .../ContainerInterfacePrivateServiceRule.php | 10 +++++----- .../ContainerInterfaceUnknownServiceRule.php | 9 ++++----- .../InvalidArgumentDefaultValueRule.php | 19 ++++++++++++------ .../Symfony/InvalidOptionDefaultValueRule.php | 20 +++++++++++++------ src/Rules/Symfony/UndefinedArgumentRule.php | 7 ++----- src/Rules/Symfony/UndefinedOptionRule.php | 7 ++----- 6 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php b/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php index 0a3a3d3e..5e10c2b8 100644 --- a/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php +++ b/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php @@ -6,7 +6,7 @@ use PhpParser\Node\Expr\MethodCall; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Symfony\ServiceMap; use PHPStan\TrinaryLogic; use PHPStan\Type\ObjectType; @@ -32,9 +32,6 @@ public function getNodeType(): string return MethodCall::class; } - /** - * @return (string|RuleError)[] errors - */ public function processNode(Node $node, Scope $scope): array { if (!$node->name instanceof Node\Identifier) { @@ -72,7 +69,10 @@ public function processNode(Node $node, Scope $scope): array if ($serviceId !== null) { $service = $this->serviceMap->getService($serviceId); if ($service !== null && !$service->isPublic()) { - return [sprintf('Service "%s" is private.', $serviceId)]; + return [ + RuleErrorBuilder::message(sprintf('Service "%s" is private.', $serviceId)) + ->build(), + ]; } } diff --git a/src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php b/src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php index 417f51f5..ccc1999e 100644 --- a/src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php +++ b/src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php @@ -7,7 +7,7 @@ use PhpParser\PrettyPrinter\Standard; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Symfony\ServiceMap; use PHPStan\Type\ObjectType; use PHPStan\Type\Symfony\Helper; @@ -36,9 +36,6 @@ public function getNodeType(): string return MethodCall::class; } - /** - * @return (string|RuleError)[] errors - */ public function processNode(Node $node, Scope $scope): array { if (!$node->name instanceof Node\Identifier) { @@ -73,7 +70,9 @@ public function processNode(Node $node, Scope $scope): array $service = $this->serviceMap->getService($serviceId); $serviceIdType = $scope->getType($node->getArgs()[0]->value); if ($service === null && !$scope->getType(Helper::createMarkerNode($node->var, $serviceIdType, $this->printer))->equals($serviceIdType)) { - return [sprintf('Service "%s" is not registered in the container.', $serviceId)]; + return [ + RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the container.', $serviceId))->build(), + ]; } } diff --git a/src/Rules/Symfony/InvalidArgumentDefaultValueRule.php b/src/Rules/Symfony/InvalidArgumentDefaultValueRule.php index e48f8718..a55881ce 100644 --- a/src/Rules/Symfony/InvalidArgumentDefaultValueRule.php +++ b/src/Rules/Symfony/InvalidArgumentDefaultValueRule.php @@ -6,7 +6,7 @@ use PhpParser\Node\Expr\MethodCall; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\ArrayType; use PHPStan\Type\Constant\ConstantIntegerType; use PHPStan\Type\IntegerType; @@ -30,9 +30,6 @@ public function getNodeType(): string return MethodCall::class; } - /** - * @return (string|RuleError)[] errors - */ public function processNode(Node $node, Scope $scope): array { if (!(new ObjectType('Symfony\Component\Console\Command\Command'))->isSuperTypeOf($scope->getType($node->var))->yes()) { @@ -62,12 +59,22 @@ public function processNode(Node $node, Scope $scope): array // not an array if (($mode & 4) !== 4 && !(new UnionType([new StringType(), new NullType()]))->isSuperTypeOf($defaultType)->yes()) { - return [sprintf('Parameter #4 $default of method Symfony\Component\Console\Command\Command::addArgument() expects string|null, %s given.', $defaultType->describe(VerbosityLevel::typeOnly()))]; + return [ + RuleErrorBuilder::message(sprintf( + 'Parameter #4 $default of method Symfony\Component\Console\Command\Command::addArgument() expects string|null, %s given.', + $defaultType->describe(VerbosityLevel::typeOnly()) + ))->build(), + ]; } // is array if (($mode & 4) === 4 && !(new UnionType([new ArrayType(new IntegerType(), new StringType()), new NullType()]))->isSuperTypeOf($defaultType)->yes()) { - return [sprintf('Parameter #4 $default of method Symfony\Component\Console\Command\Command::addArgument() expects array|null, %s given.', $defaultType->describe(VerbosityLevel::typeOnly()))]; + return [ + RuleErrorBuilder::message(sprintf( + 'Parameter #4 $default of method Symfony\Component\Console\Command\Command::addArgument() expects array|null, %s given.', + $defaultType->describe(VerbosityLevel::typeOnly()) + ))->build(), + ]; } return []; diff --git a/src/Rules/Symfony/InvalidOptionDefaultValueRule.php b/src/Rules/Symfony/InvalidOptionDefaultValueRule.php index 171f94f1..6964d25e 100644 --- a/src/Rules/Symfony/InvalidOptionDefaultValueRule.php +++ b/src/Rules/Symfony/InvalidOptionDefaultValueRule.php @@ -6,7 +6,7 @@ use PhpParser\Node\Expr\MethodCall; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Type\ArrayType; use PHPStan\Type\BooleanType; use PHPStan\Type\Constant\ConstantIntegerType; @@ -32,9 +32,6 @@ public function getNodeType(): string return MethodCall::class; } - /** - * @return (string|RuleError)[] errors - */ public function processNode(Node $node, Scope $scope): array { if (!(new ObjectType('Symfony\Component\Console\Command\Command'))->isSuperTypeOf($scope->getType($node->var))->yes()) { @@ -66,13 +63,24 @@ public function processNode(Node $node, Scope $scope): array if (($mode & 8) !== 8) { $checkType = new UnionType([new StringType(), new IntegerType(), new NullType(), new BooleanType()]); if (!$checkType->isSuperTypeOf($defaultType)->yes()) { - return [sprintf('Parameter #5 $default of method Symfony\Component\Console\Command\Command::addOption() expects %s, %s given.', $checkType->describe(VerbosityLevel::typeOnly()), $defaultType->describe(VerbosityLevel::typeOnly()))]; + return [ + RuleErrorBuilder::message(sprintf( + 'Parameter #5 $default of method Symfony\Component\Console\Command\Command::addOption() expects %s, %s given.', + $checkType->describe(VerbosityLevel::typeOnly()), + $defaultType->describe(VerbosityLevel::typeOnly()) + ))->build(), + ]; } } // is array if (($mode & 8) === 8 && !(new UnionType([new ArrayType(new MixedType(), new StringType()), new NullType()]))->isSuperTypeOf($defaultType)->yes()) { - return [sprintf('Parameter #5 $default of method Symfony\Component\Console\Command\Command::addOption() expects array|null, %s given.', $defaultType->describe(VerbosityLevel::typeOnly()))]; + return [ + RuleErrorBuilder::message(sprintf( + 'Parameter #5 $default of method Symfony\Component\Console\Command\Command::addOption() expects array|null, %s given.', + $defaultType->describe(VerbosityLevel::typeOnly()) + ))->build(), + ]; } return []; diff --git a/src/Rules/Symfony/UndefinedArgumentRule.php b/src/Rules/Symfony/UndefinedArgumentRule.php index 52f90241..07f35e2a 100644 --- a/src/Rules/Symfony/UndefinedArgumentRule.php +++ b/src/Rules/Symfony/UndefinedArgumentRule.php @@ -8,7 +8,7 @@ use PhpParser\PrettyPrinter\Standard; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Symfony\ConsoleApplicationResolver; use PHPStan\Type\ObjectType; use PHPStan\Type\Symfony\Helper; @@ -39,9 +39,6 @@ public function getNodeType(): string return MethodCall::class; } - /** - * @return (string|RuleError)[] errors - */ public function processNode(Node $node, Scope $scope): array { $classReflection = $scope->getClassReflection(); @@ -78,7 +75,7 @@ public function processNode(Node $node, Scope $scope): array if ($scope->getType(Helper::createMarkerNode($node->var, $argType, $this->printer))->equals($argType)) { continue; } - $errors[] = sprintf('Command "%s" does not define argument "%s".', $name, $argName); + $errors[] = RuleErrorBuilder::message(sprintf('Command "%s" does not define argument "%s".', $name, $argName))->build(); } } diff --git a/src/Rules/Symfony/UndefinedOptionRule.php b/src/Rules/Symfony/UndefinedOptionRule.php index 00dd750e..5a8dc8e3 100644 --- a/src/Rules/Symfony/UndefinedOptionRule.php +++ b/src/Rules/Symfony/UndefinedOptionRule.php @@ -8,7 +8,7 @@ use PhpParser\PrettyPrinter\Standard; use PHPStan\Analyser\Scope; use PHPStan\Rules\Rule; -use PHPStan\Rules\RuleError; +use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Symfony\ConsoleApplicationResolver; use PHPStan\Type\ObjectType; use PHPStan\Type\Symfony\Helper; @@ -39,9 +39,6 @@ public function getNodeType(): string return MethodCall::class; } - /** - * @return (string|RuleError)[] errors - */ public function processNode(Node $node, Scope $scope): array { $classReflection = $scope->getClassReflection(); @@ -78,7 +75,7 @@ public function processNode(Node $node, Scope $scope): array if ($scope->getType(Helper::createMarkerNode($node->var, $optType, $this->printer))->equals($optType)) { continue; } - $errors[] = sprintf('Command "%s" does not define option "%s".', $name, $optName); + $errors[] = RuleErrorBuilder::message(sprintf('Command "%s" does not define option "%s".', $name, $optName))->build(); } } From fdfd3f4f7b1f9a95f6d29d9715950d8140773785 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 8 Jun 2023 11:07:26 +0200 Subject: [PATCH 3/7] Error identifiers --- src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php | 1 + src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php | 4 +++- src/Rules/Symfony/InvalidArgumentDefaultValueRule.php | 4 ++-- src/Rules/Symfony/InvalidOptionDefaultValueRule.php | 4 ++-- src/Rules/Symfony/UndefinedArgumentRule.php | 4 +++- src/Rules/Symfony/UndefinedOptionRule.php | 4 +++- 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php b/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php index 5e10c2b8..996d3b77 100644 --- a/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php +++ b/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php @@ -71,6 +71,7 @@ public function processNode(Node $node, Scope $scope): array if ($service !== null && !$service->isPublic()) { return [ RuleErrorBuilder::message(sprintf('Service "%s" is private.', $serviceId)) + ->identifier('symfonyContainer.privateService') ->build(), ]; } diff --git a/src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php b/src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php index ccc1999e..fc7d9585 100644 --- a/src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php +++ b/src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php @@ -71,7 +71,9 @@ public function processNode(Node $node, Scope $scope): array $serviceIdType = $scope->getType($node->getArgs()[0]->value); if ($service === null && !$scope->getType(Helper::createMarkerNode($node->var, $serviceIdType, $this->printer))->equals($serviceIdType)) { return [ - RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the container.', $serviceId))->build(), + RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the container.', $serviceId)) + ->identifier('symfonyContainer.serviceNotFound') + ->build(), ]; } } diff --git a/src/Rules/Symfony/InvalidArgumentDefaultValueRule.php b/src/Rules/Symfony/InvalidArgumentDefaultValueRule.php index a55881ce..153d4af5 100644 --- a/src/Rules/Symfony/InvalidArgumentDefaultValueRule.php +++ b/src/Rules/Symfony/InvalidArgumentDefaultValueRule.php @@ -63,7 +63,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Parameter #4 $default of method Symfony\Component\Console\Command\Command::addArgument() expects string|null, %s given.', $defaultType->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('argument.type')->build(), ]; } @@ -73,7 +73,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Parameter #4 $default of method Symfony\Component\Console\Command\Command::addArgument() expects array|null, %s given.', $defaultType->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('argument.type')->build(), ]; } diff --git a/src/Rules/Symfony/InvalidOptionDefaultValueRule.php b/src/Rules/Symfony/InvalidOptionDefaultValueRule.php index 6964d25e..1595f4a8 100644 --- a/src/Rules/Symfony/InvalidOptionDefaultValueRule.php +++ b/src/Rules/Symfony/InvalidOptionDefaultValueRule.php @@ -68,7 +68,7 @@ public function processNode(Node $node, Scope $scope): array 'Parameter #5 $default of method Symfony\Component\Console\Command\Command::addOption() expects %s, %s given.', $checkType->describe(VerbosityLevel::typeOnly()), $defaultType->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('argument.type')->build(), ]; } } @@ -79,7 +79,7 @@ public function processNode(Node $node, Scope $scope): array RuleErrorBuilder::message(sprintf( 'Parameter #5 $default of method Symfony\Component\Console\Command\Command::addOption() expects array|null, %s given.', $defaultType->describe(VerbosityLevel::typeOnly()) - ))->build(), + ))->identifier('argument.type')->build(), ]; } diff --git a/src/Rules/Symfony/UndefinedArgumentRule.php b/src/Rules/Symfony/UndefinedArgumentRule.php index 07f35e2a..cd8be894 100644 --- a/src/Rules/Symfony/UndefinedArgumentRule.php +++ b/src/Rules/Symfony/UndefinedArgumentRule.php @@ -75,7 +75,9 @@ public function processNode(Node $node, Scope $scope): array if ($scope->getType(Helper::createMarkerNode($node->var, $argType, $this->printer))->equals($argType)) { continue; } - $errors[] = RuleErrorBuilder::message(sprintf('Command "%s" does not define argument "%s".', $name, $argName))->build(); + $errors[] = RuleErrorBuilder::message(sprintf('Command "%s" does not define argument "%s".', $name, $argName)) + ->identifier('symfonyConsole.argumentNotFound') + ->build(); } } diff --git a/src/Rules/Symfony/UndefinedOptionRule.php b/src/Rules/Symfony/UndefinedOptionRule.php index 5a8dc8e3..095bd44d 100644 --- a/src/Rules/Symfony/UndefinedOptionRule.php +++ b/src/Rules/Symfony/UndefinedOptionRule.php @@ -75,7 +75,9 @@ public function processNode(Node $node, Scope $scope): array if ($scope->getType(Helper::createMarkerNode($node->var, $optType, $this->printer))->equals($optType)) { continue; } - $errors[] = RuleErrorBuilder::message(sprintf('Command "%s" does not define option "%s".', $name, $optName))->build(); + $errors[] = RuleErrorBuilder::message(sprintf('Command "%s" does not define option "%s".', $name, $optName)) + ->identifier('symfonyConsole.optionNotFound') + ->build(); } } From 34c64a368411bbffae2b291c90819cdeeb5f39a5 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Thu, 8 Jun 2023 11:12:16 +0200 Subject: [PATCH 4/7] Bump PHPStan dependencies --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 14ab0970..fc3e9368 100644 --- a/composer.json +++ b/composer.json @@ -23,8 +23,8 @@ "require-dev": { "nikic/php-parser": "^4.13.0", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-strict-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.3.11", + "phpstan/phpstan-strict-rules": "^1.5.1", "phpunit/phpunit": "^8.5.29 || ^9.5", "psr/container": "1.0 || 1.1.1", "symfony/config": "^5.4 || ^6.1", From 4f984e5ad88ba61632ad73d8388f2fe80419fd45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Verlhac?= Date: Wed, 7 Jun 2023 12:47:04 +0200 Subject: [PATCH 5/7] feat: Sync Validor stubs with SF6.1 --- .../Component/Validator/ConstraintViolationInterface.stub | 3 +++ .../Validator/ConstraintViolationListInterface.stub | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/stubs/Symfony/Component/Validator/ConstraintViolationInterface.stub b/stubs/Symfony/Component/Validator/ConstraintViolationInterface.stub index ef3312bb..e7f2b8a2 100644 --- a/stubs/Symfony/Component/Validator/ConstraintViolationInterface.stub +++ b/stubs/Symfony/Component/Validator/ConstraintViolationInterface.stub @@ -2,6 +2,9 @@ namespace Symfony\Component\Validator; +/** + * @method string __toString() Converts the violation into a string for debugging purposes. Not implementing it is deprecated since Symfony 6.1. + */ interface ConstraintViolationInterface { } diff --git a/stubs/Symfony/Component/Validator/ConstraintViolationListInterface.stub b/stubs/Symfony/Component/Validator/ConstraintViolationListInterface.stub index 423bdfb0..00a2a9d5 100644 --- a/stubs/Symfony/Component/Validator/ConstraintViolationListInterface.stub +++ b/stubs/Symfony/Component/Validator/ConstraintViolationListInterface.stub @@ -3,8 +3,11 @@ namespace Symfony\Component\Validator; /** + * @extends \ArrayAccess * @extends \Traversable + * + * @method string __toString() Converts the violation into a string for debugging purposes. Not implementing it is deprecated since Symfony 6.1. */ -interface ConstraintViolationListInterface extends \Traversable +interface ConstraintViolationListInterface extends \Traversable, \Countable, \ArrayAccess { } From 771669a8ae0319a8842e0569bef1836c600de1b6 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Mon, 28 Aug 2023 17:31:11 +0200 Subject: [PATCH 6/7] Add a more precise return type for ParameterBag::keys in stubs --- stubs/Symfony/Component/HttpFoundation/ParameterBag.stub | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/stubs/Symfony/Component/HttpFoundation/ParameterBag.stub b/stubs/Symfony/Component/HttpFoundation/ParameterBag.stub index 00a40741..0a6858e3 100644 --- a/stubs/Symfony/Component/HttpFoundation/ParameterBag.stub +++ b/stubs/Symfony/Component/HttpFoundation/ParameterBag.stub @@ -7,5 +7,10 @@ namespace Symfony\Component\HttpFoundation; */ class ParameterBag implements \IteratorAggregate { - + /** + * @return list + */ + public function keys(): array + { + } } From 931c6b5bb46a17a35f8c799fd2515b08afa73154 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 00:15:15 +0000 Subject: [PATCH 7/7] chore(deps): update actions/checkout action to v4 --- .github/workflows/build.yml | 10 +++++----- .github/workflows/create-tag.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ba129bc9..06457c85 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Install PHP" uses: "shivammathur/setup-php@v2" @@ -49,10 +49,10 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Checkout build-cs" - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: repository: "phpstan/build-cs" path: "build-cs" @@ -99,7 +99,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Install PHP" uses: "shivammathur/setup-php@v2" @@ -138,7 +138,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: "Install PHP" uses: "shivammathur/setup-php@v2" diff --git a/.github/workflows/create-tag.yml b/.github/workflows/create-tag.yml index 8452d986..a8535014 100644 --- a/.github/workflows/create-tag.yml +++ b/.github/workflows/create-tag.yml @@ -21,7 +21,7 @@ jobs: runs-on: "ubuntu-latest" steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.PHPSTAN_BOT_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 92b72547..e4a8ac62 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: steps: - name: "Checkout" - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Generate changelog id: changelog