Skip to content

Add support for generating a single client from multiple OpenAPI specifications#904

Merged
christianhelle merged 4 commits into
mainfrom
copilot/generate-client-from-multiple-versions
Feb 21, 2026
Merged

Add support for generating a single client from multiple OpenAPI specifications#904
christianhelle merged 4 commits into
mainfrom
copilot/generate-client-from-multiple-versions

Conversation

Copilot AI commented Feb 20, 2026

Copy link
Copy Markdown
Contributor

Users with versioned APIs (e.g., V1 + V2) had to maintain separate generated clients and DI registrations per spec. This adds openApiPaths to .refitter settings, merging multiple OpenAPI documents into one generated client.

Description:

Core changes

  • RefitGeneratorSettings — adds OpenApiPaths string[] property; takes precedence over OpenApiPath when non-empty (including when both are specified)
  • OpenApiDocumentFactory — adds CreateAsync(IEnumerable<string>) overload with explicit null/empty argument validation (ArgumentException), and a Merge() method that combines Paths, Components.Schemas (with null-safe access), Definitions (OpenAPI 2.x), and Tags across documents; first document in the array wins on duplicates
  • RefitGeneratorGetOpenApiDocument() uses null-safe OpenApiPaths is { Length: > 0 } pattern to route to the merge path when OpenApiPaths is populated
  • SettingsValidator — accepts either openApiPath or a non-empty openApiPaths array as valid; always uses the first OpenApiPaths entry for validation when the array is non-empty (regardless of openApiPath); null-guards OpenApiPaths to handle "openApiPaths": null in settings files

Usage

{
  "openApiPaths": [
    "PetstoreV1.yaml",
    "PetstoreV2.yaml"
  ]
}

Generates a single interface containing operations and contracts merged from all specified specs:

[Get("/v1/pets")]
Task<ICollection<PetV1>> ListPetsV1();

[Get("/v2/pets")]
Task<ICollection<PetV2>> ListPetsV2();

Example OpenAPI Specifications:

# petstore-v1.yaml
openapi: '3.0.0'
info:
  title: Petstore V1
  version: '1.0'
paths:
  /pets:
    get:
      operationId: listPetsV1
      tags: [pets]
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PetV1'

Example generated Refit interface

public partial interface IPetstoreV1
{
    [Headers("Accept: application/json")]
    [Get("/pets")]
    Task<ICollection<PetV1>> ListPetsV1();
}

public partial interface IPetstoreV2
{
    [Headers("Accept: application/json")]
    [Get("/v2/pets")]
    Task<ICollection<PetV2>> ListPetsV2();
}
Original prompt

This section details on the original issue you should resolve

<issue_title>Generate the client from multiple versions</issue_title>
<issue_description>Is your feature request related to a problem? Please describe.
I have a V1 and a V2 specification of the same Api. If I now want to generate a client, I have to do this for each version and also maintain the interface and dependency injection twice.

Describe the solution you'd like
Generate a client that contains both versions. For example, the method name could contain the required version.

.refitter File

{
    "openApiPaths": [
        "PetstoreV1.yaml",
        "PetstoreV2.yaml",
    ]
}

Generated Interface:

Pet UpdatePetV1 (long? id, string name, List<string> photoUrls, List<Tag> tags, string status);

Pet UpdatePetV2 (long? id, string name, List<string> photoUrls, List<Tag> tags, string status);

Additional context

OpenAPI - PetstoreV1
openapi: 3.0.3
info:
  title: Swagger Petstore - OpenAPI
  version: 1.0.0
servers:
  - url: https://petstore.swagger.io/api/v1
tags:
  - name: pet
    description: Everything about your Pets
paths:
  /pet:
    put:
      tags:
        - pet
      summary: Update an existing pet
      description: Update an existing pet by Id
      operationId: updatePet
      requestBody:
        description: Update an existent pet in the store
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
          application/xml:
            schema:
              $ref: '#/components/schemas/Pet'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/Pet'
        required: true
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Pet'          
            application/xml:
              schema:
                $ref: '#/components/schemas/Pet'
        '400':
          description: Invalid ID supplied
        '404':
          description: Pet not found
        '422':
          description: Validation exception
      security:
        - petstore_auth:
            - write:pets
            - read:pets
