diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 71cb983e4..ea5d86e96 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,6 +13,9 @@ on: permissions: contents: read +env: + DOTNET_TARGET_FRAMEWORK: net11.0 + jobs: Linux: runs-on: ubuntu-24.04 @@ -27,15 +30,15 @@ jobs: uses: actions/setup-dotnet@9a946fdbd5fb07b82b2f5a4466058b876ab72bb2 # v5.3.0 - name: Build Unit Tests .NET - run: dotnet build -f net10.0 test/Renci.SshNet.Tests/ + run: dotnet build -f $DOTNET_TARGET_FRAMEWORK test/Renci.SshNet.Tests/ - name: Build IntegrationTests .NET - run: dotnet build -f net10.0 test/Renci.SshNet.IntegrationTests/ + run: dotnet build -f $DOTNET_TARGET_FRAMEWORK test/Renci.SshNet.IntegrationTests/ - name: Run Unit Tests .NET run: | dotnet test \ - -f net10.0 \ + -f $DOTNET_TARGET_FRAMEWORK \ --no-build \ --logger "console;verbosity=normal" \ --logger GitHubActions \ @@ -47,7 +50,7 @@ jobs: - name: Run Integration Tests .NET run: | dotnet test \ - -f net10.0 \ + -f $DOTNET_TARGET_FRAMEWORK \ --no-build \ --logger "console;verbosity=normal" \ --logger GitHubActions \ @@ -92,7 +95,7 @@ jobs: - name: Run Unit Tests .NET run: | dotnet test ` - -f net10.0 ` + -f $DOTNET_TARGET_FRAMEWORK ` --no-build ` --logger "console;verbosity=normal" ` --logger GitHubActions ` @@ -145,17 +148,8 @@ jobs: -f net48 ` --logger "console;verbosity=normal" ` --logger GitHubActions ` - -p:CollectCoverage=true ` - -p:CoverletOutputFormat=cobertura ` - -p:CoverletOutput=..\..\coverlet\windows_integration_test_net_4_8_coverage.xml ` test\Renci.SshNet.IntegrationTests\ - - name: Archive Coverlet Results - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: Coverlet Results Windows .NET Framework - path: coverlet - Windows-Integration-Tests-Net: name: Windows Integration Tests .NET runs-on: windows-2025 @@ -185,7 +179,7 @@ jobs: - name: Run Integration Tests .NET run: dotnet test ` - -f net10.0 ` + -f $env:DOTNET_TARGET_FRAMEWORK ` --logger "console;verbosity=normal" ` --logger GitHubActions ` -p:CollectCoverage=true ` diff --git a/Directory.Build.props b/Directory.Build.props index 9e82358aa..ed9935d82 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -34,7 +34,7 @@ - + $(NoWarn);CS8602;CS8604;CS8777 diff --git a/docfx/docfx.json b/docfx/docfx.json index 271763230..11cab28e2 100644 --- a/docfx/docfx.json +++ b/docfx/docfx.json @@ -13,7 +13,7 @@ "outputFormat": "apiPage", "output": "api", "properties": { - "TargetFramework": "net8.0" + "TargetFramework": "net10.0" } } ], diff --git a/global.json b/global.json index 063163147..b40840056 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.201", + "version": "11.0.0-rc.1.26425.128", "rollForward": "latestMinor" } } diff --git a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs index 1f536ff27..60679a98d 100644 --- a/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs +++ b/src/Renci.SshNet/Channels/ChannelForwardedTcpip.cs @@ -1,7 +1,7 @@ using System; using System.Net; using System.Net.Sockets; -#if NET9_0_OR_GREATER +#if NET using System.Threading; #endif diff --git a/src/Renci.SshNet/Common/Lock.cs b/src/Renci.SshNet/Common/Lock.cs index b402390ab..abd7bd09f 100644 --- a/src/Renci.SshNet/Common/Lock.cs +++ b/src/Renci.SshNet/Common/Lock.cs @@ -1,4 +1,4 @@ -#if !NET9_0_OR_GREATER +#if !NET using System.Threading; namespace Renci.SshNet.Common diff --git a/src/Renci.SshNet/Common/SshDataStream.cs b/src/Renci.SshNet/Common/SshDataStream.cs index 291839c61..a9cfb7d5d 100644 --- a/src/Renci.SshNet/Common/SshDataStream.cs +++ b/src/Renci.SshNet/Common/SshDataStream.cs @@ -66,7 +66,7 @@ public bool IsEndOfData // to write directly into the underlying buffer without the need for any intermediate // arrays (rented or otherwise). -#if NET9_0_OR_GREATER +#if NET /// public override void Write(ReadOnlySpan buffer) { @@ -75,13 +75,13 @@ public override void Write(ReadOnlySpan buffer) #endif private delegate void WriteAction(Span span, TArg arg) -#if NET9_0_OR_GREATER +#if NET where TArg : allows ref struct #endif ; private void Write(TArg arg, int numBytesToWrite, WriteAction writeAction) -#if NET9_0_OR_GREATER +#if NET where TArg : allows ref struct #endif { diff --git a/src/Renci.SshNet/Connection/HttpConnector.cs b/src/Renci.SshNet/Connection/HttpConnector.cs index 07e713dcf..693c769de 100644 --- a/src/Renci.SshNet/Connection/HttpConnector.cs +++ b/src/Renci.SshNet/Connection/HttpConnector.cs @@ -38,14 +38,11 @@ internal sealed partial class HttpConnector : ProxyConnector private const string HttpHeaderPattern = @"(?[^\[\]()<>@,;:\""/?={} \t]+):(?.+)?"; #if NET - private static readonly Regex HttpResponseRegex = GetHttpResponseRegex(); - private static readonly Regex HttpHeaderRegex = GetHttpHeaderRegex(); - [GeneratedRegex(HttpResponsePattern)] - private static partial Regex GetHttpResponseRegex(); + private static partial Regex HttpResponseRegex { get; } [GeneratedRegex(HttpHeaderPattern)] - private static partial Regex GetHttpHeaderRegex(); + private static partial Regex HttpHeaderRegex { get; } #else private static readonly Regex HttpResponseRegex = new Regex(HttpResponsePattern, RegexOptions.Compiled); private static readonly Regex HttpHeaderRegex = new Regex(HttpHeaderPattern, RegexOptions.Compiled); diff --git a/src/Renci.SshNet/Connection/ProtocolVersionExchange.cs b/src/Renci.SshNet/Connection/ProtocolVersionExchange.cs index 9464977ec..8c52e4c57 100644 --- a/src/Renci.SshNet/Connection/ProtocolVersionExchange.cs +++ b/src/Renci.SshNet/Connection/ProtocolVersionExchange.cs @@ -29,10 +29,8 @@ internal sealed partial class ProtocolVersionExchange : IProtocolVersionExchange private const int MaximumBannerLineLength = 8192; #if NET - private static readonly Regex ServerVersionRegex = GetServerVersionRegex(); - [GeneratedRegex(ServerVersionPattern, RegexOptions.ExplicitCapture)] - private static partial Regex GetServerVersionRegex(); + private static partial Regex ServerVersionRegex { get; } #else private static readonly Regex ServerVersionRegex = new Regex(ServerVersionPattern, RegexOptions.Compiled | RegexOptions.ExplicitCapture); #endif diff --git a/src/Renci.SshNet/Netconf/NetConfSession.cs b/src/Renci.SshNet/Netconf/NetConfSession.cs index 941d4959c..ee27706dc 100644 --- a/src/Renci.SshNet/Netconf/NetConfSession.cs +++ b/src/Renci.SshNet/Netconf/NetConfSession.cs @@ -24,14 +24,11 @@ internal sealed partial class NetConfSession : SubsystemSession, INetConfSession private int _messageId; #if NET - private static readonly Regex LengthRegex = GetLengthRegex(); - private static readonly Regex ReplyRegex = GetReplyRegex(); - [GeneratedRegex(LengthPattern)] - private static partial Regex GetLengthRegex(); + private static partial Regex LengthRegex { get; } [GeneratedRegex(ReplyPattern)] - private static partial Regex GetReplyRegex(); + private static partial Regex ReplyRegex { get; } #else private static readonly Regex LengthRegex = new Regex(LengthPattern, RegexOptions.Compiled); private static readonly Regex ReplyRegex = new Regex(ReplyPattern, RegexOptions.Compiled); diff --git a/src/Renci.SshNet/OrderedDictionary.net9.cs b/src/Renci.SshNet/OrderedDictionary.net.cs similarity index 93% rename from src/Renci.SshNet/OrderedDictionary.net9.cs rename to src/Renci.SshNet/OrderedDictionary.net.cs index 6bc37d025..a0d41d1cd 100644 --- a/src/Renci.SshNet/OrderedDictionary.net9.cs +++ b/src/Renci.SshNet/OrderedDictionary.net.cs @@ -1,4 +1,4 @@ -#if NET9_0_OR_GREATER +#if NET #nullable enable #pragma warning disable SA1649 // File name should match first type name @@ -209,15 +209,7 @@ public bool TryAdd(TKey key, TValue value) public bool TryAdd(TKey key, TValue value, out int index) { -#if NET10_0_OR_GREATER return _impl.TryAdd(key, value, out index); -#else - var success = _impl.TryAdd(key, value); - - index = _impl.IndexOf(key); - - return success; -#endif } public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) @@ -227,18 +219,7 @@ public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value, out int index) { -#if NET10_0_OR_GREATER return _impl.TryGetValue(key, out value, out index); -#else - if (_impl.TryGetValue(key, out value)) - { - index = _impl.IndexOf(key); - return true; - } - - index = -1; - return false; -#endif } } } diff --git a/src/Renci.SshNet/OrderedDictionary.netstandard.cs b/src/Renci.SshNet/OrderedDictionary.netstandard.cs index 4ff15442a..9932a7ed3 100644 --- a/src/Renci.SshNet/OrderedDictionary.netstandard.cs +++ b/src/Renci.SshNet/OrderedDictionary.netstandard.cs @@ -1,4 +1,4 @@ -#if !NET9_0_OR_GREATER +#if !NET #nullable enable #pragma warning disable SA1649 // File name should match first type name diff --git a/src/Renci.SshNet/PrivateKeyFile.cs b/src/Renci.SshNet/PrivateKeyFile.cs index c7b9ccbc9..93e5f2950 100644 --- a/src/Renci.SshNet/PrivateKeyFile.cs +++ b/src/Renci.SshNet/PrivateKeyFile.cs @@ -115,18 +115,14 @@ public partial class PrivateKeyFile : IPrivateKeySource, IDisposable private const string CertificatePattern = @"(?[-\w]+@openssh\.com)\s(?[a-zA-Z0-9\/+=]*)(\s+(?.*))?"; #if NET - private static readonly Regex PrivateKeyRegex = GetPrivateKeyRegex(); - private static readonly Regex PuTTYPrivateKeyRegex = GetPrivateKeyPuTTYRegex(); - private static readonly Regex CertificateRegex = GetCertificateRegex(); - [GeneratedRegex(PrivateKeyPattern, RegexOptions.Multiline | RegexOptions.ExplicitCapture)] - private static partial Regex GetPrivateKeyRegex(); + private static partial Regex PrivateKeyRegex { get; } [GeneratedRegex(PuTTYPrivateKeyPattern, RegexOptions.Multiline | RegexOptions.ExplicitCapture)] - private static partial Regex GetPrivateKeyPuTTYRegex(); + private static partial Regex PuTTYPrivateKeyRegex { get; } [GeneratedRegex(CertificatePattern, RegexOptions.ExplicitCapture)] - private static partial Regex GetCertificateRegex(); + private static partial Regex CertificateRegex { get; } #else private static readonly Regex PrivateKeyRegex = new Regex(PrivateKeyPattern, RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.ExplicitCapture); private static readonly Regex PuTTYPrivateKeyRegex = new Regex(PuTTYPrivateKeyPattern, RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.ExplicitCapture); diff --git a/src/Renci.SshNet/Renci.SshNet.csproj b/src/Renci.SshNet/Renci.SshNet.csproj index 9b7af1590..302e1dfaa 100644 --- a/src/Renci.SshNet/Renci.SshNet.csproj +++ b/src/Renci.SshNet/Renci.SshNet.csproj @@ -4,7 +4,7 @@ Renci.SshNet SSH.NET SSH.NET - net462;netstandard2.0;net8.0;net9.0;net10.0 + net462;netstandard2.0;net10.0;net11.0 @@ -36,19 +36,22 @@ true - + true - runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/src/Renci.SshNet/ScpClient.cs b/src/Renci.SshNet/ScpClient.cs index 275e000ae..635a4d65f 100644 --- a/src/Renci.SshNet/ScpClient.cs +++ b/src/Renci.SshNet/ScpClient.cs @@ -68,18 +68,14 @@ public partial class ScpClient : BaseClient private const string TimestampPattern = @"T(?\d+) 0 (?\d+) 0"; #if NET - private static readonly Regex FileInfoRegex = GetFileInfoRegex(); - private static readonly Regex DirectoryInfoRegex = GetDirectoryInfoRegex(); - private static readonly Regex TimestampRegex = GetTimestampRegex(); - [GeneratedRegex(FileInfoPattern)] - private static partial Regex GetFileInfoRegex(); + private static partial Regex FileInfoRegex { get; } [GeneratedRegex(DirectoryInfoPattern)] - private static partial Regex GetDirectoryInfoRegex(); + private static partial Regex DirectoryInfoRegex { get; } [GeneratedRegex(TimestampPattern)] - private static partial Regex GetTimestampRegex(); + private static partial Regex TimestampRegex { get; } #else private static readonly Regex FileInfoRegex = new Regex(FileInfoPattern, RegexOptions.Compiled); private static readonly Regex DirectoryInfoRegex = new Regex(DirectoryInfoPattern, RegexOptions.Compiled); diff --git a/src/Renci.SshNet/SshMessageFactory.cs b/src/Renci.SshNet/SshMessageFactory.cs index 9985e1611..a83d6cbae 100644 --- a/src/Renci.SshNet/SshMessageFactory.cs +++ b/src/Renci.SshNet/SshMessageFactory.cs @@ -4,7 +4,7 @@ using System.Globalization; using System.Linq; -#if NET9_0_OR_GREATER +#if NET using System.Threading; #endif diff --git a/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj b/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj index 9d8a4d821..bf27e1681 100644 --- a/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj +++ b/test/Renci.SshNet.AotCompatibilityTestApp/Renci.SshNet.AotCompatibilityTestApp.csproj @@ -2,7 +2,7 @@ Exe - net10.0 + net11.0 true true false diff --git a/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj b/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj index e178dc835..a4f4abb66 100644 --- a/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj +++ b/test/Renci.SshNet.Benchmarks/Renci.SshNet.Benchmarks.csproj @@ -2,7 +2,7 @@ Exe - net10.0 + net11.0 enable enable diff --git a/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj b/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj index 2a98efd7a..465b821c0 100644 --- a/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj +++ b/test/Renci.SshNet.IntegrationBenchmarks/Renci.SshNet.IntegrationBenchmarks.csproj @@ -2,7 +2,7 @@ Exe - net10.0 + net11.0 enable enable diff --git a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj index 83d1a7be7..3e8bb5a5c 100644 --- a/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj +++ b/test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj @@ -1,7 +1,7 @@  - net48;net8.0;net9.0;net10.0 + net48;net10.0;net11.0 enable true true diff --git a/test/Renci.SshNet.Tests/Common/PacketDump.cs b/test/Renci.SshNet.Tests/Common/PacketDump.cs index 273e11b5f..f6284e0ca 100644 --- a/test/Renci.SshNet.Tests/Common/PacketDump.cs +++ b/test/Renci.SshNet.Tests/Common/PacketDump.cs @@ -70,7 +70,7 @@ private static string AsHex(byte[] data, int length) if (length < data.Length) { - _ = hex.Append(new string(' ', (data.Length - length) * 3)); + _ = hex.Append(' ', (data.Length - length) * 3); } return hex.ToString(); diff --git a/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj b/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj index 25ffbd8f9..f1f1a5581 100644 --- a/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj +++ b/test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj @@ -1,7 +1,7 @@  - net462;net8.0;net9.0;net10.0 + net462;net10.0;net11.0