Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
60 changes: 9 additions & 51 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,18 @@ jobs:
- name: Upload Test Results
uses: actions/upload-artifact@v4
if: always()
timeout-minutes: 5
with:
name: unit-test-results
path: tests/TestResults/
path: |
tests/TestResults/**/*.trx
tests/TestResults/**/coverage.cobertura.xml
retention-days: 7

test-integration:
name: Integration Tests (Testcontainers + PostGIS)
runs-on: ubuntu-latest
needs: build
needs: [build, test-unit, test-architecture, aot-build] # Run after all other tests except LLM
outputs:
needs_integration: ${{ steps.changes.outputs.integration }}
services:
Expand Down Expand Up @@ -157,57 +161,11 @@ jobs:
name: architecture-test-results
path: tests/TestResults/

security-scan:
name: Security Vulnerability Scan
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Restore
run: dotnet restore Honua.sln

- name: Scan for Vulnerable NuGet Packages
id: nuget-scan
run: |
echo "Scanning for vulnerable NuGet packages..."

# Run vulnerability scan and capture output
if dotnet list package --vulnerable --include-transitive > vulnerability-report.txt 2>&1; then
echo "scan_result=success" >> $GITHUB_OUTPUT
else
echo "scan_result=failure" >> $GITHUB_OUTPUT
fi

# Display the results
cat vulnerability-report.txt

# Check if any high or critical vulnerabilities were found
if grep -E "(High|Critical)" vulnerability-report.txt; then
echo "vulnerable_packages=true" >> $GITHUB_OUTPUT
echo "::error::High or Critical vulnerabilities found in NuGet packages"
exit 1
else
echo "vulnerable_packages=false" >> $GITHUB_OUTPUT
echo "No high or critical vulnerabilities found"
fi

- name: Upload Vulnerability Report
uses: actions/upload-artifact@v4
if: always()
with:
name: vulnerability-report
path: vulnerability-report.txt

coverage:
name: Coverage Report
runs-on: ubuntu-latest
needs: [test-unit, test-integration, test-architecture, security-scan]
needs: [test-unit, test-integration, test-architecture]
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -246,7 +204,7 @@ jobs:
path: ./coverage/report/

- name: Upload to Codecov
uses: codecov/codecov-action@v5
uses: codecov/codecov-action@v4
with:
files: ./coverage/report/Cobertura.xml
flags: combined
Expand Down Expand Up @@ -279,7 +237,7 @@ jobs:
llm-architecture-review:
name: LLM Architecture Review
runs-on: ubuntu-latest
needs: build # Only run after successful build
needs: [build, test-unit, test-architecture, aot-build] # Run in parallel with integration tests
if: github.event_name == 'pull_request' && github.event.pull_request.draft == false
outputs:
assessment: ${{ steps.llm-analysis.outputs.assessment }}
Expand Down
4 changes: 0 additions & 4 deletions .github/workflows/cite-conformance.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
name: OGC CITE Conformance Tests

on:
push:
branches: [ trunk ]
pull_request:
branches: [ trunk ]
schedule:
# Run weekly to catch conformance regressions
- cron: '0 6 * * 1'
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/performance.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: Performance Benchmarks

on:
pull_request:
branches: [ trunk ]
schedule:
# Run nightly to track performance trends
- cron: '0 6 * * *'
Expand Down
110 changes: 110 additions & 0 deletions .github/workflows/security-nightly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Security Scans

on:
schedule:
# Run nightly to check for new vulnerabilities
- cron: '0 6 * * *'
workflow_dispatch:
inputs:
include_transitive:
description: 'Include transitive dependencies'
type: boolean
default: true

env:
DOTNET_VERSION: '10.0.x'
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
DOTNET_NOLOGO: true

jobs:
security-vulnerability-scan:
name: Security Vulnerability Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Restore
run: dotnet restore Honua.sln

- name: Scan for Vulnerable NuGet Packages
id: nuget-scan
run: |
echo "Scanning for vulnerable NuGet packages..."

# Run vulnerability scan and capture output
if dotnet list package --vulnerable --include-transitive > vulnerability-report.txt 2>&1; then
echo "scan_result=success" >> $GITHUB_OUTPUT
else
echo "scan_result=failure" >> $GITHUB_OUTPUT
fi

# Display the results
cat vulnerability-report.txt

