Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .azure-pipelines/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,6 @@ extends:
Write-Host "##vso[task.setvariable variable=ODataVersion]$version"
displayName: 'Validate OData component tag and project version'

- task: UseDotNet@2
displayName: 'Use .NET 6' # needed for ESRP signing
inputs:
version: 6.x

- task: UseDotNet@2
displayName: 'Use .NET 8'
inputs:
version: 8.x

- task: UseDotNet@2
displayName: 'Use .NET 10'
inputs:
Expand Down
10 changes: 1 addition & 9 deletions .azure-pipelines/hidi-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,6 @@ extends:
}
Write-Host "##vso[task.setvariable variable=HidiVersion]$version"
displayName: Validate Hidi component tag and project version
- task: UseDotNet@2
displayName: Use .NET 6 for ESRP
inputs:
version: 6.x
- task: UseDotNet@2
displayName: Use .NET 8
inputs:
version: 8.x
- task: UseDotNet@2
displayName: Use .NET 10
inputs:
Expand Down Expand Up @@ -142,7 +134,7 @@ extends:
& .\artifacts\hidi\win-x64\Microsoft.OpenApi.Hidi.exe --help
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
New-Item -ItemType Directory -Force artifacts\hidi\signing | Out-Null
Copy-Item src\Microsoft.OpenApi.Hidi\bin\$(buildConfiguration)\net8.0\Microsoft.OpenApi.Hidi.dll artifacts\hidi\signing
Copy-Item src\Microsoft.OpenApi.Hidi\bin\$(buildConfiguration)\net10.0\Microsoft.OpenApi.Hidi.dll artifacts\hidi\signing
Copy-Item artifacts\hidi\win-x64\Microsoft.OpenApi.Hidi.exe artifacts\hidi\signing
displayName: Build, test and stage hidi binaries
- task: EsrpCodeSigning@6
Expand Down
8 changes: 2 additions & 6 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@0f4a354dd5547a28c70b7853dbd95d5b67886e73 # v6.1.0
with:
dotnet-version: |
8.0.x
10.0.x
dotnet-version: 10.0.x

- name: Data gatherer
id: data_gatherer
Expand Down Expand Up @@ -172,9 +170,7 @@ jobs:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: actions/setup-dotnet@0f4a354dd5547a28c70b7853dbd95d5b67886e73 # v6.1.0
with:
dotnet-version: |
8.0.x
10.0.x
dotnet-version: 10.0.x
- name: Publish and smoke-test Windows executable
shell: pwsh
run: |
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@0f4a354dd5547a28c70b7853dbd95d5b67886e73 # v6.1.0
with:
dotnet-version: |
8.0.x
10.0.x
dotnet-version: 10.0.x

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/sonarcloud.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@0f4a354dd5547a28c70b7853dbd95d5b67886e73 # v6.1.0
with:
dotnet-version: |
8.0.x
10.0.x
dotnet-version: 10.0.x
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
Expand Down Expand Up @@ -126,7 +124,7 @@ jobs:
CoverletOutputFormat: 'opencover' # https://github.com/microsoft/vstest/issues/4014#issuecomment-1307913682
shell: pwsh
run: |
dotnet tool run dotnet-sonarscanner begin /k:"microsoft_OpenAPI.NET.OData" /o:"microsoft" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="test/**/coverage.net8.0.opencover.xml,artifacts/hidi/coverage/*opencover*.xml" /d:sonar.coverageReportPaths="artifacts/hidi/powershell-coverage/sonar-coverage.xml"
dotnet tool run dotnet-sonarscanner begin /k:"microsoft_OpenAPI.NET.OData" /o:"microsoft" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.cs.opencover.reportsPaths="test/**/coverage.opencover.xml,artifacts/hidi/coverage/*opencover*.xml" /d:sonar.coverageReportPaths="artifacts/hidi/powershell-coverage/sonar-coverage.xml"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
dotnet workload restore
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ WORKDIR /app/hidi
RUN --mount=type=secret,id=nuget_config,target=/app/hidi/NuGet.Config \
dotnet publish ./src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj -c Release -o /app/publish -p:GeneratePackageOnBuild=false -p:HidiPublicSignBuild=true

