Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
199f618
docs(#2223): update 4.x converter tool
DjordyKoert May 24, 2025
96d2f63
ci(release-please): make it possible to create backport releases (#2593)
DjordyKoert Nov 12, 2025
fc4ceac
ci(backport): add backport action & releases (#2594)
DjordyKoert Nov 12, 2025
b39d05f
ci: temporary `release-as` to fix release-please for `4.x`
DjordyKoert Nov 12, 2025
12a01d2
fix: remove unused `TypesTrait` [Backport #2588 to 4.x] (#2595)
github-actions[bot] Nov 12, 2025
5e45375
Revert "ci: temporary `release-as` to fix release-please for `4.x`"
DjordyKoert Nov 12, 2025
248dd59
ci: temporary release-as (v4.38.3)
DjordyKoert Nov 12, 2025
59214f6
chore(4.x): release 4.38.3 (#2596)
github-actions[bot] Nov 12, 2025
237de9f
Revert "chore(4.x): release 4.38.3 (#2596)"
DjordyKoert Nov 12, 2025
11dd3b3
ci(backport): fix backport PR not running workflow [Backport #2601 to…
nelmioapidocbundle-backport[bot] Nov 13, 2025
82e24b4
fix(swagger-php): conflict with broken version 5.5.0 [Backport #2568 …
nelmioapidocbundle-backport[bot] Nov 13, 2025
ef3ba7d
fix: swagger-php 5.7.0 compatatiblity [Backport #2598 to 4.x] (#2603)
nelmioapidocbundle-backport[bot] Nov 13, 2025
77b1972
Revert "ci: temporary release-as (v4.38.3)"
DjordyKoert Nov 13, 2025
75f5e50
chore(4.x): release 4.38.4 (#2605)
github-actions[bot] Nov 13, 2025
5c9caaf
ci(composer): ignore symfony cve [Backport #2607 to 4.x] (#2608)
nelmioapidocbundle-backport[bot] Nov 14, 2025
b625aa6
fix(configuration): validate `type_info` option on Symfony 6 (#2615)
DjordyKoert Nov 14, 2025
c4e2f8b
chore(4.x): release 4.38.5 (#2617)
github-actions[bot] Nov 14, 2025
ceeb348
Fix OpenAPI attributes responses not being processed
coverman-CE Nov 24, 2025
a94db36
chore: remove unnecessary comments
coverman-CE Nov 24, 2025
854ae75
chore: update .doctor-rst.yaml to version 5.x
coverman-CE Nov 24, 2025
79efed7
Revert "chore: update .doctor-rst.yaml to version 5.x"
coverman-CE Nov 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/backport.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Backport merged pull request

on:
pull_request_target:
types:
- closed
- labeled

permissions:
contents: write # so it can comment
pull-requests: write # so it can create pull requests

jobs:
backport:
name: Backport pull request
runs-on: ubuntu-latest
if: >
(
github.event.action == 'closed' &&
github.event.pull_request.merged
) ||
(
github.event.action == 'labeled'
&& startsWith(github.event.label.name, 'backport')
&& github.event.pull_request.merged
)
steps:
- uses: actions/create-github-app-token@v2
id: generate-token
with:
app-id: ${{ secrets.BACKPORT_APP_ID }}
private-key: ${{ secrets.BACKPORT_APP_PRIVATE_KEY }}
- uses: actions/checkout@v4
- name: Create backport pull requests
uses: korthout/backport-action@v3
with:
# Token to authenticate requests to GitHub, ensures that created PRs run CI
github_token: ${{ steps.generate-token.outputs.token }}
branch_name: backport-#${pull_number}-to-${target_branch}
pull_description: |
### This is an automated backport of #${pull_number} to branch `${target_branch}`.

> [!CAUTION]
> **Do not modify this pull request.**

${pull_description}
pull_title: "${pull_title} [Backport #${pull_number} to ${target_branch}]"
25 changes: 25 additions & 0 deletions .github/workflows/release.backport.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Release Backport
on:
push:
branches:
- 4.x

permissions:
contents: write
pull-requests: write

jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4.4.0
with:
# this assumes that you have created a personal access token
# (PAT) and configured it as a GitHub action secret named
# `MY_RELEASE_PLEASE_TOKEN` (this secret name is not important).
token: ${{ secrets.GITHUB_TOKEN }}
# this is a built-in strategy in release-please, see "Action Inputs"
# for more options
release-type: php
versioning-strategy: always-bump-patch
target-branch: 4.x
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# CHANGELOG

## [4.38.5](https://github.com/nelmio/NelmioApiDocBundle/compare/v4.38.4...v4.38.5) (2025-11-14)


### Bug Fixes

* **configuration:** validate `type_info` option on Symfony 6 ([#2615](https://github.com/nelmio/NelmioApiDocBundle/issues/2615)) ([b625aa6](https://github.com/nelmio/NelmioApiDocBundle/commit/b625aa6cba40d3125bcd2c3abb0c7361350bf6f8))

## [4.38.4](https://github.com/nelmio/NelmioApiDocBundle/compare/v4.38.3...v4.38.4) (2025-11-13)


### Bug Fixes

* swagger-php 5.7.0 compatatiblity [Backport [#2598](https://github.com/nelmio/NelmioApiDocBundle/issues/2598) to 4.x] ([#2603](https://github.com/nelmio/NelmioApiDocBundle/issues/2603)) ([ef3ba7d](https://github.com/nelmio/NelmioApiDocBundle/commit/ef3ba7d303cba97d5db995597d416d9ab0451c63))
* **swagger-php:** conflict with broken version 5.5.0 [Backport [#2568](https://github.com/nelmio/NelmioApiDocBundle/issues/2568) to 4.x] ([#2604](https://github.com/nelmio/NelmioApiDocBundle/issues/2604)) ([82e24b4](https://github.com/nelmio/NelmioApiDocBundle/commit/82e24b463c3253d04e29370a401539b80f52935e))

## 4.38.2
- Support of attribute MapQueryParameter with a regexp has been improved, it now converts the regexp from PCRE to ECMA-262 for better compliance with OpenApi.

Expand Down
2 changes: 1 addition & 1 deletion UPGRADE-4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Here are some additional advices that are more likely to apply to NelmioApiDocBu
- Upgrade all your ``use Swagger\Annotations as SWG`` statements to ``use OpenApi\Annotations as OA;`` (to simplify the upgrade you may also stick to the ``SWG`` aliasing).
In case you changed ``SWG`` to ``OA``, upgrade all your annotations from ``@SWG\...`` to ``@OA\...``.

- Update your config in case you used inlined swagger documentation (the field ``nelmio_api_doc.documentation``). [A tool](https://openapi-converter.herokuapp.com/) is available to help you convert it.
- Update your config in case you used inlined swagger documentation (the field ``nelmio_api_doc.documentation``). [A tool](https://converter.swagger.io/) is available to help you convert it.

- In case you used ``@OA\Response(..., @OA\Schema(...))``, you should explicit your media type by using the annotation ``@OA\JsonContent`` or ``@OA\XmlContent`` instead of ``@OA\Schema``:
``@OA\Response(..., @OA\JsonContent(...))`` or ``@OA\Response(..., @OA\XmlContent(...))``.
Expand Down
16 changes: 13 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
{
"name": "nelmio/api-doc-bundle",
"description": "Generates documentation for your REST API from annotations and attributes",
"keywords": ["api", "documentation", "doc", "rest"],
"keywords": [
"api",
"documentation",
"doc",
"rest"
],
"type": "symfony-bundle",
"license": "MIT",
"authors": [
Expand Down Expand Up @@ -61,7 +66,7 @@
"willdurand/hateoas-bundle": "^1.0 || ^2.0"
},
"conflict": {
"zircote/swagger-php": "4.8.7"
"zircote/swagger-php": "4.8.7 || 5.5.0"
},
"suggest": {
"api-platform/core": "For using an API oriented framework.",
Expand Down Expand Up @@ -89,7 +94,12 @@
}
},
"config": {
"sort-packages": true
"sort-packages": true,
"audit": {
"ignore": [
"PKSA-365x-2zjk-pt47"
]
}
},
"extra": {
"branch-alias": {
Expand Down
6 changes: 6 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
parameters:
ignoreErrors:
-
message: '#^Call to function method_exists\(\) with ''Symfony\\\\Component\\\\PropertyInfo\\\\PropertyInfoExtractor'' and ''getType'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: src/DependencyInjection/Configuration.php

-
message: "#^Class Nelmio\\\\ApiDocBundle\\\\Annotation\\\\Areas extends @final class Nelmio\\\\ApiDocBundle\\\\Attribute\\\\Areas\\.$#"
count: 1
Expand Down
5 changes: 5 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Nelmio\ApiDocBundle\Render\Html\AssetsMode;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\PropertyInfo\PropertyInfoExtractor;

final class Configuration implements ConfigurationInterface
{
Expand All @@ -28,6 +29,10 @@ public function getConfigTreeBuilder(): TreeBuilder
->booleanNode('type_info')
->info('Use the symfony/type-info component for determining types.')
->defaultFalse()
->validate()
->ifTrue(static fn ($v) => true === $v && !method_exists(PropertyInfoExtractor::class, 'getType'))
->thenInvalid('the type_info option requires Symfony 7 or higher. Please upgrade Symfony or set type_info to false.')
->end()
->end()
->booleanNode('use_validation_groups')
->info('If true, `groups` passed to @Model annotations will be used to limit validation constraints')
Expand Down
15 changes: 11 additions & 4 deletions src/Describer/DefaultDescriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,17 @@ public function describe(OA\OpenApi $api): void
foreach (Util::OPERATIONS as $method) {
/** @var OA\Operation $operation */
$operation = $path->{$method};
if (Generator::UNDEFINED !== $operation && null !== $operation && (Generator::UNDEFINED === $operation->responses || [] === $operation->responses)) {
/** @var OA\Response $response */
$response = Util::getIndexedCollectionItem($operation, OA\Response::class, 'default');
$response->description = '';
if (Generator::UNDEFINED !== $operation && null !== $operation) {
$hasAnyResponses = false;
if (Generator::UNDEFINED !== $operation->responses && [] !== $operation->responses && null !== $operation->responses) {
$hasAnyResponses = true;
}

if (!$hasAnyResponses) {
/** @var OA\Response $response */
$response = Util::getIndexedCollectionItem($operation, OA\Response::class, 'default');
$response->description = '';
}
}
}
}
Expand Down
14 changes: 14 additions & 0 deletions src/Describer/OpenApiPhpDescriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,20 @@ public function describe(OA\OpenApi $api): void
continue;
}

if ($annotation instanceof \OpenApi\Attributes\Post ||
$annotation instanceof \OpenApi\Attributes\Get ||
$annotation instanceof \OpenApi\Attributes\Put ||
$annotation instanceof \OpenApi\Attributes\Delete ||
$annotation instanceof \OpenApi\Attributes\Patch) {
$className = get_class($annotation);
$methodName = strtolower(substr($className, strrpos($className, "\\") + 1));
if (in_array($methodName, $httpMethods, true)) {
$operation = Util::getOperation($path, $methodName);
$operation->mergeProperties($annotation);
}
continue;
}

if ($annotation instanceof OA\Operation) {
if (!in_array($annotation->method, $httpMethods, true)) {
continue;
Expand Down
1 change: 1 addition & 0 deletions src/Processor/MapQueryStringProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ private function addQueryParameters(Analysis $analysis, OA\Operation $operation,
// Remove incompatible properties
$propertyVars = get_object_vars($property);
unset($propertyVars['property']);
unset($propertyVars['encoding']);

$schema = new OA\Schema($propertyVars);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,11 @@
use Nelmio\ApiDocBundle\OpenApiPhp\Util;
use OpenApi\Annotations as OA;
use OpenApi\Generator;
use OpenApi\Processors\Concerns\TypesTrait;
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;

final class SymfonyMapQueryParameterDescriber implements RouteArgumentDescriberInterface
{
use TypesTrait;

public function describe(ArgumentMetadata $argumentMetadata, OA\Operation $operation): void
{
if (!$attribute = $argumentMetadata->getAttributes(MapQueryParameter::class, ArgumentMetadata::IS_INSTANCEOF)[0] ?? null) {
Expand Down