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
7 changes: 7 additions & 0 deletions .fallout/build.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@
"Verbosity": {
"description": "Logging verbosity during build execution. Default is 'Normal'",
"$ref": "#/definitions/Verbosity"
},
"BuildProjectFile": {
"type": [
"null",
"string"
],
"description": "Path to the build project (.csproj) relative to the repository root. Defaults to 'build/_build.csproj' when unset. Read by the Fallout global tool's in-tool runner."
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,21 @@ jobs:
name: ubuntu-latest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
with:
fetch-depth: 0
- name: 'Cache: .fallout/temp, ~/.nuget/packages'
uses: actions/cache@v4
uses: actions/cache@v6
with:
path: |
.fallout/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
- name: 'Setup: .NET SDK'
uses: actions/setup-dotnet@v6
with:
global-json-file: global.json
- name: 'Restore: dotnet tools'
run: dotnet tool restore
- name: 'Run: Test'
run: ./build.cmd Test
run: dotnet fallout Test
40 changes: 20 additions & 20 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@
</ItemGroup>

<ItemGroup Label="EF Core">
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.4" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.4" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="10.0.10" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.10" />
<!-- Postgres is the default provider (DR-009); mssql remains swappable by config.
Sqlite was removed: unused in production and it dragged in a vulnerable
SQLitePCLRaw (NU1903 / GHSA-2m69-gcr7-jv3q). Tests use real Postgres via Testcontainers. -->
<PackageVersion Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.3" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.4" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.10" />
</ItemGroup>

<ItemGroup Label="Mapping (source-generated)">
<PackageVersion Include="Riok.Mapperly" Version="4.1.1" />
<PackageVersion Include="Riok.Mapperly" Version="4.3.1" />
</ItemGroup>

<ItemGroup Label="Validation">
Expand All @@ -28,42 +28,42 @@
</ItemGroup>

<ItemGroup Label="Observability (via Aspire ServiceDefaults)">
<PackageVersion Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.10.0-beta.1" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.11.2" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.11.2" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.11.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.11.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.10.0" />
<PackageVersion Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.17.0-beta.1" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.17.0" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.17.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.17.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.17.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.17.0" />
</ItemGroup>

<ItemGroup Label="Hosting">
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.10" />
</ItemGroup>

<ItemGroup Label="Extensions">
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.0.0" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.10" />
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.0.10" />
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.10" />
</ItemGroup>

<ItemGroup Label="Compression">
<PackageVersion Include="SharpCompress" Version="0.38.0" />
<PackageVersion Include="SharpCompress" Version="0.50.1" />
</ItemGroup>

<ItemGroup Label="Aspire">
<PackageVersion Include="Aspire.Hosting" Version="13.1.2" />
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="13.1.2" />
<PackageVersion Include="Aspire.Hosting" Version="13.4.6" />
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="13.4.6" />
<PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="9.3.1" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="9.4.0" />
</ItemGroup>

<ItemGroup Label="Testing">
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.8.1" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.13.0" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="Shouldly" Version="4.3.0" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="NSubstitute" Version="6.0.0" />
<PackageVersion Include="TngTech.ArchUnitNET.xUnit" Version="0.13.3" />
</ItemGroup>

Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ Built on .NET 10, Postgres, Wolverine and .NET Aspire.
## Prerequisites

- **.NET 10 SDK** (`10.0.100+`, see `global.json`)
- **.NET Aspire workload** — `dotnet workload install aspire`
- **Docker** — Aspire provisions the Postgres container
- **Docker** — Aspire provisions the Postgres container, and the repository tests use Testcontainers
- **ffmpeg** on PATH — `brew install ffmpeg` (used to remux HLS streams; the Downloader image bundles it)

> No Aspire *workload* install is needed. Aspire 13 comes in via the `Aspire.AppHost.Sdk` reference in
> `Krautwatch.AppHost.csproj` plus NuGet packages — the old `dotnet workload install aspire` step is
> legacy and does not apply.

---

## Running the fleet locally
Expand Down
4 changes: 2 additions & 2 deletions build/_build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Fallout.Common" Version="10.3.49" />
<PackageReference Include="Fallout.Components" Version="10.3.49" />
<PackageReference Include="Fallout.Common" Version="10.4.0-rc.4" />
<PackageReference Include="Fallout.Components" Version="10.4.0-rc.4" />
</ItemGroup>

</Project>
5 changes: 4 additions & 1 deletion src/Presentation/AppHost/Krautwatch.AppHost.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<Sdk Name="Aspire.AppHost.Sdk" Version="13.1.2" />
<!-- Keep in lockstep with the Aspire.Hosting* PackageVersions in Directory.Packages.props: this SDK
pins Aspire.Hosting.AppHost + the DCP orchestrator + dashboard, and DCP refuses to start if it
is older than Aspire.Hosting. -->
<Sdk Name="Aspire.AppHost.Sdk" Version="13.4.6" />

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
2 changes: 1 addition & 1 deletion tests/Application.Tests/CrawlShowHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public async Task Handle_selects_crawler_by_provider_and_upserts_the_crawled_epi
zdf.LastQuery.ShouldBe("heute-show");
otherProvider.LastQuery.ShouldBeNull(); // the ARD crawler must not be invoked
await repo.Received(1).UpsertManyAsync(
Arg.Is<IEnumerable<Episode>>(e => e.Count() == 2), Arg.Any<CancellationToken>());
Arg.Is<IEnumerable<Episode>>(e => e != null && e.Count() == 2), Arg.Any<CancellationToken>());
}

[Fact]
Expand Down
2 changes: 1 addition & 1 deletion tests/Application.Tests/RefreshProxyListHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public async Task Upserts_the_fetched_candidates()
await new RefreshProxyListHandler(source, repo, NullLogger<RefreshProxyListHandler>.Instance).HandleAsync();

await repo.Received(1).UpsertBatchAsync(
Arg.Is<IEnumerable<Proxy>>(ps => ps.Count() == 2), Arg.Any<CancellationToken>());
Arg.Is<IEnumerable<Proxy>>(ps => ps != null && ps.Count() == 2), Arg.Any<CancellationToken>());
}

[Fact]
Expand Down
4 changes: 2 additions & 2 deletions tests/Application.Tests/SabnzbdDownloadTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public async Task Creates_and_enqueues_a_job_for_a_known_token()
var jobId = await new AddDownloadByTokenHandler(episodes, jobs, queue).HandleAsync("zdf:1");

jobId.ShouldNotBeNull();
await jobs.Received(1).AddAsync(Arg.Is<DownloadJob>(j => j.EpisodeId == "zdf:1" && j.StreamUrl == "https://cdn/x.mp4"), Arg.Any<CancellationToken>());
await jobs.Received(1).AddAsync(Arg.Is<DownloadJob>(j => j != null && j.EpisodeId == "zdf:1" && j.StreamUrl == "https://cdn/x.mp4"), Arg.Any<CancellationToken>());
await queue.Received(1).EnqueueAsync(jobId!.Value, "https://cdn/x.mp4", Arg.Any<CancellationToken>());
}

Expand All @@ -82,7 +82,7 @@ public async Task Snapshots_the_episodes_geo_restriction_onto_the_job()

await new AddDownloadByTokenHandler(episodes, jobs, queue).HandleAsync("kika:1");

await jobs.Received(1).AddAsync(Arg.Is<DownloadJob>(j => j.GeoRestricted), Arg.Any<CancellationToken>());
await jobs.Received(1).AddAsync(Arg.Is<DownloadJob>(j => j != null && j.GeoRestricted), Arg.Any<CancellationToken>());
}

[Fact]
Expand Down