# Check if any high or critical vulnerabilities were found
if grep -E "(High|Critical)" vulnerability-report.txt; then
echo "vulnerable_packages=true" >> $GITHUB_OUTPUT
echo "::error::High or Critical vulnerabilities found in NuGet packages"
exit 1
else
echo "vulnerable_packages=false" >> $GITHUB_OUTPUT
echo "No high or critical vulnerabilities found"
fi

- name: Upload Vulnerability Report
uses: actions/upload-artifact@v4
if: always()
with:
name: vulnerability-report-${{ github.run_number }}
path: vulnerability-report.txt
retention-days: 30

- name: Create Issue on Vulnerabilities
if: steps.nuget-scan.outputs.vulnerable_packages == 'true'
uses: actions/github-script@v8
with:
script: |
const title = 'Security Alert: High/Critical vulnerabilities detected';
const body = `## Security Vulnerability Alert

The nightly security scan detected high or critical vulnerabilities in project dependencies.

**Scan Date**: ${{ github.run_id }}
**Report**: Available in workflow artifacts

### Next Steps
1. Review the vulnerability report in the workflow artifacts
2. Update affected packages to patched versions
3. Test updated dependencies
4. Monitor for additional security updates

This issue was created automatically by the nightly security scan.
`;

// Check if similar issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'security,automated'
});

const existingIssue = issues.data.find(issue =>
issue.title.includes('Security Alert') &&
issue.title.includes('vulnerabilities detected')
);