FROM mcr.microsoft.com/dotnet/runtime:8.0-jammy-chiseled AS runtime
FROM mcr.microsoft.com/dotnet/runtime:10.0-noble-chiseled AS runtime
WORKDIR /app

COPY --from=build-env /app/publish ./
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,16 @@ The `GetEdmModel()` method can load a model in 3 ways:

The OpenAPI.OData.reader nuget package is at: [https://www.nuget.org/packages/Microsoft.OpenApi.OData/](https://www.nuget.org/packages/Microsoft.OpenApi.OData)

The package targets .NET 10 and depends on Microsoft.OData.Edm 9.x.

## Hidi command line tool

[Hidi](src/Microsoft.OpenApi.Hidi/readme.md) validates, transforms and slices
OpenAPI documents, converts OData CSDL, and generates API diagrams.
The NuGet package remains `Microsoft.OpenApi.Hidi` and the command remains `hidi`.
Hidi 3.x is maintained on `main`; Hidi 2.x is maintained on `support/v2`.
Both tracks use independent versions and require the .NET 8 runtime.
Both tracks use independent versions. Hidi 3.x requires the .NET 10 runtime;
Hidi 2.x requires the .NET 8 runtime.
Building this repository, including the Hidi tests, requires the .NET 10 SDK.
The main Hidi pipeline sets `hidiPublishingEnabled: 'true'` for stable
`hidi-v3.*` tag releases; `hidiPreviewPublishingEnabled: 'false'` keeps main
Expand Down
2 changes: 1 addition & 1 deletion install-tool.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }

