Skip to content

Commit 822c609

Browse files
committed
ci(openapi): vacuum instead of swagger-cli
1 parent c08758c commit 822c609

23 files changed

+89
-89
lines changed

.github/workflows/ci.yml

+41-34
Original file line numberDiff line numberDiff line change
@@ -470,26 +470,6 @@ jobs:
470470
export PATH="$PATH:$HOME/.composer/vendor/bin"
471471
php-coveralls --coverage_clover=build/logs/behat/clover.xml
472472
continue-on-error: true
473-
- name: Export OpenAPI documents
474-
run: |
475-
mkdir -p build/out/openapi
476-
tests/Fixtures/app/console api:openapi:export -o build/out/openapi/openapi_v3.json
477-
tests/Fixtures/app/console api:openapi:export --yaml -o build/out/openapi/openapi_v3.yaml
478-
- name: Setup node
479-
uses: actions/setup-node@v4
480-
with:
481-
node-version: '14'
482-
- name: Validate OpenAPI documents
483-
run: |
484-
npx swagger-cli validate build/out/openapi/openapi_v3.json
485-
npx swagger-cli validate build/out/openapi/openapi_v3.yaml
486-
- name: Upload OpenAPI artifacts
487-
if: always()
488-
uses: actions/upload-artifact@v4
489-
with:
490-
name: openapi-docs-php${{ matrix.php }}
491-
path: build/out/openapi
492-
continue-on-error: true
493473

494474
postgresql:
495475
name: Behat (PHP ${{ matrix.php }}) (PostgreSQL)
@@ -1272,26 +1252,53 @@ jobs:
12721252
name: behat-logs-php${{ matrix.php }}
12731253
path: build/logs/behat
12741254
continue-on-error: true
1255+
1256+
openapi:
1257+
name: OpenAPI
1258+
runs-on: ubuntu-latest
1259+
timeout-minutes: 20
1260+
strategy:
1261+
matrix:
1262+
php:
1263+
- '8.4'
1264+
fail-fast: false
1265+
steps:
1266+
- name: Checkout
1267+
uses: actions/checkout@v4
1268+
- name: Setup PHP
1269+
uses: shivammathur/setup-php@v2
1270+
with:
1271+
php-version: ${{ matrix.php }}
1272+
tools: pecl, composer
1273+
extensions: intl, bcmath, curl, openssl, mbstring, pdo_sqlite, mongodb
1274+
ini-values: memory_limit=-1
1275+
- name: Setup node
1276+
uses: actions/setup-node@v4
1277+
with:
1278+
node-version: '22'
1279+
- name: Get composer cache directory
1280+
id: composercache
1281+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
1282+
- name: Cache dependencies
1283+
uses: actions/cache@v4
1284+
with:
1285+
path: ${{ steps.composercache.outputs.dir }}
1286+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
1287+
restore-keys: ${{ runner.os }}-composer-
1288+
- name: Update project dependencies
1289+
run: |
1290+
composer global require soyuka/pmu
1291+
composer global config allow-plugins.soyuka/pmu true --no-interaction
1292+
composer global link .
1293+
- name: Clear test app cache
1294+
run: tests/Fixtures/app/console cache:clear --ansi
12751295
- name: Export OpenAPI documents
12761296
run: |
12771297
mkdir -p build/out/openapi
1278-
tests/Fixtures/app/console api:openapi:export -o build/out/openapi/openapi_v3.json
12791298
tests/Fixtures/app/console api:openapi:export --yaml -o build/out/openapi/openapi_v3.yaml
1280-
- name: Setup node
1281-
uses: actions/setup-node@v4
1282-
with:
1283-
node-version: '14'
12841299
- name: Validate OpenAPI documents
12851300
run: |
1286-
npx swagger-cli validate build/out/openapi/openapi_v3.json
1287-
npx swagger-cli validate build/out/openapi/openapi_v3.yaml
1288-
- name: Upload OpenAPI artifacts
1289-
if: always()
1290-
uses: actions/upload-artifact@v4
1291-
with:
1292-
name: openapi-docs-php${{ matrix.php }}
1293-
path: build/out/openapi
1294-
continue-on-error: true
1301+
npx @quobix/vacuum lint -r tests/Fixtures/app/ruleset.yaml build/out/openapi/openapi_v3.yaml -d
12951302
12961303
laravel:
12971304
name: Laravel (PHP ${{ matrix.php }})

tests/Fixtures/TestBundle/ApiResource/Crud.php

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use ApiPlatform\OpenApi\Model\Operation;
2424

