diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml index 8921e7112..8bef85221 100644 --- a/.azure-pipelines/ci-build.yml +++ b/.azure-pipelines/ci-build.yml @@ -65,6 +65,11 @@ extends: displayName: 'Use .NET 8' inputs: version: 8.x + + - task: UseDotNet@2 + displayName: 'Use .NET 10' + inputs: + version: 10.x # Install the nuget tool. - task: NuGetToolInstaller@1 @@ -77,7 +82,7 @@ extends: - task: DotNetCoreCLI@2 displayName: 'build' inputs: - projects: '$(Build.SourcesDirectory)\Microsoft.OpenApi.sln' + projects: '$(Build.SourcesDirectory)\Microsoft.OpenApi.slnx' arguments: '--configuration $(BuildConfiguration) --no-incremental' # Run the Unit test @@ -85,7 +90,7 @@ extends: displayName: 'test' inputs: command: test - projects: '$(Build.SourcesDirectory)\Microsoft.OpenApi.sln' + projects: '$(Build.SourcesDirectory)\Microsoft.OpenApi.slnx' arguments: '--configuration $(BuildConfiguration) --no-build' - task: EsrpCodeSigning@5 @@ -472,4 +477,8 @@ extends: -t "$(REGISTRY)/$(IMAGE_NAME):${VERSION}" \ "$(Pipeline.Workspace)" displayName: 'Build and Push Release Image' - condition: contains(variables['Build.SourceBranch'], 'refs/tags/v') \ No newline at end of file + condition: contains(variables['Build.SourceBranch'], 'refs/tags/v') + +# once the nuget has been released, fill this form to get the public documentation updated. +# https://dev.azure.com/msft-skilling/Content/_workitems/create/User%20Story?templateId=39fb91e3-64a2-4c8a-83db-b2bdf3603dd3&ownerId=c4a28f90-17ae-4384-b514-7273392b082b +# https://learn.microsoft.com/en-us/dotnet/api/microsoft.openapi diff --git a/.config/1espt/PipelineAutobaseliningConfig.yml b/.config/1espt/PipelineAutobaseliningConfig.yml index a4d9608c6..37a1a42bd 100644 --- a/.config/1espt/PipelineAutobaseliningConfig.yml +++ b/.config/1espt/PipelineAutobaseliningConfig.yml @@ -8,15 +8,17 @@ pipelines: credscan: lastModifiedDate: 2024-09-13 eslint: - lastModifiedDate: 2024-09-13 + lastModifiedDate: 2026-05-13 psscriptanalyzer: - lastModifiedDate: 2024-09-13 + lastModifiedDate: 2026-05-13 armory: - lastModifiedDate: 2024-09-13 + lastModifiedDate: 2026-05-13 + accessibilityinsights: + lastModifiedDate: 2025-06-03 binary: credscan: - lastModifiedDate: 2025-01-27 + lastModifiedDate: 2025-01-28 binskim: - lastModifiedDate: 2025-01-27 + lastModifiedDate: 2026-05-13 spotbugs: - lastModifiedDate: 2025-01-27 + lastModifiedDate: 2026-05-13 diff --git a/.config/guardian/.gdnbaselines b/.config/guardian/.gdnbaselines new file mode 100644 index 000000000..5ed019a92 --- /dev/null +++ b/.config/guardian/.gdnbaselines @@ -0,0 +1,53 @@ +{ + "properties": { + "helpUri": "https://eng.ms/docs/microsoft-security/security/azure-security/cloudai-security-fundamentals-engineering/security-integration/guardian-wiki/microsoft-guardian/general/baselines" + }, + "version": "1.0.0", + "baselines": { + "default": { + "name": "default", + "createdDate": "2026-05-13 00:39:09Z", + "lastUpdatedDate": "2026-05-13 00:40:41Z" + } + }, + "results": { + "89411c6a070fd31f2836b38a16926ffbfb4882aff49c907cafe6c95dfba1104a": { + "signature": "89411c6a070fd31f2836b38a16926ffbfb4882aff49c907cafe6c95dfba1104a", + "alternativeSignatures": [ + "59104f1c3fec111fba3f6b5b6d2d37f3bc0d5267b425f82b8c3f852abc8b2b7a", + "4dee2b2a1887d7a952ae5c61e48c9b6f543096940991cdcd0209c60561a537ce", + "558e542a1dcc76100e4395b278f8b99f1dab960b2b3ae01a4c5cb84ac5cdc70f" + ], + "target": "src/Microsoft.OpenApi/Writers/SpecialCharacterStringExtensions.cs", + "line": 152, + "uriBaseId": "file:///D:/a/_work/1/s/", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "CA1310", + "createdDate": "2026-05-13 00:39:09Z", + "expirationDate": "2026-10-30 00:42:11Z", + "justification": "This error is baselined with an expiration date of 180 days from 2026-05-13 00:42:11Z" + }, + "f6386b2f2aa1886a31fd1b57fa9e476ff5f24efbe144c82246f931e688010861": { + "signature": "f6386b2f2aa1886a31fd1b57fa9e476ff5f24efbe144c82246f931e688010861", + "alternativeSignatures": [ + "eb5bc1ea05b68f4106e441c8d441b39afaea833e5b2cbf6804d34cb869d9ed00", + "bbe095dbf06a503925246de4a84cdc73afdafeddde3dab2440302c40560f811e", + "aaac06605663a64f92dc03d6aacf9a424f2d861eba86f4ffa06cd231479734a8" + ], + "target": "src/Microsoft.OpenApi/Reader/V2/OpenApiDocumentDeserializer.cs", + "line": 179, + "uriBaseId": "file:///D:/a/_work/1/s/", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "CA1310", + "createdDate": "2026-05-13 00:39:09Z", + "expirationDate": "2026-10-30 00:42:11Z", + "justification": "This error is baselined with an expiration date of 180 days from 2026-05-13 00:42:11Z" + } + } +} \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..16abc6aef --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,11 @@ +{ + "name": "OpenAPI.NET", + "image": "mcr.microsoft.com/devcontainers/dotnet:10.0", + "customizations": { + "vscode": { + "extensions": [ + "ms-dotnettools.csdevkit" + ] + } + } +} diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..12f65c04f --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,63 @@ +# Copilot Instructions + +## Commit Message Format + +Always use conventional commits format when creating commits. Follow this structure: + +``` +(): + +[optional body] + +[optional footer(s)] +``` + +### Types + +- **feat**: A new feature +- **fix**: A bug fix +- **docs**: Documentation only changes +- **style**: Changes that do not affect the meaning of the code (white-space, formatting, etc) +- **refactor**: A code change that neither fixes a bug nor adds a feature +- **perf**: A code change that improves performance +- **test**: Adding missing tests or correcting existing tests +- **build**: Changes that affect the build system or external dependencies +- **ci**: Changes to CI configuration files and scripts +- **chore**: Other changes that don't modify src or test files + +### Scope + +The scope should indicate the package or area affected (e.g., `library`, `yaml-reader`, `hidi`). + +### Examples + +``` +feat(library): add support for pattern properties +fix(yaml-reader): updates boolean serialization +docs(README): update installation instructions +ci(release): configure automated release workflow +``` + +### Breaking Changes + +If a commit introduces a breaking change, add `BREAKING CHANGE:` in the footer or append `!` after the type/scope: + +``` +feat(identity-emitter)!: change output format for models + +BREAKING CHANGE: The emitter now generates TypeScript interfaces instead of types +``` + + +## Updating the benchmark information + +The user might request you update the benchmark information. You might do it on your own if a previous change added new properties to models under **src/Microsoft.OpenApi/Models**. Always use a separate commit for this change. + +To do so, run the following script: + +```shell +cd performance/benchmark +dotnet run -c Release +``` + +Then commit the report files using a "chore" commit. \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 87b987112..49c969ced 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -16,6 +16,9 @@ updates: MicrosoftExtensions: patterns: - "Microsoft.Extensions.*" + coverlet: + patterns: + - "coverlet.*" - package-ecosystem: dotnet-sdk directory: / schedule: @@ -25,3 +28,8 @@ updates: update-types: - version-update:semver-major - version-update:semver-minor + - package-ecosystem: "devcontainers" + directory: "/" + open-pull-requests-limit: 10 + schedule: + interval: "daily" diff --git a/.github/workflows/auto-merge-dependabot.yml b/.github/workflows/auto-merge-dependabot.yml index d454cd186..9d9039433 100644 --- a/.github/workflows/auto-merge-dependabot.yml +++ b/.github/workflows/auto-merge-dependabot.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.4.0 + uses: dependabot/fetch-metadata@v3.1.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 9d55602b3..d91c08ad5 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -9,19 +9,29 @@ jobs: ci: name: Continuous Integration runs-on: ubuntu-latest + permissions: + contents: read + code-quality: write + pull-requests: read env: ARTIFACTS_FOLDER: ${{ github.workspace }}/Artifacts GITHUB_RUN_NUMBER: ${{ github.run_number }} steps: - - name: Setup .NET + - name: Setup .NET 8 uses: actions/setup-dotnet@v5 with: dotnet-version: 8.x + - name: Setup .NET 10 + uses: actions/setup-dotnet@v5 + with: + dotnet-version: 10.x + - name: Checkout repository id: checkout_repo - uses: actions/checkout@v5 + uses: actions/checkout@v7 with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 @@ -29,27 +39,61 @@ jobs: id: build_projects shell: pwsh run: | - dotnet build Microsoft.OpenApi.sln -c Release + dotnet build Microsoft.OpenApi.slnx -c Release - name: Run unit tests id: run_unit_tests shell: pwsh run: | - dotnet test Microsoft.OpenApi.sln -c Release -v n + dotnet test Microsoft.OpenApi.slnx -c Release --no-build -v n --collect:"XPlat Code Coverage" + + - name: Install report generator + shell: pwsh + run: | + dotnet tool install --global dotnet-reportgenerator-globaltool + + - name: Generate coverage report + shell: pwsh + run: | + reportgenerator -reports:**/coverage.cobertura.xml -targetdir:./reports/coverage -reporttypes:"Html;MarkdownSummaryGithub;Cobertura" + + - name: Add coverage to job summary + shell: bash + run: | + cat ./reports/coverage/SummaryGithub.md >> "$GITHUB_STEP_SUMMARY" + + - name: Upload coverage report + if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]') || (github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch) + uses: actions/upload-code-coverage@v1 + with: + file: ./reports/coverage/Cobertura.xml + language: CSharp + label: code-coverage/dotnet + + - name: Upload coverage artifact + uses: actions/upload-artifact@v7 + with: + name: coverage + path: reports/coverage validate-trimming: name: Validate Project for Trimming runs-on: windows-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 - - name: Setup .NET + - name: Setup .NET 8 uses: actions/setup-dotnet@v5 with: dotnet-version: 8.x + - name: Setup .NET 10 + uses: actions/setup-dotnet@v5 + with: + dotnet-version: 10.x + - name: Validate Trimming warnings - run: dotnet publish -c Release -r win-x64 /p:TreatWarningsAsErrors=true /warnaserror -f net8.0 + run: dotnet publish -c Release -r win-x64 /p:TreatWarningsAsErrors=true /warnaserror -f net10.0 working-directory: ./test/Microsoft.OpenApi.Trimming.Tests validate-performance: @@ -58,13 +102,18 @@ jobs: needs: [ci] steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v7 - - name: Setup .NET + - name: Setup .NET 8 uses: actions/setup-dotnet@v5 with: dotnet-version: 8.x + - name: Setup .NET 10 + uses: actions/setup-dotnet@v5 + with: + dotnet-version: 10.x + - name: Copy committed results run: | mkdir -p ./performanceResults @@ -76,7 +125,7 @@ jobs: working-directory: ./performance/benchmark - name: Publish benchmark results - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v7 with: if-no-files-found: error name: benchmark-results diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 72eea8bbf..4f5ad9d47 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -20,13 +20,18 @@ jobs: steps: - name: Checkout repository id: checkout_repo - uses: actions/checkout@v5 + uses: actions/checkout@v7 - - name: Setup .NET + - name: Setup .NET 8 uses: actions/setup-dotnet@v5 with: dotnet-version: 8.0.x + - name: Setup .NET 10 + uses: actions/setup-dotnet@v5 + with: + dotnet-version: 10.0.x + - name: Initialize CodeQL id: init_codeql uses: github/codeql-action/init@v4 diff --git a/.github/workflows/promote-shipped-apis.yml b/.github/workflows/promote-shipped-apis.yml new file mode 100644 index 000000000..b3c7e8b6d --- /dev/null +++ b/.github/workflows/promote-shipped-apis.yml @@ -0,0 +1,113 @@ +name: Promote Shipped APIs + +on: + push: + branches: + - main + - support/v2 + workflow_dispatch: + +jobs: + promote-apis: + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@v3 + with: + client-id: ${{ vars.RELEASE_PLEASE_TOKEN_PROVIDER_APP_ID }} + private-key: ${{ secrets.RELEASE_PLEASE_TOKEN_PROVIDER_PEM }} + + - name: Checkout code + uses: actions/checkout@v7 + with: + fetch-depth: 0 + token: ${{ steps.app-token.outputs.token }} + + - name: Configure git + shell: pwsh + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + git config --global url."https://$($env:GH_TOKEN)@github.com/".insteadOf "https://github.com/" + + - name: Check for existing PR + id: check_pr + shell: pwsh + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + $branch = "${{ github.ref_name }}" + $prs = gh pr list --state open --head "promote-shipped-apis-$branch" --json number --jq '.[0].number' 2>$null + if ($prs) { + echo "pr_number=$prs" >> $env:GITHUB_OUTPUT + echo "pr_exists=true" >> $env:GITHUB_OUTPUT + Write-Host "Found existing PR: $prs" + } else { + echo "pr_exists=false" >> $env:GITHUB_OUTPUT + Write-Host "No existing PR found" + } + + - name: Checkout existing PR branch + if: steps.check_pr.outputs.pr_exists == 'true' + shell: pwsh + run: | + $branch = "${{ github.ref_name }}" + $prBranch = "promote-shipped-apis-$branch" + + git fetch origin + git checkout $prBranch + + - name: Merge trigger branch into PR branch + if: steps.check_pr.outputs.pr_exists == 'true' + shell: pwsh + run: | + $branch = "${{ github.ref_name }}" + git merge origin/$branch -m "Merge $branch into promote branch" + + - name: Run promote unshipped script + shell: pwsh + run: | + & .\scripts\promoteUnshipped.ps1 + + - name: Check for changes + id: check_changes + shell: pwsh + run: | + $changes = git diff --name-only -- "*Shipped.txt" + if ($changes) { + echo "has_changes=true" >> $env:GITHUB_OUTPUT + Write-Host "Changed files: $changes" + } else { + echo "has_changes=false" >> $env:GITHUB_OUTPUT + Write-Host "No changes detected" + } + + - name: Commit and push changes + if: steps.check_changes.outputs.has_changes == 'true' + shell: pwsh + run: | + git add *hipped.txt + git commit -m "chore: promote shipped APIs" + + $branch = "${{ github.ref_name }}" + $prBranch = "promote-shipped-apis-$branch" + git push -u origin HEAD:$prBranch + + - name: Create new PR + if: steps.check_pr.outputs.pr_exists == 'false' && steps.check_changes.outputs.has_changes == 'true' + shell: pwsh + env: + GH_TOKEN: ${{ steps.app-token.outputs.token }} + run: | + $branch = "${{ github.ref_name }}" + $prBranch = "promote-shipped-apis-$branch" + $title = "automatic promotion of shipped APIs for $branch" + + gh pr create --title "$title" --base "$branch" --head "$prBranch" --body "Automatically promotes unshipped APIs to shipped after running the promotion script." + diff --git a/.github/workflows/release-please-gha.yml b/.github/workflows/release-please-gha.yml index e72901a53..48e87c4b5 100644 --- a/.github/workflows/release-please-gha.yml +++ b/.github/workflows/release-please-gha.yml @@ -22,20 +22,53 @@ permissions: contents: read jobs: + check-secret: + runs-on: ubuntu-latest + outputs: + has-token: ${{ steps.check.outputs.has-token }} + steps: + - id: check + run: echo "has-token=${{ secrets.RELEASE_PLEASE_TOKEN_PROVIDER_PEM != '' }}" >> $GITHUB_OUTPUT release: + needs: check-secret + if: needs.check-secret.outputs.has-token == 'true' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v7 + + - name: Validate PublicAPI.Unshipped.txt files are empty + shell: pwsh + run: | + $unshippedFiles = Get-ChildItem 'src/ ' -Recurse -Filter *.Unshipped.txt | Select -ExpandProperty FullName + + $hasUnshippedAPIs = $false + + foreach ($file in $unshippedFiles) { + $content = Get-Content -Path $file -Raw + # Remove the #nullable enable line and any whitespace + $trimmedContent = $content -replace '^\s*#nullable enable\s*$', '' -replace '^\s+', '' + + if ($trimmedContent -ne '') { + Write-Error "❌ $file contains unshipped APIs. Please promote them to PublicAPI.Shipped.txt before releasing.`nContent:`n$content" + $hasUnshippedAPIs = $true + } + } + + if ($hasUnshippedAPIs) { + exit 1 + } + + Write-Output "✅ All PublicAPI.Unshipped.txt files are clean" - name: Generate GitHub App token id: app-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@v3 with: - app-id: ${{ vars.RELEASE_PLEASE_TOKEN_PROVIDER_APP_ID }} + client-id: ${{ vars.RELEASE_PLEASE_TOKEN_PROVIDER_APP_ID }} private-key: ${{ secrets.RELEASE_PLEASE_TOKEN_PROVIDER_PEM }} - name: Release Please - uses: googleapis/release-please-action@v4 + uses: googleapis/release-please-action@v5 with: token: ${{ steps.app-token.outputs.token }} config-file: release-please-config.json diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 51f9b5986..abac4ef81 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -39,15 +39,19 @@ jobs: with: distribution: 'adopt' java-version: 17 - - name: Setup .NET + - name: Setup .NET 8 uses: actions/setup-dotnet@v5 with: dotnet-version: 8.0.x - - uses: actions/checkout@v5 + - name: Setup .NET 10 + uses: actions/setup-dotnet@v5 + with: + dotnet-version: 10.0.x + - uses: actions/checkout@v7 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Cache SonarCloud packages - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar @@ -64,5 +68,5 @@ jobs: dotnet tool run dotnet-sonarscanner begin /k:"microsoft_OpenAPI.NET" /o:"microsoft" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="test/**/coverage.opencover.xml" dotnet workload restore dotnet build - dotnet test Microsoft.OpenApi.sln --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover + dotnet test Microsoft.OpenApi.slnx --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover dotnet tool run dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}" \ No newline at end of file diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 511dd5165..9127b1bd5 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.6.0" + ".": "3.9.0" } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d2bd5722f..e68597ddc 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -10,7 +10,7 @@ "group": "build", "args": [ "build", - "${workspaceFolder}/Microsoft.OpenApi.sln", + "${workspaceFolder}/Microsoft.OpenApi.slnx", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], @@ -23,7 +23,7 @@ "group": "test", "args": [ "test", - "${workspaceFolder}/Microsoft.OpenApi.sln", + "${workspaceFolder}/Microsoft.OpenApi.slnx", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary", "--collect:\"XPlat Code Coverage\"" diff --git a/CHANGELOG.md b/CHANGELOG.md index 00819c348..558c2a93f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,30 +1,185 @@ # Changelog -## [2.6.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.5.0...v2.6.0) (2026-01-21) +## [3.9.0](https://github.com/microsoft/OpenAPI.NET/compare/v3.8.0...v3.9.0) (2026-07-15) + + +### Features + +* adds support for anchor and id external resolution ([1591007](https://github.com/microsoft/OpenAPI.NET/commit/15910070f2bf3006f79e1c43dd9c2b56e45d665c)) +* **schema:** resolve bare $dynamicRef via $dynamicAnchor index ([#2913](https://github.com/microsoft/OpenAPI.NET/issues/2913)) ([eacc2fc](https://github.com/microsoft/OpenAPI.NET/commit/eacc2fc06537fbb11fe95765e4fb6df09861c9af)) +* support relative URI resolution in $dynamicRef ([#2928](https://github.com/microsoft/OpenAPI.NET/issues/2928)) ([#2945](https://github.com/microsoft/OpenAPI.NET/issues/2945)) ([821053b](https://github.com/microsoft/OpenAPI.NET/commit/821053ba02129e92868df2ae0c26551fb3d5276a)) + + +### Bug Fixes + +* adds explicit error message for invalid json pointers ([63fc55d](https://github.com/microsoft/OpenAPI.NET/commit/63fc55d69274ebd405e677983e0a72efd2b96079)) +* adds explicit error message for invalid json pointers ([bc93efe](https://github.com/microsoft/OpenAPI.NET/commit/bc93efe9d4694e89da1ea30fbc2d031e7f1318ae)) +* default mapping is not being serialized with the correct shape ([fe4a25f](https://github.com/microsoft/OpenAPI.NET/commit/fe4a25f1f25c853404540d30f11812f1208f93c9)) +* differentiate unset value from null value in OpenApiSchema.Const ([#2936](https://github.com/microsoft/OpenAPI.NET/issues/2936)) ([07b525f](https://github.com/microsoft/OpenAPI.NET/commit/07b525f568b65b5003deaccc56829f5e7e8e2641)) +* handle nullability more accurately during serialization for 3.0/2.0 ([#2933](https://github.com/microsoft/OpenAPI.NET/issues/2933)) ([0ace243](https://github.com/microsoft/OpenAPI.NET/commit/0ace243ebbabe82aacc52d49fe58f54f039bdf76)) +* validate required properties of security scheme before serialization ([#2952](https://github.com/microsoft/OpenAPI.NET/issues/2952)) ([f31b192](https://github.com/microsoft/OpenAPI.NET/commit/f31b192e9d59d39671fdfd03b4fa4d309b03021b)) + +## [3.8.0](https://github.com/microsoft/OpenAPI.NET/compare/v3.7.0...v3.8.0) (2026-07-03) + + +### Features + +* add JsonConverter for OpenApiSchema System.Text.Json serialization ([#2915](https://github.com/microsoft/OpenAPI.NET/issues/2915)) ([2f8b3d2](https://github.com/microsoft/OpenAPI.NET/commit/2f8b3d2a160f5b44b5aeaa3d83ff2025302ce1e2)) +* **library:** support schema keywords on references ([434b2f8](https://github.com/microsoft/OpenAPI.NET/commit/434b2f8b34e4a3a27bd99e43f61692f0b00c3054)) +* **library:** support schema keywords on references ([66a9d04](https://github.com/microsoft/OpenAPI.NET/commit/66a9d04036556945ee3222849b7d071a30016b81)), closes [#2903](https://github.com/microsoft/OpenAPI.NET/issues/2903) + + +### Bug Fixes + +* Don't silently skip null assignment to OpenApiDocument.Tags ([3764142](https://github.com/microsoft/OpenAPI.NET/commit/37641424837df0b5e142ca130cb16df699bdb09f)) +* handling of nullable enums for 3.0 ([#2920](https://github.com/microsoft/OpenAPI.NET/issues/2920)) ([beb68f5](https://github.com/microsoft/OpenAPI.NET/commit/beb68f52b86c1437e50f7561d9be1ebdbe146963)) +* **library:** keep v3 schema references ref-only ([c938727](https://github.com/microsoft/OpenAPI.NET/commit/c9387274be6a6955952174d677bea0a35bda2624)) +* preserve JSON Schema 2020-12 keyword siblings on $ref schemas for OAS 3.1+ ([#2896](https://github.com/microsoft/OpenAPI.NET/issues/2896)) ([08160c8](https://github.com/microsoft/OpenAPI.NET/commit/08160c872a5f931eecd12446335c2f51fdad083e)) +* use async method for crypto flush ([6e675d9](https://github.com/microsoft/OpenAPI.NET/commit/6e675d943537312386c9683790848ad1cbacb713)) + +## [3.7.0](https://github.com/microsoft/OpenAPI.NET/compare/v3.6.0...v3.7.0) (2026-06-10) + + +### Features + +* add contains/minContains/maxContains members ([78475e3](https://github.com/microsoft/OpenAPI.NET/commit/78475e38f7c61e349f2d2ad477b5a96a9c3df848)) +* add contains/minContains/maxContains members ([1a974f8](https://github.com/microsoft/OpenAPI.NET/commit/1a974f8dfcd7850c70d80133ceecee08f6671cd7)) +* **library:** add missing json schema properties ([9b1aed6](https://github.com/microsoft/OpenAPI.NET/commit/9b1aed61041551b06926fc2ee4e12705190e16b3)) +* **library:** add missing json schema properties ([82f84e0](https://github.com/microsoft/OpenAPI.NET/commit/82f84e072d9f6b4b5907e9435212fbfc8f82d9c7)) + + +### Bug Fixes + +* **library:** always copy unevaluated properties ([4907d1c](https://github.com/microsoft/OpenAPI.NET/commit/4907d1c1c4d5b8450d32459752e64e5beb592f46)) +* **library:** avoid false circular refs for external schema re-exports ([b635242](https://github.com/microsoft/OpenAPI.NET/commit/b635242a402c3c468eb86dcf2b6d94a05717d92e)) +* **library:** avoid false circular refs for external schema re-exports ([7a443c2](https://github.com/microsoft/OpenAPI.NET/commit/7a443c298fb87346338095b5df86f6608fb4d582)) +* **library:** remove unshipped schema extension fallback ([cf54bb3](https://github.com/microsoft/OpenAPI.NET/commit/cf54bb3e2746c0f6c7a60fde5bcc7fa1139dd8b6)) +* **library:** use version-specific schema keyword callbacks ([6e22ec6](https://github.com/microsoft/OpenAPI.NET/commit/6e22ec6948509d2e256932ee55f1781a544cb53f)) +* **library:** use x-jsonschema schema extensions ([eb1891a](https://github.com/microsoft/OpenAPI.NET/commit/eb1891a8d77915add1cdd88949b40aa43cd525b8)) + +## [3.6.0](https://github.com/microsoft/OpenAPI.NET/compare/v3.5.5...v3.6.0) (2026-06-01) + + +### Features + +* **reader:** remove ParseNode infrastructure ([9b4f45b](https://github.com/microsoft/OpenAPI.NET/commit/9b4f45bee83106e2e5309c9583220f690c66c716)) + +## [3.5.5](https://github.com/microsoft/OpenAPI.NET/compare/v3.5.4...v3.5.5) (2026-05-28) + + +### Bug Fixes + +* **reader:** preserve Null flag when nullable appears before type in V3.0/V3.1/V3.2 deserializers ([2b9d7f4](https://github.com/microsoft/OpenAPI.NET/commit/2b9d7f46bfcef3e2d5da3f73fd4bf83be677c79a)) + +## [3.5.4](https://github.com/microsoft/OpenAPI.NET/compare/v3.5.3...v3.5.4) (2026-05-26) + + +### Bug Fixes + +* **library:** handle circular schema references ([b3cd42b](https://github.com/microsoft/OpenAPI.NET/commit/b3cd42b7c2405b800e633ce63b044bb2409034a0)) +* **library:** handle circular schema references ([91a989f](https://github.com/microsoft/OpenAPI.NET/commit/91a989fdf412a1267debe925d2d586292fdd297d)) + +## [3.5.3](https://github.com/microsoft/OpenAPI.NET/compare/v3.5.2...v3.5.3) (2026-04-27) + + +### Bug Fixes + +* null reference exception for boolean component schemas ([f97f91a](https://github.com/microsoft/OpenAPI.NET/commit/f97f91a9f785b88039968024d5d1f4af51332631)) +* null reference exception for boolean component schemas ([fe0b50a](https://github.com/microsoft/OpenAPI.NET/commit/fe0b50aae372e5b08625f888ae424f22da759cdf)) +* **schema:** support boolean schemas in deserializer for OpenAPI 3.1/3.2 ([05b44be](https://github.com/microsoft/OpenAPI.NET/commit/05b44beb9783f5bab1d8988b3cb916d0278d42ce)) + + +### Performance Improvements + +* **schema:** optimize boolean schema deserialization ([7316e3f](https://github.com/microsoft/OpenAPI.NET/commit/7316e3f0e7b9acc11bc1e0255d7ca33837a1bbdc)) + +## [3.5.2](https://github.com/microsoft/OpenAPI.NET/compare/v3.5.1...v3.5.2) (2026-04-14) + + +### Bug Fixes + +* **hidi:** update Microsoft.OpenApi.OData to 3.2.1 ([b0a68fb](https://github.com/microsoft/OpenAPI.NET/commit/b0a68fbe53593139ba51e758bcc01fcd188d7cb8)) +* **hidi:** update Microsoft.OpenApi.OData to 3.2.1 ([8c22ab2](https://github.com/microsoft/OpenAPI.NET/commit/8c22ab2b3a885344197bf0f05d6df63ecb771927)), closes [#2811](https://github.com/microsoft/OpenAPI.NET/issues/2811) + +## [3.5.1](https://github.com/microsoft/OpenAPI.NET/compare/v3.5.0...v3.5.1) (2026-03-31) + + +### Bug Fixes + +* security scheme references serialization ([a5acb89](https://github.com/microsoft/OpenAPI.NET/commit/a5acb896cb46a58702c07bc742b5e114ba90f95a)) + +## [3.5.0](https://github.com/microsoft/OpenAPI.NET/compare/v3.4.0...v3.5.0) (2026-03-20) + + +### Features + +* **library:** add Extensions support for schema references in v3.1/v3.2; add SerializeAsV32 with loop detection ([9b422bf](https://github.com/microsoft/OpenAPI.NET/commit/9b422bfbe1459588821ab011ba470336c63e4958)) + + +### Bug Fixes + +* a bug where path parameter validation would fail if they contained forbidden JSON pointer characters ([ef55b2c](https://github.com/microsoft/OpenAPI.NET/commit/ef55b2ce664014a854dbd4275e3fed783bc53385)) +* a bug where path parameter validation would fail if they contained forbidden JSON pointer characters ([4b3164a](https://github.com/microsoft/OpenAPI.NET/commit/4b3164a76b316951cb043aebf950663a17e51c90)) +* double encoding of json pointer for invalid reference rule ([b246cd0](https://github.com/microsoft/OpenAPI.NET/commit/b246cd0bafde78892aa22e6ffe046cf5a438eb7d)) +* encoding of special characters for JSON paths ([4c757e1](https://github.com/microsoft/OpenAPI.NET/commit/4c757e1e9806f95ed598f349e4fc35a0307b9342)) +* **library:** do not emit unevaluatedProperties for non-object schemas ([852fb4c](https://github.com/microsoft/OpenAPI.NET/commit/852fb4c744c51099a629d90797a2803d3bbdfc2a)) +* **library:** do not emit unevaluatedProperties for non-object schemas ([19538aa](https://github.com/microsoft/OpenAPI.NET/commit/19538aa169b708dac3baf04a1315bed1dd25eac6)) +* **library:** enforce spec-compliant $ref serialization; add Extensions support for schema references in v3.1/v3.2 ([9bf61de](https://github.com/microsoft/OpenAPI.NET/commit/9bf61de9c10092f744ab38fe0a41bd6adb8351d4)) +* potential double encoding of paths ([471a61a](https://github.com/microsoft/OpenAPI.NET/commit/471a61a2567bb517ede94f0bec1a53ef806b2db3)) + +## [3.4.0](https://github.com/microsoft/OpenAPI.NET/compare/v3.3.1...v3.4.0) (2026-03-04) + + +### Features + +* **library:** preserve PatternProperties as x-jsonschema-patternProperties extension for OpenAPI v2/v3.0 serialization ([d969fdc](https://github.com/microsoft/OpenAPI.NET/commit/d969fdc12632ad0879b9fe07d3ab736b21ae68cf)) +* **library:** Preserve PatternProperties via x-jsonschema-patternProperties extension for OpenAPI v2/v3.0 ([16ab5e4](https://github.com/microsoft/OpenAPI.NET/commit/16ab5e42bdef6e08e2afaf7ad3921ac8178f059c)) +* **securityscheme:** add oauth2MetadataUrl support (OpenAPI 3.2) ([4509488](https://github.com/microsoft/OpenAPI.NET/commit/4509488f2e8725e37a60a3b7a3a8a0b6c0c74378)) + + +### Bug Fixes + +* implement unevaluatedProperties as schema per JSON Schema 2020-12 ([#2728](https://github.com/microsoft/OpenAPI.NET/issues/2728)) ([7c13fb3](https://github.com/microsoft/OpenAPI.NET/commit/7c13fb3910685b5c17897cd7799b9ef1bba7f80d)) +* **library:** serialize additionalProperties schema in OpenAPI V2 ([f3165fa](https://github.com/microsoft/OpenAPI.NET/commit/f3165fa874a8bb76788684742492f48b20aab892)) +* **library:** serialize additionalProperties schema in OpenAPI V2 documents ([3d07756](https://github.com/microsoft/OpenAPI.NET/commit/3d0775610a9e74b6d5ce845195ccb935576bcd31)) +* optimize parsing V3.1 documents by reducing GetLocation method allocation on hot path([#2748](https://github.com/microsoft/OpenAPI.NET/issues/2748)) ([f690681](https://github.com/microsoft/OpenAPI.NET/commit/f6906811e616f8e6875b8d839137c846fc7bbd9e)) + +## [3.3.1](https://github.com/microsoft/OpenAPI.NET/compare/v3.3.0...v3.3.1) (2026-01-22) ### Features -* **models:** add shared Content interface ([80e4bbf](https://github.com/microsoft/OpenAPI.NET/commit/80e4bbfa4ab31d3af69fe29751714d001c1f9566)) * **models:** add shared Content interface ([#2695](https://github.com/microsoft/OpenAPI.NET/issues/2695)) ([338566f](https://github.com/microsoft/OpenAPI.NET/commit/338566fafce04ee1329f4ead61fe1e87e01144ad)) -* **models:** add shared Content interface ([#2695](https://github.com/microsoft/OpenAPI.NET/issues/2695)) ([80e4bbf](https://github.com/microsoft/OpenAPI.NET/commit/80e4bbfa4ab31d3af69fe29751714d001c1f9566)) -* **models:** support mutualTLS security scheme ([f9cf5b8](https://github.com/microsoft/OpenAPI.NET/commit/f9cf5b807d71c49e5bd7e2bec97f12d3b50ca180)) -## [2.5.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.4.3...v2.5.0) (2026-01-19) + +### Bug Fixes + +* broken binary compatibility due to interface changes in previous version ([d96bba7](https://github.com/microsoft/OpenAPI.NET/commit/d96bba72c383cd5db2b7032530aee3b4d944ebc6)) + +## [3.3.0](https://github.com/microsoft/OpenAPI.NET/compare/v3.2.0...v3.3.0) (2026-01-21) ### Features -* hidi validate command now logs warnings ([1d3d085](https://github.com/microsoft/OpenAPI.NET/commit/1d3d085e0278d9341d7bd10065eba584cb25773c)) -* hidi validate command now logs warnings ([18ed5ac](https://github.com/microsoft/OpenAPI.NET/commit/18ed5acce9661639e1698f19c194e520eb5c93c1)) +* **models:** add shared Content interface ([9e13b25](https://github.com/microsoft/OpenAPI.NET/commit/9e13b2574e68387ecc01c453b571208c40124b46)) +* **models:** add shared Content interface ([#2695](https://github.com/microsoft/OpenAPI.NET/issues/2695)) ([9e13b25](https://github.com/microsoft/OpenAPI.NET/commit/9e13b2574e68387ecc01c453b571208c40124b46)) +* **models:** support mutualTLS security scheme ([a4efdfe](https://github.com/microsoft/OpenAPI.NET/commit/a4efdfe43ee310fba4bb643d9fd28ce92da32338)) + +## [3.2.0](https://github.com/microsoft/OpenAPI.NET/compare/v3.1.3...v3.2.0) (2026-01-19) + + +### Features + +* hidi validate command now logs warnings ([76a3c0f](https://github.com/microsoft/OpenAPI.NET/commit/76a3c0fe33a6c953263d9d91669b2f1bab562a79)) +* hidi validate command now logs warnings ([62e7d56](https://github.com/microsoft/OpenAPI.NET/commit/62e7d56ac0863875999240d68a2766d2cc2d594c)) ### Bug Fixes -* discriminator property validation fails any/allOf cases when it shouldn't ([ff6e411](https://github.com/microsoft/OpenAPI.NET/commit/ff6e4115dcab8c893bbc6b97639fd620b50f105e)) -* discriminator property validation fails any/allOf cases when it shouldn't ([7def73d](https://github.com/microsoft/OpenAPI.NET/commit/7def73d774d1f0e96118e92b636e52cbea371f2d)) +* discriminator property validation fails any/allOf cases when it shouldn't ([fb6cecc](https://github.com/microsoft/OpenAPI.NET/commit/fb6cecccafd5713bc1eb22e0cf07619cf495ebb5)) +* discriminator property validation fails any/allOf cases when it shouldn't ([a8fb81c](https://github.com/microsoft/OpenAPI.NET/commit/a8fb81cf9524a3f2f721aa808db244434e1cd177)) -## [2.4.3](https://github.com/microsoft/OpenAPI.NET/compare/v2.4.2...v2.4.3) (2026-01-16) +## [3.1.3](https://github.com/microsoft/OpenAPI.NET/compare/v3.1.2...v3.1.3) (2026-01-16) ### Bug Fixes @@ -32,6 +187,69 @@ * Support custom tag ordering ([008576c](https://github.com/microsoft/OpenAPI.NET/commit/008576c31f8dcecf59363c9c2f85d691601faa73)) * Support custom tag ordering ([7610d07](https://github.com/microsoft/OpenAPI.NET/commit/7610d07bd11a99a4ce1cc31338d180dbd764d952)) +## [3.1.2](https://github.com/microsoft/OpenAPI.NET/compare/v3.1.1...v3.1.2) (2026-01-06) + +### Bug Fixes + +* correct error pointer when extension parser throws OpenApiException ([43c75a9](https://github.com/microsoft/OpenAPI.NET/commit/43c75a90746344fcc975611100e995fe4045edf0)) +* wrap extension parser calls in try-catch to ensure correct error pointers ([50b44aa](https://github.com/microsoft/OpenAPI.NET/commit/50b44aad12d8fa86a46f7f6d62896a7b1c344d2e)) + +## [3.1.1](https://github.com/microsoft/OpenAPI.NET/compare/v3.1.0...v3.1.1) (2025-12-18) + + +### Bug Fixes + +* **schema:** always serialize `additionalProperties: false` ([6651c36](https://github.com/microsoft/OpenAPI.NET/commit/6651c36ff341329c053776d65b36b1b7fa9dd3ea)) +* **schema:** always serialize `additionalProperties: false` ([e36fc95](https://github.com/microsoft/OpenAPI.NET/commit/e36fc9565bce42916eb7bf64d1f74d491dd1f407)) + +## [3.1.0](https://github.com/microsoft/OpenAPI.NET/compare/v3.0.3...v3.1.0) (2025-12-17) + +### Features + +* Add `type: "null"` downcasting when in oneOf and anyOf for OpenAPI v3 ([782cf8d](https://github.com/microsoft/OpenAPI.NET/commit/782cf8d1ff8166e3c7be706e08dabf168b9616a4)) + +## [3.0.3](https://github.com/microsoft/OpenAPI.NET/compare/v3.0.2...v3.0.3) (2025-12-16) + + +* load JSON documents that are preceded by multiple whitespace ([6461bac](https://github.com/microsoft/OpenAPI.NET/commit/6461bac01c4176424210e9ac249698f665a514a6)) +* non-seekable json streams would fail to load as a document ([2436d73](https://github.com/microsoft/OpenAPI.NET/commit/2436d7382bfbf8b9ba501d88f682e952bdf27146)) +* reading streams in an asp.net context would cause async exceptions ([f9e5248](https://github.com/microsoft/OpenAPI.NET/commit/f9e524859722476b3111cb6006f77208c2d1f526)) + +## [3.0.2](https://github.com/microsoft/OpenAPI.NET/compare/v3.0.1...v3.0.2) (2025-12-08) + +### Bug Fixes + +* additional properties serialization should not emit a schema in v2 ([946cba9](https://github.com/microsoft/OpenAPI.NET/commit/946cba992a2733a60182453e38722b4ed789b729)) +* additional properties serialization should not emit booleans in v3.1+ ([946cba9](https://github.com/microsoft/OpenAPI.NET/commit/946cba992a2733a60182453e38722b4ed789b729)) + +## [3.0.1](https://github.com/microsoft/OpenAPI.NET/compare/v3.0.0...v3.0.1) (2025-11-17) + +### Bug Fixes + +* empty strings should be quoted in yaml ([8d215f9](https://github.com/microsoft/OpenAPI.NET/commit/8d215f9ea8a780b1e2e8dd6cefb8d470cc35682d)) +* empty strings should be quoted in yaml ([0ca10db](https://github.com/microsoft/OpenAPI.NET/commit/0ca10db3bb9ffa937dd35862068926f3586d6991)) + +## [3.0.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.9...v3.0.0) (2025-11-11) + +### ⚠ BREAKING CHANGES + +* adds support for OpenAPI 3.2.0 + +> Note: Please refer to the [upgrade guide](https://github.com/microsoft/OpenAPI.NET/blob/main/docs/upgrade-guide-3.md) for a detailed description of the breaking changes. + +> Note: ASP.net users should remain on version 1.X for ASP.net < 10, and version 2.X for ASP.net 10, this new major version will be implemented in a future version of ASP.net, [more information](https://github.com/microsoft/OpenAPI.NET/blob/main/CONTRIBUTING.md#branches-and-support-policy) + +### Features + +* adds support for OpenAPI 3.2.0 ([765a8dd](https://github.com/microsoft/OpenAPI.NET/commit/765a8dd4d6efd1a31b6a76d282ccffa5877a845a)) + +## [2.4.3](https://github.com/microsoft/OpenAPI.NET/compare/v2.4.2...v2.4.3) (2026-01-16) + +## Bug Fixes + +* Support custom tag ordering ([008576c](https://github.com/microsoft/OpenAPI.NET/commit/008576c31f8dcecf59363c9c2f85d691601faa73)) +* Support custom tag ordering ([7610d07](https://github.com/microsoft/OpenAPI.NET/commit/7610d07bd11a99a4ce1cc31338d180dbd764d952)) + ## [2.4.2](https://github.com/microsoft/OpenAPI.NET/compare/v2.4.1...v2.4.2) (2025-12-22) @@ -42,7 +260,6 @@ ## [2.4.1](https://github.com/microsoft/OpenAPI.NET/compare/v2.4.0...v2.4.1) (2025-12-18) - ### Bug Fixes * **schema:** always serialize `additionalProperties: false` ([6651c36](https://github.com/microsoft/OpenAPI.NET/commit/6651c36ff341329c053776d65b36b1b7fa9dd3ea)) @@ -50,14 +267,12 @@ ## [2.4.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.12...v2.4.0) (2025-12-17) - ### Features * Add `type: "null"` downcasting when in oneOf and anyOf for OpenAPI v3 ([782cf8d](https://github.com/microsoft/OpenAPI.NET/commit/782cf8d1ff8166e3c7be706e08dabf168b9616a4)) ## [2.3.12](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.11...v2.3.12) (2025-12-15) - ### Bug Fixes * load JSON documents that are preceded by multiple whitespace ([640e59a](https://github.com/microsoft/OpenAPI.NET/commit/640e59a143a2a6d3b79c9f6a97a6029593d7dd8f)) @@ -67,7 +282,6 @@ ## [2.3.11](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.10...v2.3.11) (2025-12-08) - ### Bug Fixes * additional properties serialization should not emit a schema in v2 ([946cba9](https://github.com/microsoft/OpenAPI.NET/commit/946cba992a2733a60182453e38722b4ed789b729)) @@ -76,15 +290,11 @@ ## [2.3.10](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.9...v2.3.10) (2025-11-17) - -### Bug Fixes - * empty strings should be quoted in yaml ([e919b33](https://github.com/microsoft/OpenAPI.NET/commit/e919b33e9d09159217066248483ef4c767865c82)) * empty strings should be quoted in yaml ([0ca10db](https://github.com/microsoft/OpenAPI.NET/commit/0ca10db3bb9ffa937dd35862068926f3586d6991)) ## [2.3.9](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.8...v2.3.9) (2025-11-06) - ### Bug Fixes * a bug where null sentinel value would appear in YAML documents ([0e864c7](https://github.com/microsoft/OpenAPI.NET/commit/0e864c73791b8610a95f06da9fbb44bfa1cf75a9)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a08924c7b..7719a3839 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ OpenAPI.net is a mono-repo containing source code for the following packages: | Library | NuGet Release | |----------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [Microsoft.OpenAPI](./src/Microsoft.OpenAPI/README.md) | [![NuGet Version](https://img.shields.io/nuget/vpre/Microsoft.OpenAPI?label=Latest&logo=nuget)](https://www.nuget.org/packages/Microsoft.OpenAPI/) | -| [Microsoft.OpenAPI.Readers](./src/Microsoft.OpenAPI.Readers/README.md) | [![NuGet Version](https://img.shields.io/nuget/vpre/Microsoft.OpenAPI.Readers?label=Latest&logo=nuget)](https://www.nuget.org/packages/Microsoft.OpenAPI.Readers/) | +| [Microsoft.OpenAPI.YamlReader](./src/Microsoft.OpenApi.YamlReader/README.md) | [![NuGet Version](https://img.shields.io/nuget/vpre/Microsoft.OpenAPI.YamlReader?label=Latest&logo=nuget)](https://www.nuget.org/packages/Microsoft.OpenAPI.YamlReader/) | | [Microsoft.OpenAPI.Hidi](./src/Microsoft.OpenAPI.Hidi/README.md) | [![NuGet Version](https://img.shields.io/nuget/vpre/Microsoft.OpenAPI.Hidi?label=Latest&logo=nuget)](https://www.nuget.org/packages/Microsoft.OpenAPI.Hidi/) | OpenAPI.net is open to contributions. There are a couple of different recommended paths to get contributions into the released version of this library. @@ -20,7 +20,32 @@ The best way to get started with a contribution is to start a dialog with the ow ## Submit pull requests for bug fixes and features -Feel free to submit a pull request with a linked issue against the __main__ branch. The main branch will be updated frequently. +Feel free to submit a pull request with a linked issue. + +### Branches and support policy + +Because one major consumer of these libraries is ASP.net, the support policy of this repository is aligned with [dotnet support policy](https://dotnet.microsoft.com/platform/support/policy/dotnet-core#lifecycle). + +The following table outlines the mapping between package major versions, dotnet versions, and which contributions are accepted. As a consumer, make sure the version of this library your application is using is aligned with the version of ASP.net described in the table below. + +| Major version | Branch | Supported [AspNetCore OpenAPI versions](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi) | Supported [Swashbuckle.AspNetCore version](https://www.nuget.org/packages/Swashbuckle.AspNetCore/) | Supported OpenAPI versions | Changes provided by Microsoft | Accepted contributions | End of support date | +| ------------- | ---------- | -------------------------- | ---------- | -------------------------- | ------------------------------------------- | ------------------------------------------- | --------------- | +| 1.X | support/v1 | < 10 | < 10 | 2.0, 3.0 | security fixes | security and bugfixes | .NET 9 (Nov 2026) | +| 2.X | support/v2 | = 10 ¹ | = 10 ³ | 2.0, 3.0, 3.1 | security and bugfixes | security and bugfixes | .NET 10 (Nov 2028) ¹ | +| 3.X ² | main | not available | not available | 2.0, 3.0, 3.1, 3.2 | security, bugfixes and feature improvements | security, bugfixes and feature improvements | TBD | + +> Notes: +> +> 1. This assumes that AspNetCore OpenAPI version 11 and above will adopt version 3 or above of this library, otherwise, it'd expand the support date for version 2 of this library. +> 2. This will be conditioned by new releases of OpenAPI, this library, ASP.NET and AspNetCore OpenAPI's adoption of new versions of this library. +> 3. This assumes that Swashbuckle.AspNetCore version 11 and above will adopt version 3 or above of this library. + +### Multi-versions requirement for contributions + +When contributing to the library, start by making a contribution to the main branch first, or the uppermost version it applies to. During the review process you'll be asked to demonstrate your contribution cannot apply to prior versions or to port your contribution to the branches for prior versions before the initial pull request can get merged. + +This approach helps maintain a similar behavior across all versions under active support. + ## Commit message format To support our automated release process, pull requests are required to follow the [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/) @@ -49,4 +74,53 @@ The recommended commit types used are: - __ci__ for CI configuration file changes e.g. updating a pipeline - __chore__ for miscallaneous non-sdk changesin the repo e.g. removing an unused file -Adding an exclamation mark after the commit type (`feat!`) or footer with the prefix __BREAKING CHANGE:__ will cause an increment of the _major_ version. \ No newline at end of file +Adding an exclamation mark after the commit type (`feat!`) or footer with the prefix __BREAKING CHANGE:__ will cause an increment of the _major_ version. + +## Updates to public API surface + +Because we need to maintain a compatible public API surface within a major version, this project is using the public API analyzers to ensure no prior public API is changed/removed inadvertently. + +This means that: + +- All entries in an __Unshipped__ document need to be moved to the __Shipped__ document before any public release. +- All new APIs being added need to be __Unshipped__ document before the pull request can be merged, otherwise build will fail with a message like the example below. + +```txt +Error: /home/runner/work/OpenAPI.NET/OpenAPI.NET/src/Microsoft.OpenApi/Models/OpenApiSecurityScheme.cs(39,46): error RS0016: Symbol 'OAuth2MetadataUrl.set' is not part of the declared public API (https://github.com/dotnet/roslyn-analyzers/blob/main/src/PublicApiAnalyzers/PublicApiAnalyzers.Help.md) [/home/runner/work/OpenAPI.NET/OpenAPI.NET/src/Microsoft.OpenApi/Microsoft.OpenApi.csproj::TargetFramework=net8.0] +``` + +### Update the unshipped document + +To update the unshipped document, simply run the following commands + +```shell +# add the missing public api entries +dotnet format --diagnostics RS0016 +# discard changes to cs files to avoid creating conflicts +git checkout *.cs +``` + +### Move items from unshipped to unshipped document + +```pwsh +. ./scripts/promoteUnshipped.ps1 +``` + +> Note: the promotion of APIs is automated through the dedicated workflow and should result in pull requests being automatically opened. + +## Updating the benchmark information + +To ensure performance of the library does not degrade over time, we have continuous benchmarks running. You might see the continuous integration failing if your pull request changed any model under __src/Microsoft.OpenApi/Models__. + +```txt +Benchmark result for EmptyApiSchema does not match the existing benchmark result (original!=new). Allocated bytes differ: 408 != 416 +``` + +To update the benchmarks, run the following script: + +```shell +cd performance/benchmark +dotnet run -c Release +``` + +Then commit the report files using a "chore" commit. diff --git a/Directory.Build.props b/Directory.Build.props index 76cd2b183..aec9507b2 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,13 +12,13 @@ https://github.com/Microsoft/OpenAPI.NET © Microsoft Corporation. All rights reserved. OpenAPI .NET - 2.6.0 + 3.9.0 true - + \ No newline at end of file diff --git a/Microsoft.OpenApi.sln b/Microsoft.OpenApi.sln deleted file mode 100644 index b91029eca..000000000 --- a/Microsoft.OpenApi.sln +++ /dev/null @@ -1,103 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.1.32210.238 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi", "src\Microsoft.OpenApi\Microsoft.OpenApi.csproj", "{A8E50143-69B2-472A-9D45-3F9A05D13202}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4AEDAD90-F854-4940-BFEE-6374CC92CAB0}" - ProjectSection(SolutionItems) = preProject - .editorconfig = .editorconfig - build.cmd = build.cmd - readme.md = readme.md - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi.Workbench", "src\Microsoft.OpenApi.Workbench\Microsoft.OpenApi.Workbench.csproj", "{6A5E91E5-0441-46EE-AEB9-8334981B7F08}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi.YamlReader", "src\Microsoft.OpenApi.YamlReader\Microsoft.OpenApi.YamlReader.csproj", "{79933258-0126-4382-8755-D50820ECC483}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi.Tests", "test\Microsoft.OpenApi.Tests\Microsoft.OpenApi.Tests.csproj", "{AD83F991-DBF3-4251-8613-9CC54C826964}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi.Readers.Tests", "test\Microsoft.OpenApi.Readers.Tests\Microsoft.OpenApi.Readers.Tests.csproj", "{1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E546B92F-20A8-49C3-8323-4B25BB78F3E1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6357D7FD-2DE4-4900-ADB9-ABC37052040A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.OpenApi.Trimming.Tests", "test\Microsoft.OpenApi.Trimming.Tests\Microsoft.OpenApi.Trimming.Tests.csproj", "{1D2E0C6E-B103-4CB6-912E-D56FA1501296}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.OpenApi.Hidi", "src\Microsoft.OpenApi.Hidi\Microsoft.OpenApi.Hidi.csproj", "{538936B4-5E14-4EA3-9FD0-F43E2DD014FB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.OpenApi.Hidi.Tests", "test\Microsoft.OpenApi.Hidi.Tests\Microsoft.OpenApi.Hidi.Tests.csproj", "{6ADC5D41-EDD2-4206-B815-5DFF739C6832}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PerformanceTests", "performance\benchmark\PerformanceTests.csproj", "{537E49E3-325E-40EE-A90E-7556D4D333AA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "performance", "performance", "{4BB7E3F7-CA7E-45D3-B5AC-5DBB510FD528}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "resultsComparer", "performance\resultsComparer\resultsComparer.csproj", "{5EEA836B-3E08-4BE1-82B8-5236D031B497}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A8E50143-69B2-472A-9D45-3F9A05D13202}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A8E50143-69B2-472A-9D45-3F9A05D13202}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A8E50143-69B2-472A-9D45-3F9A05D13202}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A8E50143-69B2-472A-9D45-3F9A05D13202}.Release|Any CPU.Build.0 = Release|Any CPU - {6A5E91E5-0441-46EE-AEB9-8334981B7F08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6A5E91E5-0441-46EE-AEB9-8334981B7F08}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6A5E91E5-0441-46EE-AEB9-8334981B7F08}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6A5E91E5-0441-46EE-AEB9-8334981B7F08}.Release|Any CPU.Build.0 = Release|Any CPU - {79933258-0126-4382-8755-D50820ECC483}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {79933258-0126-4382-8755-D50820ECC483}.Debug|Any CPU.Build.0 = Debug|Any CPU - {79933258-0126-4382-8755-D50820ECC483}.Release|Any CPU.ActiveCfg = Release|Any CPU - {79933258-0126-4382-8755-D50820ECC483}.Release|Any CPU.Build.0 = Release|Any CPU - {AD83F991-DBF3-4251-8613-9CC54C826964}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD83F991-DBF3-4251-8613-9CC54C826964}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD83F991-DBF3-4251-8613-9CC54C826964}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD83F991-DBF3-4251-8613-9CC54C826964}.Release|Any CPU.Build.0 = Release|Any CPU - {1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237}.Release|Any CPU.Build.0 = Release|Any CPU - {1D2E0C6E-B103-4CB6-912E-D56FA1501296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1D2E0C6E-B103-4CB6-912E-D56FA1501296}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1D2E0C6E-B103-4CB6-912E-D56FA1501296}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1D2E0C6E-B103-4CB6-912E-D56FA1501296}.Release|Any CPU.Build.0 = Release|Any CPU - {538936B4-5E14-4EA3-9FD0-F43E2DD014FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {538936B4-5E14-4EA3-9FD0-F43E2DD014FB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {538936B4-5E14-4EA3-9FD0-F43E2DD014FB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {538936B4-5E14-4EA3-9FD0-F43E2DD014FB}.Release|Any CPU.Build.0 = Release|Any CPU - {6ADC5D41-EDD2-4206-B815-5DFF739C6832}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6ADC5D41-EDD2-4206-B815-5DFF739C6832}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6ADC5D41-EDD2-4206-B815-5DFF739C6832}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6ADC5D41-EDD2-4206-B815-5DFF739C6832}.Release|Any CPU.Build.0 = Release|Any CPU - {537E49E3-325E-40EE-A90E-7556D4D333AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {537E49E3-325E-40EE-A90E-7556D4D333AA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {537E49E3-325E-40EE-A90E-7556D4D333AA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {537E49E3-325E-40EE-A90E-7556D4D333AA}.Release|Any CPU.Build.0 = Release|Any CPU - {5EEA836B-3E08-4BE1-82B8-5236D031B497}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5EEA836B-3E08-4BE1-82B8-5236D031B497}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5EEA836B-3E08-4BE1-82B8-5236D031B497}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5EEA836B-3E08-4BE1-82B8-5236D031B497}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {A8E50143-69B2-472A-9D45-3F9A05D13202} = {E546B92F-20A8-49C3-8323-4B25BB78F3E1} - {6A5E91E5-0441-46EE-AEB9-8334981B7F08} = {E546B92F-20A8-49C3-8323-4B25BB78F3E1} - {79933258-0126-4382-8755-D50820ECC483} = {E546B92F-20A8-49C3-8323-4B25BB78F3E1} - {AD83F991-DBF3-4251-8613-9CC54C826964} = {6357D7FD-2DE4-4900-ADB9-ABC37052040A} - {1ED3C2C1-E1E7-4925-B4E6-2D969C3F5237} = {6357D7FD-2DE4-4900-ADB9-ABC37052040A} - {1D2E0C6E-B103-4CB6-912E-D56FA1501296} = {6357D7FD-2DE4-4900-ADB9-ABC37052040A} - {538936B4-5E14-4EA3-9FD0-F43E2DD014FB} = {E546B92F-20A8-49C3-8323-4B25BB78F3E1} - {6ADC5D41-EDD2-4206-B815-5DFF739C6832} = {6357D7FD-2DE4-4900-ADB9-ABC37052040A} - {5EEA836B-3E08-4BE1-82B8-5236D031B497} = {4BB7E3F7-CA7E-45D3-B5AC-5DBB510FD528} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9F171EFC-0DB5-4B10-ABFA-AF48D52CC565} - EndGlobalSection -EndGlobal diff --git a/Microsoft.OpenApi.slnx b/Microsoft.OpenApi.slnx new file mode 100644 index 000000000..f764776bf --- /dev/null +++ b/Microsoft.OpenApi.slnx @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md index 99d0a1aee..3c77f909f 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ Project Objectives: - Install core Nuget package [**Microsoft.OpenApi**](https://www.nuget.org/packages/Microsoft.OpenApi) - Install Yaml Reader Nuget package [**Microsoft.OpenApi.YamlReader**](https://www.nuget.org/packages/Microsoft.OpenApi.YamlReader) -> Note: we just released a new major version of the library, which brings support for OpenAPI 3.1! -> You can read more about the changes of this upcoming version [in the upgrade guide](./docs/upgrade-guide-2.md). +> Note: we just released a new major version of the library, which brings support for OpenAPI 3.2! +> You can read more about the changes of this upcoming version [in the upgrade guide](./docs/upgrade-guide-3.md). # Processors The OpenAPI.NET project holds the base object model for representing OpenAPI documents as .NET objects. Some developers have found the need to write processors that convert other data formats into this OpenAPI.NET object model. We'd like to curate that list of processors in this section of the readme. @@ -98,7 +98,7 @@ In order to test the validity of an OpenApi document, we avail the following too #### Installation guidelines: 1. Clone the repo locally by running this command: `git clone https://github.com/microsoft/OpenAPI.NET.git` - 2. Open the solution file `(.sln)` in the root of the project with Visual Studio + 2. Open the solution file `(.slnx)` in the root of the project with Visual Studio 3. Navigate to the `src/Microsoft.OpenApi.Workbench` directory and set it as the startup project 4. Run the project and you'll see a GUI pop up resembling the one below: diff --git a/build.cmd b/build.cmd index 43cc95956..07daf7b6c 100644 --- a/build.cmd +++ b/build.cmd @@ -6,9 +6,9 @@ dotnet msbuild %PROJ% /t:restore /p:Configuration=Release dotnet msbuild %PROJ% /t:build /p:Configuration=Release dotnet msbuild %PROJ% /t:pack /p:Configuration=Release;PackageOutputPath=%~dp0artifacts -Echo Building Microsoft.OpenApi.Readers +Echo Building Microsoft.OpenApi.YamlReader -SET PROJ=%~dp0src\Microsoft.OpenApi.Readers\Microsoft.OpenApi.Readers.csproj +SET PROJ=%~dp0src\Microsoft.OpenApi.YamlReader\Microsoft.OpenApi.YamlReader.csproj dotnet msbuild %PROJ% /t:restore /p:Configuration=Release dotnet msbuild %PROJ% /t:build /p:Configuration=Release dotnet msbuild %PROJ% /t:pack /p:Configuration=Release;PackageOutputPath=%~dp0artifacts diff --git a/build.sh b/build.sh index e716aa272..0de30b6df 100755 --- a/build.sh +++ b/build.sh @@ -7,9 +7,9 @@ dotnet msbuild "$PROJ" /t:restore /p:Configuration=Release dotnet msbuild "$PROJ" /t:build /p:Configuration=Release dotnet msbuild "$PROJ" /t:pack "/p:Configuration=Release;PackageOutputPath=$(dirname "$0")/artifacts" -echo "Building Microsoft.OpenApi.Readers" +echo "Building Microsoft.OpenApi.YamlReader" -PROJ="$(dirname "$0")/src/Microsoft.OpenApi.Readers/Microsoft.OpenApi.Readers.csproj" +PROJ="$(dirname "$0")/src/Microsoft.OpenApi.YamlReader/Microsoft.OpenApi.YamlReader.csproj" dotnet msbuild "$PROJ" /t:restore /p:Configuration=Release dotnet msbuild "$PROJ" /t:build /p:Configuration=Release dotnet msbuild "$PROJ" /t:pack "/p:Configuration=Release;PackageOutputPath=$(dirname "$0")/artifacts" diff --git a/docs/upgrade-guide-2.md b/docs/upgrade-guide-2.md index 5546e4896..752b60c95 100644 --- a/docs/upgrade-guide-2.md +++ b/docs/upgrade-guide-2.md @@ -12,7 +12,15 @@ We are excited to announce the new version of the OpenAPI.NET library! OpenAPI.NET v2 is a major update to the OpenAPI.NET library. This release includes a number of performance improvements, API enhancements, and support for OpenAPI v3.1. > [!WARNING] -> If you are using this library with ASP.NET Core version `< 10.0` then you must remain on version `1.x` as it's not compatible. +> This is a major version update that includes breaking changes. Please review this guide carefully before upgrading. + +## Integrations with ASP.NET Core + +If you are using this library with [AspNetCore OpenAPI versions](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi) `< 10.0` then you must remain on version `1.x` as it's not compatible with version 2 or above of this library. + +If you are using this library with [Swashbuckle.AspNetCore version](https://www.nuget.org/packages/Swashbuckle.AspNetCore/) `< 10.0` then you must remain on version `1.x` as it's not compatible with version 2 or above of this library. + +The latest support policy information for this library, and integration with ASP.NET Core can be found on [the contributing documentation](https://github.com/microsoft/OpenAPI.NET/blob/main/CONTRIBUTING.md#branches-and-support-policy). ## The biggest update ever @@ -24,7 +32,7 @@ One of the key features of OpenAPI.NET is its performance. This version makes it In v1, instances of `$ref` were resolved in a second pass of the document to ensure the target of the reference has been parsed before attempting to resolve it. In v2, reference targets are lazily resolved when reference objects are accessed. This improves load time performance for documents that make heavy use of references. -[How does this change the behavior of external references?] +Because references are lazily loaded and depend on the workspace context, loading a document with unresolved references (internal or external) does not lead to an exception being thrown anymore. Instead warnings are logged in the diagnostics object. This gives you an opportunity to load additional documents in the workspace if needed, [more information](#component-registration-in-a-documents-workspace). ### Results diff --git a/docs/upgrade-guide-3.md b/docs/upgrade-guide-3.md new file mode 100644 index 000000000..49e467d24 --- /dev/null +++ b/docs/upgrade-guide-3.md @@ -0,0 +1,398 @@ +# Upgrade guide to OpenAPI.NET 3.0 + +## Introduction + +We are excited to announce OpenAPI.NET v3.0! This major update introduces support for OpenAPI v3.2 specification along with several API enhancements and refinements to the existing model architecture. + +> [!WARNING] +> This is a major version update that includes breaking changes. Please review this guide carefully before upgrading. + +## Integrations with ASP.NET Core + +If you are using this library with [AspNetCore OpenAPI versions](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi) `< 10.0` then you must remain on version `1.x` as it's not compatible with version 3 or above of this library. + +If you are using this library with [AspNetCore OpenAPI versions](https://www.nuget.org/packages/Microsoft.AspNetCore.OpenApi) `= 10.X` then you must remain on version `2.x` as it's not compatible with version 3 or above of this library. + +If you are using this library with [Swashbuckle.AspNetCore version](https://www.nuget.org/packages/Swashbuckle.AspNetCore/) `< 10.0` then you must remain on version `1.x` as it's not compatible with version 3 or above of this library. + +If you are using this library with [Swashbuckle.AspNetCore version](https://www.nuget.org/packages/Swashbuckle.AspNetCore/) `= 10.X` then you must remain on version `2.x` as it's not compatible with version 3 or above of this library. + +The latest support policy information for this library, and integration with ASP.NET Core can be found on [the contributing documentation](https://github.com/microsoft/OpenAPI.NET/blob/main/CONTRIBUTING.md#branches-and-support-policy). + +## OpenAPI v3.2 Support + +The primary focus of OpenAPI.NET v3.0 is adding comprehensive support for OpenAPI specification v3.2. This includes new serialization methods, enhanced model properties, and expanded functionality across the entire API surface. + +### New Serialization Methods + +All serializable components now include a `SerializeAsV32` method alongside the existing serialization methods: + +```csharp +// v2.x +document.SerializeAsV31(writer); + +// v3.0 +document.SerializeAsV31(writer); +document.SerializeAsV32(writer); // New! +``` + +### OpenApiSpecVersion Enum Update + +A new version constant has been added: + +```csharp +public enum OpenApiSpecVersion +{ + OpenApi2_0 = 0, + OpenApi3_0 = 1, + OpenApi3_1 = 2, + OpenApi3_2 = 3, // New! +} +``` + +## Enhanced Media Type Support + +### IOpenApiMediaType Interface + +Media types are now represented by the `IOpenApiMediaType` interface, providing better abstraction and consistency across the API: + +```csharp +// v2.x +public IDictionary? Content { get; set; } + +// v3.0 +public IDictionary? Content { get; set; } +``` + +### New Media Type Properties + +The `IOpenApiMediaType` interface includes additional properties for enhanced functionality: + +```csharp +public interface IOpenApiMediaType +{ + IDictionary? Encoding { get; } + JsonNode? Example { get; } + IDictionary? Examples { get; } + OpenApiEncoding? ItemEncoding { get; } // New! + IOpenApiSchema? ItemSchema { get; } // New! + IList? PrefixEncoding { get; } // New! + IOpenApiSchema? Schema { get; } +} +``` + +### MediaTypes in Components + +Components now support reusable media types: + +```csharp +public class OpenApiComponents +{ + public IDictionary? MediaTypes { get; set; } // New! + // ... other existing properties +} +``` + +## Enhanced Example Support + +### New Example Properties + +Example objects now support additional data representation options: + +```csharp +public class OpenApiExample : IOpenApiExample +{ + public JsonNode? DataValue { get; set; } // New! + public string? SerializedValue { get; set; } // New! + public string? ExternalValue { get; set; } + public JsonNode? Value { get; set; } + // ... other properties +} +``` + +## Security Scheme Enhancements + +### Deprecated Property + +Security schemes now support a deprecated flag: + +```csharp +public interface IOpenApiSecurityScheme +{ + bool Deprecated { get; } // New! + // ... other existing properties +} +``` + +### Device Authorization Flow + +OAuth flows now support device authorization: + +```csharp +public class OpenApiOAuthFlows +{ + public OpenApiOAuthFlow? DeviceAuthorization { get; set; } // New! + // ... other existing flows +} + +public class OpenApiOAuthFlow +{ + public Uri? DeviceAuthorizationUrl { get; set; } // New! + // ... other existing properties +} +``` + +## Tag System Improvements + +### Hierarchical Tags + +Tags now support hierarchical organization with enhanced metadata: + +```csharp +public interface IOpenApiTag +{ + string? Kind { get; } // New! + string? Summary { get; } // New! + OpenApiTagReference? Parent { get; } // New! + string? Name { get; } + // ... other existing properties +} +``` + +## Response Enhancements + +### Summary Support + +Responses now implement `IOpenApiSummarizedElement` and support summary text: + +```csharp +// v2.x +public interface IOpenApiResponse : IOpenApiDescribedElement, ... +{ + // No summary support +} + +// v3.0 +public interface IOpenApiResponse : IOpenApiDescribedElement, + IOpenApiSummarizedElement, ... // New! +{ + // Inherits Summary property from IOpenApiSummarizedElement +} +``` + +## XML Improvements + +### Enhanced Node Type Support + +The XML object has been refactored to use a more flexible node type system: + +```csharp +// v2.x +public class OpenApiXml +{ + public bool Attribute { get; set; } // Removed! + public bool Wrapped { get; set; } // Removed! +} + +// v3.0 +public class OpenApiXml +{ + public OpenApiXmlNodeType? NodeType { get; set; } // New! +} + +public enum OpenApiXmlNodeType +{ + Element = 0, + Attribute = 1, + Text = 2, + Cdata = 3, + None = 4, +} +``` + +## Discriminator Enhancements + +### Default Mapping Support + +Discriminators now support default mapping scenarios: + +```csharp +public class OpenApiDiscriminator +{ + public OpenApiSchemaReference? DefaultMapping { get; set; } // New! + // ... other existing properties +} +``` + +## Document Enhancements + +### Self-Reference Support + +Documents can now specify their own identity URI: + +```csharp +public class OpenApiDocument +{ + public Uri? Self { get; set; } // New! + // ... other existing properties +} +``` + +## Parameter Location Enhancements + +### New Parameter Locations + +Additional parameter locations are now supported: + +```csharp +public enum ParameterLocation +{ + Query = 0, + Header = 1, + Path = 2, + Cookie = 3, + QueryString = 4, // New! +} +``` + +### New Parameter Styles + +```csharp +public enum ParameterStyle +{ + Matrix = 0, + Label = 1, + Form = 2, + Simple = 3, + SpaceDelimited = 4, + PipeDelimited = 5, + DeepObject = 6, + Cookie = 7, // New! +} +``` + +## Reference Type Enhancements + +### New Reference Types + +```csharp +public enum ReferenceType +{ + Schema = 0, + Response = 1, + Parameter = 2, + Example = 3, + RequestBody = 4, + Header = 5, + SecurityScheme = 6, + Link = 7, + Callback = 8, + Tag = 9, + PathItem = 10, + MediaType = 11, // New! +} +``` + +## Visitor Pattern Updates + +### Interface-Based Visiting + +The visitor pattern now works with interface types for better abstraction: + +```csharp +// v2.x +public virtual void Visit(OpenApiMediaType mediaType) { } + +// v3.0 +public virtual void Visit(IOpenApiMediaType mediaType) { } +``` + +## Version Detection + +### New Version Detection Method + +```csharp +public static class VersionService +{ + public static bool is3_2(this string version) { } // New! + // ... other existing version methods +} +``` + +## Migration Steps + +### 1. Update Media Type References + +Replace concrete `OpenApiMediaType` references with `IOpenApiMediaType`: + +```csharp +// Before +public IDictionary? Content { get; set; } + +// After +public IDictionary? Content { get; set; } +``` + +### 2. Update XML Object Usage + +Replace boolean properties with the new enum-based approach: + +```csharp +// Before +var xml = new OpenApiXml +{ + Attribute = true, + Wrapped = false +}; + +// After +var xml = new OpenApiXml +{ + NodeType = OpenApiXmlNodeType.Attribute +}; +``` + +### 3. Update Visitor Implementations + +Update visitor methods to use interface types: + +```csharp +// Before +public override void Visit(OpenApiMediaType mediaType) { /* ... */ } + +// After +public override void Visit(IOpenApiMediaType mediaType) { /* ... */ } +``` + +### 4. Add v3.2 Serialization Support + +If you have custom serialization logic, add support for v3.2: + +```csharp +public void SerializeAsV32(IOpenApiWriter writer) +{ + // Implement v3.2 specific serialization + SerializeInternal(writer, OpenApiSpecVersion.OpenApi3_2); +} +``` + +## Breaking Changes Summary + +1. **Media Type Abstraction**: `OpenApiMediaType` replaced with `IOpenApiMediaType` interface in collection properties +2. **XML Object Refactoring**: `Attribute` and `Wrapped` boolean properties replaced with `NodeType` enum +3. **Visitor Pattern**: Methods now accept interface types instead of concrete types +4. **Response Interface**: `IOpenApiResponse` now extends `IOpenApiSummarizedElement` + +## New Features Summary + +1. **OpenAPI v3.2 Support**: Full serialization and model support +2. **Enhanced Media Types**: New properties for encoding and schema support +3. **Hierarchical Tags**: Support for tag organization with kind, summary, and parent relationships +4. **Security Enhancements**: Deprecated flag and device authorization flow support +5. **Enhanced Examples**: New data value and serialized value properties +6. **Document Self-Reference**: Support for document identity URIs +7. **Extended Parameter Support**: New locations and styles for parameters + +## Feedback + +If you have any feedback please file [a new GitHub issue](https://github.com/microsoft/OpenAPI.NET/issues). The team looks forward to hearing about your experience with OpenAPI.NET v3.0 and OpenAPI v3.2 support! diff --git a/global.json b/global.json index 4c2f00caf..d0c1ec64c 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "8.0.415" + "version": "10.0.302" } } \ No newline at end of file diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md index 3f182cfb6..2abba8670 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md @@ -1,18 +1,20 @@ ``` -BenchmarkDotNet v0.15.4, Windows 11 (10.0.26200.6899) -11th Gen Intel Core i7-1185G7 3.00GHz, 1 CPU, 8 logical and 4 physical cores -.NET SDK 8.0.415 - [Host] : .NET 8.0.21 (8.0.21, 8.0.2125.47513), X64 RyuJIT x86-64-v4 - ShortRun : .NET 8.0.21 (8.0.21, 8.0.2125.47513), X64 RyuJIT x86-64-v4 +BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat) +AMD EPYC 7763 2.45GHz, 1 CPU, 4 logical and 2 physical cores +.NET SDK 10.0.301 + [Host] : .NET 8.0.28 (8.0.28, 8.0.2826.26413), X64 RyuJIT x86-64-v3 + ShortRun : .NET 8.0.28 (8.0.28, 8.0.2826.26413), X64 RyuJIT x86-64-v3 Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3 ``` -| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | -|------------- |-------------:|--------------:|-------------:|-----------:|-----------:|----------:|-------------:| -| PetStoreYaml | 407.7 μs | 134.55 μs | 7.38 μs | 58.5938 | 7.8125 | - | 360.8 KB | -| PetStoreJson | 166.3 μs | 23.12 μs | 1.27 μs | 36.1328 | 6.8359 | - | 222.95 KB | -| GHESYaml | 896,578.2 μs | 138,441.39 μs | 7,588.44 μs | 60000.0000 | 23000.0000 | 4000.0000 | 345015.7 KB | -| GHESJson | 432,991.2 μs | 243,041.11 μs | 13,321.90 μs | 33000.0000 | 12000.0000 | 2000.0000 | 206538.29 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------- |---------------:|--------------:|-------------:|-----------:|-----------:|----------:|-------------:| +| PetStoreYaml | 582.2 μs | 208.61 μs | 11.43 μs | 19.5313 | 3.9063 | - | 375.68 KB | +| PetStoreJson | 252.3 μs | 29.46 μs | 1.61 μs | 11.7188 | 1.9531 | - | 209.67 KB | +| GHESYaml | 1,005,560.1 μs | 211,112.24 μs | 11,571.77 μs | 22000.0000 | 18000.0000 | 3000.0000 | 311035.48 KB | +| GHESJson | 369,047.2 μs | 94,799.88 μs | 5,196.30 μs | 9000.0000 | 8000.0000 | 2000.0000 | 140644.21 KB | +| GHESNextYaml | 1,241,432.6 μs | 106,390.00 μs | 5,831.60 μs | 34000.0000 | 19000.0000 | 3000.0000 | 513301.23 KB | +| GHESNextJson | 626,499.0 μs | 70,802.74 μs | 3,880.94 μs | 22000.0000 | 10000.0000 | 2000.0000 | 345119.94 KB | diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv index 36925dad9..316be68f2 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv @@ -1,5 +1,7 @@ Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Gen0,Gen1,Gen2,Allocated -PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,407.7 μs,134.55 μs,7.38 μs,58.5938,7.8125,0.0000,360.8 KB -PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,166.3 μs,23.12 μs,1.27 μs,36.1328,6.8359,0.0000,222.95 KB -GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"896,578.2 μs","138,441.39 μs","7,588.44 μs",60000.0000,23000.0000,4000.0000,345015.7 KB -GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,11111111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"432,991.2 μs","243,041.11 μs","13,321.90 μs",33000.0000,12000.0000,2000.0000,206538.29 KB +PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,582.2 μs,208.61 μs,11.43 μs,19.5313,3.9063,0.0000,375.68 KB +PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,252.3 μs,29.46 μs,1.61 μs,11.7188,1.9531,0.0000,209.67 KB +GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,005,560.1 μs","211,112.24 μs","11,571.77 μs",22000.0000,18000.0000,3000.0000,311035.48 KB +GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"369,047.2 μs","94,799.88 μs","5,196.30 μs",9000.0000,8000.0000,2000.0000,140644.21 KB +GHESNextYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,241,432.6 μs","106,390.00 μs","5,831.60 μs",34000.0000,19000.0000,3000.0000,513301.23 KB +GHESNextJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"626,499.0 μs","70,802.74 μs","3,880.94 μs",22000.0000,10000.0000,2000.0000,345119.94 KB diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html index 39bab3925..95b1dadc6 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html @@ -2,7 +2,7 @@ -performance.Descriptions-20251023-154034 +performance.Descriptions-20260714-121715