Skip to content

Modernize OpenAPI generation#713

Draft
Copilot wants to merge 9 commits into
masterfrom
copilot/implement-openapi-spec-generation
Draft

Modernize OpenAPI generation#713
Copilot wants to merge 9 commits into
masterfrom
copilot/implement-openapi-spec-generation

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 27, 2026

Summary

  • Add Microsoft OpenAPI as the default Ark startup generation path with UseSwashbuckleOpenApi as the legacy opt-in.
  • Enable WebApplicationDemo and Ark.Reference WebInterface build-time OpenAPI document generation with generated specs written to the output for static serving.
  • Serve generated OpenAPI specs in production without runtime document generation; runtime generation fallback and MapOpenApi are DEBUG-only.
  • Preserve Swagger UI and add Redoc support against /swagger/docs/{documentName}.
  • Add default compatibility transformers for Swashbuckle SwaggerOperationAttribute and SwaggerResponseAttribute.
  • Add a Microsoft OpenAPI customization hook for Ark startup classes and demonstrate migration of Ark.Reference schema, operation, OAuth, and hosted-worker generation guards.
  • Preserve XML documentation publishing by avoiding OpenAPI XML filtering and adjusting Polyfill usage for net10.0.
  • Add Swashbuckle attribute/filter migration documentation and a step-by-step migration guide.

Validation

  • dotnet build Ark.Tools.slnx --no-restore
  • dotnet build samples/WebApplicationDemo/WebApplicationDemo.csproj -c Release --no-restore
  • dotnet build samples/Ark.ReferenceProject/Core/Ark.Reference.Core.WebInterface/Ark.Reference.Core.WebInterface.csproj -c Release --no-restore
  • dotnet test --solution Ark.Tools.slnx --no-build
  • Dependency advisory check for new NuGet packages: no vulnerabilities found
  • Code review validation completed; CodeQL validation timed out in the validation tool and was not rerun per tool guidance.

Copilot AI and others added 5 commits April 27, 2026 06:17
Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/ea77a270-a4cf-4719-8709-555565079f74

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/ea77a270-a4cf-4719-8709-555565079f74

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/ea77a270-a4cf-4719-8709-555565079f74

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/ea77a270-a4cf-4719-8709-555565079f74

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/ea77a270-a4cf-4719-8709-555565079f74

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Comment thread docs/openapi/migration-from-swashbuckle.md Outdated
Comment thread docs/openapi/migration-from-swashbuckle.md Outdated
Comment thread docs/openapi/migration-from-swashbuckle.md Outdated
Comment thread samples/WebApplicationDemo/WebApplicationDemo.csproj Outdated
Comment thread samples/WebApplicationDemo/WebApplicationDemo.csproj Outdated
Copilot AI and others added 2 commits April 27, 2026 07:31
Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/12e682ba-fd19-4a29-8e7e-ebabcc929815

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/12e682ba-fd19-4a29-8e7e-ebabcc929815

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 27, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dc.applicationinsights.azure.com
    • Triggering command: /home/REDACTED/work/Ark.Tools/Ark.Tools/tests/WebApplicationDemo.Tests/bin/Debug/net10.0/WebApplicationDemo.Tests /home/REDACTED/work/Ark.Tools/Ark.Tools/tests/WebApplicationDemo.Tests/bin/Debug/net10.0/WebApplicationDemo.Tests --server dotnettestcli --dotnet-test-pipe /tmp/2e60f6d725444d6e905ac6916ee1e3b7 (dns block)
    • Triggering command: /home/REDACTED/work/Ark.Tools/Ark.Tools/tests/WebApplicationDemo.Tests/bin/Debug/net10.0/WebApplicationDemo.Tests /home/REDACTED/work/Ark.Tools/Ark.Tools/tests/WebApplicationDemo.Tests/bin/Debug/net10.0/WebApplicationDemo.Tests --server dotnettestcli --dotnet-test-pipe /tmp/65a6d3dc54554d468ede0e2f70f8abd0 (dns block)
    • Triggering command: /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/Ark.ReferenceProject/Core/Ark.Reference.Core.Tests/bin/Debug/net10.0/Ark.Reference.Core.Tests /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/Ark.ReferenceProject/Core/Ark.Reference.Core.Tests/bin/Debug/net10.0/Ark.Reference.Core.Tests --server dotnettestcli --dotnet-test-pipe /tmp/ca91680186b447ac8b9ba0ba003096ff (dns block)
  • rt.services.visualstudio.com
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --depsFile /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Release/net10.0/WebApplicationDemo.deps.json --additionalProbingPath /home/REDACTED/.nuget/packages --runtimeConfig /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Release/net10.0/WebApplicationDemo.runtimeconfig.json /home/REDACTED/.nuget/packages/microsoft.extensions.apidescription.server/10.0.7/tools/net10.0/GetDocument.Insider.dll --file-list obj/WebApplicationDemo.OpenApiFiles.cache --output /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/obj/ --openapi-version OpenApi3_1 --assembly /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Release/net10.0/WebApplicationDemo.dll --project WebApplicationDemo --tools-directory (dns block)
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --depsFile /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/WebApplicationDemo.deps.json --additionalProbingPath /home/REDACTED/.nuget/packages --runtimeConfig /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/WebApplicationDemo.runtimeconfig.json /home/REDACTED/.nuget/packages/microsoft.extensions.apidescription.server/10.0.7/tools/net10.0/GetDocument.Insider.dll --file-list obj/WebApplicationDemo.OpenApiFiles.cache --output /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/obj/ --openapi-version OpenApi3_1 --assembly /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/WebApplicationDemo.dll --project WebApplicationDemo --tools-directory (dns block)
    • Triggering command: /home/REDACTED/work/Ark.Tools/Ark.Tools/tests/WebApplicationDemo.Tests/bin/Debug/net10.0/WebApplicationDemo.Tests /home/REDACTED/work/Ark.Tools/Ark.Tools/tests/WebApplicationDemo.Tests/bin/Debug/net10.0/WebApplicationDemo.Tests --server dotnettestcli --dotnet-test-pipe /tmp/2e60f6d725444d6e905ac6916ee1e3b7 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link