2525
#[ApiResource(
26+
description: 'A resource used for OpenAPI tests.',
2627
operations: [
2728
new Get(),
2829
new GetCollection(openapi: new Operation(extensionProperties: [OpenApiFactory::API_PLATFORM_TAG => ['internal', 'anotherone']])),

tests/Fixtures/TestBundle/ApiResource/EntityClassWithDateTime.php

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
),
2626
new GetCollection(
2727
uriTemplate: '/EntityClassWithDateTime',
28-
uriVariables: ['id']
2928
),
3029
],
3130
stateOptions: new Options(entityClass: \ApiPlatform\Tests\Fixtures\TestBundle\Entity\EntityClassWithDateTime::class)

tests/Fixtures/TestBundle/ApiResource/Headers.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
)]
2828
class Headers
2929
{
30-
public $id;
30+
public int $id;
3131

3232
public static function provide(): self
3333
{

tests/Fixtures/TestBundle/ApiResource/Issue6211/ArrayPropertyDtoOperation.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use ApiPlatform\Metadata\Get;
1717
use ApiPlatform\Tests\Fixtures\TestBundle\Dto\ArrayPropertyDto;
1818

19-
#[Get(provider: [ArrayPropertyDtoOperation::class, 'provide'], output: ArrayPropertyDto::class)]
19+
#[Get(provider: [ArrayPropertyDtoOperation::class, 'provide'], output: ArrayPropertyDto::class, openapi: false)]
2020
class ArrayPropertyDtoOperation
2121
{
2222
public static function provide(): ArrayPropertyDto

tests/Fixtures/TestBundle/ApiResource/Issue6299/Issue6299.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use ApiPlatform\Metadata\Get;
1818

1919
#[ApiResource]
20-
#[Get(output: Issue6299OutputDto::class)]
20+
#[Get(output: Issue6299OutputDto::class, openapi: false)]
2121
final class Issue6299
2222
{
2323
}

tests/Fixtures/TestBundle/ApiResource/Issue6355/OrderProductCount.php

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class: OrderDto::class,
3232
read: false,
3333
write: false,
3434
name: 'order_product_update_count',
35+
uriVariables: ['id']
3536
),
3637
],
3738
order: ['position' => 'ASC'],

tests/Fixtures/TestBundle/ApiResource/Issue6810/JsonLdContextOutput.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use ApiPlatform\Metadata\Get;
1717
use ApiPlatform\Metadata\Operation;
1818

19-
#[Get('/json_ld_context_output', provider: [self::class, 'getData'], output: Output::class, normalizationContext: ['hydra_prefix' => false])]
19+
#[Get('/json_ld_context_output', provider: [self::class, 'getData'], output: Output::class, normalizationContext: ['hydra_prefix' => false], openapi: false)]
2020
class JsonLdContextOutput
2121
{
2222
public function __construct(public string $id)

tests/Fixtures/TestBundle/Document/User.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
* @author Théo FIDRY <[email protected]>
3535
* @author Kévin Dunglas <[email protected]>
3636
*/
37-
#[ApiResource(operations: [new Get(), new Put(), new Delete(), new Put(input: RecoverPasswordInput::class, output: RecoverPasswordOutput::class, uriTemplate: 'users/recover/{id}'), new Post(), new GetCollection(), new Post(uriTemplate: '/users/password_reset_request', messenger: 'input', input: PasswordResetRequest::class, output: PasswordResetRequestResult::class, normalizationContext: ['groups' => ['user_password_reset_request']], denormalizationContext: ['groups' => ['user_password_reset_request']])], normalizationContext: ['groups' => ['user', 'user-read']], denormalizationContext: ['groups' => ['user', 'user-write']])]
37+
#[ApiResource(openapi: false, operations: [new Get(), new Put(), new Delete(), new Put(input: RecoverPasswordInput::class, output: RecoverPasswordOutput::class, uriTemplate: 'users/recover/{id}'), new Post(), new GetCollection(), new Post(uriTemplate: '/users/password_reset_request', messenger: 'input', input: PasswordResetRequest::class, output: PasswordResetRequestResult::class, normalizationContext: ['groups' => ['user_password_reset_request']], denormalizationContext: ['groups' => ['user_password_reset_request']])], normalizationContext: ['groups' => ['user', 'user-read']], denormalizationContext: ['groups' => ['user', 'user-write']])]
3838
#[ODM\Document(collection: 'user_test')]
3939
class User implements UserInterface, PasswordAuthenticatedUserInterface
4040
{

tests/Fixtures/TestBundle/Entity/AttributeOnlyOperation.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
namespace ApiPlatform\Tests\Fixtures\TestBundle\Entity;
1515

1616
use ApiPlatform\Metadata\Get;
17+
use ApiPlatform\OpenApi\Model\Operation;
1718

18-
#[Get(name: 'my own name')]
19+
#[Get(name: 'my own name', openapi: new Operation(operationId: 'my_own_name'))]
1920
final class AttributeOnlyOperation
2021
{
2122
}

tests/Fixtures/TestBundle/Entity/FilteredDateParameter.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,18 @@
3232
'date' => new QueryParameter(
3333
filter: new DateFilter(),
3434
property: 'createdAt',
35-
openApi: new Parameter('createdAt', 'query', allowEmptyValue: true)
35+
openApi: new Parameter('date', 'query', allowEmptyValue: true)
3636
),
3737
'date_include_null_always' => new QueryParameter(
3838
filter: new DateFilter(),
3939
property: 'createdAt',
4040
filterContext: DateFilterInterface::INCLUDE_NULL_BEFORE_AND_AFTER,
41-
openApi: new Parameter('createdAt', 'query', allowEmptyValue: true)
41+
openApi: new Parameter('date_include_null_always', 'query', allowEmptyValue: true)
4242
),
4343
'date_old_way' => new QueryParameter(
4444
filter: new DateFilter(properties: ['createdAt' => DateFilterInterface::INCLUDE_NULL_BEFORE_AND_AFTER]),
4545
property: 'createdAt',
46-
openApi: new Parameter('createdAt', 'query', allowEmptyValue: true)
46+
openApi: new Parameter('date_old_way', 'query', allowEmptyValue: true)
4747
),
4848
],
4949
)]