components:
  schemas:
    Tag:
      type: object
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
      xml:
        name: tag
    Pet:
      required:
        - name
        - photoUrls
      type: object
      properties:
        id:
          type: integer
          format: int64
          example: 10
        name:
          type: string
          example: doggie
        photoUrls:
          type: array
          xml:
            wrapped: true
          items:
            type: string
            xml:
              name: photoUrl
        tags:
          type: array
          xml:
            wrapped: true
          items:
            $ref: '#/components/schemas/Tag'
        status:
          type: string
          description: pet status in the store
          enum:
            - available
            - pending
            - sold
      xml:
        name: pet
    ApiResponse:
      type: object
      properties:
        code:
          type: integer
          format: int32
        type:
          type: string
        message:
          type: string
      xml:
        name: '##default'
  securitySchemes:
    petstore_auth:
      type: oauth2
      flows:
        implicit:
          authorizationUrl: https://petstore3.swagger.io/oauth/authorize
          scopes:
            write:pets: modify pets in your account
            read:pets: read your pets
    api_key:
      type: apiKey
      name: api_key
      in: header
OpenAPI - PetstoreV2
openapi: 3.0.3
info:
  title: Swagger Petstore - OpenAPI
  version: 2.0.0
servers:
  - url: https://petstore.swagger.io/api/v2
tags:
  - name: pet
    description: Everything about your Pets
paths:
  /pet:
    put:
      tags:
        - pet
      summary: Update an existing pet
      description: Update an existing pet by Id
      operationId: updatePet
      requestBody:
        description: Update an existent pet in the store
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pet'
          application/xml:
            schema:
              $ref: '#/components/schemas/Pet'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/Pet'
        required: true
      responses:
        '200':
          description: Successful operation
          content:
            applica...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes christianhelle/refitter#350

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

…s (openApiPaths)

Co-authored-by: christianhelle <710400+christianhelle@users.noreply.github.com>
Copilot AI changed the title [WIP] Generate client that supports multiple API versions Add support for generating a single client from multiple OpenAPI specifications Feb 20, 2026
Copilot AI requested a review from christianhelle February 20, 2026 18:47
@codecov

codecov Bot commented Feb 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.00000% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.68%. Comparing base (5cc8f38) to head (1f663ee).
⚠️ Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
src/Refitter.Core/OpenApiDocumentFactory.cs 73.33% 3 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #904      +/-   ##
==========================================
- Coverage   93.33%   92.68%   -0.66%     
==========================================
  Files          23       23              
  Lines        1396     2063     +667     
