diff --git a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs
index 5faa30dbd2..2aeca4f8f3 100644
--- a/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/ChatManager.cs
@@ -351,28 +351,11 @@ namespace Tgstation.Server.Host.Components.Chat
///
public void QueueWatchdogMessage(string message)
- {
- ArgumentNullException.ThrowIfNull(message);
+ => QueueMessageGeneric(mapping => mapping.IsWatchdogChannel, message, "WD");
- message = String.Format(CultureInfo.InvariantCulture, "WD: {0}", message);
-
- if (!initialProviderConnectionsTask!.IsCompleted)
- logger.LogTrace("Waiting for initial provider connections before sending watchdog message...");
-
- // Reimplementing QueueMessage
- QueueMessageInternal(
- new MessageContent
- {
- Text = message,
- },
- () =>
- {
- // so it doesn't change while we're using it
- lock (mappedChannels)
- return mappedChannels.Where(x => x.Value.IsWatchdogChannel).Select(x => x.Key).ToList();
- },
- true);
- }
+ ///
+ public void QueueRawDeploymentMessage(string message)
+ => QueueMessageGeneric(mapping => mapping.IsUpdatesChannel, message, null);
///
public Func> QueueDeploymentMessage(
@@ -1111,5 +1094,38 @@ namespace Tgstation.Server.Host.Components.Chat
AddMessageTask(SendMessageTask());
}
+
+ ///
+ /// Queues a message to a selected set of s.
+ ///
+ /// A for selecting the s to send to.
+ /// The message to send.
+ /// The optional prefix to the message to be sent.
+ void QueueMessageGeneric(Predicate channelSelector, string message, string? prefix)
+ {
+ ArgumentNullException.ThrowIfNull(message);
+
+ if (prefix != null)
+ {
+ message = $"{prefix}: {message}";
+ }
+
+ if (!initialProviderConnectionsTask!.IsCompleted)
+ logger.LogTrace("Waiting for initial provider connections before sending chat message...");
+
+ // Reimplementing QueueMessage
+ QueueMessageInternal(
+ new MessageContent
+ {
+ Text = message,
+ },
+ () =>
+ {
+ // so it doesn't change while we're using it
+ lock (mappedChannels)
+ return mappedChannels.Where(x => channelSelector(x.Value)).Select(x => x.Key).ToList();
+ },
+ true);
+ }
}
}
diff --git a/src/Tgstation.Server.Host/Components/Chat/IChatManager.cs b/src/Tgstation.Server.Host/Components/Chat/IChatManager.cs
index 669f21b305..4f112afb69 100644
--- a/src/Tgstation.Server.Host/Components/Chat/IChatManager.cs
+++ b/src/Tgstation.Server.Host/Components/Chat/IChatManager.cs
@@ -57,6 +57,12 @@ namespace Tgstation.Server.Host.Components.Chat
/// The message being sent.
void QueueWatchdogMessage(string message);
+ ///
+ /// Queue a chat to configured deployment channels.
+ ///
+ /// The message being sent.
+ void QueueRawDeploymentMessage(string message);
+
///
/// Send the message for a deployment to configured deployment channels.
///
diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs
index f0fd27f661..37454b7dbc 100644
--- a/src/Tgstation.Server.Host/Components/Instance.cs
+++ b/src/Tgstation.Server.Host/Components/Instance.cs
@@ -531,7 +531,10 @@ namespace Tgstation.Server.Host.Components
}
}
else if (preserveTestMerges)
+ {
+ Chat.QueueRawDeploymentMessage("Automatic update has failed due to a conflicting testmerge!");
throw new JobException(Api.Models.ErrorCode.InstanceUpdateTestMergeConflict);
+ }
if (!preserveTestMerges)
{