$installedDlls = @(Get-ChildItem $toolDirectory -Force -Recurse -Filter Microsoft.OpenApi.Hidi.dll)
if ($installedDlls.Count -ne 1) { throw 'Expected exactly one installed hidi DLL.' }
$builtDll = Join-Path $PSScriptRoot 'src\Microsoft.OpenApi.Hidi\bin\Release\net8.0\Microsoft.OpenApi.Hidi.dll'
$builtDll = Join-Path $PSScriptRoot 'src\Microsoft.OpenApi.Hidi\bin\Release\net10.0\Microsoft.OpenApi.Hidi.dll'
if ((Get-FileHash $installedDlls[0].FullName).Hash -ne (Get-FileHash $builtDll).Hash) {
throw 'Installed hidi does not match the locally built package.'
}
4 changes: 2 additions & 2 deletions scripts/verify-hidi-package-assembly.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ $archive = $null
try {
$archive = [IO.Compression.ZipFile]::OpenRead((Resolve-Path -LiteralPath $PackagePath).Path)
$assemblies = @($archive.Entries | Where-Object { $_.Name -ieq 'Microsoft.OpenApi.Hidi.dll' })
if ($assemblies.Count -ne 1 -or $assemblies[0].FullName -cne 'tools/net8.0/any/Microsoft.OpenApi.Hidi.dll') {
throw 'Expected exactly one Hidi DLL at tools/net8.0/any/Microsoft.OpenApi.Hidi.dll.'
if ($assemblies.Count -ne 1 -or $assemblies[0].FullName -cne 'tools/net10.0/any/Microsoft.OpenApi.Hidi.dll') {
throw 'Expected exactly one Hidi DLL at tools/net10.0/any/Microsoft.OpenApi.Hidi.dll.'
}
[IO.Compression.ZipFileExtensions]::ExtractToFile($assemblies[0], $packagedAssembly)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public override void Visit(OpenApiOperation operation)

var operationId = operation.OperationId;
var operationTypeExtension = operation.Extensions?.GetExtension("x-ms-docs-operation-type");
if (operationTypeExtension.IsEquals("function") && operation.Parameters is { Count :> 0})
if (operationTypeExtension.IsEquals("function") && operation.Parameters is { Count: > 0 })
ResolveFunctionParameters(operation.Parameters);

// Order matters. Resolve operationId.
Expand Down Expand Up @@ -106,7 +106,7 @@ private static string ResolveByRefOperationId(string operationId)
// Update $ref path operationId name
// Ref key word is enclosed between lower-cased and upper-cased letters
// Ex.: applications_GetRefCreatedOnBehalfOf to applications_GetCreatedOnBehalfOfByRef
return s_oDataRefRegex.Match(operationId).Success ? $"{s_oDataRefRegex.Replace(operationId, string.Empty)}ByRef" : operationId;
return s_oDataRefRegex.IsMatch(operationId) ? $"{s_oDataRefRegex.Replace(operationId, string.Empty)}ByRef" : operationId;
}

private static string ResolveODataCastOperationId(string operationId)
Expand Down Expand Up @@ -175,8 +175,8 @@ private static void ResolveFunctionParameters(IList<IOpenApiParameter> parameter

private void AddAdditionalPropertiesToSchema(IOpenApiSchema schema)
{
if (schema is OpenApiSchema openApiSchema
&& !_schemaLoop.Contains(schema)
if (schema is OpenApiSchema openApiSchema
&& !_schemaLoop.Contains(schema)
&& schema.Type.Equals(JsonSchemaType.Object))
{
openApiSchema.AdditionalProperties = new OpenApiSchema() { Type = JsonSchemaType.Object };
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi.Hidi/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.OpenApi.Hidi
{
public static class Logger
internal static class Logger
{
public static ILoggerFactory ConfigureLogger(LogLevel logLevel)
{
Expand Down
3 changes: 1 addition & 2 deletions src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackAsTool>true</PackAsTool>
Expand Down Expand Up @@ -44,7 +44,6 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="System.CommandLine" Version="2.0.13"/>
<PackageReference Include="Microsoft.OData.Edm" Version="8.4.4"/>
<PackageReference Include="Microsoft.OpenApi" Version="3.10.2"/>
<PackageReference Include="Microsoft.OpenApi.YamlReader" Version="3.10.2"/>
<PackageReference Include="Microsoft.OpenApi.ApiManifest" Version="3.0.0-preview.1"/>
Expand Down
42 changes: 30 additions & 12 deletions src/Microsoft.OpenApi.Hidi/OpenApiService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public static async Task TransformOpenApiDocumentAsync(HidiOptions options, ILog
{
#pragma warning disable CA1308 // Normalize strings to uppercase
var extension = options.OpenApiFormat?.ToLowerInvariant();
var inputExtension = !string.IsNullOrEmpty(extension) ? string.Concat(".", extension)
var inputExtension = !string.IsNullOrEmpty(extension) ? string.Concat(".", extension)
: GetInputPathExtension(options.OpenApi, options.Csdl);

#pragma warning restore CA1308 // Normalize strings to uppercase
Expand Down Expand Up @@ -178,7 +178,10 @@ private static OpenApiDocument ApplyFilters(HidiOptions options, ILogger logger,
stopwatch.Start();
document = OpenApiFilterService.CreateFilteredDocument(document, predicate);
stopwatch.Stop();
logger.LogTrace("{Timestamp}ms: Creating filtered OpenApi document with {Paths} paths.", stopwatch.ElapsedMilliseconds, document.Paths.Count);
if (logger.IsEnabled(LogLevel.Trace))
{
logger.LogTrace("{Timestamp}ms: Creating filtered OpenApi document with {Paths} paths.", stopwatch.ElapsedMilliseconds, document.Paths.Count);
}
}

return document;
Expand Down Expand Up @@ -215,7 +218,10 @@ private static async Task WriteOpenApiAsync(HidiOptions options, string openApiF
await document.SerializeAsync(writer, openApiVersion, cancellationToken).ConfigureAwait(false);
stopwatch.Stop();

logger.LogTrace("Finished serializing in {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
if (logger.IsEnabled(LogLevel.Trace))
{
logger.LogTrace("Finished serializing in {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
}
await textWriter.FlushAsync(cancellationToken).ConfigureAwait(false);
}
}
Expand Down Expand Up @@ -244,7 +250,10 @@ private static async Task WriteOpenApiAsync(HidiOptions options, string openApiF

document = await ConvertCsdlToOpenApiAsync(filteredStream ?? stream, format, metadataVersion, options.SettingsConfig, cancellationToken).ConfigureAwait(false);
stopwatch.Stop();
logger.LogTrace("{Timestamp}ms: Generated OpenAPI with {Paths} paths.", stopwatch.ElapsedMilliseconds, document?.Paths.Count);
if (logger.IsEnabled(LogLevel.Trace))
{
logger.LogTrace("{Timestamp}ms: Generated OpenAPI with {Paths} paths.", stopwatch.ElapsedMilliseconds, document?.Paths.Count);
}
}
}
else if (!string.IsNullOrEmpty(options.OpenApi))
Expand Down Expand Up @@ -356,9 +365,12 @@ private static MemoryStream ApplyFilterToCsdl(Stream csdlStream, string entitySe
walker.Walk(result.Document);

logger.LogTrace("Finished walking through the OpenApi document. Generating a statistics report..");
#pragma warning disable CA2254
logger.LogInformation(statsVisitor.GetStatisticsReport());
#pragma warning restore CA2254
if (logger.IsEnabled(LogLevel.Information))
{
#pragma warning disable CA2254
logger.LogInformation(statsVisitor.GetStatisticsReport());
#pragma warning restore CA2254
}
}
}
catch (TaskCanceledException)
Expand Down Expand Up @@ -395,7 +407,10 @@ private static async Task<ReadResult> ParseOpenApiAsync(string openApiFile, bool

result = await OpenApiDocument.LoadAsync(stream, settings: settings, cancellationToken: cancellationToken).ConfigureAwait(false);

logger.LogTrace("{Timestamp}ms: Completed parsing.", stopwatch.ElapsedMilliseconds);
if (logger.IsEnabled(LogLevel.Trace))
{
logger.LogTrace("{Timestamp}ms: Completed parsing.", stopwatch.ElapsedMilliseconds);
}

LogErrors(logger, result);
LogWarnings(logger, result);
Expand Down Expand Up @@ -482,7 +497,7 @@ private static Dictionary<string, List<string>> EnumerateJsonDocument(JsonElemen
}
else
{
paths.Add(path, new() {method});
paths.Add(path, new() { method });
}
}
else
Expand Down Expand Up @@ -547,7 +562,10 @@ SecurityException or
}
}
stopwatch.Stop();
logger.LogTrace("{Timestamp}ms: Read file {Input}", stopwatch.ElapsedMilliseconds, input);
if (logger.IsEnabled(LogLevel.Trace))
{
logger.LogTrace("{Timestamp}ms: Read file {Input}", stopwatch.ElapsedMilliseconds, input);
}
}
return stream;
}
Expand Down Expand Up @@ -637,7 +655,7 @@ private static string GetInputPathExtension(string? openapi = null, string? csdl
return options.Output.FullName;
}
}
}
}
}
catch (TaskCanceledException)
{
Expand Down Expand Up @@ -766,7 +784,7 @@ internal static async Task PluginManifestAsync(HidiOptions options, ILogger logg
options.OpenApi = apiDependency.ApiDescriptionUrl;
}

var openApiFormat = options.OpenApiFormat ?? (!string.IsNullOrEmpty(options.OpenApi)
var openApiFormat = options.OpenApiFormat ?? (!string.IsNullOrEmpty(options.OpenApi)
? GetOpenApiFormat(options.OpenApi, logger) : OpenApiConstants.Yaml);

// Load OpenAPI document
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.OpenApi.Hidi/OpenApiSpecVersionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.OpenApi.Hidi
{
public static class OpenApiSpecVersionHelper
internal static class OpenApiSpecVersionHelper
{
public static OpenApiSpecVersion TryParseOpenApiSpecVersion(string value)
{
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.OpenApi.Hidi/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Hidi has these key capabilities that enable you to build different scenarios off

Install [Microsoft.OpenApi.Hidi](https://www.nuget.org/packages/Microsoft.OpenApi.Hidi)
from NuGet. Hidi 3.x is maintained on this repository's `main` branch and requires
.NET 8. Hidi 2.x is maintained separately on `support/v2`.
.NET 10. Hidi 2.x is maintained separately on `support/v2`.

### .NET CLI(Global)

Expand All @@ -32,7 +32,7 @@ dotnet tool install --local Microsoft.OpenApi.Hidi --version 3.10.2

### Build and install from this repository

Run these commands from the repository root with the .NET 10 SDK and .NET 8 runtime installed:
Run these commands from the repository root with the .NET 10 SDK installed:

```powershell
dotnet pack src\Microsoft.OpenApi.Hidi\Microsoft.OpenApi.Hidi.csproj -c Release -o artifacts\hidi\nuget
Expand Down
Loading
Loading