diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 75cc3508b..1f2df5d74 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,11 +3,11 @@ "isRoot": true, "tools": { "jetbrains.resharper.globaltools": { - "version": "2025.3.0", + "version": "2025.3.0.2", "commands": [ "jb" ], "rollForward": false } } -} \ No newline at end of file +} diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml index 55aba389f..5cbcdfff6 100644 --- a/.github/workflows/artifacts.yml +++ b/.github/workflows/artifacts.yml @@ -48,7 +48,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.0.203 + dotnet-version: '10.0.x' - name: Clean run: dotnet clean --configuration Release && dotnet nuget locals all --clear @@ -163,7 +163,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.0.203 + dotnet-version: '10.0.x' - name: Clean run: dotnet clean --configuration Release && dotnet nuget locals all --clear @@ -220,7 +220,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.0.203 + dotnet-version: '10.0.x' - name: Clean run: dotnet clean --configuration Release && dotnet nuget locals all --clear diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 1a05a013d..9cafba33f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -11,7 +11,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.0.203 + dotnet-version: '10.0.x' - name: Clean run: dotnet clean --configuration Release && dotnet nuget locals all --clear @@ -52,7 +52,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.0.203 + dotnet-version: '10.0.x' - name: Clean run: dotnet clean --configuration Release && dotnet nuget locals all --clear @@ -80,7 +80,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 9.0.203 + dotnet-version: '10.0.x' - name: Clean run: dotnet clean --configuration Release && dotnet nuget locals all --clear diff --git a/CHANGELOG.md b/CHANGELOG.md index f68ad98e0..ab7ab9a26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Template groups in template list - Block groups and blocks in template editor - Replace template tree view with searchable table (like blocks) +- Upgrade to dotnet 10 ## [25.8.0] - 2025-10-26 ### Added diff --git a/ErsatzTV.Application/ErsatzTV.Application.csproj b/ErsatzTV.Application/ErsatzTV.Application.csproj index a18b23d9b..bd8d54c51 100644 --- a/ErsatzTV.Application/ErsatzTV.Application.csproj +++ b/ErsatzTV.Application/ErsatzTV.Application.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 VSTHRD200 enable latest-Recommended @@ -12,10 +12,10 @@ - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj index 4bf701dc4..3c94325d5 100644 --- a/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj +++ b/ErsatzTV.Core.Tests/ErsatzTV.Core.Tests.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 VSTHRD200 enable @@ -10,11 +10,11 @@ - - - - - + + + + + all @@ -24,7 +24,7 @@ - + diff --git a/ErsatzTV.Core/ErsatzTV.Core.csproj b/ErsatzTV.Core/ErsatzTV.Core.csproj index 968663ec3..dba80a000 100644 --- a/ErsatzTV.Core/ErsatzTV.Core.csproj +++ b/ErsatzTV.Core/ErsatzTV.Core.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 VSTHRD200 enable latest-Recommended @@ -12,14 +12,14 @@ - + - - - - + + + + all diff --git a/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj b/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj index a6f7c7b0a..b42e40ab4 100644 --- a/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj +++ b/ErsatzTV.FFmpeg.Tests/ErsatzTV.FFmpeg.Tests.csproj @@ -1,21 +1,19 @@  - net9.0 + net10.0 enable false - + - - all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj index d89d79356..a406a29fc 100644 --- a/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj +++ b/ErsatzTV.FFmpeg/ErsatzTV.FFmpeg.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable latest-Recommended @@ -14,8 +14,8 @@ - - + + diff --git a/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj b/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj index f6b1b374a..eba7c26c8 100644 --- a/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj +++ b/ErsatzTV.Infrastructure.MySql/ErsatzTV.Infrastructure.MySql.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable diff --git a/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj b/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj index 97b9cf191..0fc4a88c9 100644 --- a/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj +++ b/ErsatzTV.Infrastructure.Sqlite/ErsatzTV.Infrastructure.Sqlite.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable diff --git a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj index 6787d0d0c..f9d32ec96 100644 --- a/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj +++ b/ErsatzTV.Infrastructure.Tests/ErsatzTV.Infrastructure.Tests.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable diff --git a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj index 290bcef7f..53b20e284 100644 --- a/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj +++ b/ErsatzTV.Infrastructure/ErsatzTV.Infrastructure.csproj @@ -1,12 +1,13 @@ - net9.0 + net10.0 true VSTHRD200 enable latest-Recommended true + Linux @@ -52,4 +53,10 @@ + + + .dockerignore + + + diff --git a/ErsatzTV.Scanner.Tests/Core/Metadata/LocalSubtitlesProviderTests.cs b/ErsatzTV.Scanner.Tests/Core/Metadata/LocalSubtitlesProviderTests.cs index b3b0f48ec..f9b2dc7f6 100644 --- a/ErsatzTV.Scanner.Tests/Core/Metadata/LocalSubtitlesProviderTests.cs +++ b/ErsatzTV.Scanner.Tests/Core/Metadata/LocalSubtitlesProviderTests.cs @@ -28,8 +28,6 @@ public class LocalSubtitlesProviderTests // Avatar (2009).de.srt // Avatar (2009).de.sdh.forced.srt - private readonly string _prefix = OperatingSystem.IsWindows() ? "C:\\" : "/"; - [Test] public void Should_Find_All_Languages_Codecs_And_Flags_With_Full_Paths() { @@ -52,7 +50,7 @@ public class LocalSubtitlesProviderTests new(@"/Movies/Avatar (2009)/Avatar (2009).DE.SDH.FORCED.SRT") }; - var fileSystem = new MockFileSystem(); + var fileSystem = new MockFileSystem(o => o.SimulatingOperatingSystem(SimulationMode.Linux)); IFileSystemInitializer init = fileSystem.Initialize(); foreach (var file in fakeFiles) { @@ -62,6 +60,7 @@ public class LocalSubtitlesProviderTests var provider = new LocalSubtitlesProvider( Substitute.For(), Substitute.For(), + fileSystem, new LocalFileSystem(fileSystem, Substitute.For(), Substitute.For>()), Substitute.For>()); @@ -78,8 +77,7 @@ public class LocalSubtitlesProviderTests result.Count(s => s.Codec == "subrip").ShouldBe(4); result.Count(s => s.Codec == "ass").ShouldBe(1); - string path = Path.Combine(_prefix, "Movies", "Avatar (2009)"); - result.All(s => s.Path.Contains(path)).ShouldBeTrue(); + result.All(s => s.Path.Contains("/Movies/Avatar (2009)")).ShouldBeTrue(); } [Test] @@ -106,7 +104,7 @@ public class LocalSubtitlesProviderTests new(@"/Movies/Avatar (2009)/Avatar (2009).DE.SDH.FORCED.SRT") }; - var fileSystem = new MockFileSystem(); + var fileSystem = new MockFileSystem(o => o.SimulatingOperatingSystem(SimulationMode.Linux)); IFileSystemInitializer init = fileSystem.Initialize(); foreach (var file in fakeFiles) { @@ -116,6 +114,7 @@ public class LocalSubtitlesProviderTests var provider = new LocalSubtitlesProvider( Substitute.For(), Substitute.For(), + fileSystem, new LocalFileSystem(fileSystem, Substitute.For(), Substitute.For>()), Substitute.For>()); @@ -132,7 +131,6 @@ public class LocalSubtitlesProviderTests result.Count(s => s.Codec == "subrip").ShouldBe(5); result.Count(s => s.Codec == "ass").ShouldBe(2); - string path = Path.Combine(_prefix, "Movies", "Avatar (2009)"); - result.Count(s => s.Path.Contains(path)).ShouldBe(0); + result.Count(s => s.Path.Contains("/Movies/Avatar (2009)")).ShouldBe(0); } } diff --git a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj index 6642108f1..71916d4a3 100644 --- a/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj +++ b/ErsatzTV.Scanner.Tests/ErsatzTV.Scanner.Tests.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 enable enable diff --git a/ErsatzTV.Scanner/Core/Metadata/LocalSubtitlesProvider.cs b/ErsatzTV.Scanner/Core/Metadata/LocalSubtitlesProvider.cs index abbb8486c..bc123d36a 100644 --- a/ErsatzTV.Scanner/Core/Metadata/LocalSubtitlesProvider.cs +++ b/ErsatzTV.Scanner/Core/Metadata/LocalSubtitlesProvider.cs @@ -1,4 +1,5 @@ using System.Globalization; +using System.IO.Abstractions; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Extensions; using ErsatzTV.Core.Interfaces.Metadata; @@ -15,6 +16,7 @@ public class LocalSubtitlesProvider : ILocalSubtitlesProvider private readonly ILogger _logger; private readonly IMediaItemRepository _mediaItemRepository; private readonly IMetadataRepository _metadataRepository; + private readonly IFileSystem _fileSystem; private readonly SemaphoreSlim _slim = new(1, 1); private bool _disposedValue; @@ -22,11 +24,13 @@ public class LocalSubtitlesProvider : ILocalSubtitlesProvider public LocalSubtitlesProvider( IMediaItemRepository mediaItemRepository, IMetadataRepository metadataRepository, + IFileSystem fileSystem, ILocalFileSystem localFileSystem, ILogger logger) { _mediaItemRepository = mediaItemRepository; _metadataRepository = metadataRepository; + _fileSystem = fileSystem; _localFileSystem = localFileSystem; _logger = logger; } @@ -108,19 +112,19 @@ public class LocalSubtitlesProvider : ILocalSubtitlesProvider { var result = new List(); - string? folder = Path.GetDirectoryName(mediaItemPath); - string withoutExtension = Path.GetFileNameWithoutExtension(mediaItemPath); + string? folder = _fileSystem.Path.GetDirectoryName(mediaItemPath); + string withoutExtension = _fileSystem.Path.GetFileNameWithoutExtension(mediaItemPath); foreach (string file in _localFileSystem.ListFiles(folder, $"{withoutExtension}*")) { string lowerFile = file.ToLowerInvariant(); - string fileName = Path.GetFileName(file); + string fileName = _fileSystem.Path.GetFileName(file); if (!fileName.StartsWith(withoutExtension, StringComparison.OrdinalIgnoreCase)) { continue; } - string extension = Path.GetExtension(lowerFile); + string extension = _fileSystem.Path.GetExtension(lowerFile); string codec = extension switch { ".ssa" or ".ass" => "ass", @@ -134,7 +138,7 @@ public class LocalSubtitlesProvider : ILocalSubtitlesProvider continue; } - string language = Path.GetFileName(lowerFile); + string language = _fileSystem.Path.GetFileName(lowerFile); var forced = false; var sdh = false; @@ -181,7 +185,7 @@ public class LocalSubtitlesProvider : ILocalSubtitlesProvider Forced = forced, SDH = sdh, Language = language, - Path = saveFullPath ? file : Path.GetFileName(file), + Path = saveFullPath ? file : _fileSystem.Path.GetFileName(file), DateAdded = DateTime.UtcNow, DateUpdated = _localFileSystem.GetLastWriteTime(file) }); @@ -200,7 +204,7 @@ public class LocalSubtitlesProvider : ILocalSubtitlesProvider Forced = forced, SDH = sdh, Language = culture.ThreeLetterISOLanguageName, - Path = saveFullPath ? file : Path.GetFileName(file), + Path = saveFullPath ? file : _fileSystem.Path.GetFileName(file), DateAdded = DateTime.UtcNow, DateUpdated = _localFileSystem.GetLastWriteTime(file) }); diff --git a/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj b/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj index e3ecb6b68..0b0bbcd54 100644 --- a/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj +++ b/ErsatzTV.Scanner/ErsatzTV.Scanner.csproj @@ -2,7 +2,7 @@ Exe - net9.0 + net10.0 enable enable Debug;Release;Debug No Sync @@ -21,12 +21,12 @@ - + - - - + + + diff --git a/ErsatzTV/ErsatzTV.csproj b/ErsatzTV/ErsatzTV.csproj index 5aa8030ee..6415866ae 100644 --- a/ErsatzTV/ErsatzTV.csproj +++ b/ErsatzTV/ErsatzTV.csproj @@ -1,7 +1,7 @@ - net9.0 + net10.0 true Latest false @@ -62,7 +62,6 @@ - diff --git a/ErsatzTV/Startup.cs b/ErsatzTV/Startup.cs index 3544118a5..384da8a0c 100644 --- a/ErsatzTV/Startup.cs +++ b/ErsatzTV/Startup.cs @@ -125,7 +125,7 @@ public class Startup { options.ForwardedHeaders = ForwardedHeaders.All; options.ForwardLimit = 2; - options.KnownNetworks.Clear(); + options.KnownIPNetworks.Clear(); options.KnownProxies.Clear(); }); diff --git a/docker/Dockerfile b/docker/Dockerfile index c832666ae..c2773430f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/aspnet:9.0-noble-amd64 AS dotnet-runtime +FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-amd64 AS dotnet-runtime FROM --platform=linux/amd64 ghcr.io/ersatztv/ersatztv-ffmpeg:7.1.1 AS runtime-base COPY --from=dotnet-runtime /usr/share/dotnet /usr/share/dotnet @@ -9,7 +9,7 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* # https://hub.docker.com/_/microsoft-dotnet -FROM mcr.microsoft.com/dotnet/sdk:9.0-noble-amd64 AS build +FROM mcr.microsoft.com/dotnet/sdk:10.0-noble-amd64 AS build RUN apt-get update && apt-get install -y ca-certificates gnupg default-jre-headless python3-pip WORKDIR /source diff --git a/docker/arm32v7/Dockerfile b/docker/arm32v7/Dockerfile index 4624fcf24..f5ce6b634 100644 --- a/docker/arm32v7/Dockerfile +++ b/docker/arm32v7/Dockerfile @@ -1,10 +1,10 @@ -FROM mcr.microsoft.com/dotnet/aspnet:9.0-noble-arm32v7 AS dotnet-runtime +FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-arm32v7 AS dotnet-runtime FROM --platform=linux/arm/v7 ghcr.io/ersatztv/ersatztv-ffmpeg:7.1.1 AS runtime-base COPY --from=dotnet-runtime /usr/share/dotnet /usr/share/dotnet # https://hub.docker.com/_/microsoft-dotnet -FROM mcr.microsoft.com/dotnet/sdk:9.0-noble-amd64 AS build +FROM mcr.microsoft.com/dotnet/sdk:10.0-noble-amd64 AS build RUN apt-get update && apt-get install -y ca-certificates gnupg WORKDIR /source diff --git a/docker/arm64/Dockerfile b/docker/arm64/Dockerfile index 8fcb0bb46..7ad91ba74 100644 --- a/docker/arm64/Dockerfile +++ b/docker/arm64/Dockerfile @@ -1,10 +1,10 @@ -FROM mcr.microsoft.com/dotnet/aspnet:9.0-noble-arm64v8 AS dotnet-runtime +FROM mcr.microsoft.com/dotnet/aspnet:10.0-noble-arm64v8 AS dotnet-runtime FROM --platform=linux/arm64 ghcr.io/ersatztv/ersatztv-ffmpeg:7.1.1 AS runtime-base COPY --from=dotnet-runtime /usr/share/dotnet /usr/share/dotnet # https://hub.docker.com/_/microsoft-dotnet -FROM mcr.microsoft.com/dotnet/sdk:9.0-noble-arm64v8 AS build +FROM mcr.microsoft.com/dotnet/sdk:10.0-noble-arm64v8 AS build RUN apt-get update && apt-get install -y ca-certificates gnupg WORKDIR /source diff --git a/global.json b/global.json index 4f85ebc60..90e5a4215 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.100", + "version": "10.0.0", "rollForward": "latestMinor", "allowPrerelease": false }