diff --git a/.azure-pipelines/ci-build.yml b/.azure-pipelines/ci-build.yml index c916a3bc6..8921e7112 100644 --- a/.azure-pipelines/ci-build.yml +++ b/.azure-pipelines/ci-build.yml @@ -7,6 +7,7 @@ trigger: include: - main - support/v1 + - support/v2 tags: include: - 'v*' @@ -15,6 +16,7 @@ pr: include: - main - support/v1 + - support/v2 variables: buildPlatform: 'Any CPU' @@ -49,6 +51,10 @@ extends: displayName: 'Publish Artifact: Nugets' artifactName: Nugets targetPath: '$(Build.ArtifactStagingDirectory)/Nugets' + - output: pipelineArtifact + displayName: 'Publish Artifact: RepoFiles' + artifactName: RepoFiles + targetPath: '$(Build.ArtifactStagingDirectory)/RepoFiles' steps: - task: UseDotNet@2 displayName: 'Use .NET 6' @@ -198,12 +204,29 @@ extends: targetFolder: $(Build.ArtifactStagingDirectory)/Nugets sourceFolder: $(Build.ArtifactStagingDirectory) content: '*.nupkg' - + + # Copy repository files to be used in the deploy stage + - task: CopyFiles@2 + displayName: 'Copy repository files for deploy stage' + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: | + **/* + !**/bin/** + !**/obj/** + !**/.git/** + TargetFolder: '$(Build.ArtifactStagingDirectory)/RepoFiles' + - stage: deploy - condition: and(contains(variables['build.sourceBranch'], 'refs/tags/v'), succeeded()) + condition: and(or(contains(variables['Build.SourceBranch'], 'refs/tags/v'), eq(variables['Build.SourceBranch'], variables['PREVIEW_BRANCH'])), succeeded()) dependsOn: build + pool: + name: Azure-Pipelines-1ESPT-ExDShared + os: linux + image: ubuntu-latest jobs: - deployment: deploy_hidi + condition: and(contains(variables['build.SourceBranch'], 'refs/tags/v'), succeeded()) templateContext: type: releaseJob isProduction: true @@ -228,6 +251,7 @@ extends: publishFeedCredentials: 'OpenAPI Nuget Connection' - deployment: deploy_lib + condition: and(contains(variables['build.SourceBranch'], 'refs/tags/v'), succeeded()) templateContext: type: releaseJob isProduction: true @@ -243,11 +267,11 @@ extends: pool: vmImage: ubuntu-latest steps: - - powershell: | + - pwsh: | $fileNames = "$(Pipeline.Workspace)/Microsoft.OpenApi.Hidi.*.nupkg", "$(Pipeline.Workspace)/Microsoft.OpenApi.YamlReader.*.nupkg", "$(Pipeline.Workspace)/Microsoft.OpenApi.Workbench.*.nupkg" foreach($fileName in $fileNames) { if(Test-Path $fileName) { - rm $fileName -Verbose + Remove-Item $fileName -Verbose } } displayName: remove other nupkgs to avoid duplication @@ -260,6 +284,7 @@ extends: publishFeedCredentials: 'OpenAPI Nuget Connection' - deployment: deploy_yaml_reader + condition: and(contains(variables['build.SourceBranch'], 'refs/tags/v'), succeeded()) templateContext: type: releaseJob isProduction: true @@ -284,6 +309,7 @@ extends: publishFeedCredentials: 'OpenAPI Nuget Connection' - deployment: create_github_release + condition: and(contains(variables['build.SourceBranch'], 'refs/tags/v'), succeeded()) templateContext: type: releaseJob isProduction: true @@ -318,119 +344,132 @@ extends: assets: '$(Pipeline.Workspace)\**\*.exe' addChangeLog: false - - stage: Build_and_deploy_docker_images - displayName: 'Build and deploy docker images' - condition: or(eq(variables['build.sourceBranch'], 'refs/tags/v'), eq(variables['build.sourceBranch'], variables['PREVIEW_BRANCH'])) - dependsOn: build - pool: - name: Azure-Pipelines-1ESPT-ExDShared - image: ubuntu-latest - os: linux - jobs: - - job: buildAndPush - steps: - - task: AzureCLI@2 - displayName: 'Login to Azure Container Registry' - inputs: - azureSubscription: 'ACR Images Push Service Connection' - scriptType: bash - scriptLocation: inlineScript - inlineScript: | - az acr login --name msgraphprodregistry - - - powershell: | - $content = [XML](Get-Content ./Directory.Build.props) - Write-Host "XML loaded, finding version..." - - # Handle PropertyGroup as either a single element or array - $version = $null - if ($content.Project.PropertyGroup -is [array]) { - Write-Host "PropertyGroup is an array, checking each entry..." - foreach ($pg in $content.Project.PropertyGroup) { - if ($pg.Version) { - $version = $pg.Version.ToString().Trim() - Write-Host "Found version in PropertyGroup array: $version" - break + - deployment: deploy_docker_image + environment: docker-images-deploy + templateContext: + type: releaseJob + isProduction: true + inputs: + - input: pipelineArtifact + artifactName: RepoFiles + targetPath: '$(Pipeline.Workspace)' + strategy: + runOnce: + deploy: + pool: + vmImage: 'ubuntu-latest' + steps: + - task: AzureCLI@2 + displayName: 'Login to Azure Container Registry' + inputs: + azureSubscription: 'ACR Images Push Service Connection' + scriptType: bash + scriptLocation: inlineScript + inlineScript: | + az acr login --name $(REGISTRY) + + - pwsh: | + $content = [XML](Get-Content $(Pipeline.Workspace)/Directory.Build.props) + Write-Host "XML loaded, finding version..." + + # Handle PropertyGroup as either a single element or array + $version = $null + if ($content.Project.PropertyGroup -is [array]) { + Write-Host "PropertyGroup is an array, checking each entry..." + foreach ($pg in $content.Project.PropertyGroup) { + if ($pg.Version) { + $version = $pg.Version.ToString().Trim() + Write-Host "Found version in PropertyGroup array: $version" + break + } + } + } else { + # Single PropertyGroup + $version = $content.Project.PropertyGroup.Version + if ($version) { + $version = $version.ToString().Trim() + Write-Host "Found version in PropertyGroup: $version" + } } - } - } else { - # Single PropertyGroup - $version = $content.Project.PropertyGroup.Version - if ($version) { - $version = $version.ToString().Trim() - Write-Host "Found version in PropertyGroup: $version" - } - } - - if (-not $version) { - Write-Host "##vso[task.logissue type=error]Version not found in Directory.Build.props" - exit 1 - } + + if (-not $version) { + Write-Host "##vso[task.logissue type=error]Version not found in Directory.Build.props" + exit 1 + } + + Write-Host "Version found: $version" + Write-Host "##vso[task.setvariable variable=version;isoutput=true]$version" + Write-Host "##vso[task.setvariable variable=VERSION]$version" + displayName: 'Get version from csproj' + name: getversion - Write-Host "Version found: $version" - Write-Host "##vso[task.setvariable variable=version;isoutput=true]$version" - Write-Host "##vso[task.setvariable variable=VERSION]$version" - displayName: 'Get version from csproj' - name: getversion - - - bash: | - # Debug output to verify version variable - echo "Version from previous step: $VERSION" - displayName: 'Verify version variable' - - - bash: | - echo "Build Number: $(Build.BuildNumber)" - # Extract the last 3 characters for the run number - runnumber=$(echo "$(Build.BuildNumber)" | grep -o '[0-9]\+$') - echo "Extracted Run Number: $runnumber" + - bash: | + # Debug output to verify version variable + echo "Version from previous step: $VERSION" + displayName: 'Verify version variable' - # If extraction fails, set a default - if [ -z "$runnumber" ]; then - echo "Extraction failed, using default value" - runnumber=$(date +"%S%N" | cut -c1-3) - echo "Generated fallback run number: $runnumber" - fi + - bash: | + echo "Build Number: $(Build.BuildNumber)" + # Extract the last 3 characters for the run number + runnumber=$(echo "$(Build.BuildNumber)" | grep -o '[0-9]\+$') + echo "Extracted Run Number: $runnumber" + + # If extraction fails, set a default + if [ -z "$runnumber" ]; then + echo "Extraction failed, using default value" + runnumber=$(date +"%S%N" | cut -c1-3) + echo "Generated fallback run number: $runnumber" + fi + + # Set the variable for later steps + echo "##vso[task.setvariable variable=RUNNUMBER]$runnumber" + echo "##vso[task.setvariable variable=RUNNUMBER;isOutput=true]$runnumber" + displayName: 'Get truncated run number' + name: getrunnumber + condition: eq(variables['Build.SourceBranch'], variables['PREVIEW_BRANCH']) + + - bash: | + date=$(date +'%Y%m%d') + echo "Date value: $date" + echo "##vso[task.setvariable variable=BUILDDATE;isOutput=true]$date" + echo "##vso[task.setvariable variable=BUILDDATE]$date" + displayName: 'Get current date' + name: setdate + condition: eq(variables['Build.SourceBranch'], variables['PREVIEW_BRANCH']) - # Set the variable for later steps - echo "##vso[task.setvariable variable=RUNNUMBER]$runnumber" - echo "##vso[task.setvariable variable=RUNNUMBER;isOutput=true]$runnumber" - displayName: 'Get truncated run number' - name: getrunnumber - condition: eq(variables['Build.SourceBranch'], variables['PREVIEW_BRANCH']) - - - bash: | - date=$(date +'%Y%m%d') - echo "Date value: $date" - echo "##vso[task.setvariable variable=BUILDDATE;isOutput=true]$date" - echo "##vso[task.setvariable variable=BUILDDATE]$date" - displayName: 'Get current date' - name: setdate - condition: eq(variables['Build.SourceBranch'], variables['PREVIEW_BRANCH']) - - - bash: | - echo "Building Docker image..." - echo "Using build date: ${BUILDDATE}" - # Using quotes around tags to prevent flag interpretation - docker build \ - -t "$(REGISTRY)/$(IMAGE_NAME):nightly" \ - -t "$(REGISTRY)/$(IMAGE_NAME):${VERSION}.${BUILDDATE}${RUNNUMBER}" \ - "$(Build.SourcesDirectory)" + - script: | + docker run --privileged --rm msgraphprodregistry.azurecr.io/tonistiigi/binfmt --install all + displayName: "Enable multi-platform builds" + + - script: | + docker buildx create --use --name mybuilder + displayName: "Set up Docker BuildX" + + - script: | + docker buildx inspect --bootstrap + displayName: "Ensure BuildX is working" - echo "Pushing Docker image with nightly tag..." - docker push "$(REGISTRY)/$(IMAGE_NAME):nightly" - docker push "$(REGISTRY)/$(IMAGE_NAME):${VERSION}.${BUILDDATE}${RUNNUMBER}" - displayName: 'Build and Push Nightly Image' - condition: eq(variables['Build.SourceBranch'], variables['PREVIEW_BRANCH']) - - - bash: | - echo "Building Docker image for release..." - docker build \ - -t "$(REGISTRY)/$(IMAGE_NAME):latest" \ - -t "$(REGISTRY)/$(IMAGE_NAME):${VERSION}.${BUILDDATE}${RUNNUMBER}" \ - "$(Build.SourcesDirectory)" + - bash: | + echo "Building Docker image..." + echo "Using build date: ${BUILDDATE}" + # Using quotes around tags to prevent flag interpretation + docker buildx build \ + --platform linux/amd64,linux/arm64/v8 \ + --push \ + -t "$(REGISTRY)/$(IMAGE_NAME):nightly" \ + -t "$(REGISTRY)/$(IMAGE_NAME):${VERSION}.${BUILDDATE}${RUNNUMBER}" \ + "$(Pipeline.Workspace)" + + displayName: 'Build and Push Nightly Image' + condition: eq(variables['Build.SourceBranch'], variables['PREVIEW_BRANCH']) - echo "Pushing Docker image with latest and version tags..." - docker push "$(REGISTRY)/$(IMAGE_NAME):latest" - docker push "$(REGISTRY)/$(IMAGE_NAME):${VERSION}.${BUILDDATE}${RUNNUMBER}" - displayName: 'Build and Push Release Image' - condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v') \ No newline at end of file + - bash: | + echo "Building Docker image for release..." + docker buildx build\ + --platform linux/amd64,linux/arm64/v8 \ + --push \ + -t "$(REGISTRY)/$(IMAGE_NAME):latest" \ + -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 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f3952729f..87b987112 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,13 +5,23 @@ updates: directory: "/" open-pull-requests-limit: 10 schedule: - interval: "weekly" - + interval: "daily" - package-ecosystem: "nuget" # location of package manifests directory: "/" open-pull-requests-limit: 10 schedule: interval: "daily" - -# Built with ❤ by [Pipeline Foundation](https://pipeline.foundation) \ No newline at end of file + groups: + MicrosoftExtensions: + patterns: + - "Microsoft.Extensions.*" + - package-ecosystem: dotnet-sdk + directory: / + schedule: + interval: "daily" + ignore: + - dependency-name: '*' + update-types: + - version-update:semver-major + - version-update:semver-minor diff --git a/.github/policies/OpenAPI.NET-branch-protection.yml b/.github/policies/OpenAPI.NET-branch-protection.yml index 6deeb87fa..2d8fd2a73 100644 --- a/.github/policies/OpenAPI.NET-branch-protection.yml +++ b/.github/policies/OpenAPI.NET-branch-protection.yml @@ -81,3 +81,39 @@ configuration: # Restrict who can dismiss pull request reviews. boolean restrictsReviewDismissals: false + - branchNamePattern: support/v2 + # This branch pattern applies to the following branches as of approximately 02/27/2025 15:28:20: + # support/v1 + + # Specifies whether this branch can be deleted. boolean + allowsDeletions: false + # Specifies whether forced pushes are allowed on this branch. boolean + allowsForcePushes: false + # Specifies whether new commits pushed to the matching branches dismiss pull request review approvals. boolean + dismissStaleReviews: true + # Specifies whether admins can overwrite branch protection. boolean + isAdminEnforced: true + # Indicates whether "Require a pull request before merging" is enabled. boolean + requiresPullRequestBeforeMerging: true + # Specifies the number of pull request reviews before merging. int (0-6). Should be null/empty if PRs are not required + requiredApprovingReviewsCount: 1 + # Require review from Code Owners. Requires requiredApprovingReviewsCount. boolean + requireCodeOwnersReview: true + # Are commits required to be signed. boolean. TODO: all contributors must have commit signing on local machines. + requiresCommitSignatures: false + # Are conversations required to be resolved before merging? boolean + requiresConversationResolution: true + # Are merge commits prohibited from being pushed to this branch. boolean + requiresLinearHistory: false + # Required status checks to pass before merging. Values can be any string, but if the value does not correspond to any existing status check, the status check will be stuck on pending for status since nothing exists to push an actual status + requiredStatusChecks: + - license/cla + - CodeQL + - Continuous Integration + # Require branches to be up to date before merging. boolean + requiresStrictStatusChecks: false + # Indicates whether there are restrictions on who can push. boolean. Should be set with whoCanPush. + restrictsPushes: false + # Restrict who can dismiss pull request reviews. boolean + restrictsReviewDismissals: false + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..0d19e6ac4 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,54 @@ +# Pull Request + + + +## Description + + +## Type of Change + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Documentation update +- [ ] Other (please describe): + +## Related Issue(s) + + +## Changes Made + +- +- +- + +## Testing + +- [ ] Unit tests added/updated +- [ ] Integration tests added/updated +- [ ] Manual testing performed +- [ ] All existing tests pass + +## Checklist + +- [ ] My code follows the code style of this project +- [ ] I have performed a self-review of my own code +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes + +## Versions applicability + +- [ ] My change applies to the version 1.X of the library, if so PR link: +- [ ] My change applies to the version 2.X of the library, if so PR link: +- [ ] My change applies to the version 3.X of the library, if so PR link: +- [ ] I have evaluated the applicability of my change against the other versions above. + +See [the contributing guidelines](https://github.com/microsoft/OpenAPI.NET/blob/main/CONTRIBUTING.md) for more information about how patches are applied across multiple versions. + +## Additional Notes + \ No newline at end of file diff --git a/.github/release-please.yml b/.github/release-please.yml index c821fc166..ce23f6ec0 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -3,5 +3,8 @@ primaryBranch: main handleGHRelease: true branches: - branch: support/v1 + manifest: true + handleGHRelease: true + - branch: support/v2 manifest: true handleGHRelease: true \ No newline at end of file diff --git a/.github/workflows/auto-merge-dependabot.yml b/.github/workflows/auto-merge-dependabot.yml index df4b487a7..d454cd186 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.3.0 + uses: dependabot/fetch-metadata@v2.4.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 595d473c8..9d55602b3 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -14,13 +14,13 @@ jobs: GITHUB_RUN_NUMBER: ${{ github.run_number }} steps: - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: dotnet-version: 8.x - name: Checkout repository id: checkout_repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 with: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 @@ -41,10 +41,10 @@ jobs: name: Validate Project for Trimming runs-on: windows-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: dotnet-version: 8.x @@ -58,10 +58,10 @@ jobs: needs: [ci] steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: dotnet-version: 8.x @@ -75,6 +75,13 @@ jobs: dotnet run -c Release working-directory: ./performance/benchmark + - name: Publish benchmark results + uses: actions/upload-artifact@v5 + with: + if-no-files-found: error + name: benchmark-results + path: "${{ github.workspace }}/performance/benchmark/BenchmarkDotNet.Artifacts/results" + - name: Run comparison tool for empty models run: dotnet run -c Release --project ./performance/resultsComparer/resultsComparer.csproj -- compare $OLD_REPORT $NEW_REPORT -p IdenticalMemoryUsage shell: bash diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e7810ec2d..72eea8bbf 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,10 +2,11 @@ name: CodeQL Analysis on: push: - branches: [ main, support/v1 ] + branches: [ main, support/v1, support/v2 ] pull_request: schedule: - cron: '0 8 * * *' + workflow_dispatch: permissions: contents: read # these permissions are required to run the codeql analysis @@ -19,16 +20,16 @@ jobs: steps: - name: Checkout repository id: checkout_repo - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: dotnet-version: 8.0.x - name: Initialize CodeQL id: init_codeql - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: queries: security-and-quality @@ -48,6 +49,6 @@ jobs: - name: Perform CodeQL Analysis id: analyze_codeql - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 # Built with ❤ by [Pipeline Foundation](https://pipeline.foundation) \ No newline at end of file diff --git a/.github/workflows/release-please-gha.yml b/.github/workflows/release-please-gha.yml new file mode 100644 index 000000000..9c76a0d64 --- /dev/null +++ b/.github/workflows/release-please-gha.yml @@ -0,0 +1,42 @@ +## ----------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See LICENSE.txt in the project root for license information. +## ----------------------------------------------------------------------------- +# +# Summary: +# This GitHub Actions workflow automates the release process using Release Please. +# It triggers on pushes to the main branch, generates a GitHub App token using organization +# variables and secrets, and then runs the release-please-action to manage versioning and changelogs. + +name: Release Please + +on: + push: + branches: + - main + - support/v1 + - support/v2 + +permissions: + contents: read + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + + - name: Generate GitHub App token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-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 + with: + token: ${{ steps.app-token.outputs.token }} + config-file: release-please-config.json + manifest-file: .release-please-manifest.json + target-branch: ${{ github.ref_name }} diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index a99c68d66..51f9b5986 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -35,15 +35,15 @@ jobs: runs-on: windows-latest steps: - name: Set up JDK 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'adopt' java-version: 17 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: dotnet-version: 8.0.x - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Cache SonarCloud packages diff --git a/.gitignore b/.gitignore index 4caae17f4..258fee87a 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,7 @@ ipch/ *.VC.VC.opendb # Visual Studio profiler +*.diagsession *.psess *.vsp *.vspx @@ -286,3 +287,7 @@ __pycache__/ *.btm.cs *.odx.cs *.xsd.cs + +# BenchmarkDotNet profiler files +*.nettrace +*.speedscope.json diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 4c324336f..4191c8899 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.0.0-preview.16" + ".": "3.0.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index f590fa76d..f2561d642 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,348 @@ # Changelog +## [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.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)) +* a bug where null sentinel value would appear in YAML documents ([15618e1](https://github.com/microsoft/OpenAPI.NET/commit/15618e1f6a79874ae61dc31e3bcd5e1f3177d7ff)) + +## [2.3.8](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.7...v2.3.8) (2025-10-27) + + +### Bug Fixes + +* an issue where numeric property names would be missing quotes in yaml conversion ([da43c98](https://github.com/microsoft/OpenAPI.NET/commit/da43c98cfd7938a2354bfe57f431aa4bd0407b66)) +* an issue where numeric property names would be missing quotes in yaml conversion ([234504c](https://github.com/microsoft/OpenAPI.NET/commit/234504c6a1a53be8630b1f2eda8640f04a92327d)) +* quote property names in yaml that match boolean values ([39a9f41](https://github.com/microsoft/OpenAPI.NET/commit/39a9f4112a123b9207504d4a840a9be553703555)) +* yaml blocks and line returns ([b053848](https://github.com/microsoft/OpenAPI.NET/commit/b05384872e9364aedf8d8fc24b36bab9824594c5)) +* yaml multi-line literals maintain their lines ([558a1ce](https://github.com/microsoft/OpenAPI.NET/commit/558a1ceafc22e6075470a8799582575c8c1e125d)) + +## [2.3.7](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.6...v2.3.7) (2025-10-24) + + +### Bug Fixes + +* adds a null value sentinel to enable roundtrip serializations of JsonNode typed properties ([337c6eb](https://github.com/microsoft/OpenAPI.NET/commit/337c6eb08a9cc99bfbe2cd08fed61678030b8b8b)) +* adds a null value sentinel to enable roundtrip serializations of JsonNode typed properties ([63b2b98](https://github.com/microsoft/OpenAPI.NET/commit/63b2b98b64633fdef3b7fafee882060a3e0808fd)) +* fixes a bug where yaml null values would end up as a string "null" during roundtrip serialization ([6e62de2](https://github.com/microsoft/OpenAPI.NET/commit/6e62de205f0a5d58b385b4536dc30035a9977054)) +* fixes a bug where yaml null values would end up as a string "null" during roundtrip serialization ([994184b](https://github.com/microsoft/OpenAPI.NET/commit/994184b41bcd433a078cdeef75ba43d92b6b9762)) +* YamlConverter adding extra quotes to string values when converting from JSON to YAML ([ccfebc8](https://github.com/microsoft/OpenAPI.NET/commit/ccfebc828c2793b00faf3d5b12bd95bc68901104)) + + +### Performance Improvements + +* do not duplicate nodes when indexing ([dbbbf13](https://github.com/microsoft/OpenAPI.NET/commit/dbbbf1330934bc35fb35610a6a5db65514596c48)) +* only initialize map node nodes on demand ([bdb5264](https://github.com/microsoft/OpenAPI.NET/commit/bdb5264bc41b345f9ea95924ca5ab679178b82b6)) +* reduce allocations in mapnode ([f58aad2](https://github.com/microsoft/OpenAPI.NET/commit/f58aad235f904f94704aa14700aaca4ac16205af)) +* removes the lazy initialization since the node is always enumerated ([1c96521](https://github.com/microsoft/OpenAPI.NET/commit/1c96521c82cfa7414602e4f4da64e629b6c69c29)) +* switches to lazy instantiation ([d3c758b](https://github.com/microsoft/OpenAPI.NET/commit/d3c758b0d4421d1da9979587dfaee91bbdee0c7c)) +* use deep equals for comparison to reduce allocations ([6ce3214](https://github.com/microsoft/OpenAPI.NET/commit/6ce3214ad3beb5abe6045e5aa1743db4249c1974)) + +## [2.3.6](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.5...v2.3.6) (2025-10-20) + + +### Bug Fixes + +* a bug where empty collections would not be serialized for default values ([4c4d257](https://github.com/microsoft/OpenAPI.NET/commit/4c4d257c0cf10d1742fae9f3961e4a6242c0ce1d)) + +## [2.3.5](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.4...v2.3.5) (2025-10-14) + + +### Bug Fixes + +* use settings for terse output in serialization extension methods ([246039b](https://github.com/microsoft/OpenAPI.NET/commit/246039bfa8a16c042a10a87126289de82d18b321)) +* use settings for terse output in serialization extension methods ([8b91278](https://github.com/microsoft/OpenAPI.NET/commit/8b912788ef18b44a083d3fd2a1d6e25c9e6e17cb)) + +## [2.3.4](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.3...v2.3.4) (2025-10-06) + + +### Bug Fixes + +* Improve server creation and URL handling logic to maintain port ([3e6ee80](https://github.com/microsoft/OpenAPI.NET/commit/3e6ee80491ab32d810d40f29761b8eb8e4c4ce23)) +* missing deserialization for header content property in 3.1 and 3.0 ([717f154](https://github.com/microsoft/OpenAPI.NET/commit/717f1547bf94c3e9f76078d9a3b93ce684e17306)) +* missing deserialization for header content property in 3.1 and 3.0 ([0fdfae1](https://github.com/microsoft/OpenAPI.NET/commit/0fdfae1b0bf4d371af8ad3bfa6ad4df3da8d545b)) + +## [2.3.3](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.2...v2.3.3) (2025-10-02) + + +### Bug Fixes + +* typo in allowReserved property name for deserialization ([1633453](https://github.com/microsoft/OpenAPI.NET/commit/16334536dcb5182f26c0d58463bd15a124dd1505)) +* typo in allowReserved property name for deserialization ([f7e34be](https://github.com/microsoft/OpenAPI.NET/commit/f7e34be28566a4f714d43667f8c43be7159d27a2)) + +## [2.3.2](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.1...v2.3.2) (2025-09-19) + + +### Bug Fixes + +* Fix URL processing in InternalLoad method would not detect the filename/scheme properly in some scenarios ([d93689c](https://github.com/microsoft/OpenAPI.NET/commit/d93689c87ababdf64a82dc492a19b963f65b3fd1)) +* OpenApiEncoding explode property serialization defaults with form style ([ae03eab](https://github.com/microsoft/OpenAPI.NET/commit/ae03eaba3fe7aa20bf0d03f895bbd4ae85d9d344)) + +## [2.3.1](https://github.com/microsoft/OpenAPI.NET/compare/v2.3.0...v2.3.1) (2025-09-08) + + +### Bug Fixes + +* file access for "file" URI scheme with special characters ([6dded81](https://github.com/microsoft/OpenAPI.NET/commit/6dded810cfba50d3a8093795a9359c384dd52c6a)) + +## [2.3.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.2.0...v2.3.0) (2025-08-29) + + +### Features + +* adds the detected format as part of the diagnostic ([#2482](https://github.com/microsoft/OpenAPI.NET/issues/2482)) ([59d7c81](https://github.com/microsoft/OpenAPI.NET/commit/59d7c81fae8cbc320a9005c529806e94cc4e9444)) +* adds the detected format to the diagnostics ([59d7c81](https://github.com/microsoft/OpenAPI.NET/commit/59d7c81fae8cbc320a9005c529806e94cc4e9444)) + +## [2.2.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.1.0...v2.2.0) (2025-08-25) + + +### Features + +* add Validation Rule for path operations to not have a request body ([d101fc3](https://github.com/microsoft/OpenAPI.NET/commit/d101fc30cfc701f2d6c52a51b9e39fa7eae96194)) + + +### Bug Fixes + +* missing examples when one example is with an empty array. ([cb1c496](https://github.com/microsoft/OpenAPI.NET/commit/cb1c4967f37f11dad6ad42784e6c3cf8570081f9)) + +## [2.1.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.1...v2.1.0) (2025-08-20) + + +### Features + +* adds a default validation rule for unresolved references ([90b3966](https://github.com/microsoft/OpenAPI.NET/commit/90b3966e5e071e26570050733482660f41f944b0)) + + +### Bug Fixes + +* Improve OpenApiWalker performance ([a007c03](https://github.com/microsoft/OpenAPI.NET/commit/a007c039eb2a9190d4adeafd865f6d42df4221aa)) +* Validate schema property is not null ([3326022](https://github.com/microsoft/OpenAPI.NET/commit/3326022b016fd3fc795f45926a55895b02557a09)) + +## [2.0.1](https://github.com/microsoft/openapi.net/compare/v2.0.0...v2.0.1) (2025-08-18) + + +### Bug Fixes + +* add missing disposable for stream ([9318c00](https://github.com/microsoft/openapi.net/commit/9318c00c31466bf67d2e9701659a4cda3d82d1dd)) +* add missing disposable for stream ([0c1ccbd](https://github.com/microsoft/openapi.net/commit/0c1ccbdc1ba4c53662ff6c7132366ae435d8fedb)) + +## [2.0.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.31...v2.0.0) (2025-07-10) + + +### Features + +* General availability of version 2 with support for OpenAPI 3.1!!! 🎉🎉🎉 ([a02d74c](https://github.com/microsoft/OpenAPI.NET/commit/a02d74c2467d591a7c4d8fa89b3b18e2452be0a5)) +* General availability of version 2 with support for OpenAPI 3.1!!! 🎉🎉🎉 ([97824e5](https://github.com/microsoft/OpenAPI.NET/commit/97824e5a9dc36b0c2ac56bbceef3439b9e8dfcf3)) + + +### Bug Fixes + +* inconsistent visibility of properties in current keys class ([cb9772f](https://github.com/microsoft/OpenAPI.NET/commit/cb9772fd4eb2a6fa36b65f0388f471eb66653aa2)) +* removes extraneous default value constant ([bf8d0b6](https://github.com/microsoft/OpenAPI.NET/commit/bf8d0b63adc16013fdb22f38715f167ce6e21c98)) +* removes extraneous default value constant ([b6eb46e](https://github.com/microsoft/OpenAPI.NET/commit/b6eb46ebb46ccd7314e00b5698fa7f6b9b6ae0da)) +* removes loop methods from parsing context as its available in loop detector instead ([de3531b](https://github.com/microsoft/OpenAPI.NET/commit/de3531bc944bcb2bbc55e278e28f1a05d6d0a29f)) +* removes loop methods from parsing context as its available in loop detector instead ([18a8cbe](https://github.com/microsoft/OpenAPI.NET/commit/18a8cbeeb00ee39e5bbdaabdde097ee9f8a75668)) +* removes public mermaid types that were not usuable ([ef7ae33](https://github.com/microsoft/OpenAPI.NET/commit/ef7ae338dc6122a9ffc58c7661b161b319d307d9)) +* removes public mermaid types that were not usuable ([a26096c](https://github.com/microsoft/OpenAPI.NET/commit/a26096c8cf9c3e53a547235a446296eaff3f413d)) +* removes redundant marker interface ([5a055f9](https://github.com/microsoft/OpenAPI.NET/commit/5a055f9f616028116f1d035ee744820f37a85464)) +* removes redundant marker interface ([74a9f08](https://github.com/microsoft/OpenAPI.NET/commit/74a9f083674134482b1349bce1643d9f4636ed82)) +* switches to a getter for API consistency ([7975082](https://github.com/microsoft/OpenAPI.NET/commit/797508257501c8b4a336310c84030d0e128caf14)) +* switches to a getter for API consistency ([0091f1c](https://github.com/microsoft/OpenAPI.NET/commit/0091f1cbf5f430fe9f54cfb5e2b66279663de632)) +* unconsistent visibility of properties in current keys class ([d0c20ab](https://github.com/microsoft/OpenAPI.NET/commit/d0c20ab2209b3e7ed57cb89dbd4107d915975302)) +* visibility of extension methods ([1e9112a](https://github.com/microsoft/OpenAPI.NET/commit/1e9112a4cfc01a54f265858c81b0effb8a897976)) +* visibility of extension methods ([50c8e34](https://github.com/microsoft/OpenAPI.NET/commit/50c8e3459d9849d0f9acfc1e7efc99668828e8a4)) + +## [2.0.0-preview.31](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.30...v2.0.0-preview.31) (2025-07-02) + + +### Bug Fixes + +* bumps openapi.net.odata to fix two critical bugs in hidi ([00c3018](https://github.com/microsoft/OpenAPI.NET/commit/00c30181214b35f4817be0cbd3827d765efd04d9)) +* bumps openapi.net.odata to fix two critical bugs in hidi ([cf41355](https://github.com/microsoft/OpenAPI.NET/commit/cf41355aac3326c1cb9337078de989179f1b3b67)) + +## [2.0.0-preview.30](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.29...v2.0.0-preview.30) (2025-07-02) + + +### Bug Fixes + +* migration of hidi to the latest version of system.commandline ([a5f8721](https://github.com/microsoft/OpenAPI.NET/commit/a5f8721a18e93ee881cfee371ba6d23ce0c55ae4)) +* throw on circular reference ([e14258d](https://github.com/microsoft/OpenAPI.NET/commit/e14258dd2a8639702c8e0bc81a643874d207facb)) +* throw on circular reference ([caea292](https://github.com/microsoft/OpenAPI.NET/commit/caea292b39d2c754bd2e2d214280add53a0a47ea)) +* upgrades openapi.odata to avoid hidi failing to load ([0bea5ed](https://github.com/microsoft/OpenAPI.NET/commit/0bea5ed3cbb10230bf026288e118ce0e5025e55a)) +* upgrades openapi.odata to avoid hidi failing to load ([6735397](https://github.com/microsoft/OpenAPI.NET/commit/67353976b8a17dcb6760223d06c097469fa6f794)) +* validation to accept lowercase status code ranges (4xx, 5xx) in OpenAPI responses ([09f661f](https://github.com/microsoft/OpenAPI.NET/commit/09f661f0ff0511d5937fad49ae8a6182b1ea1aff)) + +## [2.0.0-preview.29](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.28...v2.0.0-preview.29) (2025-06-18) + + +### Bug Fixes + +* avoid stack overflow on cyclical references ([06cc025](https://github.com/microsoft/OpenAPI.NET/commit/06cc025dca43d24955bcd205facefa4347d3f0c7)) + +## [2.0.0-preview.28](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.27...v2.0.0-preview.28) (2025-06-16) + + +### Bug Fixes + +* sub-schema references are invalid ([92db49b](https://github.com/microsoft/OpenAPI.NET/commit/92db49b98ade782de3dec229936c100a1339b491)) +* sub-schema references are invalid ([75d1d2b](https://github.com/microsoft/OpenAPI.NET/commit/75d1d2b62a6fab3727047be5c0e10b9987ad9f37)) + +## [2.0.0-preview.27](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.26...v2.0.0-preview.27) (2025-06-13) + + +### Bug Fixes + +* implementation drift between the different version services ([1ed02e3](https://github.com/microsoft/OpenAPI.NET/commit/1ed02e3cbe7a6b484ee7db224e056ae2f0244a30)) +* implementation drift between the different version services ([2514526](https://github.com/microsoft/OpenAPI.NET/commit/25145266a70a961e6899368951d95ce41fe55f5b)) +* relative uri in json schema references would not parse appropriately or provide feedback to the user ([940945d](https://github.com/microsoft/OpenAPI.NET/commit/940945df29bea338a22553a3ddfb7e61853cb4e7)) +* relative uri in json schema references would not parse appropriately or provide feedback to the user ([e0bceaa](https://github.com/microsoft/OpenAPI.NET/commit/e0bceaaa39e8e475652b390324254149e867f39f)) +* warn instead of error out when $schema is present in the document ([388d6f7](https://github.com/microsoft/OpenAPI.NET/commit/388d6f79b4b45d1c30bddbff66dd79eef2d4e4b7)) +* warn instead of error out when $schema is present in the document ([7c7b053](https://github.com/microsoft/OpenAPI.NET/commit/7c7b053b543ebdedf05b0357175fea3dc9d345db)) + +## [2.0.0-preview.26](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.25...v2.0.0-preview.26) (2025-06-12) + + +### Bug Fixes + +* a bug where relative relative and sub-component JSON references would not resolve properly ([b7bc6be](https://github.com/microsoft/OpenAPI.NET/commit/b7bc6be4a05f1001130efb9af0b677dbec3055bc)) +* a bug where relative relative and sub-component JSON references would not resolve properly ([c53165c](https://github.com/microsoft/OpenAPI.NET/commit/c53165c72fae25ba0864a9f3c52d42e4ee05184d)) +* recursive relative reference resolution ([873acd4](https://github.com/microsoft/OpenAPI.NET/commit/873acd45eb6adecdc4219a08b028ddf35a568f01)) +* recursive relative reference resolution ([f296505](https://github.com/microsoft/OpenAPI.NET/commit/f296505b7123f35b2e45eedc9118c59b8f925cbd)) +* upgrades sharp yaml to avodi signing issues on netfx ([5dc7e81](https://github.com/microsoft/OpenAPI.NET/commit/5dc7e81fa7fad856edd96640ea7ee0e23e25a7f2)) +* upgrades sharp yaml to avodi signing issues on netfx ([4db5c1a](https://github.com/microsoft/OpenAPI.NET/commit/4db5c1ae39d4bc6c5138fda5d9d14904f069fa3e)) + +## [2.0.0-preview.25](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.24...v2.0.0-preview.25) (2025-06-10) + + +### Bug Fixes + +* ci configuration ([e7f76f7](https://github.com/microsoft/OpenAPI.NET/commit/e7f76f753649d5747a720b55babe2c59bbedfd49)) +* ci configuration ([a8fd917](https://github.com/microsoft/OpenAPI.NET/commit/a8fd91728bc57102d36bfdb6442e3c273b2818e6)) + +## [2.0.0-preview.24](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.23...v2.0.0-preview.24) (2025-06-09) + + +### Bug Fixes + +* callback reference annotations parsing ([86892b3](https://github.com/microsoft/OpenAPI.NET/commit/86892b361c7dcbe445ddfe10fd57fd9ab2d8a5a9)) +* example reference annotation parsing ([8bf012b](https://github.com/microsoft/OpenAPI.NET/commit/8bf012b7d576f5efd6d0953859b98494958c2c4e)) +* link reference annotations parsing ([2a62c5a](https://github.com/microsoft/OpenAPI.NET/commit/2a62c5a2874d935aba09c1995d022988ac793609)) +* loading of header reference description ([9248560](https://github.com/microsoft/OpenAPI.NET/commit/9248560d0bac2c3e2d635b653a26d4bfa14e51f4)) +* makes reference serialization object generic ([f0802e5](https://github.com/microsoft/OpenAPI.NET/commit/f0802e5cb1974b6b2d4dc7100b2e3f808ab3538b)) +* parameter reference annoation parsing ([b1578f3](https://github.com/microsoft/OpenAPI.NET/commit/b1578f3fdc8bdbdeab3063ae3d3e6a554800f6d6)) +* path item reference annoations parsing ([d31ed4c](https://github.com/microsoft/OpenAPI.NET/commit/d31ed4c9e0a095eb247de450b3122f0b1dd675d6)) +* removes description field from references that do not support it ([03659f7](https://github.com/microsoft/OpenAPI.NET/commit/03659f7d055e6b339e15ac4434ae4037abb3a546)) +* request body reference annotations parsing ([d9a78dc](https://github.com/microsoft/OpenAPI.NET/commit/d9a78dc5e5433d0f1b628569f4124d4de575cba1)) +* response reference annotations parsing ([e455f52](https://github.com/microsoft/OpenAPI.NET/commit/e455f52f30fdb4937c27132b9596f89f17997663)) +* security scheme reference annoations parsing ([ccc3733](https://github.com/microsoft/OpenAPI.NET/commit/ccc3733a2700d087aac289bb31a6107e9e6d743f)) + +## [2.0.0-preview.23](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.22...v2.0.0-preview.23) (2025-06-03) + + +### Features + +* upgrades OData lib in Hidi to preview15 ([540240a](https://github.com/microsoft/OpenAPI.NET/commit/540240aba9f96b598459cd49b67cd02adc82713d)) +* upgrades OData lib to preview15 ([b300265](https://github.com/microsoft/OpenAPI.NET/commit/b3002652805ff2a36e55531178d4fe579b196c56)) + +## [2.0.0-preview.22](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.21...v2.0.0-preview.22) (2025-06-02) + + +### Features + +* Add writer settings to enable collection sorting using a comparer ([d7eaf47](https://github.com/microsoft/OpenAPI.NET/commit/d7eaf4707c26351cff4e4ec798b64967d9dd932f)) + + +### Bug Fixes + +* rename class; add logic for sorting IEnumerable collections ([58cb4ac](https://github.com/microsoft/OpenAPI.NET/commit/58cb4ac718a840a8dfb5c8821a3c0a484c29befd)) + +## [2.0.0-preview.21](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.20...v2.0.0-preview.21) (2025-05-21) + + +### Bug Fixes + +* do not throw when operation tag is missing matching global tag ([fe133f2](https://github.com/microsoft/OpenAPI.NET/commit/fe133f2604e9b65cc1c7011aab7c62f44e649d19)) +* do not throw when operation tag is missing matching global tag ([2c5aa40](https://github.com/microsoft/OpenAPI.NET/commit/2c5aa40cbb8bf1e96c1ccce6273579e70b69ade2)) + +## [2.0.0-preview.20](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.19...v2.0.0-preview.20) (2025-05-20) + + +### Bug Fixes + +* nullable and type ordering should be maintain to ease up migration work ([6c82aa6](https://github.com/microsoft/OpenAPI.NET/commit/6c82aa6b2d6e4f39af3c594edd8590a0cf749530)) +* nullable should not be inserted as an attempt to normalize the document ([6c82aa6](https://github.com/microsoft/OpenAPI.NET/commit/6c82aa6b2d6e4f39af3c594edd8590a0cf749530)) +* refactor to avoid adding duplicate entries ([41fd508](https://github.com/microsoft/OpenAPI.NET/commit/41fd508074f1b70415026df3aa878cd5f5e7b1ee)) +* refactor to avoid adding duplicate entries ([#2359](https://github.com/microsoft/OpenAPI.NET/issues/2359)) ([9791eb6](https://github.com/microsoft/OpenAPI.NET/commit/9791eb684a0f040feeb8c58701fd4f3577e73e2c)) +* tree node has the wrong structure because of trailing slashes ([2ffb273](https://github.com/microsoft/OpenAPI.NET/commit/2ffb2735aa3718370d6094186142f9cf50b194fa)) +* tree node has the wrong structure because of trailing slashes ([4439340](https://github.com/microsoft/OpenAPI.NET/commit/443934060e1e446de726addde69a2de955b95a7b)) +* wrong link to json schema spec in schema doc comments ([d9b0c90](https://github.com/microsoft/OpenAPI.NET/commit/d9b0c906f7173b81fea15001d588edcbc3eed8f1)) +* wrong link to json schema spec in schema doc comments ([9a73ec6](https://github.com/microsoft/OpenAPI.NET/commit/9a73ec6e5486d84b6a30a5fa0ac5961b381fc3d3)) + +## [2.0.0-preview.19](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.18...v2.0.0-preview.19) (2025-05-16) + + +### Bug Fixes + +* base url should be read from the settings when available ([f5d6e81](https://github.com/microsoft/OpenAPI.NET/commit/f5d6e81c21fd18b6de0fb19b535ad6dbc187790d)) +* base url should be read from the settings when available ([b17b7d8](https://github.com/microsoft/OpenAPI.NET/commit/b17b7d8d25fdf9a767411481287aacee31434aaa)) +* discriminator mapping references don't get a document when created from DOM ([767d3fb](https://github.com/microsoft/OpenAPI.NET/commit/767d3fb163b273b275cd67d710c573c59e4e642b)) +* discriminator mapping references don't get a document when created from DOM ([fdfe002](https://github.com/microsoft/OpenAPI.NET/commit/fdfe002d551fc3feaaeb5af24042826f13bdf412)) + +## [2.0.0-preview.18](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.17...v2.0.0-preview.18) (2025-05-13) + + +### Features + +* upgrades openapi.net.odata and apimanifest to the latest version ([80844a6](https://github.com/microsoft/OpenAPI.NET/commit/80844a60ae50ba0a4d54d7dd2e45ce8360206bf5)) +* upgrades openapi.net.odata and apimanifest to the latest version ([938a2e0](https://github.com/microsoft/OpenAPI.NET/commit/938a2e07b40b082e01ed1cdf3244767cbdca4061)) + + +### Bug Fixes + +* avoid calling virtual members in constructor ([5835057](https://github.com/microsoft/OpenAPI.NET/commit/5835057a7e905e371f859e727ddaf65ec08c6db0)) +* Fix typo in error message ([#2345](https://github.com/microsoft/OpenAPI.NET/issues/2345)) ([3f8b2b9](https://github.com/microsoft/OpenAPI.NET/commit/3f8b2b99c07bd3c58825728c2dd2ffed91d88fbe)) +* handle deserializing and writing empty security requirements [#1426](https://github.com/microsoft/OpenAPI.NET/issues/1426) ([#2323](https://github.com/microsoft/OpenAPI.NET/issues/2323)) ([962e0e4](https://github.com/microsoft/OpenAPI.NET/commit/962e0e436f96b1b68613013d75307dc1f92ce15c)) +* normalized override implementation for parameter types serialization in v2 ([5930916](https://github.com/microsoft/OpenAPI.NET/commit/593091621926defcbc2727a922613e34557d882a)) + +## [2.0.0-preview.17](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.16...v2.0.0-preview.17) (2025-04-16) + + +### Features + +* discriminator mappings now use schema references ([b4877f6](https://github.com/microsoft/OpenAPI.NET/commit/b4877f674ad1a240a367390d40d122eebccc0b20)) +* openapiformat enum cleanup ([#2326](https://github.com/microsoft/OpenAPI.NET/issues/2326)) ([19ffd13](https://github.com/microsoft/OpenAPI.NET/commit/19ffd136a7d2137f3de0896148d9a39f469ac711)) +* Remove default collection initialization for perf reasons ([#2284](https://github.com/microsoft/OpenAPI.NET/issues/2284)) ([3604382](https://github.com/microsoft/OpenAPI.NET/commit/36043829d29340a47fc93c6477a38ea93e59ef57)) + + +### Bug Fixes + +* Empty tag causes error generating Kiota client [#2283](https://github.com/microsoft/OpenAPI.NET/issues/2283) ([#2286](https://github.com/microsoft/OpenAPI.NET/issues/2286)) ([521d636](https://github.com/microsoft/OpenAPI.NET/commit/521d636e2c437c25e1758e9f6a22793d74adf2d7)) +* hidi fails to parse yaml files when fixing references ([a5c4d61](https://github.com/microsoft/OpenAPI.NET/commit/a5c4d6109c433b949cdb1665c00ad778b82b28b0)) +* hidi fails to parse yaml files when fixing references ([c5b69fe](https://github.com/microsoft/OpenAPI.NET/commit/c5b69fed9c413a6399c36e0f543e1019faac77e6)) +* Improve handling of OpenAPI tag references ([#2325](https://github.com/microsoft/OpenAPI.NET/issues/2325)) ([bf9954a](https://github.com/microsoft/OpenAPI.NET/commit/bf9954a257691231fac6f56667bde208a98a5b42)) +* read (Exclusive)Maximum and (Exclusive)Minimum values as strings and write their raw values during serialization ([#2309](https://github.com/microsoft/OpenAPI.NET/issues/2309)) ([ac66756](https://github.com/microsoft/OpenAPI.NET/commit/ac667560a951bef2824851c208c55ba070e96163)) +* relative references in subdirectory documents are not loading [#1674](https://github.com/microsoft/OpenAPI.NET/issues/1674) ([#2243](https://github.com/microsoft/OpenAPI.NET/issues/2243)) ([4bcbd51](https://github.com/microsoft/OpenAPI.NET/commit/4bcbd51caff689a73e90efbc08f683383741e004)) +* renames annotations schema property to metadata to match [#2241](https://github.com/microsoft/OpenAPI.NET/issues/2241) ([28e4a75](https://github.com/microsoft/OpenAPI.NET/commit/28e4a7590fb3525e30970112191d72eaf048ad6b)) +* renames annotations schema property to metadata to match [#2241](https://github.com/microsoft/OpenAPI.NET/issues/2241) ([33fc7cb](https://github.com/microsoft/OpenAPI.NET/commit/33fc7cbcda71efea47070ab7a6ebf9db8787a7f8)) +* set format to binary for file uploads ([#2305](https://github.com/microsoft/OpenAPI.NET/issues/2305)) ([47f10d3](https://github.com/microsoft/OpenAPI.NET/commit/47f10d323e78b9e6caa757c0d2efa378a19fc28c)) + ## [2.0.0-preview.16](https://github.com/microsoft/OpenAPI.NET/compare/v2.0.0-preview.15...v2.0.0-preview.16) (2025-03-20) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a08924c7b..195723567 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/) diff --git a/Directory.Build.props b/Directory.Build.props index 36d681cf5..fa48dd7ac 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,7 +12,7 @@ https://github.com/Microsoft/OpenAPI.NET © Microsoft Corporation. All rights reserved. OpenAPI .NET - 2.0.0-preview.16 + 3.0.0 diff --git a/README.md b/README.md index f903038cd..6a7f787f8 100644 --- a/README.md +++ b/README.md @@ -1,131 +1,124 @@ - -![Category overview screenshot](https://raw.githubusercontent.com/microsoft/OpenAPI.NET/main/docs/images/oainet.png "Microsoft + OpenAPI = Love") - -# OpenAPI.NET - -|Package|Nuget| -|--|--| -|Models and Writers|[![nuget](https://img.shields.io/nuget/v/Microsoft.OpenApi.svg)](https://www.nuget.org/packages/Microsoft.OpenApi/) | -|Readers | [![nuget](https://img.shields.io/nuget/v/Microsoft.OpenApi.Readers.svg)](https://www.nuget.org/packages/Microsoft.OpenApi.Readers/) | -|Hidi|[![nuget](https://img.shields.io/nuget/v/Microsoft.OpenApi.Hidi.svg)](https://www.nuget.org/packages/Microsoft.OpenApi.Hidi/) - - -The **OpenAPI.NET** SDK contains a useful object model for OpenAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model. - -**See more information on the OpenAPI specification and its history here: OpenAPI Initiative** - -Project Objectives - -- Provide a single shared object model in .NET for OpenAPI descriptions. -- Include the most primitive Reader for ingesting OpenAPI JSON and YAML documents in both V2 and V3 formats. -- Provide OpenAPI description writers for both V2 and V3 specification formats. -- Enable developers to create Readers that translate different data formats into OpenAPI descriptions. - -# Installation - -- Install core Nuget package [**Microsoft.OpenApi**](https://www.nuget.org/packages/Microsoft.OpenApi) -- Install readers Nuget package [**Microsoft.OpenApi.Readers**](https://www.nuget.org/packages/Microsoft.OpenApi.Readers) - -# 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. - -The base JSON and YAML processors are built into this project. Below is the list of the other supported processor projects. - -- [**C# Comment / Annotation Processor**](https://github.com/Microsoft/OpenAPI.NET.CSharpAnnotations) : Converts standard .NET annotations ( /// comments ) emitted from your build (MSBuild.exe) into OpenAPI.NET document object. - -- [**OData CSDL Processor**](https://github.com/Microsoft/OpenAPI.NET.OData) : Converts the XML representation of the Entity Data Model (EDM) describing an OData Service into OpenAPI.NET document object. - -# Example Usage - -Creating an OpenAPI Document - -```C# -var document = new OpenApiDocument -{ - Info = new OpenApiInfo - { - Version = "1.0.0", - Title = "Swagger Petstore (Simple)", - }, - Servers = new List - { - new OpenApiServer { Url = "http://petstore.swagger.io/api" } - }, - Paths = new OpenApiPaths - { - ["/pets"] = new OpenApiPathItem - { - Operations = new() - { - [HttpMethod.Get] = new OpenApiOperation - { - Description = "Returns all pets from the system that the user has access to", - Responses = new OpenApiResponses - { - ["200"] = new OpenApiResponse - { - Description = "OK" - } - } - } - } - } - } -}; -``` - -Reading and writing an OpenAPI description - -```C# -var httpClient = new HttpClient -{ - BaseAddress = new Uri("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/") -}; - -var stream = await httpClient.GetStreamAsync("main/examples/v3.0/petstore.yaml"); - -// Read V3 as YAML -var openApiDocument = new OpenApiStreamReader().Read(stream, out var diagnostic); - -// Write V2 as JSON -var outputString = openApiDocument.Serialize(OpenApiSpecVersion.OpenApi2_0, OpenApiFormat.Json); - -``` - -# Validating/Testing OpenAPI descriptions -In order to test the validity of an OpenApi document, we avail the following tools: -- [Microsoft.OpenApi.Hidi](https://www.nuget.org/packages/Microsoft.OpenApi.Hidi) - - A commandline tool for validating and transforming OpenAPI descriptions. [Installation guidelines and documentation](https://github.com/microsoft/OpenAPI.NET/blob/main/src/Microsoft.OpenApi.Hidi/readme.md) - -- Microsoft.OpenApi.Workbench - - A workbench tool consisting of a GUI where you can test and convert OpenAPI descriptions in both JSON and YAML from v2-->v3 and vice versa. - - #### 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 - 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: - - - ![workbench preview](https://raw.githubusercontent.com/microsoft/OpenAPI.NET/main/docs/images/workbench.png "a screenshot of the workbench application") - - 5. Copy and paste your OpenAPI descriptions in the **Input Content** window or paste the path to the descriptions file in the **Input File** textbox and click on `Convert` to render the results. - -# Contributing - -This project welcomes contributions and suggestions. Most contributions require you to agree to a -Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us -the rights to use your contribution. For details, visit https://cla.microsoft.com. - -When you submit a pull request, a CLA-bot will automatically determine whether you need to provide -a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions -provided by the bot. You will only need to do this once across all repos using our CLA. - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. - -To provide feedback and ask questions you can use Stack Overflow with the [OpenAPI.NET](https://stackoverflow.com/questions/tagged/openapi.net) tag. + +![Category overview screenshot](https://raw.githubusercontent.com/microsoft/OpenAPI.NET/main/docs/images/oainet.png "Microsoft + OpenAPI = Love") + +# OpenAPI.NET + +|Package|Nuget| +|--|--| +|Models and Writers|[![nuget](https://img.shields.io/nuget/v/Microsoft.OpenApi.svg)](https://www.nuget.org/packages/Microsoft.OpenApi/) | +|YamlReader | [![nuget](https://img.shields.io/nuget/v/Microsoft.OpenApi.YamlReader.svg)](https://www.nuget.org/packages/Microsoft.OpenApi.YamlReader/) | +|Hidi|[![nuget](https://img.shields.io/nuget/v/Microsoft.OpenApi.Hidi.svg)](https://www.nuget.org/packages/Microsoft.OpenApi.Hidi/) + +The **OpenAPI.NET** SDK contains a useful object model for OpenAPI documents in .NET along with common serializers to extract raw OpenAPI JSON and YAML documents from the model. + +**See more information on the OpenAPI specification and its history here: OpenAPI Initiative** + +Project Objectives: + +- Provide a single shared object model in .NET for OpenAPI descriptions. +- Include the most primitive Reader for ingesting OpenAPI JSON and YAML documents in both V2 and V3 formats. +- Provide OpenAPI description writers for both V2 and V3 specification formats. +- Enable developers to create Readers that translate different data formats into OpenAPI descriptions. + +# Installation + +- 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.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. + +The base JSON and YAML processors are built into this project. Below is the list of the other supported processor projects. + +- [**C# Comment / Annotation Processor**](https://github.com/Microsoft/OpenAPI.NET.CSharpAnnotations) : Converts standard .NET annotations ( /// comments ) emitted from your build (MSBuild.exe) into OpenAPI.NET document object. + +- [**OData CSDL Processor**](https://github.com/Microsoft/OpenAPI.NET.OData) : Converts the XML representation of the Entity Data Model (EDM) describing an OData Service into OpenAPI.NET document object. + +# Example Usage + +Creating an OpenAPI Document + +```C# +var document = new OpenApiDocument +{ + Info = new OpenApiInfo + { + Version = "1.0.0", + Title = "Swagger Petstore (Simple)", + }, + Servers = new List + { + new OpenApiServer { Url = "http://petstore.swagger.io/api" } + }, + Paths = new OpenApiPaths + { + ["/pets"] = new OpenApiPathItem + { + Operations = new() + { + [HttpMethod.Get] = new OpenApiOperation + { + Description = "Returns all pets from the system that the user has access to", + Responses = new OpenApiResponses + { + ["200"] = new OpenApiResponse + { + Description = "OK" + } + } + } + } + } + } +}; +``` + +Reading and writing an OpenAPI description + +```C# +var (openApiDocument, _) = await OpenApiDocument.LoadAsync("https://raw.githubusercontent.com/OAI/OpenAPI-Specification/refs/heads/main/_archive_/schemas/v3.0/pass/petstore.yaml"); + +// Write V2 as JSON +var outputString = await openApiDocument.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); +``` + +# Validating/Testing OpenAPI descriptions +In order to test the validity of an OpenApi document, we avail the following tools: +- [Microsoft.OpenApi.Hidi](https://www.nuget.org/packages/Microsoft.OpenApi.Hidi) + + A commandline tool for validating and transforming OpenAPI descriptions. [Installation guidelines and documentation](https://github.com/microsoft/OpenAPI.NET/blob/main/src/Microsoft.OpenApi.Hidi/readme.md) + +- Microsoft.OpenApi.Workbench + + A workbench tool consisting of a GUI where you can test and convert OpenAPI descriptions in both JSON and YAML from v2-->v3 and vice versa. + + #### 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 + 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: + + + ![workbench preview](https://raw.githubusercontent.com/microsoft/OpenAPI.NET/main/docs/images/workbench.png "a screenshot of the workbench application") + + 5. Copy and paste your OpenAPI descriptions in the **Input Content** window or paste the path to the descriptions file in the **Input File** textbox and click on `Convert` to render the results. + +# Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +To provide feedback and ask questions you can use Stack Overflow with the [OpenAPI.NET](https://stackoverflow.com/questions/tagged/openapi.net) tag. 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 7860a2434..14eaacdf0 100644 --- a/docs/upgrade-guide-2.md +++ b/docs/upgrade-guide-2.md @@ -1,6 +1,6 @@ --- -title: Upgrade guide to OpenAPI.NET 2.1 -description: Learn how to upgrade your OpenAPI.NET version from 1.6 to 2.0 +title: Upgrade guide to OpenAPI.NET 2.0 +description: Learn how to upgrade your OpenAPI.NET version from 1.6 to 2.0 author: rachit.malik ms.author: malikrachit ms.topic: conceptual @@ -8,12 +8,23 @@ ms.topic: conceptual # Introduction -We are excited to announce the preview of a new version of the OpenAPI.NET library! +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] +> 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 -Since the release of the first version of the OpenAPI.NET library in 2018, there has not been a major version update to the library. With the addition of support for OpenAPI v3.1 it was necessary to make some breaking changes. With this opportunity, we have taken the time to make some other improvements to the library, based on the experience we have gained supporting a large community of users for the last six years . +Since the release of the first version of the OpenAPI.NET library in 2018, there has not been a major version update to the library. With the addition of support for OpenAPI v3.1 it was necessary to make some breaking changes. With this opportunity, we have taken the time to make some other improvements to the library, based on the experience we have gained supporting a large community of users for the last six years. ## Performance Improvements @@ -21,40 +32,116 @@ 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 behaviour of external references?] +[How does this change the behavior of external references?] + +### Results + +The following benchmark results outline an overall 50% reduction in processing time for the document parsing as well as 35% reduction in memory allocation when parsing JSON. +For YAML, the results between the different versions of the library are similar (some of the optimizations being compensated by the additional features). + +#### 1.X + +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------- |---------------:|-------------:|-------------:|-----------:|-----------:|----------:|-------------:| +| PetStoreYaml | 448.7 μs | 326.6 μs | 17.90 μs | 58.5938 | 11.7188 | - | 381.79 KB | +| PetStoreJson | 484.8 μs | 156.9 μs | 8.60 μs | 62.5000 | 15.6250 | - | 389.28 KB | +| GHESYaml | 1,008,349.6 μs | 565,392.0 μs | 30,991.04 μs | 66000.0000 | 23000.0000 | 4000.0000 | 382785 KB | +| GHESJson | 1,039,447.0 μs | 267,501.0 μs | 14,662.63 μs | 67000.0000 | 23000.0000 | 4000.0000 | 389970.77 KB | + +#### 2.X + +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------- |-------------:|--------------:|-------------:|-----------:|-----------:|----------:|-------------:| +| PetStoreYaml | 450.5 μs | 59.26 μs | 3.25 μs | 58.5938 | 11.7188 | - | 377.15 KB | +| PetStoreJson | 172.8 μs | 123.46 μs | 6.77 μs | 39.0625 | 7.8125 | - | 239.29 KB | +| GHESYaml | 943,452.7 μs | 137,685.49 μs | 7,547.01 μs | 66000.0000 | 21000.0000 | 3000.0000 | 389463.91 KB | +| GHESJson | 468,401.8 μs | 300,711.80 μs | 16,483.03 μs | 41000.0000 | 15000.0000 | 3000.0000 | 250934.62 KB | + +### Asynchronous API surface + +Any method which results in input/output access (memory, network, storage) is now Async and returns a `Task` to avoid any blocking calls an improve concurrency. + +For example: + +```csharp +var result = myOperation.SerializeAsJson(OpenApiSpecVersion.OpenApi2_0); +``` + +Is now: + +```csharp +var result = await myOperation.SerializeAsJsonAsync(OpenApiSpecVersion.OpenApi2_0); +``` + +### Trimming support + +To better support applications deployed in high performance environments or on devices which have limited compute available, any usage of reflection has been removed from the code base. This also brings support for trimming to the library. Any method relying on reflection has been removed or re-written. + +> Note: as part of this change, the following types have been removed: +> +> - StringExtensions + +### Collections are not initialized + +To lower the memory footprint of the library, collections are now NOT initialized anymore when instantiating any of the models. + +Example + +```csharp +var mySchema = new OpenApiSchema(); + +// 1.6: works +// 2.X: if null reference types is enabled in the target application, +// this will lead to a warning or error at compile time. +// And fail at runtime with a null reference exception. +mySchema.AnyOf.Add(otherSchema); + +// one solution +mySchema.AnyOf ??= new List(); +mySchema.AnyOf.Add(otherSchema); + +// alternative +mySchema.AnyOf = new List { otherSchema }; +``` ## Reduced Dependencies -In OpenAPI v1, it was necessary to include the Microsoft.OpenApi.Readers library to be able to read OpenAPI descriptions in either YAML or JSON. In OpenAPI.NET v2, the core Microsoft.OpenAPI library can both read and write JSON. It is only necessary to use the newly renamed [Microsoft.OpenApi.YamlReader](https://www.nuget.org/packages/Microsoft.OpenApi.YamlReader/) library if you need YAML support. This allows teams who are only working in JSON to avoid the additional dependency and therefore eliminate all non-.NET library references. +In OpenAPI v1, it was necessary to include the Microsoft.OpenApi.Readers library to be able to read OpenAPI descriptions in either YAML or JSON. In OpenAPI.NET v2, the core Microsoft.OpenAPI library can both read and write JSON. It is only necessary to use the newly renamed [Microsoft.OpenApi.YamlReader](https://www.nuget.org/packages/Microsoft.OpenApi.YamlReader/) library if you need YAML support. This allows teams who are only working in JSON to avoid the additional dependency and therefore eliminate all non-.NET library references. Once the dependency is added, the reader needs to be added to the reader settings as demonstrated below ```csharp -var settings = new OpenApiReaderSettings(); -settings.AddYamlReader(); +var settings = new OpenApiReaderSettings(); +settings.AddYamlReader(); -var result = OpenApiDocument.LoadAsync(openApiString, settings: settings); +var result = OpenApiDocument.LoadAsync(openApiString, settings: settings); ``` ## API Enhancements +### Loading the document + The v1 library attempted to mimic the pattern of `XmlTextReader` and `JsonTextReader` for the purpose of loading OpenAPI documents from strings, streams and text readers. ```csharp - var reader = new OpenApiStringReader(); - var openApiDoc = reader.Read(stringOpenApiDoc, out var diagnostic); +var reader = new OpenApiStringReader(); +var openApiDoc = reader.Read(stringOpenApiDoc, out var diagnostic); ``` -The same pattern can be used for `OpenApiStreamReader` and `OpenApiTextReader`. When we introduced the `ReadAsync` methods we eliminated the use of the `out` parameter. +The same pattern can be used for `OpenApiStreamReader` and `OpenApiTextReader`. When we introduced the `ReadAsync` methods we eliminated the use of the `out` parameter. To improve code readability, we've added deconstruction support to `ReadResult`. The properties also have been renamed to avoid confusion with their types. ```csharp - var reader = new OpenApiStreamReader(); - var (document, diagnostics) = await reader.ReadAsync(streamOpenApiDoc); +var reader = new OpenApiStreamReader(); +var (document, diagnostics) = await reader.ReadAsync(streamOpenApiDoc); +// or +var result = await reader.ReadAsync(streamOpenApiDoc); +var document = result.Document; +var diagnostics = result.Diagnostics; ``` A `ReadResult` object acts as a tuple of `OpenApiDocument` and `OpenApiDiagnostic`. -The challenge with this approach is that the reader classes are not very discoverable and the behaviour is not actually consistent with the `*TextReader` pattern that allows incrementally reading the document. This library does not support incrementally reading the OpenAPI Document. It only reads a complete document and returns an `OpenApiDocument` instance. +The challenge with this approach is that the reader classes are not very discoverable and the behavior is not actually consistent with the `*TextReader` pattern that allows incrementally reading the document. This library does not support incrementally reading the OpenAPI Document. It only reads a complete document and returns an `OpenApiDocument` instance. In the v2 library we are moving to the pattern used by classes like `XDocument` where a set of static `Load` and `Parse` methods are used as factory methods. @@ -67,11 +154,18 @@ public class OpenApiDocument { } ``` -This API design allows a developer to use IDE autocomplete to present all the loading options by simply knowing the name of the `OpenApiDocument` class. Each of these methods are layered on top of the more primitive methods to ensure consistent behaviour. +This API design allows a developer to use IDE autocomplete to present all the loading options by simply knowing the name of the `OpenApiDocument` class. Each of these methods are layered on top of the more primitive methods to ensure consistent behavior. + +As the YAML format is only supported when including the `Microsoft.OpenApi.YamlReader` library it was decided not to use an enum for the `format` parameter. We are considering implementing a more [strongly typed solution](https://github.com/microsoft/OpenAPI.NET/issues/1952) similar to the way that `HttpMethod` is implemented so that we have a strongly typed experience that is also extensible. -As the YAML format is only supported when including the `Microsoft.OpenApi.YamlReader` library it was decided not to use an enum for the `format` parameter. We are considering implementing a more [strongly typed solution](https://github.com/microsoft/OpenAPI.NET/issues/1952) similar to the way that `HttpMethod` is implemented so that we have a strongly typed experience that is also extensible. +When the loading methods are used without a format parameter, we will attempt to parse the document using the default JSON reader. If that fails and the YAML reader is registered, then we will attempt to read as YAML. The goal is always to provide the fastest path with JSON but still maintain the convenience of not having to care whether a URL points to YAML or JSON if you need that flexibility. -When the loading methods are used without a format parameter, we will attempt to parse the document using the default JSON reader. If that fails and the YAML reader is registered, then we will attempt to read as YAML. The goal is always to provide the fastest path with JSON but still maintain the convenience of not having to care whether a URL points to YAML or JSON if you need that flexibility. +### Additional exceptions + +While parsing an OpenAPI description, the library will now throw the following new exceptions: + +- `OpenApiReaderException` when the reader for the format cannot be found, the document cannot be parsed because it does not follow the format conventions, etc... +- `OpenApiUnsupportedSpecVersionException` when the document's version is not implemented by this version of the library and therefore cannot be parsed. ### Removing the OpenAPI Any classes @@ -89,109 +183,160 @@ In v2 we are removing this abstraction and relying on the `JsonNode` model to re Due to `JsonNode` implicit operators, this makes initialization sometimes easier, instead of: ```csharp - new OpenApiParameter - { - In = null, - Name = "username", - Description = "username to fetch", - Example = new OpenApiFloat(5), - }; +new OpenApiParameter +{ + In = null, + Name = "username", + Description = "username to fetch", + Example = new OpenApiFloat(5), +}; ``` the assignment becomes simply, ```csharp - Example = 0.5f, + Example = 0.5f, ``` For a more complex example, where the developer wants to create an extension that is an object they would do this in v1: ```csharp - var openApiObject = new OpenApiObject - { - {"stringProp", new OpenApiString("stringValue1")}, - {"objProp", new OpenApiObject()}, - { - "arrayProp", - new OpenApiArray - { - new OpenApiBoolean(false) - } - } - }; - var parameter = new OpenApiParameter(); - parameter.Extensions.Add("x-foo", new OpenApiAny(openApiObject)); +var openApiObject = new OpenApiObject +{ + {"stringProp", new OpenApiString("stringValue1")}, + {"objProp", new OpenApiObject()}, + { + "arrayProp", + new OpenApiArray + { + new OpenApiBoolean(false) + } + } +}; +var parameter = new OpenApiParameter(); +parameter.Extensions.Add("x-foo", openApiObject); ``` In v2, the equivalent code would be, ```csharp - var openApiObject = new JsonObject - { - {"stringProp", "stringValue1"}, - {"objProp", new JsonObject()}, - { - "arrayProp", - new JsonArray - { - false - } - } - }; - var parameter = new OpenApiParameter(); - parameter.Extensions.Add("x-foo", new OpenApiAny(openApiObject)); +var openApiObject = new JsonObject +{ + {"stringProp", "stringValue1"}, + {"objProp", new JsonObject()}, + { + "arrayProp", + new JsonArray + { + false + } + } +}; +var parameter = new OpenApiParameter(); +parameter.Extensions.Add("x-foo", new JsonNodeExtension(openApiObject)); + +``` + +> Note: as part of this change, the following types have been removed from the library: +> +> - AnyType +> - IOpenApiAny +> - OpenApiAnyCloneHelper +> - OpenApiArray +> - OpenApiBinary +> - OpenApiBoolean +> - OpenApiByte +> - OpenApiDate +> - OpenApiDateTime +> - OpenApiDouble +> - OpenApiFloat +> - OpenApiInteger +> - OpenApiLong +> - OpenApiNull +> - OpenApiObject +> - OpenApiPassword +> - OpenApiPrimitive +> - OpenApiString +> - PrimitiveType + +### Enable Null Reference Type Support + +Version 2.0 introduces support for null reference types, which improves type safety and reduces the likelihood of null reference exceptions. + +**Example:** + +```csharp +var document = new OpenApiDocument +{ + Components = null +}; +// 1.X: no compilation error or warning, but fails with a null reference exception at runtime +// 2.X: compilation error or warning depending on the project configuration +var componentA = document.Components["A"]; +``` + +### Ephemeral object properties are now in Metadata + +In version 1.X applications could add ephemeral properties to some of the models from the libraries. These properties would be carried along in an "Annotations" property, but not serialized. This is especially helpful when building integrations that build document in multiple phases and need additional context to complete the work. The property is now named metadata to avoid any confusion with other terms. The parent interface has also been renamed from `IOpenApiAnnotatable` to `IMetadataContainer`. + +```csharp +var schema = new OpenApiSchema(); + +// 1.X +var info = schema.Annotations["foo"]; +// 2.X +var info = schema.Metadata["foo"]; ``` ### Updates to OpenApiSchema -The OpenAPI 3.1 specification changes significantly how it leverages JSON Schema. In 3.0 and earlier, OpenAPI used a "subset, superset" of JSON Schema draft-4. This caused many problems for developers trying to use JSON Schema validation libraries with the JSON Schema in their OpenAPI descriptions. In OpenAPI 3.1, the 2020-12 draft version of JSON Schema was adopted and a new JSON Schema vocabulary was adopted to support OpenAPI specific keywords. All attempts to constrain what JSON Schema keywords could be used in OpenAPI were removed. +The OpenAPI 3.1 specification changes significantly how it leverages JSON Schema. In 3.0 and earlier, OpenAPI used a "subset, superset" of JSON Schema draft-4. This caused many problems for developers trying to use JSON Schema validation libraries with the JSON Schema in their OpenAPI descriptions. In OpenAPI 3.1, the 2020-12 draft version of JSON Schema was adopted and a new JSON Schema vocabulary was adopted to support OpenAPI specific keywords. All attempts to constrain what JSON Schema keywords could be used in OpenAPI were removed. #### New keywords introduced in 2020-12 ```csharp - /// $schema, a JSON Schema dialect identifier. Value must be a URI - public string Schema { get; set; } - /// $id - Identifies a schema resource with its canonical URI. - public string Id { get; set; } - /// $comment - reserves a location for comments from schema authors to readers or maintainers of the schema. - public string Comment { get; set; } - /// $vocabulary- used in meta-schemas to identify the vocabularies available for use in schemas described by that meta-schema. - public IDictionary Vocabulary { get; set; } - /// $dynamicRef - an applicator that allows for deferring the full resolution until runtime, at which point it is resolved each time it is encountered while evaluating an instance - public string DynamicRef { get; set; } - /// $dynamicAnchor - used to create plain name fragments that are not tied to any particular structural location for referencing purposes, which are taken into consideration for dynamic referencing. - public string DynamicAnchor { get; set; } - /// $defs - reserves a location for schema authors to inline re-usable JSON Schemas into a more general schema. - public IDictionary Definitions { get; set; } - public IDictionary PatternProperties { get; set; } = new Dictionary(); - public bool UnevaluatedProperties { get; set;} +/// $schema, a JSON Schema dialect identifier. Value must be a URI +public string Schema { get; set; } +/// $id - Identifies a schema resource with its canonical URI. +public string Id { get; set; } +/// $comment - reserves a location for comments from schema authors to readers or maintainers of the schema. +public string Comment { get; set; } +/// $vocabulary- used in meta-schemas to identify the vocabularies available for use in schemas described by that meta-schema. +public IDictionary Vocabulary { get; set; } +/// $dynamicRef - an applicator that allows for deferring the full resolution until runtime, at which point it is resolved each time it is encountered while evaluating an instance +public string DynamicRef { get; set; } +/// $dynamicAnchor - used to create plain name fragments that are not tied to any particular structural location for referencing purposes, which are taken into consideration for dynamic referencing. +public string DynamicAnchor { get; set; } +/// $defs - reserves a location for schema authors to inline re-usable JSON Schemas into a more general schema. +public IDictionary Definitions { get; set; } +public IDictionary PatternProperties { get; set; } = new Dictionary(); +public bool UnevaluatedProperties { get; set;} ``` #### Changes to existing keywords ```csharp - - public string? ExclusiveMaximum { get; set; } // type changed to reflect the new version of JSON schema - public string? ExclusiveMinimum { get; set; } // type changed to reflect the new version of JSON schema - public JsonSchemaType? Type { get; set; } // Was string, now flagged enum - public string? Maximum { get; set; } // type changed to overcome double vs decimal issues - public string? Minimum { get; set; } // type changed to overcome double vs decimal issues - - public JsonNode Default { get; set; } // Type matching no longer enforced. Was IOpenApiAny - public bool ReadOnly { get; set; } // No longer has defined semantics in OpenAPI 3.1 - public bool WriteOnly { get; set; } // No longer has defined semantics in OpenAPI 3.1 - - public JsonNode Example { get; set; } // No longer IOpenApiAny - public IList Examples { get; set; } - public IList Enum { get; set; } - public OpenApiExternalDocs ExternalDocs { get; set; } // OpenApi Vocab - public bool Deprecated { get; set; } // OpenApi Vocab - public OpenApiXml Xml { get; set; } // OpenApi Vocab - - public IDictionary Metadata { get; set; } // Custom property bag to be used by the application, used to be named annotations +public string? ExclusiveMaximum { get; set; } // type changed to reflect the new version of JSON schema +public string? ExclusiveMinimum { get; set; } // type changed to reflect the new version of JSON schema +public JsonSchemaType? Type { get; set; } // Was string, now flagged enum +public string? Maximum { get; set; } // type changed to overcome double vs decimal issues +public string? Minimum { get; set; } // type changed to overcome double vs decimal issues + +public JsonNode Default { get; set; } // Type matching no longer enforced. Was IOpenApiAny +public bool ReadOnly { get; set; } // No longer has defined semantics in OpenAPI 3.1 +public bool WriteOnly { get; set; } // No longer has defined semantics in OpenAPI 3.1 + +public JsonNode Example { get; set; } // No longer IOpenApiAny +public IList Examples { get; set; } +public IList Enum { get; set; } +public OpenApiExternalDocs ExternalDocs { get; set; } // OpenApi Vocab +public bool Deprecated { get; set; } // OpenApi Vocab +public OpenApiXml Xml { get; set; } // OpenApi Vocab + +public IDictionary Metadata { get; set; } // Custom property bag to be used by the application, used to be named annotations ``` #### OpenApiSchema methods @@ -199,13 +344,13 @@ The OpenAPI 3.1 specification changes significantly how it leverages JSON Schema Other than the addition of `SerializeAsV31`, the methods have not changed. ```csharp -public class OpenApiSchema : IOpenApiAnnotatable, IOpenApiExtensible, IOpenApiReferenceable, IOpenApiSerializable +public class OpenApiSchema : IMetadataContainer, IOpenApiExtensible, IOpenApiReferenceable, IOpenApiSerializable { - public OpenApiSchema() { } - public OpenApiSchema(OpenApiSchema schema) { } - public void SerializeAsV31(IOpenApiWriter writer) { } - public void SerializeAsV3(IOpenApiWriter writer) { } - public void SerializeAsV2(IOpenApiWriter writer) { } + public OpenApiSchema() { } + public OpenApiSchema(OpenApiSchema schema) { } + public void SerializeAsV31(IOpenApiWriter writer) { } + public void SerializeAsV3(IOpenApiWriter writer) { } + public void SerializeAsV2(IOpenApiWriter writer) { } } ``` @@ -214,75 +359,98 @@ public class OpenApiSchema : IOpenApiAnnotatable, IOpenApiExtensible, IOpenApiRe There are a number of new features in OpenAPI v3.1 that are now supported in OpenAPI.NET. +### JsonSchema Dialect and BaseUri in OpenApiDocument + +To enable full compatibility with JSON Schema, the `OpenApiDocument` class now supports a `JsonSchemaDialect` property. This property specifies the JSON Schema dialect used throughout the document, using a URI. By explicitly declaring the dialect, tooling can be directed to use a JSON Schema version other than the default [2020-12 draft](https://json-schema.org/draft/2020-12/json-schema-core.html). However, OpenAPI.NET does not guarantee compatibility with versions other than 2020-12. + +In addition, a `BaseUri` property has been added to represent the identity of the OpenAPI document. If the document’s identity is not provided or cannot be determined at based on its location, this property will be set to a generated placeholder URI. + +```csharp +/// +/// Describes an OpenAPI object (OpenAPI document). See: https://spec.openapis.org +/// +public class OpenApiDocument : IOpenApiSerializable, IOpenApiExtensible, IMetadataContainer +{ + /// + /// The default value for the $schema keyword within Schema Objects contained within this OAS document. This MUST be in the form of a URI. + /// + public Uri? JsonSchemaDialect { get; set; } + + /// + /// Absolute location of the document or a generated placeholder if location is not given + /// + public Uri BaseUri { get; internal set; } +} +``` + ### Webhooks ```csharp -public class OpenApiDocument : IOpenApiSerializable, IOpenApiExtensible, IOpenApiAnnotatable { - /// - /// The incoming webhooks that MAY be received as part of this API and that the API consumer MAY choose to implement. - /// A map of requests initiated other than by an API call, for example by an out of band registration. - /// The key name is a unique string to refer to each webhook, while the (optionally referenced) Path Item Object describes a request that may be initiated by the API provider and the expected responses - /// - public IDictionary? Webhooks { get; set; } = new Dictionary(); +public class OpenApiDocument : IOpenApiSerializable, IOpenApiExtensible, IOpenApiMetadataContainer +{ + public IDictionary? Webhooks { get; set; } = new Dictionary(); } ``` ### Summary in info object ```csharp - +public class OpenApiInfo : IOpenApiSerializable, IOpenApiExtensible +{ /// - /// Open API Info Object, it provides the metadata about the Open API. + /// A short summary of the API. /// - public class OpenApiInfo : IOpenApiSerializable, IOpenApiExtensible - { - /// - /// A short summary of the API. - /// - public string Summary { get; set; } - } + public string Summary { get; set; } +} ``` ### License SPDX identifiers ```csharp +/// +/// License Object. +/// +public class OpenApiLicense : IOpenApiSerializable, IOpenApiExtensible +{ /// - /// License Object. + /// An SPDX license expression for the API. The identifier field is mutually exclusive of the Url property. /// - public class OpenApiLicense : IOpenApiSerializable, IOpenApiExtensible - { - /// - /// An SPDX license expression for the API. The identifier field is mutually exclusive of the Url property. - /// - public string Identifier { get; set; } - } + public string Identifier { get; set; } +} ``` ### Reusable path items ```csharp +/// +/// Components Object. +/// +public class OpenApiComponents : IOpenApiSerializable, IOpenApiExtensible +{ /// - /// Components Object. + /// An object to hold reusable Object. /// - public class OpenApiComponents : IOpenApiSerializable, IOpenApiExtensible - { - /// - /// An object to hold reusable Object. - /// - public IDictionary? PathItems { get; set; } = new Dictionary(); - } + public IDictionary? PathItems { get; set; } +} ``` -#### Summary and Description alongside $ref +### Summary and Description alongside $ref Through the use of proxy objects in order to represent references, it is now possible to set the Summary and Description property on an object that is a reference. This was previously not possible. ```csharp - var parameter = new OpenApiParameterReference("id", hostdocument) - { - Description = "Customer Id" - }; +var parameter = new OpenApiParameterReference("id", hostDocument) +{ + Description = "Customer Id" +}; +``` + +Once serialized results in: + +```yaml +$ref: id +description: Customer Id ``` ### Use HTTP Method Object Instead of Enum @@ -304,31 +472,7 @@ OpenApiOperation operation = new OpenApiOperation }; ``` -#### 2. Enable Null Reference Type Support - -Version 2.0 preview 13 introduces support for null reference types, which improves type safety and reduces the likelihood of null reference exceptions. - -**Example:** - -```csharp -// Before (1.6) -OpenApiDocument document = new OpenApiDocument -{ - Components = new OpenApiComponents() -}; - -// After (2.0) -OpenApiDocument document = new OpenApiDocument -{ - Components = new OpenApiComponents() - { - Schemas = new Dictionary() - } -}; - -``` - -#### 3. References as Components +### References as Components References can now be used as components, allowing for more modular and reusable OpenAPI documents. @@ -350,9 +494,9 @@ OpenApiComponents components = new OpenApiComponents { Schemas = new Dictionary { - ["MySchema"] = new OpenApiSchema + ["MySchema"] = new OpenApiSchemaReference("MyOtherSchema") { - Reference = new OpenApiSchemaReference("MySchema") + Description = "Other reusable schema from initial schema" } } }; @@ -361,14 +505,160 @@ OpenApiComponents components = new OpenApiComponents ### OpenApiDocument.SerializeAs() The `SerializeAs()` method simplifies serialization scenarios, making it easier to convert OpenAPI documents to different formats. + **Example:** ```csharp OpenApiDocument document = new OpenApiDocument(); -string json = document.SerializeAs(OpenApiSpecVersion.OpenApi3_0, OpenApiFormat.Json); +string json = await document.SerializeAsync(OpenApiSpecVersion.OpenApi3_0, OpenApiConstants.Json); + +``` + +### Use OpenApiConstants string Instead of OpenApiFormat Enum + +`OpenApiConstants` are now used instead the `OpenApiFormat` enumeration. + +**Example:** + +```csharp +// Before (1.6) +var outputString = openApiDocument.Serialize(OpenApiSpecVersion.OpenApi2_0, OpenApiFormat.Json); + +// After (2.0) +var outputString = await openApiDocument.SerializeAsync(OpenApiSpecVersion.OpenApi2_0, OpenApiConstants.Json); +``` + +### OpenApiSchema's Type property is now a flaggable enum + +In v2.0, the Type property in `OpenApiSchema` is now defined as a flaggable enum, allowing consumers to swap nullable for type arrays. + +**Example:** + +```csharp +// v1.6.x +var schema = new OpenApiSchema +{ + Type = "string", + Nullable = true +} + +// v2.0 +// bitwise OR(|) - combines flags to allow multiple types +var schema = new OpenApiSchema +{ + Type = JsonSchemaType.String | JsonSchemaType.Null +} + +// bitwise NOT(~) - inverts bits; filters out null flag +var schema = new OpenApiSchema +{ + Type = JsonSchemaType.String & ~JsonSchemaType.Null +} + +// bitwise AND(&) - intersects flags to check for a specific type +var schema = new OpenApiSchema +{ + Type = (JsonSchemaType.String & JsonSchemaType.Null) == JsonSchemaType.Null +} ``` +### Component registration in a document's workspace + +When loading up a file into an in-memory document, all the components contained in the document are registered within the document's workspace by default to aid with reference resolution. +However if you're working directly with a DOM and you need the references resolved, you can register the components as below: + +```csharp +// register all components +document.Workspace.RegisterComponents(OpenApiDocument document); + +// register single component +document.AddComponent(string id, T componentToRegister); +``` + +### Refactored model architecture + +The following structural improvements have been made to the OpenAPI model layer to enhance type safety, extensibility, and maintainability: + +1. Model Interfaces Introduced: +Each model now has a corresponding interface (e.g., `IOpenApiSchema` for `OpenApiSchema`). This allows for better abstraction and testing support, while also simplifying cross-cutting concerns like serialization. + +2. Models as Reference Types: +All models are now implemented as reference types to ensure consistent identity semantics, especially when managing circular references or shared definitions. + +3. Type Assertion Pattern Adopted: +A standardized pattern has been introduced for casting model instances to specific types safely and predictably, reducing the risk of invalid casts or reflection-based logic. + +4. Removed Reference Fields from Base Models: +Properties like `Reference` that were previously defined on base model types have been removed. Models that support referencing now handle this behavior explicitly via composition rather than inheritance. + +5. New Target and RecursiveTarget Properties: +A `Target` property that points to the actual resolved model instance as well as a `RecursiveTarget` property that handles recursive references and supports advanced dereferencing logic have been introduced. + +6. Removed OpenApiReferenceResolver: +This resolver class has been removed in favor of a more streamlined resolution model using the `Target` and `RecursiveTarget` properties along with updated reader/serializer pipelines. + +### Visitor and Validator now pass an interface model + +**Example:** + +```csharp +//v1.6.x +public override void Visit(OpenApiParameter parameter){} + +//v2.0 +public override void Visit(IOpenApiParameter parameter){} +``` + +### Cleaned up the IEffective/GetEffective infrastructure + +All the `IEffective` and `GetEffective` infrastructure in the models have been removed as we've implemented lazy reference resolution using the proxy design. + +### Shallow Copy in place of copy constructors + +Copy constructors for referenceable components have been made internal, a new `CreateShallowCopy()` method has been exposed on these models to facilitate cloning. + +**Example:** + +```csharp +var schema = new OpenApiSchema(); +var schemaCopy = schema.CreateShallowCopy(); +``` + +### Duplicated _style Property on Parameter Removed + +The redundant _style property on the Parameter model has been removed to simplify the model's structure. + +### Discriminator now use References + +Discriminator mappings have been updated from using a `Dictionary` to a `Dictionary`. This change improves the handling of discriminator mappings by referencing OpenAPI schema components more explicitly, which enhances schema resolution. + +**Example:** + +```csharp +// v1.6.x +Discriminator = new() +{ + PropertyName = "@odata.type", + Mapping = new Dictionary { + { + "#microsoft.graph.directoryObject", "#/components/schemas/microsoft.graph.directoryObject" + } + } +} + +//v2.0 +Discriminator = new() +{ + PropertyName = "@odata.type", + Mapping = new Dictionary { + { + "#microsoft.graph.directoryObject", new OpenApiSchemaReference("microsoft.graph.directoryObject") + } + } +} +``` + ### Bug Fixes ## Serialization of References @@ -386,5 +676,5 @@ OpenApiSchemaReference schemaRef = new OpenApiSchemaReference("MySchema") ## Feedback -If you have any feedback please file a GitHub issue [here](https://github.com/microsoft/OpenAPI.NET/issues) +If you have any feedback please file [a new GitHub issue](https://github.com/microsoft/OpenAPI.NET/issues) The team is looking forward to hear your experience trying the new version and we hope you have fun busting out your OpenAPI 3.1 descriptions. diff --git a/docs/upgrade-guide-3.md b/docs/upgrade-guide-3.md new file mode 100644 index 000000000..e874a8998 --- /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.0` 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.0` 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 aea4e9e3a..3d946171e 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "8.0.406" + "version": "8.0.416" } } \ 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 e1ca8eed6..993b5da5e 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,18 @@ ``` -BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.3476) +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.408 - [Host] : .NET 8.0.15 (8.0.1525.16413), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI - ShortRun : .NET 8.0.15 (8.0.1525.16413), X64 RyuJIT AVX-512F+CD+BW+DQ+VL+VBMI +.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 Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3 ``` -| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | -|------------- |-------------:|--------------:|-------------:|-----------:|-----------:|----------:|-------------:| -| PetStoreYaml | 450.5 μs | 59.26 μs | 3.25 μs | 58.5938 | 11.7188 | - | 377.15 KB | -| PetStoreJson | 172.8 μs | 123.46 μs | 6.77 μs | 39.0625 | 7.8125 | - | 239.29 KB | -| GHESYaml | 943,452.7 μs | 137,685.49 μs | 7,547.01 μs | 66000.0000 | 21000.0000 | 3000.0000 | 389463.91 KB | -| GHESJson | 468,401.8 μs | 300,711.80 μs | 16,483.03 μs | 41000.0000 | 15000.0000 | 3000.0000 | 250934.62 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------- |---------------:|---------------:|--------------:|-----------:|-----------:|----------:|-------------:| +| PetStoreYaml | 913.5 μs | 3,348.1 μs | 183.52 μs | 58.5938 | 11.7188 | - | 361.25 KB | +| PetStoreJson | 425.1 μs | 327.5 μs | 17.95 μs | 35.1563 | 5.8594 | - | 223.39 KB | +| GHESYaml | 1,765,825.8 μs | 5,036,336.6 μs | 276,058.60 μs | 60000.0000 | 23000.0000 | 4000.0000 | 345082.98 KB | +| GHESJson | 848,197.4 μs | 1,381,723.6 μs | 75,736.93 μs | 33000.0000 | 12000.0000 | 2000.0000 | 206597.63 KB | diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv index ff86e86e7..ec3b99fae 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv @@ -1,5 +1,5 @@ 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,450.5 μs,59.26 μs,3.25 μs,58.5938,11.7188,0.0000,377.15 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,172.8 μs,123.46 μs,6.77 μs,39.0625,7.8125,0.0000,239.29 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,"943,452.7 μs","137,685.49 μs","7,547.01 μs",66000.0000,21000.0000,3000.0000,389463.91 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,"468,401.8 μs","300,711.80 μs","16,483.03 μs",41000.0000,15000.0000,3000.0000,250934.62 KB +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,913.5 μs,"3,348.1 μs",183.52 μs,58.5938,11.7188,0.0000,361.25 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,425.1 μs,327.5 μs,17.95 μs,35.1563,5.8594,0.0000,223.39 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,"1,765,825.8 μs","5,036,336.6 μs","276,058.60 μs",60000.0000,23000.0000,4000.0000,345082.98 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,"848,197.4 μs","1,381,723.6 μs","75,736.93 μs",33000.0000,12000.0000,2000.0000,206597.63 KB diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html index 497e2dda7..feb037f9f 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-20250409-150544 +performance.Descriptions-20251024-100447