From 0b12263205be0ae5a89be04185b6228b3373367b Mon Sep 17 00:00:00 2001 From: williambza Date: Tue, 6 Aug 2024 12:57:40 +0200 Subject: [PATCH 01/12] Update build props --- src/Custom.Build.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Custom.Build.props b/src/Custom.Build.props index dc95a5770..297088dd9 100644 --- a/src/Custom.Build.props +++ b/src/Custom.Build.props @@ -1,8 +1,8 @@ - 9.0 - minor + 9.1 + patch From d07d03ef605335b4855f7b53c2c6452fe4262e91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 10 Aug 2024 13:03:47 +0000 Subject: [PATCH 02/12] Bump Particular/setup-rabbitmq-action from 1.6.0 to 1.7.0 (#1432) * Bump Particular/setup-rabbitmq-action from 1.6.0 to 1.7.0 Bumps [Particular/setup-rabbitmq-action](https://github.com/particular/setup-rabbitmq-action) from 1.6.0 to 1.7.0. - [Commits](https://github.com/particular/setup-rabbitmq-action/compare/v1.6.0...v1.7.0) --- updated-dependencies: - dependency-name: Particular/setup-rabbitmq-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Fix flaky tests --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Daniel Marbach --- .github/workflows/ci.yml | 2 +- .../When_changing_concurrency.cs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c920c71d0..d5d0620a5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,7 +51,7 @@ jobs: creds: ${{ secrets.AZURE_ACI_CREDENTIALS }} enable-AzPSSession: true - name: Setup RabbitMQ - uses: Particular/setup-rabbitmq-action@v1.6.0 + uses: Particular/setup-rabbitmq-action@v1.7.0 with: connection-string-name: RabbitMQTransport_ConnectionString tag: RabbitMQTransport diff --git a/src/NServiceBus.Transport.RabbitMQ.TransportTests/When_changing_concurrency.cs b/src/NServiceBus.Transport.RabbitMQ.TransportTests/When_changing_concurrency.cs index 665dedfd7..75ab33744 100644 --- a/src/NServiceBus.Transport.RabbitMQ.TransportTests/When_changing_concurrency.cs +++ b/src/NServiceBus.Transport.RabbitMQ.TransportTests/When_changing_concurrency.cs @@ -16,6 +16,7 @@ public class When_changing_concurrency : NServiceBusTransportTest public async Task Should_complete_current_message(TransportTransactionMode transactionMode) { var triggeredChangeConcurrency = CreateTaskCompletionSource(); + var sentMessageReceived = CreateTaskCompletionSource(); Task concurrencyChanged = null; int invocationCounter = 0; @@ -30,6 +31,7 @@ await StartPump(async (context, ct) => await task; }, ct); + sentMessageReceived.SetResult(); await triggeredChangeConcurrency.Task; }, (_, _) => @@ -40,8 +42,10 @@ await StartPump(async (context, ct) => transactionMode); await SendMessage(InputQueueName); + await sentMessageReceived.Task; await concurrencyChanged; await StopPump(); + Assert.AreEqual(1, invocationCounter, "message should successfully complete on first processing attempt"); } @@ -62,6 +66,7 @@ await StartPump((context, _) => if (context.Headers.TryGetValue("FromOnError", out var value) && value == bool.TrueString) { sentMessageReceived.SetResult(); + return Task.CompletedTask; } throw new Exception("triggering recoverability pipeline"); @@ -84,9 +89,9 @@ await SendMessage(InputQueueName, transactionMode); await SendMessage(InputQueueName); - await sentMessageReceived.Task; await StopPump(); + Assert.AreEqual(2, invocationCounter, "there should be exactly 2 messages (initial message and new message from onError pipeline)"); } } From 020c9e02d7dd2769e2dab5e30c999e7a26e07b5f Mon Sep 17 00:00:00 2001 From: Daniel Marbach Date: Thu, 22 Aug 2024 06:23:10 +0000 Subject: [PATCH 03/12] Improve reliability of channel provider in case of reconnects (#1435) * Abort loop earlier if possible * Reduce nesting * Swap the connection when ready * Explicit break to reduce nesting * Nullable enable * Move connection related stuff into the connection folder * Adjust the channel provider design slightly to achieve better testability without too much test induced damage * Test various races that can occur during shutdown and reconnection --------- Co-authored-by: Daniel Marbach --- .../Connection/ChannelProviderTests.cs | 168 ++++++++++++++++++ .../ConnectionConfigurationTests.cs | 0 .../ConnectionConfigurationWithAmqpTests.cs | 0 .../Connection/ChannelProvider.cs | 79 ++++++-- 4 files changed, 228 insertions(+), 19 deletions(-) create mode 100644 src/NServiceBus.Transport.RabbitMQ.Tests/Connection/ChannelProviderTests.cs rename src/NServiceBus.Transport.RabbitMQ.Tests/{ConnectionString => Connection}/ConnectionConfigurationTests.cs (100%) rename src/NServiceBus.Transport.RabbitMQ.Tests/{ConnectionString => Connection}/ConnectionConfigurationWithAmqpTests.cs (100%) diff --git a/src/NServiceBus.Transport.RabbitMQ.Tests/Connection/ChannelProviderTests.cs b/src/NServiceBus.Transport.RabbitMQ.Tests/Connection/ChannelProviderTests.cs new file mode 100644 index 000000000..cac893b3d --- /dev/null +++ b/src/NServiceBus.Transport.RabbitMQ.Tests/Connection/ChannelProviderTests.cs @@ -0,0 +1,168 @@ +namespace NServiceBus.Transport.RabbitMQ.Tests.ConnectionString +{ + using System; + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; + using global::RabbitMQ.Client; + using global::RabbitMQ.Client.Events; + using NUnit.Framework; + + [TestFixture] + public class ChannelProviderTests + { + [Test] + public async Task Should_recover_connection_and_dispose_old_one_when_connection_shutdown() + { + var channelProvider = new TestableChannelProvider(); + channelProvider.CreateConnection(); + + var publishConnection = channelProvider.PublishConnections.Dequeue(); + publishConnection.RaiseConnectionShutdown(new ShutdownEventArgs(ShutdownInitiator.Library, 0, "Test")); + + channelProvider.DelayTaskCompletionSource.SetResult(); + + await channelProvider.FireAndForgetAction(CancellationToken.None); + + var recoveredConnection = channelProvider.PublishConnections.Dequeue(); + + Assert.That(publishConnection.WasDisposed, Is.True); + Assert.That(recoveredConnection.WasDisposed, Is.False); + } + + [Test] + public void Should_dispose_connection_when_disposed() + { + var channelProvider = new TestableChannelProvider(); + channelProvider.CreateConnection(); + + var publishConnection = channelProvider.PublishConnections.Dequeue(); + channelProvider.Dispose(); + + Assert.That(publishConnection.WasDisposed, Is.True); + } + + [Test] + public async Task Should_not_attempt_to_recover_during_dispose_when_retry_delay_still_pending() + { + var channelProvider = new TestableChannelProvider(); + channelProvider.CreateConnection(); + + var publishConnection = channelProvider.PublishConnections.Dequeue(); + publishConnection.RaiseConnectionShutdown(new ShutdownEventArgs(ShutdownInitiator.Library, 0, "Test")); + + // Deliberately not completing the delay task with channelProvider.DelayTaskCompletionSource.SetResult(); before disposing + // to simulate a pending delay task + channelProvider.Dispose(); + + await channelProvider.FireAndForgetAction(CancellationToken.None); + + Assert.That(publishConnection.WasDisposed, Is.True); + Assert.That(channelProvider.PublishConnections.TryDequeue(out _), Is.False); + } + + [Test] + public async Task Should_dispose_newly_established_connection() + { + var channelProvider = new TestableChannelProvider(); + channelProvider.CreateConnection(); + + var publishConnection = channelProvider.PublishConnections.Dequeue(); + publishConnection.RaiseConnectionShutdown(new ShutdownEventArgs(ShutdownInitiator.Library, 0, "Test")); + + // This simulates the race of the reconnection loop being fired off with the delay task completed during + // the disposal of the channel provider. To achieve that it is necessary to kick off the reconnection loop + // and await its completion after the channel provider has been disposed. + var fireAndForgetTask = channelProvider.FireAndForgetAction(CancellationToken.None); + channelProvider.DelayTaskCompletionSource.SetResult(); + channelProvider.Dispose(); + + await fireAndForgetTask; + + var recoveredConnection = channelProvider.PublishConnections.Dequeue(); + + Assert.That(publishConnection.WasDisposed, Is.True); + Assert.That(recoveredConnection.WasDisposed, Is.True); + } + + class TestableChannelProvider() : ChannelProvider(null!, TimeSpan.Zero, null!) + { + public Queue PublishConnections { get; } = new(); + + public TaskCompletionSource DelayTaskCompletionSource { get; } = new(TaskCreationOptions.RunContinuationsAsynchronously); + + public Func FireAndForgetAction { get; private set; } + + protected override IConnection CreatePublishConnection() + { + var connection = new FakeConnection(); + PublishConnections.Enqueue(connection); + return connection; + } + + protected override void FireAndForget(Func action, CancellationToken cancellationToken = default) + => FireAndForgetAction = _ => action(cancellationToken); + + protected override async Task DelayReconnect(CancellationToken cancellationToken = default) + { + await using var _ = cancellationToken.Register(() => DelayTaskCompletionSource.TrySetCanceled(cancellationToken)); + await DelayTaskCompletionSource.Task; + } + } + + class FakeConnection : IConnection + { + public int LocalPort { get; } + public int RemotePort { get; } + + public void Dispose() => WasDisposed = true; + + public bool WasDisposed { get; private set; } + + public void UpdateSecret(string newSecret, string reason) => throw new NotImplementedException(); + + public void Abort() => throw new NotImplementedException(); + + public void Abort(ushort reasonCode, string reasonText) => throw new NotImplementedException(); + + public void Abort(TimeSpan timeout) => throw new NotImplementedException(); + + public void Abort(ushort reasonCode, string reasonText, TimeSpan timeout) => throw new NotImplementedException(); + + public void Close() => throw new NotImplementedException(); + + public void Close(ushort reasonCode, string reasonText) => throw new NotImplementedException(); + + public void Close(TimeSpan timeout) => throw new NotImplementedException(); + + public void Close(ushort reasonCode, string reasonText, TimeSpan timeout) => throw new NotImplementedException(); + + public IModel CreateModel() => throw new NotImplementedException(); + + public void HandleConnectionBlocked(string reason) => throw new NotImplementedException(); + + public void HandleConnectionUnblocked() => throw new NotImplementedException(); + + public ushort ChannelMax { get; } + public IDictionary ClientProperties { get; } + public ShutdownEventArgs CloseReason { get; } + public AmqpTcpEndpoint Endpoint { get; } + public uint FrameMax { get; } + public TimeSpan Heartbeat { get; } + public bool IsOpen { get; } + public AmqpTcpEndpoint[] KnownHosts { get; } + public IProtocol Protocol { get; } + public IDictionary ServerProperties { get; } + public IList ShutdownReport { get; } + public string ClientProvidedName { get; } = $"FakeConnection{Interlocked.Increment(ref connectionCounter)}"; + public event EventHandler CallbackException = (_, _) => { }; + public event EventHandler ConnectionBlocked = (_, _) => { }; + public event EventHandler ConnectionShutdown = (_, _) => { }; + public event EventHandler ConnectionUnblocked = (_, _) => { }; + + public void RaiseConnectionShutdown(ShutdownEventArgs args) => ConnectionShutdown?.Invoke(this, args); + + static int connectionCounter; + } + } +} \ No newline at end of file diff --git a/src/NServiceBus.Transport.RabbitMQ.Tests/ConnectionString/ConnectionConfigurationTests.cs b/src/NServiceBus.Transport.RabbitMQ.Tests/Connection/ConnectionConfigurationTests.cs similarity index 100% rename from src/NServiceBus.Transport.RabbitMQ.Tests/ConnectionString/ConnectionConfigurationTests.cs rename to src/NServiceBus.Transport.RabbitMQ.Tests/Connection/ConnectionConfigurationTests.cs diff --git a/src/NServiceBus.Transport.RabbitMQ.Tests/ConnectionString/ConnectionConfigurationWithAmqpTests.cs b/src/NServiceBus.Transport.RabbitMQ.Tests/Connection/ConnectionConfigurationWithAmqpTests.cs similarity index 100% rename from src/NServiceBus.Transport.RabbitMQ.Tests/ConnectionString/ConnectionConfigurationWithAmqpTests.cs rename to src/NServiceBus.Transport.RabbitMQ.Tests/Connection/ConnectionConfigurationWithAmqpTests.cs diff --git a/src/NServiceBus.Transport.RabbitMQ/Connection/ChannelProvider.cs b/src/NServiceBus.Transport.RabbitMQ/Connection/ChannelProvider.cs index 01419652c..afd572a0f 100644 --- a/src/NServiceBus.Transport.RabbitMQ/Connection/ChannelProvider.cs +++ b/src/NServiceBus.Transport.RabbitMQ/Connection/ChannelProvider.cs @@ -1,3 +1,5 @@ +#nullable enable + namespace NServiceBus.Transport.RabbitMQ { using System; @@ -7,7 +9,7 @@ namespace NServiceBus.Transport.RabbitMQ using global::RabbitMQ.Client; using Logging; - sealed class ChannelProvider : IDisposable + class ChannelProvider : IDisposable { public ChannelProvider(ConnectionFactory connectionFactory, TimeSpan retryDelay, IRoutingTopology routingTopology) { @@ -19,36 +21,56 @@ public ChannelProvider(ConnectionFactory connectionFactory, TimeSpan retryDelay, channels = new ConcurrentQueue(); } - public void CreateConnection() + public void CreateConnection() => connection = CreateConnectionWithShutdownListener(); + + protected virtual IConnection CreatePublishConnection() => connectionFactory.CreatePublishConnection(); + + IConnection CreateConnectionWithShutdownListener() { - connection = connectionFactory.CreatePublishConnection(); - connection.ConnectionShutdown += Connection_ConnectionShutdown; + var newConnection = CreatePublishConnection(); + newConnection.ConnectionShutdown += Connection_ConnectionShutdown; + return newConnection; } - void Connection_ConnectionShutdown(object sender, ShutdownEventArgs e) + void Connection_ConnectionShutdown(object? sender, ShutdownEventArgs e) { - if (e.Initiator != ShutdownInitiator.Application) + if (e.Initiator == ShutdownInitiator.Application || sender is null) { - var connection = (IConnection)sender; - - // Task.Run() so the call returns immediately instead of waiting for the first await or return down the call stack - _ = Task.Run(() => ReconnectSwallowingExceptions(connection.ClientProvidedName), CancellationToken.None); + return; } + + var connectionThatWasShutdown = (IConnection)sender; + + FireAndForget(cancellationToken => ReconnectSwallowingExceptions(connectionThatWasShutdown.ClientProvidedName, cancellationToken), stoppingTokenSource.Token); } -#pragma warning disable PS0018 // A task-returning method should have a CancellationToken parameter unless it has a parameter implementing ICancellableContext - async Task ReconnectSwallowingExceptions(string connectionName) -#pragma warning restore PS0018 // A task-returning method should have a CancellationToken parameter unless it has a parameter implementing ICancellableContext + async Task ReconnectSwallowingExceptions(string connectionName, CancellationToken cancellationToken) { - while (true) + while (!cancellationToken.IsCancellationRequested) { Logger.InfoFormat("'{0}': Attempting to reconnect in {1} seconds.", connectionName, retryDelay.TotalSeconds); - await Task.Delay(retryDelay).ConfigureAwait(false); - try { - CreateConnection(); + await DelayReconnect(cancellationToken).ConfigureAwait(false); + + var newConnection = CreateConnectionWithShutdownListener(); + + // A race condition is possible where CreatePublishConnection is invoked during Dispose + // where the returned connection isn't disposed so invoking Dispose to be sure + if (cancellationToken.IsCancellationRequested) + { + newConnection.Dispose(); + break; + } + + var oldConnection = Interlocked.Exchange(ref connection, newConnection); + oldConnection?.Dispose(); + break; + } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + Logger.InfoFormat("'{0}': Stopped trying to reconnecting to the broker due to shutdown", connectionName); break; } catch (Exception ex) @@ -60,6 +82,12 @@ async Task ReconnectSwallowingExceptions(string connectionName) Logger.InfoFormat("'{0}': Connection to the broker reestablished successfully.", connectionName); } + protected virtual void FireAndForget(Func action, CancellationToken cancellationToken = default) => + // Task.Run() so the call returns immediately instead of waiting for the first await or return down the call stack + _ = Task.Run(() => action(cancellationToken), CancellationToken.None); + + protected virtual Task DelayReconnect(CancellationToken cancellationToken = default) => Task.Delay(retryDelay, cancellationToken); + public ConfirmsAwareChannel GetPublishChannel() { if (!channels.TryDequeue(out var channel) || channel.IsClosed) @@ -86,19 +114,32 @@ public void ReturnPublishChannel(ConfirmsAwareChannel channel) public void Dispose() { - connection?.Dispose(); + if (disposed) + { + return; + } + + stoppingTokenSource.Cancel(); + stoppingTokenSource.Dispose(); + + var oldConnection = Interlocked.Exchange(ref connection, null); + oldConnection?.Dispose(); foreach (var channel in channels) { channel.Dispose(); } + + disposed = true; } readonly ConnectionFactory connectionFactory; readonly TimeSpan retryDelay; readonly IRoutingTopology routingTopology; readonly ConcurrentQueue channels; - IConnection connection; + readonly CancellationTokenSource stoppingTokenSource = new(); + volatile IConnection? connection; + bool disposed; static readonly ILog Logger = LogManager.GetLogger(typeof(ChannelProvider)); } From defb04e12325aff2d4ab8aa7c87f3daff351fe22 Mon Sep 17 00:00:00 2001 From: "internalautomation[bot]" <85681268+internalautomation[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 19:49:41 +0000 Subject: [PATCH 04/12] GitHubSync update - release-9.1 --- .gitattributes | 1 + src/.editorconfig | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/.gitattributes b/.gitattributes index dfe077042..31bb7740b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ # Auto detect text files and perform LF normalization * text=auto +*.sh text eol=lf diff --git a/src/.editorconfig b/src/.editorconfig index f24a83fba..6a0594940 100644 --- a/src/.editorconfig +++ b/src/.editorconfig @@ -4,6 +4,7 @@ [*.{csproj,props,targets,xml}] indent_style = space indent_size = 2 +xml_space_inside_empty_tag = true [*.cs] @@ -317,6 +318,10 @@ dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = error dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case +dotnet_naming_rule.fields.style = camel_case +dotnet_naming_rule.fields.symbols = fields +dotnet_naming_rule.fields.severity = none + # Symbol specifications dotnet_naming_symbols.interface.applicable_kinds = interface dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected @@ -330,6 +335,10 @@ dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, meth dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected dotnet_naming_symbols.non_field_members.required_modifiers = +dotnet_naming_symbols.fields.applicable_kinds = field +dotnet_naming_symbols.fields.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.fields.required_modifiers = + # Naming styles dotnet_naming_style.pascal_case.required_prefix = dotnet_naming_style.pascal_case.required_suffix = @@ -340,3 +349,8 @@ dotnet_naming_style.begins_with_i.required_prefix = I dotnet_naming_style.begins_with_i.required_suffix = dotnet_naming_style.begins_with_i.word_separator = dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.camel_case.required_prefix = +dotnet_naming_style.camel_case.required_suffix = +dotnet_naming_style.camel_case.word_separator = +dotnet_naming_style.camel_case.capitalization = camel_case From 7ca9c0c86d0932909da50dfc28b56647bee520ba Mon Sep 17 00:00:00 2001 From: "internalautomation[bot]" <85681268+internalautomation[bot]@users.noreply.github.com> Date: Wed, 30 Oct 2024 00:11:16 +0000 Subject: [PATCH 05/12] GitHubSync update - release-9.1 --- src/Directory.Build.props | 4 +- src/Directory.Build.targets | 4 +- src/msbuild/AutomaticVersionRanges.targets | 42 ++++++++++++++++ src/msbuild/ConvertToVersionRange.cs | 57 ++++++++++++++++++++++ 4 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 src/msbuild/AutomaticVersionRanges.targets create mode 100644 src/msbuild/ConvertToVersionRange.cs diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 7e3a698c3..4b7369cc5 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -7,10 +7,10 @@ true 5.0 true - low + all - 2.1.2 + 2.1.3 0024000004800000940000000602000000240000525341310004000001000100dde965e6172e019ac82c2639ffe494dd2e7dd16347c34762a05732b492e110f2e4e2e1b5ef2d85c848ccfb671ee20a47c8d1376276708dc30a90ff1121b647ba3b7259a6bc383b2034938ef0e275b58b920375ac605076178123693c6c4f1331661a62eba28c249386855637780e3ff5f23a6d854700eaa6803ef48907513b92 00240000048000009400000006020000002400005253413100040000010001007f16e21368ff041183fab592d9e8ed37e7be355e93323147a1d29983d6e591b04282e4da0c9e18bd901e112c0033925eb7d7872c2f1706655891c5c9d57297994f707d16ee9a8f40d978f064ee1ffc73c0db3f4712691b23bf596f75130f4ec978cf78757ec034625a5f27e6bb50c618931ea49f6f628fd74271c32959efb1c5 diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index d47a6af61..98966408a 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -1,7 +1,5 @@ - - all - + diff --git a/src/msbuild/AutomaticVersionRanges.targets b/src/msbuild/AutomaticVersionRanges.targets new file mode 100644 index 000000000..973721032 --- /dev/null +++ b/src/msbuild/AutomaticVersionRanges.targets @@ -0,0 +1,42 @@ + + + + false + false + false + true + + + + + + + + + + + @(_ProjectReferencesWithVersions->Count()) + + + + + + <_ProjectReferencesWithVersions Remove="@(_ProjectReferencesWithVersions)" /> + <_ProjectReferencesWithVersions Include="@(_ProjectReferencesWithVersionRanges)" /> + + + + + + @(PackageReference->Count()) + + + + + + + + + + + diff --git a/src/msbuild/ConvertToVersionRange.cs b/src/msbuild/ConvertToVersionRange.cs new file mode 100644 index 000000000..d91847845 --- /dev/null +++ b/src/msbuild/ConvertToVersionRange.cs @@ -0,0 +1,57 @@ +using System; +using System.Text.RegularExpressions; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +public class ConvertToVersionRange : Task +{ + [Required] + public ITaskItem[] References { get; set; } = []; + + [Required] + public string VersionProperty { get; set; } = string.Empty; + + [Output] + public ITaskItem[] ReferencesWithVersionRanges { get; private set; } = []; + + public override bool Execute() + { + var success = true; + + foreach (var reference in References) + { + var automaticVersionRange = reference.GetMetadata("AutomaticVersionRange"); + + if (automaticVersionRange.Equals("false", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + var privateAssets = reference.GetMetadata("PrivateAssets"); + + if (privateAssets.Equals("All", StringComparison.OrdinalIgnoreCase)) + { + continue; + } + + var version = reference.GetMetadata(VersionProperty); + var match = Regex.Match(version, @"^\d+"); + + if (match.Value.Equals(string.Empty, StringComparison.Ordinal)) + { + Log.LogError("Reference '{0}' with version '{1}' is not valid for automatic version range conversion. Fix the version or exclude the reference from conversion by setting 'AutomaticVersionRange=\"false\"' on the reference.", reference.ItemSpec, version); + success = false; + continue; + } + + var nextMajor = Convert.ToInt32(match.Value) + 1; + + var versionRange = $"[{version}, {nextMajor}.0.0)"; + reference.SetMetadata(VersionProperty, versionRange); + } + + ReferencesWithVersionRanges = References; + + return success; + } +} From 48aaecc9d4d0e4a369b4ef2706db049652d2a16c Mon Sep 17 00:00:00 2001 From: Tamara Rivera Date: Thu, 31 Oct 2024 17:35:39 -0700 Subject: [PATCH 06/12] Fixes --- .../NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj | 2 -- .../NServiceBus.Transport.RabbitMQ.Tests.csproj | 5 +---- .../NServiceBus.Transport.RabbitMQ.TransportTests.csproj | 2 -- .../NServiceBus.Transport.RabbitMQ.csproj | 6 +++--- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj b/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj index fb9018de4..c2f8f5436 100644 --- a/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj @@ -18,9 +18,7 @@ - - diff --git a/src/NServiceBus.Transport.RabbitMQ.Tests/NServiceBus.Transport.RabbitMQ.Tests.csproj b/src/NServiceBus.Transport.RabbitMQ.Tests/NServiceBus.Transport.RabbitMQ.Tests.csproj index 4c27357a6..7c512f4ac 100644 --- a/src/NServiceBus.Transport.RabbitMQ.Tests/NServiceBus.Transport.RabbitMQ.Tests.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.Tests/NServiceBus.Transport.RabbitMQ.Tests.csproj @@ -18,11 +18,8 @@ - - - + - diff --git a/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj b/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj index b34c8a1b7..d10ef445b 100644 --- a/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj @@ -16,9 +16,7 @@ - - diff --git a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj index 2d033b7c0..9b153aa37 100644 --- a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj +++ b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj @@ -8,9 +8,9 @@ - - - + + + From 556bf4c37d59b2b5775a0a870e69e18bbd054eb8 Mon Sep 17 00:00:00 2001 From: Tamara Rivera Date: Thu, 31 Oct 2024 18:35:13 -0700 Subject: [PATCH 07/12] Bump NServiceBus to 9.1.2 --- .../NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj | 2 +- .../NServiceBus.Transport.RabbitMQ.TransportTests.csproj | 2 +- .../NServiceBus.Transport.RabbitMQ.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj b/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj index c2f8f5436..178b283bd 100644 --- a/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj @@ -18,7 +18,7 @@ - + diff --git a/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj b/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj index d10ef445b..84b25582f 100644 --- a/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj index 9b153aa37..62ffad0b4 100644 --- a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj +++ b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj @@ -9,7 +9,7 @@ - + From 75b083154035dae0481dd6305261d3738138286b Mon Sep 17 00:00:00 2001 From: Tamara Rivera Date: Mon, 4 Nov 2024 17:55:12 -0800 Subject: [PATCH 08/12] Bump version --- .../NServiceBus.Transport.RabbitMQ.CommandLine.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NServiceBus.Transport.RabbitMQ.CommandLine/NServiceBus.Transport.RabbitMQ.CommandLine.csproj b/src/NServiceBus.Transport.RabbitMQ.CommandLine/NServiceBus.Transport.RabbitMQ.CommandLine.csproj index 098f4da19..2cd51ab3e 100644 --- a/src/NServiceBus.Transport.RabbitMQ.CommandLine/NServiceBus.Transport.RabbitMQ.CommandLine.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.CommandLine/NServiceBus.Transport.RabbitMQ.CommandLine.csproj @@ -15,7 +15,7 @@ - + From fb501067aa668eeb576ed1b9a313220882c6ee4d Mon Sep 17 00:00:00 2001 From: Brandon Ording Date: Tue, 5 Nov 2024 17:26:47 -0500 Subject: [PATCH 09/12] Update testing packages --- .../NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj | 2 +- .../NServiceBus.Transport.RabbitMQ.CommandLine.Tests.csproj | 2 +- .../NServiceBus.Transport.RabbitMQ.Tests.csproj | 2 +- .../NServiceBus.Transport.RabbitMQ.TransportTests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj b/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj index 178b283bd..2b00b6bc4 100644 --- a/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.AcceptanceTests/NServiceBus.Transport.RabbitMQ.AcceptanceTests.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/NServiceBus.Transport.RabbitMQ.CommandLine.Tests/NServiceBus.Transport.RabbitMQ.CommandLine.Tests.csproj b/src/NServiceBus.Transport.RabbitMQ.CommandLine.Tests/NServiceBus.Transport.RabbitMQ.CommandLine.Tests.csproj index ac31dc3e9..eb835463e 100644 --- a/src/NServiceBus.Transport.RabbitMQ.CommandLine.Tests/NServiceBus.Transport.RabbitMQ.CommandLine.Tests.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.CommandLine.Tests/NServiceBus.Transport.RabbitMQ.CommandLine.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/NServiceBus.Transport.RabbitMQ.Tests/NServiceBus.Transport.RabbitMQ.Tests.csproj b/src/NServiceBus.Transport.RabbitMQ.Tests/NServiceBus.Transport.RabbitMQ.Tests.csproj index 7c512f4ac..69741b108 100644 --- a/src/NServiceBus.Transport.RabbitMQ.Tests/NServiceBus.Transport.RabbitMQ.Tests.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.Tests/NServiceBus.Transport.RabbitMQ.Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj b/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj index 84b25582f..c5aec8579 100644 --- a/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.TransportTests/NServiceBus.Transport.RabbitMQ.TransportTests.csproj @@ -10,7 +10,7 @@ - + From 8639d6e70ee28193eb47a641b8fa62d8ebdcd470 Mon Sep 17 00:00:00 2001 From: Brandon Ording Date: Tue, 5 Nov 2024 17:27:47 -0500 Subject: [PATCH 10/12] Update BitFaster.Caching --- .../NServiceBus.Transport.RabbitMQ.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj index 62ffad0b4..1202213f7 100644 --- a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj +++ b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj @@ -8,7 +8,7 @@ - + From 3c3b5acb24e09aad487aad8736995d9746d8aa8c Mon Sep 17 00:00:00 2001 From: Brandon Ording Date: Tue, 5 Nov 2024 17:28:55 -0500 Subject: [PATCH 11/12] Update Fody --- .../NServiceBus.Transport.RabbitMQ.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj index 1202213f7..011bcbe00 100644 --- a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj +++ b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj @@ -14,7 +14,7 @@ - + From 6f560e069df03b5d5fe8916a177580499f786556 Mon Sep 17 00:00:00 2001 From: Brandon Ording Date: Tue, 5 Nov 2024 17:29:44 -0500 Subject: [PATCH 12/12] Update Particular.Packaging --- .../NServiceBus.Transport.RabbitMQ.CommandLine.csproj | 2 +- .../NServiceBus.Transport.RabbitMQ.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NServiceBus.Transport.RabbitMQ.CommandLine/NServiceBus.Transport.RabbitMQ.CommandLine.csproj b/src/NServiceBus.Transport.RabbitMQ.CommandLine/NServiceBus.Transport.RabbitMQ.CommandLine.csproj index 2cd51ab3e..00d106457 100644 --- a/src/NServiceBus.Transport.RabbitMQ.CommandLine/NServiceBus.Transport.RabbitMQ.CommandLine.csproj +++ b/src/NServiceBus.Transport.RabbitMQ.CommandLine/NServiceBus.Transport.RabbitMQ.CommandLine.csproj @@ -21,7 +21,7 @@ - + diff --git a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj index 011bcbe00..5580b5439 100644 --- a/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj +++ b/src/NServiceBus.Transport.RabbitMQ/NServiceBus.Transport.RabbitMQ.csproj @@ -16,7 +16,7 @@ - +