==========================================
+ Hits         1303     1912     +609     
- Misses         47       51       +4     
- Partials       46      100      +54     
Flag Coverage Δ
unittests 92.68% <75.00%> (-0.66%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@christianhelle
christianhelle marked this pull request as ready for review February 21, 2026 14:39
Copilot AI review requested due to automatic review settings February 21, 2026 14:39

Copilot AI left a comment

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.

Pull request overview

Adds the ability to generate a single Refit client by merging multiple OpenAPI specifications provided via a new openApiPaths setting, intended to simplify generation for versioned APIs (e.g., V1 + V2).

Changes:

  • Introduces OpenApiPaths to RefitGeneratorSettings and routes generation through a multi-doc merge path when populated.
  • Implements OpenAPI document merging in OpenApiDocumentFactory (paths, schemas/definitions, tags; first document wins on duplicates).
  • Updates CLI settings validation, unit tests, and README documentation to reflect the new configuration option.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/Refitter/SettingsValidator.cs Accepts openApiPaths in settings file and validates using the first entry when openApiPath is missing.
src/Refitter.Tests/SettingsValidatorTests.cs Expands validator test coverage for openApiPaths scenarios and updates the required-setting error text.
src/Refitter.Tests/MultipleOpenApiPathsTests.cs Adds new tests verifying merged generation behavior from multiple specs.
src/Refitter.Core/Settings/RefitGeneratorSettings.cs Adds OpenApiPaths setting and documents precedence over OpenApiPath.
src/Refitter.Core/RefitGenerator.cs Uses merged OpenAPI document creation when OpenApiPaths is populated.
src/Refitter.Core/OpenApiDocumentFactory.cs Adds multi-path CreateAsync overload and merge logic for documents.
README.md Documents openApiPaths usage and behavior in .refitter files.

Comment on lines +44 to +60
if (document.Components?.Schemas != null)
{
foreach (var schema in document.Components.Schemas)
{
if (!baseDocument.Components.Schemas.ContainsKey(schema.Key))
baseDocument.Components.Schemas[schema.Key] = schema.Value;
}
}

if (document.Definitions != null)
{
foreach (var definition in document.Definitions)
{
if (!baseDocument.Definitions.ContainsKey(definition.Key))
baseDocument.Definitions[definition.Key] = definition.Value;
}
}

Copilot AI Feb 21, 2026

Copy link

Choose a reason for hiding this comment

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

Merge() assumes baseDocument.Components/baseDocument.Definitions are non-null when later documents contain schemas/definitions. If the base document lacks these sections but a subsequent document has them, this will throw when accessing baseDocument.Components.Schemas or baseDocument.Definitions. Initialize the target collections (e.g., create Components/Schemas/Definitions when null) before merging.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 1f663ee. Added null-conditional access (baseDocument.Components?.Schemas != null) before merging schemas. Note: NSwag initializes Components as a read-only property (it cannot be assigned), so we guard with the null-conditional operator rather than re-initializing.

Comment on lines +73 to +101
[Test]
public async Task Can_Generate_Code_From_Multiple_Paths()
{
var (file1, file2) = await CreateTestSpecFiles();
var settings = new RefitGeneratorSettings
{
OpenApiPaths = [file1, file2]
};

var sut = await RefitGenerator.CreateAsync(settings);
var generatedCode = sut.Generate();
generatedCode.Should().NotBeNullOrWhiteSpace();
}

[Test]
public async Task Generated_Code_Contains_Operations_From_Both_Specs()
{
var (file1, file2) = await CreateTestSpecFiles();
var settings = new RefitGeneratorSettings
{
OpenApiPaths = [file1, file2]
};

var sut = await RefitGenerator.CreateAsync(settings);
var generatedCode = sut.Generate();

generatedCode.Should().Contain("ListPetsV1");
generatedCode.Should().Contain("ListPetsV2");
}

Copilot AI Feb 21, 2026

Copy link

Choose a reason for hiding this comment

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

These tests validate merged output via string assertions, but they never compile the generated code. Given the generator is expected to produce buildable C# (and the repo commonly verifies this with BuildHelper.BuildCSharp(...)), please add at least one test that builds the code produced from multiple OpenApiPaths to catch merge regressions that still contain the expected substrings.

Copilot generated this review using guidance from repository custom instructions.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added Can_Build_Generated_Code_From_Multiple_Paths test that uses BuildHelper.BuildCSharp() in commit 1f663ee.

Comment thread README.md Outdated
Comment on lines +199 to +203
"openApiPath": "/path/to/your/openAPI", // Required if openApiPaths is not specified
"openApiPaths": [ // Required if openApiPath is not specified. Multiple OpenAPI specs are merged into a single client
"/path/to/your/openAPI/v1",
"/path/to/your/openAPI/v2"
],

Copilot AI Feb 21, 2026

Copy link

Choose a reason for hiding this comment

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

The README example shows both openApiPath and openApiPaths in the same .refitter file. Since they are described as an either/or (and openApiPaths taking precedence), this example can mislead users into thinking both are required or used together. Consider showing two separate examples (single vs multiple) or explicitly stating that openApiPath is ignored when openApiPaths is provided.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 1f663ee. The README example block now shows openApiPath alone (single spec) and a separate example showing openApiPaths (multiple specs) with the description clarifying they are mutually exclusive.

Comment thread src/Refitter/SettingsValidator.cs Outdated
Comment on lines +45 to +53
if (string.IsNullOrWhiteSpace(refitGeneratorSettings.OpenApiPath) &&
refitGeneratorSettings.OpenApiPaths.Length > 0)
{
settings.OpenApiPath = refitGeneratorSettings.OpenApiPaths[0];
}
else
{
settings.OpenApiPath = refitGeneratorSettings.OpenApiPath;
}

Copilot AI Feb 21, 2026

Copy link

Choose a reason for hiding this comment

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

OpenApiPaths is documented/implemented as taking precedence when non-empty, but this validator only uses the first OpenApiPaths entry when OpenApiPath is blank. If a settings file contains both (e.g., legacy openApiPath plus new openApiPaths), validation will use/validate the wrong spec and can fail even though generation will merge openApiPaths. Consider selecting the first OpenApiPaths entry whenever the array is non-empty (or explicitly error when both are provided).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 1f663ee. ValidateFilePath now uses OpenApiPaths is { Length: > 0 } to prefer OpenApiPaths whenever the array is non-empty, regardless of whether OpenApiPath is also set.

Comment on lines +62 to 64
if (string.IsNullOrWhiteSpace(refitGeneratorSettings.OpenApiPath) &&
refitGeneratorSettings.OpenApiPaths.Length == 0)
{

Copilot AI Feb 21, 2026

Copy link

Choose a reason for hiding this comment

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

refitGeneratorSettings.OpenApiPaths.Length will throw if the settings file contains "openApiPaths": null (System.Text.Json will set the array property to null despite the default initializer). Please null-guard (OpenApiPaths?.Length ?? 0) so invalid/partial configs fail with a validation error instead of crashing.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 1f663ee with (refitGeneratorSettings.OpenApiPaths?.Length ?? 0) == 0.

Comment thread src/Refitter.Core/RefitGenerator.cs Outdated

private static async Task<OpenApiDocument> GetOpenApiDocument(RefitGeneratorSettings settings)
{
if (settings.OpenApiPaths.Length > 0)

Copilot AI Feb 21, 2026

Copy link

Choose a reason for hiding this comment

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

settings.OpenApiPaths.Length can throw if OpenApiPaths is deserialized as null (e.g., settings JSON has "openApiPaths": null). Prefer a null-safe check such as settings.OpenApiPaths is { Length: > 0 } (and treat null as empty).

Suggested change
if (settings.OpenApiPaths.Length > 0)
if (settings.OpenApiPaths is { Length: > 0 })

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Applied the suggested change in commit 1f663ee: if (settings.OpenApiPaths is { Length: > 0 }).

Comment on lines +20 to +31
public static async Task<OpenApiDocument> CreateAsync(IEnumerable<string> openApiPaths)
{
var paths = openApiPaths.ToArray();
if (paths.Length == 1)
return await CreateAsync(paths[0]);

var documents = new OpenApiDocument[paths.Length];
for (var i = 0; i < paths.Length; i++)
documents[i] = await CreateAsync(paths[i]);

return Merge(documents);
}

Copilot AI Feb 21, 2026

Copy link

Choose a reason for hiding this comment

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

CreateAsync(IEnumerable<string> openApiPaths) doesn't handle an empty sequence: paths.Length == 0 leads to documents[0] in Merge() throwing. Add explicit argument validation (null/empty) and return a clear ArgumentException/ArgumentOutOfRangeException instead of an index error.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in commit 1f663ee. CreateAsync(IEnumerable<string>) now throws ArgumentException for both null and empty inputs before proceeding. Also added a OpenApiDocumentFactory_Throws_For_Empty_Paths test to verify this.

@christianhelle

Copy link
Copy Markdown
Owner

@copilot apply changes based on the comments in this thread

christianhelle and others added 2 commits February 21, 2026 16:08
…ld test, README

Co-authored-by: christianhelle <710400+christianhelle@users.noreply.github.com>

Copilot AI commented Feb 21, 2026

Copy link
Copy Markdown
Contributor Author

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:

  • collector.exceptionless.io
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests (dns block)
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests rpClientGenerato--norc rpPropertyNameGe--noprofile InjectionGenerator.cs ions�� 78772c446680b8321748f17d42/Project.csproj ode.cs utput.cs rfaceGenerator.cdotnet Utils.cs e.cs umentFactory.cs ameG�� se/net8.0/ff4e23446d3a4133a93a298bff3a49b1/Project.csproj atedCode.cs (dns block)
  • config.exceptionless.io
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests (dns block)
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests rpClientGenerato--norc rpPropertyNameGe--noprofile InjectionGenerator.cs ions�� 78772c446680b8321748f17d42/Project.csproj ode.cs utput.cs rfaceGenerator.cdotnet Utils.cs e.cs umentFactory.cs ameG�� se/net8.0/ff4e23446d3a4133a93a298bff3a49b1/Project.csproj atedCode.cs (dns block)
  • developers.intellihr.io
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests (dns block)
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests rpClientGenerato--norc rpPropertyNameGe--noprofile InjectionGenerator.cs ions�� 78772c446680b8321748f17d42/Project.csproj ode.cs utput.cs rfaceGenerator.cdotnet Utils.cs e.cs umentFactory.cs ameG�� se/net8.0/ff4e23446d3a4133a93a298bff3a49b1/Project.csproj atedCode.cs (dns block)
  • heartbeat.exceptionless.io
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests (dns block)
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests rpClientGenerato--norc rpPropertyNameGe--noprofile InjectionGenerator.cs ions�� 78772c446680b8321748f17d42/Project.csproj ode.cs utput.cs rfaceGenerator.cdotnet Utils.cs e.cs umentFactory.cs ameG�� se/net8.0/ff4e23446d3a4133a93a298bff3a49b1/Project.csproj atedCode.cs (dns block)
  • petstore.swagger.io
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests (dns block)
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests rpClientGenerato--norc rpPropertyNameGe--noprofile InjectionGenerator.cs ions�� 78772c446680b8321748f17d42/Project.csproj ode.cs utput.cs rfaceGenerator.cdotnet Utils.cs e.cs umentFactory.cs ameG�� se/net8.0/ff4e23446d3a4133a93a298bff3a49b1/Project.csproj atedCode.cs (dns block)
  • petstore3.swagger.io
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests (dns block)
    • Triggering command: /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests /home/REDACTED/work/refitter/refitter/src/Refitter.Tests/bin/Release/net8.0/Refitter.Tests rpClientGenerato--norc rpPropertyNameGe--noprofile InjectionGenerator.cs ions�� 78772c446680b8321748f17d42/Project.csproj ode.cs utput.cs rfaceGenerator.cdotnet Utils.cs e.cs umentFactory.cs ameG�� se/net8.0/ff4e23446d3a4133a93a298bff3a49b1/Project.csproj atedCode.cs (dns block)

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

@sonarqubecloud

Copy link
Copy Markdown

@christianhelle christianhelle added enhancement New feature, bug fix, or request .NET Pull requests that contain changes to .NET code labels Feb 21, 2026
@christianhelle
christianhelle merged commit af0d4c7 into main Feb 21, 2026
10 of 12 checks passed
@christianhelle
christianhelle deleted the copilot/generate-client-from-multiple-versions branch February 21, 2026 15:55
hwinther pushed a commit to hwinther/test that referenced this pull request May 6, 2026
Updated [refitter](https://github.com/christianhelle/refitter) from
1.7.1 to 2.0.0.

<details>
<summary>Release notes</summary>

_Sourced from [refitter's
releases](https://github.com/christianhelle/refitter/releases)._

## 2.0.0

## What's Changed

* Fix numeric format with pattern quirk - infer type from format for all
numeric types by @​Copilot in
christianhelle/refitter#869
* Read group documentation from document tags. by @​DJ4ddi in
christianhelle/refitter#887
* Fix null reference and XML escaping in XmlDocumentationGenerator by
@​Copilot in christianhelle/refitter#890
* Fix build workflow: add dotnet restore before dotnet msbuild in
Prepare step by @​Copilot in
christianhelle/refitter#892
christianhelle/refitter#895
* Fix MSBuild workflow by @​christianhelle in
christianhelle/refitter#898
* Add support for generating a single client from multiple OpenAPI
specifications by @​Copilot in
christianhelle/refitter#904
* Migrate from Microsoft.OpenApi.Readers 1.x to Microsoft.OpenApi 3.x by
@​vgmello in christianhelle/refitter#907
* Improve Smoke Tests execution time by @​christianhelle in
christianhelle/refitter#915
* Fix #​580: Nullable strings marked correctly by @​christianhelle in
christianhelle/refitter#921
* Fix #​672: MultipleInterfaces ByTag method naming scoped per-interface
by @​christianhelle in
christianhelle/refitter#922
* Fix #​635: Refactor source generator to use context.AddSource() by
@​christianhelle in christianhelle/refitter#923
* Add custom format mappings configuration by @​christianhelle in
christianhelle/refitter#927
* Fix multipart form-data parameter extraction by @​christianhelle in
christianhelle/refitter#928
christianhelle/refitter#911
christianhelle/refitter#902
* Fix smoke tests: --interface-only variant missing using directive for
contract types by @​Copilot in
christianhelle/refitter#933
* Fix SonarCloud Code Quality Issues by @​Copilot in
christianhelle/refitter#932
* Add debug logging for source generator when searching for .refitter
files by @​codymullins in
christianhelle/refitter#743
* Fix: Base type not generated for types using oneOf with discriminator
by @​Copilot in christianhelle/refitter#906
* Add option for Method Level Authorization header attribute by
@​Roflincopter in christianhelle/refitter#897
* Fix PR #​897 review feedback and add comprehensive bearer auth tests
by @​christianhelle in
christianhelle/refitter#936
* Fix numeric suffix added to interface method names in ByTag mode by
@​Copilot in christianhelle/refitter#914
* Improve OpenAPI parse + codegen throughput by removing avoidable
allocations and repeated regex work by @​Copilot in
christianhelle/refitter#937
* Move [JsonConverter] from enum properties to enum types by
@​christianhelle in christianhelle/refitter#938
* Fix broken CLI tool help text by @​christianhelle in
christianhelle/refitter#940
* Improve code coverage to >90% by @​christianhelle in
christianhelle/refitter#941
* Microsoft.OpenApi v3.4 by @​christianhelle in
christianhelle/refitter#945
* Add Unicode support for XML doc comment generation by @​christianhelle
in christianhelle/refitter#948
* Add PropertyNamingPolicy support for JSON property naming by
@​christianhelle in christianhelle/refitter#969
christianhelle/refitter#966
* Fix recursive schema stack overflows by @​christianhelle in
christianhelle/refitter#971
* Made Header Parameters for Security Schemes safe to use as C# variable
name by @​smoerijf in
christianhelle/refitter#977
* Enhance schema alias handling and property name generation by
@​christianhelle in christianhelle/refitter#996
* Verify alias handling and sanitize PascalCase properties by
@​christianhelle in christianhelle/refitter#997
* Harden .refitter settings deserialization and output path handling by
@​christianhelle in christianhelle/refitter#1000
* Special-case the default .refitter filename before deriving
OutputFilename by @​coderabbitai[bot] in
christianhelle/refitter#1002
* [v2.0 audit] Fix pre-release regressions from #​1057 by
@​christianhelle in christianhelle/refitter#1064
* Resolve high-severity audit findings from #​1057 by @​christianhelle
in christianhelle/refitter#1067
* [v2.0 audit] Close remaining verified #​1057 regressions by
@​christianhelle in christianhelle/refitter#1070
* Harden generation flows by @​christianhelle in
christianhelle/refitter#1071
* Breaking changes and Migration Guide for v2.0.0 by @​christianhelle in
christianhelle/refitter#1009
* Handle equivalent duplicate schemas in multi-spec merge by
@​christianhelle in christianhelle/refitter#1076
* Tighten warning handling across Refitter builds by @​christianhelle in
christianhelle/refitter#1079
* Fix default solution path and update .NET version in VS Code config by
@​christianhelle in christianhelle/refitter#1082
* Fix docker smoke tests by @​christianhelle in
christianhelle/refitter#1081
* Sanitize malformed schema type names without renaming clean schemas by
@​christianhelle in christianhelle/refitter#1085

 ... (truncated)

## 1.7.3

## What's Changed
* Add support for systems running only .NET 10.0 (without .NET 8.0 or
9.0) in Refitter.MSBuild by @​christianhelle in
christianhelle/refitter#882
* Update to return HttpResponseMessage for file downloads by @​frogcrush
in christianhelle/refitter#877

## New Contributors
* @​frogcrush made their first contribution in
christianhelle/refitter#877

**Full Changelog**:
christianhelle/refitter@1.7.2...1.7.3

## 1.7.2

**Implemented enhancements:**

- Improve Immutable Records ergonomics
[\#​844](christianhelle/refitter#844)
- Omit certain operation headers and include all others
[\#​840](christianhelle/refitter#840)
- Create .refitter settings file as part of output
[\#​859](christianhelle/refitter#859) by
@[christianhelle
- Fix integerType enum deserialization issue
[\#​855](christianhelle/refitter#855)
([christianhelle](https://github.com/christianhelle))
- support custom nswag template directory \#​844
[\#​854](christianhelle/refitter#854) by
@​kmc059000
- Fix missing method parameter XML code-documentation
[\#​850](christianhelle/refitter#850)
([christianhelle](https://github.com/christianhelle))

**Fixed bugs:**

- integerType parsing in settings file fails
[\#​851](christianhelle/refitter#851)
- CS1573 : Method parameter has no matching XML comment
[\#​846](christianhelle/refitter#846)

**Merged pull requests:**

- docs: add frogcrush as a contributor for code
[\#​878](christianhelle/refitter#878)
([allcontributors[bot]](https://github.com/apps/allcontributors))
- Migrate solution files from .sln to .slnx format
[\#​876](christianhelle/refitter#876)
([Copilot](https://github.com/apps/copilot-swe-agent))
- Fix issue with randomly failing tests to due parallel execution
[\#​872](christianhelle/refitter#872)
([christianhelle](https://github.com/christianhelle))
- chore\(deps\): update dependency tunit to 1.9.2
[\#​863](christianhelle/refitter#863)
([renovate[bot]](https://github.com/apps/renovate))
- chore\(deps\): update dependency tunit to 1.7.7
[\#​862](christianhelle/refitter#862)
([renovate[bot]](https://github.com/apps/renovate))
- Add unit tests for WriteRefitterSettingsFile functionality
[\#​860](christianhelle/refitter#860)
([Copilot](https://github.com/apps/copilot-swe-agent))
- chore\(deps\): update dependency ruby to v4
[\#​858](christianhelle/refitter#858)
([renovate[bot]](https://github.com/apps/renovate))
- chore\(deps\): update dependency tunit to 1.6.28
[\#​857](christianhelle/refitter#857)
([renovate[bot]](https://github.com/apps/renovate))
- docs: add 0x2badc0de as a contributor for bug
[\#​856](christianhelle/refitter#856)
([allcontributors[bot]](https://github.com/apps/allcontributors))
- chore\(deps\): update dependency swashbuckle.aspnetcore to 10.1.0
[\#​853](christianhelle/refitter#853)
([renovate[bot]](https://github.com/apps/renovate))
- chore\(deps\): update dependency tunit to 1.6.0
[\#​852](christianhelle/refitter#852)
([renovate[bot]](https://github.com/apps/renovate))
- docs: add lilinus as a contributor for code
[\#​849](christianhelle/refitter#849)
([allcontributors[bot]](https://github.com/apps/allcontributors))
- chore\(deps\): update dependency ruby to v3.4.8
[\#​845](christianhelle/refitter#845)
([renovate[bot]](https://github.com/apps/renovate))
- chore\(deps\): update dependency tunit to 1.5.70
[\#​837](christianhelle/refitter#837)
([renovate[bot]](https://github.com/apps/renovate))


**Full Changelog**:
christianhelle/refitter@1.7.1...1.7.2

Commits viewable in [compare
view](christianhelle/refitter@1.7.1...2.0.0).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=refitter&package-manager=nuget&previous-version=1.7.1&new-version=2.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
vgmello pushed a commit to vgmello/momentum that referenced this pull request May 10, 2026
Updated [Refitter.MSBuild](https://github.com/christianhelle/refitter)
from 1.7.3 to 2.0.0.

<details>
<summary>Release notes</summary>

_Sourced from [Refitter.MSBuild's
releases](https://github.com/christianhelle/refitter/releases)._

## 2.0.0

## What's Changed

* Fix numeric format with pattern quirk - infer type from format for all
numeric types by @​Copilot in
christianhelle/refitter#869
* Read group documentation from document tags. by @​DJ4ddi in
christianhelle/refitter#887
* Fix null reference and XML escaping in XmlDocumentationGenerator by
@​Copilot in christianhelle/refitter#890
* Fix build workflow: add dotnet restore before dotnet msbuild in
Prepare step by @​Copilot in
christianhelle/refitter#892
christianhelle/refitter#895
* Fix MSBuild workflow by @​christianhelle in
christianhelle/refitter#898
* Add support for generating a single client from multiple OpenAPI
specifications by @​Copilot in
christianhelle/refitter#904
* Migrate from Microsoft.OpenApi.Readers 1.x to Microsoft.OpenApi 3.x by
@​vgmello in christianhelle/refitter#907
* Improve Smoke Tests execution time by @​christianhelle in
christianhelle/refitter#915
* Fix #​580: Nullable strings marked correctly by @​christianhelle in
christianhelle/refitter#921
* Fix #​672: MultipleInterfaces ByTag method naming scoped per-interface
by @​christianhelle in
christianhelle/refitter#922
* Fix #​635: Refactor source generator to use context.AddSource() by
@​christianhelle in christianhelle/refitter#923
* Add custom format mappings configuration by @​christianhelle in
christianhelle/refitter#927
* Fix multipart form-data parameter extraction by @​christianhelle in
christianhelle/refitter#928
christianhelle/refitter#911
christianhelle/refitter#902
* Fix smoke tests: --interface-only variant missing using directive for
contract types by @​Copilot in
christianhelle/refitter#933
* Fix SonarCloud Code Quality Issues by @​Copilot in
christianhelle/refitter#932
* Add debug logging for source generator when searching for .refitter
files by @​codymullins in
christianhelle/refitter#743
* Fix: Base type not generated for types using oneOf with discriminator
by @​Copilot in christianhelle/refitter#906
* Add option for Method Level Authorization header attribute by
@​Roflincopter in christianhelle/refitter#897
* Fix PR #​897 review feedback and add comprehensive bearer auth tests
by @​christianhelle in
christianhelle/refitter#936
* Fix numeric suffix added to interface method names in ByTag mode by
@​Copilot in christianhelle/refitter#914
* Improve OpenAPI parse + codegen throughput by removing avoidable
allocations and repeated regex work by @​Copilot in
christianhelle/refitter#937
* Move [JsonConverter] from enum properties to enum types by
@​christianhelle in christianhelle/refitter#938
* Fix broken CLI tool help text by @​christianhelle in
christianhelle/refitter#940
* Improve code coverage to >90% by @​christianhelle in
christianhelle/refitter#941
* Microsoft.OpenApi v3.4 by @​christianhelle in
christianhelle/refitter#945
* Add Unicode support for XML doc comment generation by @​christianhelle
in christianhelle/refitter#948
* Add PropertyNamingPolicy support for JSON property naming by
@​christianhelle in christianhelle/refitter#969
christianhelle/refitter#966
* Fix recursive schema stack overflows by @​christianhelle in
christianhelle/refitter#971
* Made Header Parameters for Security Schemes safe to use as C# variable
name by @​smoerijf in
christianhelle/refitter#977
* Enhance schema alias handling and property name generation by
@​christianhelle in christianhelle/refitter#996
* Verify alias handling and sanitize PascalCase properties by
@​christianhelle in christianhelle/refitter#997
* Harden .refitter settings deserialization and output path handling by
@​christianhelle in christianhelle/refitter#1000
* Special-case the default .refitter filename before deriving
OutputFilename by @​coderabbitai[bot] in
christianhelle/refitter#1002
* [v2.0 audit] Fix pre-release regressions from #​1057 by
@​christianhelle in christianhelle/refitter#1064
* Resolve high-severity audit findings from #​1057 by @​christianhelle
in christianhelle/refitter#1067
* [v2.0 audit] Close remaining verified #​1057 regressions by
@​christianhelle in christianhelle/refitter#1070
* Harden generation flows by @​christianhelle in
christianhelle/refitter#1071
* Breaking changes and Migration Guide for v2.0.0 by @​christianhelle in
christianhelle/refitter#1009
* Handle equivalent duplicate schemas in multi-spec merge by
@​christianhelle in christianhelle/refitter#1076
* Tighten warning handling across Refitter builds by @​christianhelle in
christianhelle/refitter#1079
* Fix default solution path and update .NET version in VS Code config by
@​christianhelle in christianhelle/refitter#1082
* Fix docker smoke tests by @​christianhelle in
christianhelle/refitter#1081
* Sanitize malformed schema type names without renaming clean schemas by
@​christianhelle in christianhelle/refitter#1085

 ... (truncated)

Commits viewable in [compare
view](christianhelle/refitter@1.7.3...2.0.0).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=Refitter.MSBuild&package-manager=nuget&previous-version=1.7.3&new-version=2.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature, bug fix, or request .NET Pull requests that contain changes to .NET code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate the client from multiple versions

3 participants