Copy Markdown
Contributor

@AndreaCuneo AndreaCuneo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apply the changes to Ark.Reference project in samples/ to demostrate the migration changes required. Create a step-by-step migration guide.

{
base.ConfigureServices(services);

foreach (var version in Versions)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be in base class and guarded based on the OpenApi enablement

<Target Name="RemoveReferencedXmlCommentsFromOpenApi" AfterTargets="GenerateAdditionalXmlFilesForOpenApi">
<ItemGroup>
<!-- The Microsoft OpenAPI XML source generator receives referenced project XML files as AdditionalFiles.
Ark projects include shared Polyfill XML members, which currently produce duplicate XML comment keys. -->
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

find alternative solution as xml docs are required to be publish. Consider changing the polyfill configuration.

Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/efb0656b-1125-4d27-b1dc-ac2ee95348e2

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
var baseDirectory = AppContext.BaseDirectory;
var candidates = new[]
{
Path.Combine(baseDirectory, $"{entryAssemblyName}_{documentName}.json"),
var candidates = new[]
{
Path.Combine(baseDirectory, $"{entryAssemblyName}_{documentName}.json"),
Path.Combine(baseDirectory, $"{entryAssemblyName}.json"),
{
Path.Combine(baseDirectory, $"{entryAssemblyName}_{documentName}.json"),
Path.Combine(baseDirectory, $"{entryAssemblyName}.json"),
Path.Combine(baseDirectory, $"{documentName}.json")
Comment on lines +61 to +65
foreach (var version in versions)
{
var documentName = ToDocumentName(version);
c.SwaggerEndpoint($@"docs/{documentName}", $@"{documentName} Docs");
}
Comment on lines +305 to +311
foreach (var contentType in response.Content.Keys.ToArray())
{
if (!responseType.ApiResponseFormats.Any(x => string.Equals(x.MediaType, contentType, StringComparison.Ordinal)))
{
response.Content.Remove(contentType);
}
}
Comment on lines +377 to +383
foreach (var contentType in content.Keys.ToArray())
{
if (contentType.Contains("odata", StringComparison.OrdinalIgnoreCase))
{
content.Remove(contentType);
}
}
Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/efb0656b-1125-4d27-b1dc-ac2ee95348e2

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 27, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dc.applicationinsights.azure.com
    • Triggering command: /home/REDACTED/work/Ark.Tools/Ark.Tools/tests/WebApplicationDemo.Tests/bin/Debug/net10.0/WebApplicationDemo.Tests /home/REDACTED/work/Ark.Tools/Ark.Tools/tests/WebApplicationDemo.Tests/bin/Debug/net10.0/WebApplicationDemo.Tests --server dotnettestcli --dotnet-test-pipe /tmp/56fb58cd209e4304b42c7cfc1b15c321 (dns block)
    • Triggering command: /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/Ark.ReferenceProject/Core/Ark.Reference.Core.Tests/bin/Debug/net10.0/Ark.Reference.Core.Tests /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/Ark.ReferenceProject/Core/Ark.Reference.Core.Tests/bin/Debug/net10.0/Ark.Reference.Core.Tests --server dotnettestcli --dotnet-test-pipe /tmp/5dce646fc53e402c8334d293e2c74cc4 (dns block)
  • rt.services.visualstudio.com
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --depsFile /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/WebApplicationDemo.deps.json --additionalProbingPath /home/REDACTED/.nuget/packages --runtimeConfig /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/WebApplicationDemo.runtimeconfig.json /home/REDACTED/.nuget/packages/microsoft.extensions.apidescription.server/10.0.7/tools/net10.0/GetDocument.Insider.dll --file-list obj/WebApplicationDemo.OpenApiFiles.cache --output /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/obj/ --openapi-version OpenApi3_1 --assembly /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/WebApplicationDemo.dll --project WebApplicationDemo --tools-directory (dns block)
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --depsFile /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/WebApplicationDemo.deps.json --additionalProbingPath /home/REDACTED/.nuget/packages --runtimeConfig /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/WebApplicationDemo.runtimeconfig.json /home/REDACTED/.nuget/packages/microsoft.extensions.apidescription.server/10.0.7/tools/net10.0/GetDocument.Insider.dll --file-list obj/WebApplicationDemo.OpenApiFiles.cache --output /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/ --openapi-version OpenApi3_1 --assembly /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/WebApplicationDemo/bin/Debug/net10.0/WebApplicationDemo.dll --project WebApplicationDemo --tools-directory (dns block)
    • Triggering command: /usr/share/dotnet/dotnet /usr/share/dotnet/dotnet exec --depsFile /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/Ark.ReferenceProject/Core/Ark.Reference.Core.WebInterface/bin/Debug/net10.0/Ark.Reference.Core.WebInterface.deps.json --additionalProbingPath /home/REDACTED/.nuget/packages --runtimeConfig /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/Ark.ReferenceProject/Core/Ark.Reference.Core.WebInterface/bin/Debug/net10.0/Ark.Reference.Core.WebInterface.runtimeconfig.json /home/REDACTED/.nuget/packages/microsoft.extensions.apidescription.server/10.0.7/tools/net10.0/GetDocument.Insider.dll --file-list obj/Ark.Reference.Core.WebInterface.OpenApiFiles.cache --output /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/Ark.ReferenceProject/Core/Ark.Reference.Core.WebInterface/bin/Debug/net10.0/ --openapi-version OpenApi3_1 --assembly /home/REDACTED/work/Ark.Tools/Ark.Tools/samples/Ark.ReferenceProject/Core/Ark.Reference.Core.WebInterface/bin/Debug/net10.0/Ark.Reference.Core.WebInterface.dll --project Ark.Reference.Core.WebInterface --tools-directory (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Comment on lines +171 to +208
foreach (var descriptor in descriptors)
{
var propertyInfo = _getPropertyInfo(descriptor);

if (propertyInfo is null || operation.RequestBody?.Content is null || operation.RequestBody.Content.Count == 0)
{
continue;
}

var mediaType = operation.RequestBody.Content.First().Value;

if (mediaType.Schema is not OpenApiSchema schema || schema.Properties is null)
{
continue;
}

var groupedProperties = schema.Properties
.GroupBy(pair => pair.Key.Split('.')[0], StringComparer.Ordinal);

var schemaProperties = new Dictionary<string, IOpenApiSchema>(StringComparer.Ordinal);

foreach (var property in groupedProperties)
{
if (property.Key == propertyInfo.Name)
{
_addEncoding(mediaType, propertyInfo);

var openApiSchema = await _getSchema(context, propertyInfo, cancellationToken).ConfigureAwait(false);
schemaProperties.Add(property.Key, openApiSchema);
}
else
{
schemaProperties.Add(property.Key, property.First().Value);
}
}

schema.Properties = schemaProperties;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants