diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 87b987112..c3da60bcb 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -16,6 +16,9 @@ updates: MicrosoftExtensions: patterns: - "Microsoft.Extensions.*" + coverlet: + patterns: + - "coverlet.*" - package-ecosystem: dotnet-sdk directory: / schedule: diff --git a/.github/workflows/auto-merge-dependabot.yml b/.github/workflows/auto-merge-dependabot.yml index ba2243c97..9d9039433 100644 --- a/.github/workflows/auto-merge-dependabot.yml +++ b/.github/workflows/auto-merge-dependabot.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.5.0 + uses: dependabot/fetch-metadata@v3.1.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index b9d453d2a..fb99868ee 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -9,6 +9,10 @@ jobs: ci: name: Continuous Integration runs-on: ubuntu-latest + permissions: + contents: read + code-quality: write + pull-requests: read env: ARTIFACTS_FOLDER: ${{ github.workspace }}/Artifacts GITHUB_RUN_NUMBER: ${{ github.run_number }} @@ -27,6 +31,7 @@ jobs: id: checkout_repo uses: actions/checkout@v6 with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 @@ -40,7 +45,36 @@ jobs: id: run_unit_tests shell: pwsh run: | - dotnet test Microsoft.OpenApi.slnx -c Release -v n + dotnet test Microsoft.OpenApi.slnx -c Release --no-build -v n --collect:"XPlat Code Coverage" + + - name: Install report generator + shell: pwsh + run: | + dotnet tool install --global dotnet-reportgenerator-globaltool + + - name: Generate coverage report + shell: pwsh + run: | + reportgenerator -reports:**/coverage.cobertura.xml -targetdir:./reports/coverage -reporttypes:"Html;MarkdownSummaryGithub;Cobertura" + + - name: Add coverage to job summary + shell: bash + run: | + cat ./reports/coverage/SummaryGithub.md >> "$GITHUB_STEP_SUMMARY" + + - name: Upload coverage report + if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]') || (github.event_name != 'pull_request' && github.ref_name == github.event.repository.default_branch) + uses: actions/upload-code-coverage@v1 + with: + file: ./reports/coverage/Cobertura.xml + language: CSharp + label: code-coverage/dotnet + + - name: Upload coverage artifact + uses: actions/upload-artifact@v7 + with: + name: coverage + path: reports/coverage validate-trimming: name: Validate Project for Trimming diff --git a/.github/workflows/promote-shipped-apis.yml b/.github/workflows/promote-shipped-apis.yml index aa611b7a0..569a73905 100644 --- a/.github/workflows/promote-shipped-apis.yml +++ b/.github/workflows/promote-shipped-apis.yml @@ -16,9 +16,9 @@ jobs: steps: - name: Generate GitHub App token id: app-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@v3 with: - app-id: ${{ vars.RELEASE_PLEASE_TOKEN_PROVIDER_APP_ID }} + client-id: ${{ vars.RELEASE_PLEASE_TOKEN_PROVIDER_APP_ID }} private-key: ${{ secrets.RELEASE_PLEASE_TOKEN_PROVIDER_PEM }} - name: Checkout code diff --git a/.github/workflows/release-please-gha.yml b/.github/workflows/release-please-gha.yml index 6e2c9825d..a6fdc1927 100644 --- a/.github/workflows/release-please-gha.yml +++ b/.github/workflows/release-please-gha.yml @@ -22,7 +22,16 @@ permissions: contents: read jobs: + check-secret: + runs-on: ubuntu-latest + outputs: + has-token: ${{ steps.check.outputs.has-token }} + steps: + - id: check + run: echo "has-token=${{ secrets.RELEASE_PLEASE_TOKEN_PROVIDER_PEM != '' }}" >> $GITHUB_OUTPUT release: + needs: check-secret + if: needs.check-secret.outputs.has-token == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 @@ -53,13 +62,13 @@ jobs: - name: Generate GitHub App token id: app-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@v3 with: - app-id: ${{ vars.RELEASE_PLEASE_TOKEN_PROVIDER_APP_ID }} + client-id: ${{ vars.RELEASE_PLEASE_TOKEN_PROVIDER_APP_ID }} private-key: ${{ secrets.RELEASE_PLEASE_TOKEN_PROVIDER_PEM }} - name: Release Please - uses: googleapis/release-please-action@v4 + uses: googleapis/release-please-action@v5 with: token: ${{ steps.app-token.outputs.token }} config-file: release-please-config.json diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ca3f730c7..21f60560a 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.7.5" + ".": "2.10.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index b22097196..ef8c896c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,61 @@ # Changelog +## [2.10.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.9.0...v2.10.0) (2026-07-03) + + +### Features + +* add JsonConverter for OpenApiSchema System.Text.Json serialization ([#2915](https://github.com/microsoft/OpenAPI.NET/issues/2915)) ([465521b](https://github.com/microsoft/OpenAPI.NET/commit/465521ba723ea9377d6838395d58e7212d64ece7)) +* **library:** support schema keywords on references ([2749463](https://github.com/microsoft/OpenAPI.NET/commit/2749463f1ec1d452ba2334876d32466ea45ee8d1)), closes [#2903](https://github.com/microsoft/OpenAPI.NET/issues/2903) + + +### Bug Fixes + +* Don't silently skip null assignment to OpenApiDocument.Tags ([#2917](https://github.com/microsoft/OpenAPI.NET/issues/2917)) ([6a45a82](https://github.com/microsoft/OpenAPI.NET/commit/6a45a826e095d198605b340c50d46c066eed72ad)) +* handling of nullable enums for 3.0 ([#2920](https://github.com/microsoft/OpenAPI.NET/issues/2920)) ([f4778e0](https://github.com/microsoft/OpenAPI.NET/commit/f4778e024e6bf033a4b6c4b90ea6636de712f826)) +* **library:** keep v3 schema references ref-only ([8d811c3](https://github.com/microsoft/OpenAPI.NET/commit/8d811c3e76a8963be6e7a605b80c98d0ea0c63a5)) +* preserve JSON Schema 2020-12 keyword siblings on $ref schemas for OAS 3.1+ ([#2896](https://github.com/microsoft/OpenAPI.NET/issues/2896)) ([fb20d46](https://github.com/microsoft/OpenAPI.NET/commit/fb20d460ffe95505847da5a6e4c6fc065e41d9d1)) +* preserve JSON Schema 2020-12 keyword siblings on $ref schemas for OAS 3.1+ ([#2896](https://github.com/microsoft/OpenAPI.NET/issues/2896)) ([c79a83e](https://github.com/microsoft/OpenAPI.NET/commit/c79a83e74a0a41367c37f050d78d3e0ace838bc0)) +* use async method for crypto flush ([677b519](https://github.com/microsoft/OpenAPI.NET/commit/677b5197d9c4f7de2122852ad49d5012f7082e71)) + +## [2.9.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.8.0...v2.9.0) (2026-06-10) + + +### Features + +* add contains/minContains/maxContains members ([fadb422](https://github.com/microsoft/OpenAPI.NET/commit/fadb42225561e150aa99459c0c359c00cf52fb1a)) +* **library:** add missing json schema properties ([db41a3c](https://github.com/microsoft/OpenAPI.NET/commit/db41a3c952e651f80a6bbdb7d8aac001031e6dd3)) + + +### Bug Fixes + +* **library:** always copy unevaluated properties ([3951a31](https://github.com/microsoft/OpenAPI.NET/commit/3951a310da6056fd7a6852fda129a8ad8583639a)) +* **library:** avoid false circular refs for external schema re-exports ([a058913](https://github.com/microsoft/OpenAPI.NET/commit/a058913943d4c197ccf03742f1c67ecc50e11a03)) +* **library:** avoid false circular refs for external schema re-exports ([1bace68](https://github.com/microsoft/OpenAPI.NET/commit/1bace6804bc15c22b7665df7c66bed2a4a27bad0)) +* **library:** merge contains compat members into missing properties ([7dc45e1](https://github.com/microsoft/OpenAPI.NET/commit/7dc45e14160825f79d5e64e6c9c8ba2a02900bcf)) +* **library:** remove unshipped schema extension fallback ([b301827](https://github.com/microsoft/OpenAPI.NET/commit/b30182773fd875fb0a55c1a2bf48018910922ead)) +* **library:** use version-specific schema keyword callbacks ([f93d76a](https://github.com/microsoft/OpenAPI.NET/commit/f93d76a4643022fc5d35b3d8ca8078276bbcce4f)) +* **library:** use x-jsonschema schema extensions ([ec04a7f](https://github.com/microsoft/OpenAPI.NET/commit/ec04a7fcd43c296602edc15c197dc49cee112472)) + +## [2.8.0](https://github.com/microsoft/OpenAPI.NET/compare/v2.7.6...v2.8.0) (2026-06-01) + + +### Features + +* **reader:** remove ParseNode infrastructure ([d7c6a9d](https://github.com/microsoft/OpenAPI.NET/commit/d7c6a9dbe2da8cccac2a3dcbc5277bf0f20b0aa9)) + + +### Bug Fixes + +* **reader:** adapt no-parse-node backport for v2 ([ddd2539](https://github.com/microsoft/OpenAPI.NET/commit/ddd253990f9741bcc3b5e649c71c8908728694c2)) + +## [2.7.6](https://github.com/microsoft/OpenAPI.NET/compare/v2.7.5...v2.7.6) (2026-05-28) + + +### Bug Fixes + +* **reader:** preserve nullable Null flag when type appears after nullable in V3.1/V3.2 deserializers ([288e95a](https://github.com/microsoft/OpenAPI.NET/commit/288e95aa743cb98dc69b44577ae78956f3f1c7c4)) + ## [2.7.5](https://github.com/microsoft/OpenAPI.NET/compare/v2.7.4...v2.7.5) (2026-05-26) diff --git a/Directory.Build.props b/Directory.Build.props index f06b5bb92..d8aa99b81 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.7.5 + 2.10.0 diff --git a/global.json b/global.json index d895dfe5a..12f5b9de6 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "10.0.300" + "version": "10.0.301" } } \ 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 36532861e..c6bade521 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report-github.md @@ -1,20 +1,20 @@ ``` -BenchmarkDotNet v0.15.8, Linux Ubuntu 24.04.4 LTS (Noble Numbat) -AMD EPYC 7763 2.79GHz, 1 CPU, 4 logical and 2 physical cores -.NET SDK 10.0.204 - [Host] : .NET 8.0.27 (8.0.27, 8.0.2726.22922), X64 RyuJIT x86-64-v3 - ShortRun : .NET 8.0.27 (8.0.27, 8.0.2726.22922), X64 RyuJIT x86-64-v3 +BenchmarkDotNet v0.15.8, Windows 11 (10.0.26200.8655/25H2/2025Update/HudsonValley2) +Snapdragon X 12-core X1E80100 3.40 GHz (Max: 3.42GHz), 1 CPU, 12 logical and 12 physical cores +.NET SDK 10.0.301 + [Host] : .NET 8.0.28 (8.0.28, 8.0.2826.26413), Arm64 RyuJIT armv8.0-a + ShortRun : .NET 8.0.28 (8.0.28, 8.0.2826.26413), Arm64 RyuJIT armv8.0-a Job=ShortRun IterationCount=3 LaunchCount=1 WarmupCount=3 ``` -| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | -|------------- |---------------:|--------------:|-------------:|-----------:|-----------:|----------:|-------------:| -| PetStoreYaml | 528.6 μs | 178.98 μs | 9.81 μs | 19.5313 | 3.9063 | - | 363.54 KB | -| PetStoreJson | 232.1 μs | 12.90 μs | 0.71 μs | 13.6719 | 1.9531 | - | 225.39 KB | -| GHESYaml | 1,072,146.4 μs | 200,482.34 μs | 10,989.11 μs | 24000.0000 | 19000.0000 | 3000.0000 | 345905.05 KB | -| GHESJson | 483,939.6 μs | 288,033.88 μs | 15,788.11 μs | 13000.0000 | 9000.0000 | 2000.0000 | 207426.91 KB | -| GHESNextYaml | 1,325,231.0 μs | 240,938.48 μs | 13,206.65 μs | 36000.0000 | 20000.0000 | 3000.0000 | 542041.88 KB | -| GHESNextJson | 699,920.8 μs | 85,692.01 μs | 4,697.07 μs | 25000.0000 | 11000.0000 | 2000.0000 | 407243.96 KB | +| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | +|------------- |--------------:|---------------:|--------------:|-----------:|-----------:|----------:|-------------:| +| PetStoreYaml | 281.26 μs | 87.951 μs | 4.821 μs | 74.2188 | 15.6250 | - | 313.05 KB | +| PetStoreJson | 99.37 μs | 7.974 μs | 0.437 μs | 42.4805 | 8.3008 | - | 175.2 KB | +| GHESYaml | 558,007.40 μs | 245,240.510 μs | 13,442.460 μs | 45000.0000 | 19000.0000 | 3000.0000 | 254573.63 KB | +| GHESJson | 263,444.90 μs | 586,112.802 μs | 32,126.821 μs | 18000.0000 | 9000.0000 | 2000.0000 | 111745.13 KB | +| GHESNextYaml | 785,094.03 μs | 214,946.431 μs | 11,781.939 μs | 80000.0000 | 20000.0000 | 3000.0000 | 450674.2 KB | +| GHESNextJson | 461,067.00 μs | 50,227.814 μs | 2,753.156 μs | 53000.0000 | 13000.0000 | 3000.0000 | 312434.25 KB | diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv index 7bf9078cd..7d98a61ea 100644 --- a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv +++ b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.csv @@ -1,7 +1,7 @@ Method,Job,AnalyzeLaunchVariance,EvaluateOverhead,MaxAbsoluteError,MaxRelativeError,MinInvokeCount,MinIterationTime,OutlierMode,Affinity,EnvironmentVariables,Jit,LargeAddressAware,Platform,PowerPlanMode,Runtime,AllowVeryLargeObjects,Concurrent,CpuGroups,Force,HeapAffinitizeMask,HeapCount,NoAffinitize,RetainVm,Server,Arguments,BuildConfiguration,Clock,EngineFactory,NuGetReferences,Toolchain,IsMutator,InvocationCount,IterationCount,IterationTime,LaunchCount,MaxIterationCount,MaxWarmupIterationCount,MemoryRandomization,MinIterationCount,MinWarmupIterationCount,RunStrategy,UnrollFactor,WarmupCount,Mean,Error,StdDev,Gen0,Gen1,Gen2,Allocated -PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,528.6 μs,178.98 μs,9.81 μs,19.5313,3.9063,0.0000,363.54 KB -PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,232.1 μs,12.90 μs,0.71 μs,13.6719,1.9531,0.0000,225.39 KB -GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,072,146.4 μs","200,482.34 μs","10,989.11 μs",24000.0000,19000.0000,3000.0000,345905.05 KB -GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"483,939.6 μs","288,033.88 μs","15,788.11 μs",13000.0000,9000.0000,2000.0000,207426.91 KB -GHESNextYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"1,325,231.0 μs","240,938.48 μs","13,206.65 μs",36000.0000,20000.0000,3000.0000,542041.88 KB -GHESNextJson,ShortRun,False,Default,Default,Default,Default,Default,Default,1111,Empty,RyuJit,Default,X64,8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c,.NET 8.0,False,True,False,True,Default,Default,False,False,False,Default,Default,Default,Default,Default,Default,Default,Default,3,Default,1,Default,Default,Default,Default,Default,Default,16,3,"699,920.8 μs","85,692.01 μs","4,697.07 μs",25000.0000,11000.0000,2000.0000,407243.96 KB +PetStoreYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,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,281.26 μs,87.951 μs,4.821 μs,74.2188,15.6250,0.0000,313.05 KB +PetStoreJson,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,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,99.37 μs,7.974 μs,0.437 μs,42.4805,8.3008,0.0000,175.2 KB +GHESYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,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,"558,007.40 μs","245,240.510 μs","13,442.460 μs",45000.0000,19000.0000,3000.0000,254573.63 KB +GHESJson,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,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,"263,444.90 μs","586,112.802 μs","32,126.821 μs",18000.0000,9000.0000,2000.0000,111745.13 KB +GHESNextYaml,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,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,"785,094.03 μs","214,946.431 μs","11,781.939 μs",80000.0000,20000.0000,3000.0000,450674.2 KB +GHESNextJson,ShortRun,False,Default,Default,Default,Default,Default,Default,111111111111,Empty,RyuJit,Default,Arm64,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,"461,067.00 μs","50,227.814 μs","2,753.156 μs",53000.0000,13000.0000,3000.0000,312434.25 KB diff --git a/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html b/performance/benchmark/BenchmarkDotNet.Artifacts/results/performance.Descriptions-report.html index a694be1ea..f09c24ea8 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-20260526-151849 +performance.Descriptions-20260626-150505