tests/Fixtures/TestBundle/Entity/FilteredRangeParameter.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626
parameters: [
2727
'quantity' => new QueryParameter(
2828
filter: new RangeFilter(),
29-
openApi: new Parameter('createdAt', 'query', allowEmptyValue: true)
29+
openApi: new Parameter('quantity', 'query', allowEmptyValue: true)
3030
),
3131
'amount' => new QueryParameter(
3232
filter: new RangeFilter(),
3333
property: 'quantity',
34-
openApi: new Parameter('createdAt', 'query', allowEmptyValue: true)
34+
openApi: new Parameter('amount', 'query', allowEmptyValue: true)
3535
),
3636
],
3737
)]

tests/Fixtures/TestBundle/Entity/IdentifierShortcut.php

-22
This file was deleted.

tests/Fixtures/TestBundle/Entity/Issue5625/Currency.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
* Currency.
2222
*/
2323
#[ApiResource(operations: [
24-
new Get(uriTemplate: '/get_security_1', openapi: new Operation(security: [['JWT' => ['CURRENCY_READ']]])),
24+
new Get(uriTemplate: '/get_security_1', openapi: new Operation(security: [['oauth' => ['CURRENCY_READ']]])),
2525
])]
2626
class Currency
2727
{

tests/Fixtures/TestBundle/Entity/Issue5662/Book.php

+2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313

1414
namespace ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue5662;
1515

16+
use ApiPlatform\Metadata\ApiResource;
1617
use ApiPlatform\Metadata\Get;
1718
use ApiPlatform\Metadata\GetCollection;
1819
use ApiPlatform\Metadata\Operation;
1920

21+
#[ApiResource(openapi: false)]
2022
#[GetCollection(
2123
uriTemplate: '/issue5662/books{._format}',
2224
itemUriTemplate: '/issue5662/books/{id}{._format}',

tests/Fixtures/TestBundle/Entity/Issue5662/Review.php

+2
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@
1313

1414
namespace ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue5662;
1515

16+
use ApiPlatform\Metadata\ApiResource;
1617
use ApiPlatform\Metadata\Get;
1718
use ApiPlatform\Metadata\GetCollection;
1819
use ApiPlatform\Metadata\Link;
1920
use ApiPlatform\Metadata\Operation;
2021
use ApiPlatform\Metadata\Post;
2122
use ApiPlatform\State\CreateProvider;
2223

24+
#[ApiResource(openapi: false)]
2325
#[GetCollection(
2426
uriTemplate: '/issue5662/admin/reviews{._format}',
2527
itemUriTemplate: '/issue5662/reviews/{id}{._format}',

tests/Fixtures/TestBundle/Entity/JsonSchemaResource.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
class JsonSchemaResource
2323
{
2424
#[ApiProperty(identifier: true)]
25-
public $id;
25+
public string $id;
2626

2727
#[ApiProperty(writable: false, readableLink: true)]
2828
public ?JsonSchemaResourceRelated $resourceRelated = null;

tests/Fixtures/TestBundle/Entity/SearchFilterParameter.php

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Tests\Fixtures\TestBundle\Entity;
1515

1616
use ApiPlatform\Metadata\ApiFilter;
17+
use ApiPlatform\Metadata\ApiResource;
1718
use ApiPlatform\Metadata\GetCollection;
1819
use ApiPlatform\Metadata\GraphQl\QueryCollection;
1920
use ApiPlatform\Metadata\QueryParameter;
@@ -22,6 +23,7 @@
2223
use ApiPlatform\Tests\Fixtures\TestBundle\Filter\SearchTextAndDateFilter;
2324
use Doctrine\ORM\Mapping as ORM;
2425

26+
#[ApiResource(openapi: false)]
2527
#[GetCollection(
2628
uriTemplate: 'search_filter_parameter{._format}',
2729
parameters: [

tests/Fixtures/TestBundle/Entity/User.php

+6-6
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,6 @@
3636
* @author Kévin Dunglas <[email protected]>
3737
*/
3838
#[ApiResource(operations: [
39-
new Get(),
40-
new Put(),
41-
new Delete(),
42-
new Put(input: RecoverPasswordInput::class, output: RecoverPasswordOutput::class, uriTemplate: 'users/recover/{id}', processor: RecoverPasswordProcessor::class),
43-
new Post(),
44-
new GetCollection(),
4539
new Post(
4640
uriTemplate: '/users/password_reset_request',
4741
messenger: 'input',
@@ -50,6 +44,12 @@
5044
normalizationContext: ['groups' => ['user_password_reset_request']],
5145
denormalizationContext: ['groups' => ['user_password_reset_request']]
5246
),
47+
new Put(input: RecoverPasswordInput::class, output: RecoverPasswordOutput::class, uriTemplate: 'users/recover/{id}', processor: RecoverPasswordProcessor::class),
48+
new Get(),
49+
new Put(),
50+
new Delete(),
51+
new Post(),
52+
new GetCollection(),
5353
new Get('users-with-groups/{id}', normalizationContext: ['groups' => ['api-test-case-group']]),
5454
new GetCollection('users-with-groups', normalizationContext: ['groups' => ['api-test-case-group']]),
5555
], normalizationContext: ['groups' => ['user', 'user-read']], denormalizationContext: ['groups' => ['user', 'user-write']])]

