From 41e3ef66ba49218fe170f5a2cbbf95de96b0c8fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Aug 2025 15:15:24 +0000 Subject: [PATCH 1/3] chore(deps): bump actions/setup-java from 4 to 5 Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5. - [Release notes](https://github.com/actions/setup-java/releases) - [Commits](https://github.com/actions/setup-java/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-java dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/sonarcloud.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sonarcloud.yml b/.github/workflows/sonarcloud.yml index 3bad1bc53..5ec33537f 100644 --- a/.github/workflows/sonarcloud.yml +++ b/.github/workflows/sonarcloud.yml @@ -35,7 +35,7 @@ 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 From 59d7c81fae8cbc320a9005c529806e94cc4e9444 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Thu, 28 Aug 2025 20:50:56 -0400 Subject: [PATCH 2/3] feat: adds the detected format as part of the diagnostic (#2482) feat: adds the detected format to the diagnostics ------- Signed-off-by: Vincent Biret --- .../OpenApiYamlReader.cs | 17 +++++++++----- .../Reader/OpenApiDiagnostic.cs | 5 +++++ .../Reader/OpenApiJsonReader.cs | 10 +++++---- .../OpenApiStreamReaderTests.cs | 3 ++- .../V2Tests/OpenApiServerTests.cs | 3 ++- .../V31Tests/OpenApiDocumentTests.cs | 4 ++-- .../V3Tests/OpenApiCallbackTests.cs | 4 ++-- .../V3Tests/OpenApiDocumentTests.cs | 22 +++++++++++-------- .../V3Tests/OpenApiSchemaTests.cs | 6 +++-- .../PublicApi/PublicApi.approved.txt | 1 + .../Reader/OpenApiModelFactoryTests.cs | 1 + 11 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/Microsoft.OpenApi.YamlReader/OpenApiYamlReader.cs b/src/Microsoft.OpenApi.YamlReader/OpenApiYamlReader.cs index a2000327d..171c3cc38 100644 --- a/src/Microsoft.OpenApi.YamlReader/OpenApiYamlReader.cs +++ b/src/Microsoft.OpenApi.YamlReader/OpenApiYamlReader.cs @@ -31,14 +31,14 @@ public async Task ReadAsync(Stream input, if (input is null) throw new ArgumentNullException(nameof(input)); if (input is MemoryStream memoryStream) { - return Read(memoryStream, location, settings); + return UpdateFormat(Read(memoryStream, location, settings)); } else { using var preparedStream = new MemoryStream(); await input.CopyToAsync(preparedStream, copyBufferSize, cancellationToken).ConfigureAwait(false); preparedStream.Position = 0; - return Read(preparedStream, location, settings); + return UpdateFormat(Read(preparedStream, location, settings)); } } @@ -67,20 +67,27 @@ public ReadResult Read(MemoryStream input, { var diagnostic = new OpenApiDiagnostic(); diagnostic.Errors.Add(new($"#line={ex.LineNumber}", ex.Message)); + diagnostic.Format = OpenApiConstants.Yaml; return new() { Document = null, - Diagnostic = diagnostic + Diagnostic = diagnostic, }; } - return Read(jsonNode, location, settings); + return UpdateFormat(Read(jsonNode, location, settings)); + } + private static ReadResult UpdateFormat(ReadResult result) + { + result.Diagnostic ??= new OpenApiDiagnostic(); + result.Diagnostic.Format = OpenApiConstants.Yaml; + return result; } /// public static ReadResult Read(JsonNode jsonNode, Uri location, OpenApiReaderSettings settings) { - return _jsonReader.Read(jsonNode, location, settings); + return UpdateFormat(_jsonReader.Read(jsonNode, location, settings)); } /// diff --git a/src/Microsoft.OpenApi/Reader/OpenApiDiagnostic.cs b/src/Microsoft.OpenApi/Reader/OpenApiDiagnostic.cs index c66df68eb..2a6143fbf 100644 --- a/src/Microsoft.OpenApi/Reader/OpenApiDiagnostic.cs +++ b/src/Microsoft.OpenApi/Reader/OpenApiDiagnostic.cs @@ -25,6 +25,11 @@ public class OpenApiDiagnostic /// public OpenApiSpecVersion SpecificationVersion { get; set; } + /// + /// The format of the OpenAPI document (e.g., "json", "yaml"). + /// + public string? Format { get; set; } + /// /// Append another set of diagnostic Errors and Warnings to this one, this may be appended from another external /// document's parsing and we want to indicate which file it originated from. diff --git a/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs b/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs index 0d29c6a6b..6b7a5fb9d 100644 --- a/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs +++ b/src/Microsoft.OpenApi/Reader/OpenApiJsonReader.cs @@ -42,10 +42,11 @@ public ReadResult Read(MemoryStream input, catch (JsonException ex) { diagnostic.Errors.Add(new OpenApiError($"#line={ex.LineNumber}", $"Please provide the correct format, {ex.Message}")); + diagnostic.Format = OpenApiConstants.Json; return new ReadResult { Document = null, - Diagnostic = diagnostic + Diagnostic = diagnostic, }; } @@ -102,11 +103,11 @@ public ReadResult Read(JsonNode jsonNode, } } } - + diagnostic.Format = OpenApiConstants.Json; return new() { Document = document, - Diagnostic = diagnostic + Diagnostic = diagnostic, }; } @@ -138,10 +139,11 @@ public async Task ReadAsync(Stream input, catch (JsonException ex) { diagnostic.Errors.Add(new OpenApiError($"#line={ex.LineNumber}", $"Please provide the correct format, {ex.Message}")); + diagnostic.Format = OpenApiConstants.Json; return new ReadResult { Document = null, - Diagnostic = diagnostic + Diagnostic = diagnostic, }; } diff --git a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs index 347611fce..d2da0d7a4 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/OpenApiReaderTests/OpenApiStreamReaderTests.cs @@ -20,8 +20,9 @@ public async Task StreamShouldCloseIfLeaveStreamOpenSettingEqualsFalse() using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "petStore.yaml")); var settings = new OpenApiReaderSettings { LeaveStreamOpen = false }; settings.AddYamlReader(); - _ = await OpenApiDocument.LoadAsync(stream, settings: settings); + (_, var diagnostic) = await OpenApiDocument.LoadAsync(stream, settings: settings); Assert.False(stream.CanRead); + Assert.Equal(OpenApiConstants.Yaml, diagnostic.Format); } [Fact] diff --git a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs index 6df5d2853..f5f6078a2 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V2Tests/OpenApiServerTests.cs @@ -314,7 +314,8 @@ public void InvalidHostShouldYieldError() { new OpenApiError("#/", "Invalid host") }, - SpecificationVersion = OpenApiSpecVersion.OpenApi2_0 + SpecificationVersion = OpenApiSpecVersion.OpenApi2_0, + Format = OpenApiConstants.Yaml }, result.Diagnostic); } } diff --git a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs index ed8577b0d..46be108b6 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V31Tests/OpenApiDocumentTests.cs @@ -207,7 +207,7 @@ public async Task ParseDocumentWithWebhooksShouldSucceed() }; // Assert - Assert.Equivalent(new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_1 }, actual.Diagnostic); + Assert.Equivalent(new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_1, Format = OpenApiConstants.Yaml }, actual.Diagnostic); actual.Document.Should().BeEquivalentTo(expected, options => options.Excluding(x => x.Workspace).Excluding(y => y.BaseUri)); } @@ -414,7 +414,7 @@ public async Task ParseDocumentsWithReusablePathItemInWebhooksSucceeds() .Excluding(x => x.Workspace) .Excluding(y => y.BaseUri)); Assert.Equivalent( - new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_1 }, actual.Diagnostic); + new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_1, Format = OpenApiConstants.Yaml }, actual.Diagnostic); } [Fact] diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs index 52cfdbde0..1dee79059 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiCallbackTests.cs @@ -71,7 +71,7 @@ public async Task ParseCallbackWithReferenceShouldSucceed() var callback = subscribeOperation.Callbacks["simpleHook"]; Assert.Equivalent( - new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }, result.Diagnostic); + new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, Format = OpenApiConstants.Yaml }, result.Diagnostic); Assert.Equivalent( new OpenApiCallbackReference("simpleHook", result.Document) @@ -120,7 +120,7 @@ public async Task ParseMultipleCallbacksWithReferenceShouldSucceed() var subscribeOperation = path.Operations[HttpMethod.Post]; Assert.Equivalent( - new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }, result.Diagnostic); + new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, Format = OpenApiConstants.Yaml }, result.Diagnostic); var callback1 = subscribeOperation.Callbacks["simpleHook"]; diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs index 370743141..10e4c4e0e 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs @@ -69,7 +69,8 @@ public void ParseDocumentFromInlineStringShouldSucceed() Assert.Equivalent( new OpenApiDiagnostic() { - SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 + SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, + Format = OpenApiConstants.Yaml }, result.Diagnostic); } @@ -147,7 +148,8 @@ public async Task ParseBrokenMinimalDocumentShouldYieldExpectedDiagnostic() { new OpenApiValidatorError(nameof(OpenApiInfoRules.InfoRequiredFields),"#/info/title", "The field 'title' in 'info' object is REQUIRED.") }, - SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 + SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, + Format = OpenApiConstants.Yaml }, result.Diagnostic); } @@ -170,7 +172,8 @@ public async Task ParseMinimalDocumentShouldSucceed() Assert.Equivalent( new OpenApiDiagnostic() { - SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 + SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, + Format = OpenApiConstants.Yaml }, result.Diagnostic); } @@ -557,7 +560,7 @@ public async Task ParseStandardPetStoreDocumentShouldSucceed() actual.Document.Should().BeEquivalentTo(expectedDoc, options => options.Excluding(x => x.Workspace).Excluding(y => y.BaseUri)); Assert.Equivalent( - new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }, actual.Diagnostic); + new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, Format = OpenApiConstants.Yaml }, actual.Diagnostic); } [Fact] @@ -1031,7 +1034,7 @@ [new OpenApiSecuritySchemeReference("securitySchemeName2")] = .Excluding(y => y.BaseUri)); Assert.Equivalent( - new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }, actual.Diagnostic); + new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, Format = OpenApiConstants.Yaml }, actual.Diagnostic); } [Fact] @@ -1042,7 +1045,7 @@ public async Task ParsePetStoreExpandedShouldSucceed() // TODO: Create the object in memory and compare with the one read from YAML file. Assert.Equivalent( - new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 }, actual.Diagnostic); + new OpenApiDiagnostic() { SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, Format = OpenApiConstants.Yaml }, actual.Diagnostic); } [Fact] @@ -1444,9 +1447,10 @@ public void ParseBasicDocumentWithServerVariableShouldSucceed() }; Assert.Equivalent( - new OpenApiDiagnostic - { - SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 + new OpenApiDiagnostic + { + SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, + Format = OpenApiConstants.Yaml }, result.Diagnostic); result.Document.Should().BeEquivalentTo(expected, options => options.Excluding(x => x.BaseUri)); diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs index aea5d46a4..e16e40594 100644 --- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs +++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiSchemaTests.cs @@ -231,7 +231,8 @@ public async Task ParseBasicSchemaWithReferenceShouldSucceed() Assert.Equivalent( new OpenApiDiagnostic() { - SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 + SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, + Format = OpenApiConstants.Yaml }, result.Diagnostic); var expectedComponents = new OpenApiComponents @@ -394,7 +395,8 @@ public async Task ParseExternalReferenceSchemaShouldSucceed() Assert.Equivalent( new OpenApiDiagnostic() { - SpecificationVersion = OpenApiSpecVersion.OpenApi3_0 + SpecificationVersion = OpenApiSpecVersion.OpenApi3_0, + Format = OpenApiConstants.Yaml }, result.Diagnostic); var expectedComponents = new OpenApiComponents diff --git a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt index 29e7ddc74..408ddb15e 100644 --- a/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt +++ b/test/Microsoft.OpenApi.Tests/PublicApi/PublicApi.approved.txt @@ -1934,6 +1934,7 @@ namespace Microsoft.OpenApi.Reader { public OpenApiDiagnostic() { } public System.Collections.Generic.IList Errors { get; set; } + public string? Format { get; set; } public Microsoft.OpenApi.OpenApiSpecVersion SpecificationVersion { get; set; } public System.Collections.Generic.IList Warnings { get; set; } public void AppendDiagnostic(Microsoft.OpenApi.Reader.OpenApiDiagnostic diagnosticToAdd, string? fileNameToAdd = null) { } diff --git a/test/Microsoft.OpenApi.Tests/Reader/OpenApiModelFactoryTests.cs b/test/Microsoft.OpenApi.Tests/Reader/OpenApiModelFactoryTests.cs index 5cbfa93b0..26bd6d472 100644 --- a/test/Microsoft.OpenApi.Tests/Reader/OpenApiModelFactoryTests.cs +++ b/test/Microsoft.OpenApi.Tests/Reader/OpenApiModelFactoryTests.cs @@ -114,6 +114,7 @@ await File.WriteAllTextAsync(tempFilePathReferrer, BaseUrl = baseUri, }; var readResult = await OpenApiDocument.LoadAsync(stream, settings: settings); + Assert.Equal(OpenApiConstants.Json, readResult.Diagnostic.Format); Assert.NotNull(readResult.Document); Assert.NotNull(readResult.Document.Components); Assert.Equal(baseUri, readResult.Document.BaseUri); From 1eeb35c088d4236221da31a7f20d5bdccbc31431 Mon Sep 17 00:00:00 2001 From: "release-please-token-provider[bot]" <225477224+release-please-token-provider[bot]@users.noreply.github.com> Date: Fri, 29 Aug 2025 00:51:33 +0000 Subject: [PATCH 3/3] chore(main): release 2.3.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ Directory.Build.props | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index bfc26f9c4..75ec52fc9 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.2.0" + ".": "2.3.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c064f287..e5e57b24f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [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) diff --git a/Directory.Build.props b/Directory.Build.props index c7dadf189..41fccdae1 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.2.0 + 2.3.0