if (!existingIssue) {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['security', 'automated', 'high-priority']
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Validating benchmarks:
// Benchmark QueryBenchmarks.SimpleWhereQuery: .NET 9.0(Runtime=.NET 9.0)
// * The required .NET Core SDK version 9.0 for runtime moniker Net90 is not installed.

// Benchmark QueryBenchmarks.SpatialBboxQuery: .NET 9.0(Runtime=.NET 9.0)
// * The required .NET Core SDK version 9.0 for runtime moniker Net90 is not installed.

// Benchmark QueryBenchmarks.CombinedWhereAndSpatialQuery: .NET 9.0(Runtime=.NET 9.0)
// * The required .NET Core SDK version 9.0 for runtime moniker Net90 is not installed.

// Benchmark QueryBenchmarks.PaginatedQuery: .NET 9.0(Runtime=.NET 9.0)
// * The required .NET Core SDK version 9.0 for runtime moniker Net90 is not installed.

// Benchmark QueryBenchmarks.LargeResultSet: .NET 9.0(Runtime=.NET 9.0)
// * The required .NET Core SDK version 9.0 for runtime moniker Net90 is not installed.

6 changes: 3 additions & 3 deletions src/Honua.AppHost/Honua.AppHost.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Hosting" Version="13.0.0" />
<PackageReference Include="Aspire.Hosting.PostgreSQL" Version="13.0.0" />
<PackageReference Include="Aspire.Hosting.Redis" Version="13.0.0" />
<PackageReference Include="Aspire.Hosting" Version="13.1.0" />
<PackageReference Include="Aspire.Hosting.PostgreSQL" Version="13.1.0" />
<PackageReference Include="Aspire.Hosting.Redis" Version="13.1.0" />
</ItemGroup>

<ItemGroup>
Expand Down
5 changes: 3 additions & 2 deletions src/Honua.Postgres/Honua.Postgres.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.1" />
<PackageReference Include="Npgsql" Version="9.0.2" />
<PackageReference Include="Polly" Version="8.4.2" />
<PackageReference Include="Npgsql" Version="10.0.0" />
<PackageReference Include="Polly" Version="8.6.5" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="NetTopologySuite" Version="2.6.0" />
<ProjectReference Include="..\Honua.Core\Honua.Core.csproj" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,9 @@ public class EditError
[JsonSerializable(typeof(ImmutableArray<ImmutableArray<double>>))]
[JsonSerializable(typeof(ImmutableArray<ImmutableArray<string?>>))]
[JsonSerializable(typeof(ImmutableArray<string>?))]
// Interface types for AOT compatibility
[JsonSerializable(typeof(Honua.Core.Features.FeatureStore.Abstractions.IFeatureStore))]
[JsonSerializable(typeof(Honua.Core.Features.Catalog.Abstractions.ILayerCatalog))]
[JsonSourceGenerationOptions(
PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
Expand Down
1 change: 1 addition & 0 deletions src/Honua.Server/Features/OgcFeatures/Models/OgcModels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -436,3 +436,4 @@ public static class MediaTypes
/// </summary>
public const string OpenApi = "application/vnd.oai.openapi+json;version=3.0";
}

4 changes: 2 additions & 2 deletions src/Honua.Server/Features/OgcFeatures/OgcFeaturesEndpoints.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1237,13 +1237,13 @@ private static async Task<IResult> HandleGetCollection(
// For now, try to parse the string as an integer
if (!int.TryParse(collectionId, out var layerId))
{
return TypedResults.NotFound();
return Results.NotFound();
}

var layer = await layerCatalog.GetLayerAsync(layerId);
if (layer == null)
{
return TypedResults.NotFound();
return Results.NotFound();
}

var collection = CreateCollection(layer, baseUrl);
Expand Down
1 change: 1 addition & 0 deletions src/Honua.Server/Features/OgcFeatures/OgcJsonContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace Honua.Server.Features.OgcFeatures;
[JsonSerializable(typeof(ImmutableArray<Link>))]
[JsonSerializable(typeof(ImmutableArray<CollectionInfo>))]
[JsonSerializable(typeof(ImmutableArray<string>))]
[JsonSerializable(typeof(ImmutableArray<double>))]
[JsonSerializable(typeof(ImmutableArray<ImmutableArray<double>>))]
[JsonSerializable(typeof(ImmutableArray<ImmutableArray<string?>>))]
[JsonSerializable(typeof(FeatureCollection))]
Expand Down
7 changes: 4 additions & 3 deletions src/Honua.Server/Honua.Server.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="dbup-postgresql" Version="6.0.3" />
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders" Version="1.1.0" />
<PackageReference Include="Polly" Version="8.4.2" />
<PackageReference Include="dbup-postgresql" Version="6.1.5" />
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders" Version="1.3.1" />
<PackageReference Include="Polly" Version="8.6.5" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
<PackageReference Include="Serilog.Enrichers.Environment" Version="2.3.0" />
<PackageReference Include="Serilog.Enrichers.Thread" Version="4.0.0" />
Expand All @@ -40,6 +40,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="NetTopologySuite" Version="2.6.0" />
<EmbeddedResource Include="Migrations\*.sql" />
</ItemGroup>

Expand Down
6 changes: 1 addition & 5 deletions src/Honua.Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,7 @@
Honua.Server.Features.FeatureServer.Services.QueryFormatter>();
builder.Services.AddScoped<Honua.Server.Features.FeatureServer.Services.IFeatureQueryValidator,
Honua.Server.Features.FeatureServer.Services.FeatureQueryValidator>();
builder.Services.AddScoped(provider => new Honua.Server.Features.FeatureServer.Services.FeatureServerServices(
provider.GetRequiredService<Honua.Server.Features.FeatureServer.Services.IQueryFormatter>(),
provider.GetRequiredService<Honua.Server.Features.FeatureServer.Services.IFeatureQueryValidator>(),
provider.GetRequiredService<Honua.Server.Features.Infrastructure.Services.IGeometryConverter>()
));
builder.Services.AddScoped<Honua.Server.Features.FeatureServer.Services.FeatureServerServices>();
builder.Services.AddScoped<Honua.Server.Features.FeatureServer.FeatureServerHandler>();

// OData services use existing FeatureServer services
Expand Down
16 changes: 8 additions & 8 deletions src/Honua.ServiceDefaults/Honua.ServiceDefaults.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Aspire.Npgsql" Version="13.0.0" />
<PackageReference Include="Aspire.StackExchange.Redis.DistributedCaching" Version="13.0.0" />
<PackageReference Include="Aspire.Npgsql" Version="13.1.0" />
<PackageReference Include="Aspire.StackExchange.Redis.DistributedCaching" Version="13.1.0" />
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="10.1.0" />
<PackageReference Include="Microsoft.Extensions.Resilience" Version="10.1.0" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.12.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.12.0" />
<PackageReference Include="Npgsql.OpenTelemetry" Version="9.0.4" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.14.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.14.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.14.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.14.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.14.0" />
<PackageReference Include="Npgsql.OpenTelemetry" Version="10.0.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="7.0.0" />
<PackageReference Include="FluentAssertions" Version="7.2.0" />
<PackageReference Include="NetArchTest.Rules" Version="1.3.2" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion tests/Honua.Server.Tests/Honua.Server.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.1" />
<PackageReference Include="Microsoft.OData.Client" Version="8.4.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="Polly" Version="8.4.2" />
<PackageReference Include="Polly" Version="8.6.5" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Loading
Loading