tests/Fixtures/TestBundle/Entity/WrappedResponseEntity.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use Doctrine\ORM\Mapping as ORM;
2020
use Symfony\Component\Serializer\Annotation\Groups;
2121

22-
#[ApiResource(operations: [new Get(normalizationContext: ['groups' => ['read']], output: CustomOutputEntityWrapperDto::class
22+
#[ApiResource(operations: [new Get(openapi: false, normalizationContext: ['groups' => ['read']], output: CustomOutputEntityWrapperDto::class
2323
)])]
2424
#[ORM\Entity]
2525
class WrappedResponseEntity

tests/Fixtures/app/ruleset.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extends: [[spectral:oas, recommended]]
2+
rules:
3+
circular-references: false
4+
operation-success-response: false
5+
oas3-parameter-description: false
6+
oas3-missing-example: false
7+
description-duplication: false
8+
component-description: false
9+
paths-kebab-case: false

tests/Functional/OpenApiTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public function testFilterExtensionTags(): void
8282
$this->assertArrayHasKey('/cruds', $res['paths']);
8383
$this->assertArrayHasKey('post', $res['paths']['/cruds']);
8484
$this->assertArrayHasKey('get', $res['paths']['/cruds']);
85-
$this->assertEquals([['name' => 'Crud']], $res['tags']);
85+
$this->assertEquals([['name' => 'Crud', 'description' => 'A resource used for OpenAPI tests.']], $res['tags']);
8686

8787
$response = self::createClient()->request('GET', '/docs?filter_tags[]=anotherone', [
8888
'headers' => ['Accept' => 'application/vnd.openapi+json'],
@@ -96,6 +96,6 @@ public function testFilterExtensionTags(): void
9696
$this->assertArrayNotHasKey('post', $res['paths']['/cruds']);
9797
$this->assertArrayHasKey('get', $res['paths']['/cruds']);
9898
$this->assertArrayHasKey('/crud_open_api_api_platform_tags/{id}', $res['paths']);
99-
$this->assertEquals([['name' => 'Crud'], ['name' => 'CrudOpenApiApiPlatformTag', 'description' => 'Something nice']], $res['tags']);
99+
$this->assertEquals([['name' => 'Crud', 'description' => 'A resource used for OpenAPI tests.'], ['name' => 'CrudOpenApiApiPlatformTag', 'description' => 'Something nice']], $res['tags']);
100100
}
101101
}

0 commit comments

Comments
 (0)