diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml
index 54007f37f3..375fb7dc40 100644
--- a/.github/workflows/ci-pipeline.yml
+++ b/.github/workflows/ci-pipeline.yml
@@ -555,6 +555,8 @@ jobs:
database-type: [ 'SqlServer', 'Sqlite', 'PostgresSql', 'MariaDB', 'MySql' ]
watchdog-type: [ 'Basic', 'Advanced' ]
configuration: [ 'Debug', 'Release' ]
+ env:
+ TGS_TELEMETRY_KEY_FILE: C:/tgs_telemetry_key.txt
runs-on: windows-latest
steps:
- name: Wait for LocalDB Connection # Do this first because we don't want to find out it's failing later
@@ -642,9 +644,18 @@ jobs:
- name: Restore
run: dotnet restore
+ - name: Setup Telemetry Key File
+ shell: bash
+ run: echo "${{ secrets.TGS_TELEMETRY_KEY }}" > ${{ env.TGS_TELEMETRY_KEY_FILE }}
+
- name: Build
run: dotnet build -c ${{ matrix.configuration }} tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj
+ - name: Delete Telemetry Key File
+ shell: bash
+ if: always()
+ run: rm ${{ env.TGS_TELEMETRY_KEY_FILE }}
+
- name: Cache BYOND .zips
uses: actions/cache@v4
id: cache-byond
@@ -786,6 +797,8 @@ jobs:
database-type: [ 'Sqlite', 'PostgresSql', 'MariaDB', 'MySql' ]
watchdog-type: [ 'Basic', 'Advanced' ]
configuration: [ 'Debug', 'Release' ]
+ env:
+ TGS_TELEMETRY_KEY_FILE: /tmp/tgs_telemetry_key.txt
runs-on: ubuntu-latest
steps:
- name: Disable ptrace_scope
@@ -848,9 +861,16 @@ jobs:
- name: Restore
run: dotnet restore
+ - name: Setup Telemetry Key File
+ run: echo "${{ secrets.TGS_TELEMETRY_KEY }}" > ${{ env.TGS_TELEMETRY_KEY_FILE }}
+
- name: Build
run: dotnet build -c ${{ matrix.configuration }}NoWindows tests/Tgstation.Server.Tests/Tgstation.Server.Tests.csproj
+ - name: Delete Telemetry Key File
+ if: always()
+ run: rm ${{ env.TGS_TELEMETRY_KEY_FILE }}
+
- name: Cache BYOND .zips
uses: actions/cache@v4
id: cache-byond
@@ -1194,6 +1214,8 @@ jobs:
needs: start-ci-run-gate
runs-on: ubuntu-latest
if: (!(cancelled() || failure()) && needs.start-ci-run-gate.result == 'success')
+ env:
+ TGS_TELEMETRY_KEY_FILE: /tmp/tgs_telemetry_key.txt
steps:
- name: Install Native Dependencies
run: |
@@ -1244,6 +1266,9 @@ jobs:
- name: Grab Most Recent Changelog
run: curl -L https://raw.githubusercontent.com/tgstation/tgstation-server/gh-pages/changelog.yml -o changelog.yml
+ - name: Setup Telemetry Key File
+ run: echo "${{ secrets.TGS_TELEMETRY_KEY }}" > ${{ env.TGS_TELEMETRY_KEY_FILE }}
+
- name: Execute Build Script (Unsigned)
if: (!(github.event_name == 'push' && contains(github.event.head_commit.message, '[TGSDeploy]') && (github.event.ref == 'refs/heads/master' || github.event.ref == 'refs/heads/dev')))
run: sudo -E build/package/deb/build_package.sh
@@ -1258,6 +1283,10 @@ jobs:
gpg --verify tgstation-server_${{ env.TGS_VERSION }}-1_amd64.changes
gpg --verify tgstation-server_${{ env.TGS_VERSION }}-1_amd64.buildinfo
+ - name: Delete Telemetry Key File
+ if: always()
+ run: rm ${{ env.TGS_TELEMETRY_KEY_FILE }}
+
- name: Test Install
run: |
sudo mkdir /etc/tgstation-server
@@ -1298,6 +1327,8 @@ jobs:
needs: start-ci-run-gate
runs-on: windows-latest
if: (!(cancelled() || failure()) && needs.start-ci-run-gate.result == 'success')
+ env:
+ TGS_TELEMETRY_KEY_FILE: C:/tgs_telemetry_key.txt
steps:
- name: Install winget
uses: Cyberboss/install-winget@v1
@@ -1331,9 +1362,18 @@ jobs:
- name: Restore
run: dotnet restore
+ - name: Setup Telemetry Key File
+ shell: bash
+ run: echo "${{ secrets.TGS_TELEMETRY_KEY }}" > ${{ env.TGS_TELEMETRY_KEY_FILE }}
+
- name: Build Host
run: dotnet build -c Release src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
+ - name: Delete Telemetry Key File
+ shell: bash
+ if: always()
+ run: rm ${{ env.TGS_TELEMETRY_KEY_FILE }}
+
- name: Build Service
run: dotnet build -c Release src/Tgstation.Server.Host.Service/Tgstation.Server.Host.Service.csproj
diff --git a/README.md b/README.md
index 794543dc85..c130e2d76b 100644
--- a/README.md
+++ b/README.md
@@ -313,6 +313,12 @@ The following providers use the `ServerUrl` setting:
- Keycloak
- InvisionCommunity
+- `Telemetry:DisableVersionReporting`: Prevents you installation and the version you're using from being reported on the source repository's deployments list
+
+- `Telemetry:ServerFriendlyName`: Prevents anonymous TGS version usage statistics from being sent to be displayed on the repository.
+
+- `Telemetry:VersionReportingRepositoryId`: The repository telemetry is sent to. For security reasons, this is not the main TGS repo. See the [tgstation-server-deployments](https://github.com/tgstation/tgstation-server-deployments) repository for more information.
+
### Database Configuration
If using a MariaDB/MySQL server, our client library [recommends you set 'utf8mb4' as your default charset](https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql#1-recommended-server-charset) disregard at your own risk.
diff --git a/src/Tgstation.Server.Host/Configuration/TelemetryConfiguration.cs b/src/Tgstation.Server.Host/Configuration/TelemetryConfiguration.cs
new file mode 100644
index 0000000000..7ec0361759
--- /dev/null
+++ b/src/Tgstation.Server.Host/Configuration/TelemetryConfiguration.cs
@@ -0,0 +1,33 @@
+namespace Tgstation.Server.Host.Configuration
+{
+ ///
+ /// Configuration options for telemetry.
+ ///
+ public sealed class TelemetryConfiguration
+ {
+ ///
+ /// The key for the the resides in.
+ ///
+ public const string Section = "Telemetry";
+
+ ///
+ /// The default value of .
+ ///
+ private const long DefaultVersionReportingRepositoryId = 841149827; // https://github.com/tgstation/tgstation-server-deployments
+
+ ///
+ /// If version reporting telemetry is disabled.
+ ///
+ public bool DisableVersionReporting { get; set; }
+
+ ///
+ /// The friendly name used on GitHub deployments for version reporting. If only the server will be shown.
+ ///
+ public string? ServerFriendlyName { get; set; }
+
+ ///
+ /// The GitHub repository ID used for version reporting.
+ ///
+ public long? VersionReportingRepositoryId { get; set; } = DefaultVersionReportingRepositoryId;
+ }
+}
diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs
index 36970000c5..7e981066c0 100644
--- a/src/Tgstation.Server.Host/Core/Application.cs
+++ b/src/Tgstation.Server.Host/Core/Application.cs
@@ -143,6 +143,7 @@ namespace Tgstation.Server.Host.Core
services.UseStandardConfig(Configuration);
services.UseStandardConfig(Configuration);
services.UseStandardConfig(Configuration);
+ services.UseStandardConfig(Configuration);
// enable options which give us config reloading
services.AddOptions();
@@ -423,6 +424,7 @@ namespace Tgstation.Server.Host.Core
services.AddSingleton();
services.AddSingleton();
services.AddHostedService();
+ services.AddHostedService();
services.AddFileDownloader();
services.AddGitHub();
diff --git a/src/Tgstation.Server.Host/Core/VersionReportingService.cs b/src/Tgstation.Server.Host/Core/VersionReportingService.cs
new file mode 100644
index 0000000000..7e03e12951
--- /dev/null
+++ b/src/Tgstation.Server.Host/Core/VersionReportingService.cs
@@ -0,0 +1,234 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+using Octokit;
+
+using Tgstation.Server.Common.Extensions;
+using Tgstation.Server.Host.Configuration;
+using Tgstation.Server.Host.Extensions;
+using Tgstation.Server.Host.IO;
+using Tgstation.Server.Host.Properties;
+using Tgstation.Server.Host.System;
+using Tgstation.Server.Host.Utils;
+using Tgstation.Server.Host.Utils.GitHub;
+
+namespace Tgstation.Server.Host.Core
+{
+ ///
+ /// Handles TGS version reporting, if enabled.
+ ///
+ sealed class VersionReportingService : BackgroundService
+ {
+ ///
+ /// The for the .
+ ///
+ readonly IGitHubClientFactory gitHubClientFactory;
+
+ ///
+ /// The for the .
+ ///
+ readonly IIOManager ioManager;
+
+ ///
+ /// The for the .
+ ///
+ readonly IAsyncDelayer asyncDelayer;
+
+ ///
+ /// The for the .
+ ///
+ readonly IAssemblyInformationProvider assemblyInformationProvider;
+
+ ///
+ /// The for the .
+ ///
+ readonly ILogger logger;
+
+ ///
+ /// The for the .
+ ///
+ readonly TelemetryConfiguration telemetryConfiguration;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The value of .
+ /// The value of .
+ /// The value of .
+ /// The value of .
+ /// The containing the value of .
+ /// The value of .
+ public VersionReportingService(
+ IGitHubClientFactory gitHubClientFactory,
+ IIOManager ioManager,
+ IAsyncDelayer asyncDelayer,
+ IAssemblyInformationProvider assemblyInformationProvider,
+ IOptions telemetryConfigurationOptions,
+ ILogger logger)
+ {
+ this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory));
+ this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
+ this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
+ this.assemblyInformationProvider = assemblyInformationProvider ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
+ telemetryConfiguration = telemetryConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(telemetryConfigurationOptions));
+ this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ }
+
+ ///
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ if (telemetryConfiguration.DisableVersionReporting)
+ {
+ logger.LogDebug("Version telemetry disabled");
+ return;
+ }
+
+ if (!telemetryConfiguration.VersionReportingRepositoryId.HasValue)
+ {
+ logger.LogError("Version reporting repository is misconfigured. Telemetry cannot be sent!");
+ return;
+ }
+
+ var attribute = TelemetryAppSerializedKeyAttribute.Instance;
+ if (attribute == null)
+ {
+ logger.LogDebug("TGS build configuration does not allow for version telemetry");
+ return;
+ }
+
+ logger.LogDebug("Starting...");
+
+ try
+ {
+ var telemetryIdFile = ioManager.ResolvePath(
+ ioManager.ConcatPath(
+ ioManager.GetPathInLocalDirectory(assemblyInformationProvider),
+ "telemetry.id"));
+
+ Guid telemetryId;
+ if (!await ioManager.FileExists(telemetryIdFile, stoppingToken))
+ {
+ telemetryId = Guid.NewGuid();
+ await ioManager.WriteAllBytes(telemetryIdFile, Encoding.UTF8.GetBytes(telemetryId.ToString()), stoppingToken);
+ logger.LogInformation("Generated telemetry ID {telemetryId} and wrote to {file}", telemetryId, telemetryIdFile);
+ }
+ else
+ {
+ var contents = await ioManager.ReadAllBytes(telemetryIdFile, stoppingToken);
+
+ string guidStr;
+ try
+ {
+ guidStr = Encoding.UTF8.GetString(contents);
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "Cannot decode telemetry ID from installation file ({path}). Telemetry will not be sent!", telemetryIdFile);
+ return;
+ }
+
+ if (!Guid.TryParse(guidStr, out telemetryId))
+ {
+ logger.LogError("Cannot parse telemetry ID from installation file ({path}). Telemetry will not be sent!", telemetryIdFile);
+ return;
+ }
+ }
+
+ var nextDelayHours = await TryReportVersion(
+ telemetryId,
+ attribute.SerializedKey,
+ telemetryConfiguration.VersionReportingRepositoryId.Value,
+ stoppingToken)
+ ? 24
+ : 1;
+
+ logger.LogDebug("Next version report in {hours} hours", nextDelayHours);
+ await asyncDelayer.Delay(TimeSpan.FromHours(nextDelayHours), stoppingToken);
+ }
+ catch (OperationCanceledException ex)
+ {
+ logger.LogTrace(ex, "Exiting...");
+ }
+ catch (Exception ex)
+ {
+ logger.LogError(ex, "Crashed!");
+ }
+ }
+
+ ///
+ /// Make an attempt to report the current to the configured GitHub repository.
+ ///
+ /// The telemetry for the installation.
+ /// The serialized authentication for the .
+ /// The ID of the repository to send telemetry to.
+ /// The for the operation.
+ /// A resulting in if telemetry was reported successfully, otherwise.
+ async ValueTask TryReportVersion(Guid telemetryId, string serializedPem, long repositoryId, CancellationToken cancellationToken)
+ {
+ logger.LogDebug("Sending version telemetry...");
+
+ var serverFriendlyName = telemetryConfiguration.ServerFriendlyName;
+ if (String.IsNullOrWhiteSpace(serverFriendlyName))
+ serverFriendlyName = null;
+
+ logger.LogTrace(
+ "Repository ID: {repoId}, Server friendly name: {friendlyName}",
+ repositoryId,
+ serverFriendlyName == null
+ ? "(null)"
+ : $"\"{serverFriendlyName}\"");
+ try
+ {
+ var gitHubClient = await gitHubClientFactory.CreateInstallationClient(
+ serializedPem,
+ repositoryId,
+ cancellationToken);
+
+ if (gitHubClient == null)
+ {
+ logger.LogWarning("Could not create GitHub client to connect to repository ID {repoId}!", repositoryId);
+ return false;
+ }
+
+ // remove this lookup once https://github.com/octokit/octokit.net/pull/2960 is merged and released
+ var repository = await gitHubClient.Repository.Get(repositoryId);
+
+ logger.LogTrace("Repository ID {id} resolved to {owner}/{name}", repositoryId, repository.Owner.Name, repository.Name);
+
+ var inputs = new Dictionary
+ {
+ { "telemetry_id", telemetryId.ToString() },
+ { "tgs_semver", assemblyInformationProvider.Version.Semver().ToString() },
+ };
+
+ if (serverFriendlyName != null)
+ inputs.Add("server_friendly_name", serverFriendlyName);
+
+ await gitHubClient.Actions.Workflows.CreateDispatch(
+ repository.Owner.Login,
+ repository.Name,
+ ".github/workflows/tgs_deployments_telemetry.yml",
+ new CreateWorkflowDispatch("main")
+ {
+ Inputs = inputs,
+ });
+
+ logger.LogTrace("Telemetry sent successfully");
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ logger.LogWarning(ex, "Failed to report version!");
+ return false;
+ }
+ }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Properties/TelemetryAppSerializedKeyAttribute.cs b/src/Tgstation.Server.Host/Properties/TelemetryAppSerializedKeyAttribute.cs
new file mode 100644
index 0000000000..6d2ff1be5b
--- /dev/null
+++ b/src/Tgstation.Server.Host/Properties/TelemetryAppSerializedKeyAttribute.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Reflection;
+
+namespace Tgstation.Server.Host.Properties
+{
+ ///
+ /// Attribute for bundling the GitHub App serialized private key used for version telemetry.
+ ///
+ [AttributeUsage(AttributeTargets.Assembly)]
+ sealed class TelemetryAppSerializedKeyAttribute : Attribute
+ {
+ ///
+ /// Return the 's instance of the .
+ ///
+ public static TelemetryAppSerializedKeyAttribute? Instance => Assembly
+ .GetExecutingAssembly()
+ .GetCustomAttribute();
+
+ ///
+ /// The serialized GitHub App Client ID and private key.
+ ///
+ public string SerializedKey { get; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The value of .
+ public TelemetryAppSerializedKeyAttribute(string serializedKey)
+ {
+ SerializedKey = serializedKey ?? throw new ArgumentNullException(nameof(serializedKey));
+ }
+ }
+}
diff --git a/src/Tgstation.Server.Host/Setup/SetupWizard.cs b/src/Tgstation.Server.Host/Setup/SetupWizard.cs
index 04cc54a3bf..387f2afe7a 100644
--- a/src/Tgstation.Server.Host/Setup/SetupWizard.cs
+++ b/src/Tgstation.Server.Host/Setup/SetupWizard.cs
@@ -950,6 +950,31 @@ namespace Tgstation.Server.Host.Setup
};
}
+ ///
+ /// Prompts the user to create a .
+ ///
+ /// The for the operation.
+ /// A resulting in the new .
+ async ValueTask ConfigureTelemetry(CancellationToken cancellationToken)
+ {
+ bool enableReporting = await PromptYesNo("Enable version telemetry? This anonymously reports the TGS version in use.", true, cancellationToken);
+
+ string? serverFriendlyName = null;
+ if (enableReporting)
+ {
+ await console.WriteAsync("(Optional) Publically associate your reported version with a friendly name:", false, cancellationToken);
+ serverFriendlyName = await console.ReadLineAsync(false, cancellationToken);
+ if (String.IsNullOrWhiteSpace(serverFriendlyName))
+ serverFriendlyName = null;
+ }
+
+ return new TelemetryConfiguration
+ {
+ DisableVersionReporting = !enableReporting,
+ ServerFriendlyName = serverFriendlyName,
+ };
+ }
+
///
/// Saves a given set to .
///
@@ -961,6 +986,7 @@ namespace Tgstation.Server.Host.Setup
/// The to save.
/// The to save.
/// The to save.
+ /// The to save.
/// The for the operation.
/// A representing the running operation.
async ValueTask SaveConfiguration(
@@ -972,6 +998,7 @@ namespace Tgstation.Server.Host.Setup
ElasticsearchConfiguration? elasticsearchConfiguration,
ControlPanelConfiguration controlPanelConfiguration,
SwarmConfiguration? swarmConfiguration,
+ TelemetryConfiguration? telemetryConfiguration,
CancellationToken cancellationToken)
{
newGeneralConfiguration.ApiPort = hostingPort ?? GeneralConfiguration.DefaultApiPort;
@@ -984,6 +1011,7 @@ namespace Tgstation.Server.Host.Setup
{ ElasticsearchConfiguration.Section, elasticsearchConfiguration },
{ ControlPanelConfiguration.Section, controlPanelConfiguration },
{ SwarmConfiguration.Section, swarmConfiguration },
+ { TelemetryConfiguration.Section, telemetryConfiguration },
};
var versionConverter = new VersionConverter();
@@ -1055,6 +1083,8 @@ namespace Tgstation.Server.Host.Setup
var swarmConfiguration = await ConfigureSwarm(cancellationToken);
+ var telemetryConfiguration = await ConfigureTelemetry(cancellationToken);
+
await console.WriteAsync(null, true, cancellationToken);
await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "Configuration complete! Saving to {0}", userConfigFileName), true, cancellationToken);
@@ -1067,6 +1097,7 @@ namespace Tgstation.Server.Host.Setup
elasticSearchConfiguration,
controlPanelConfiguration,
swarmConfiguration,
+ telemetryConfiguration,
cancellationToken);
}
@@ -1184,6 +1215,7 @@ namespace Tgstation.Server.Host.Setup
AllowAnyOrigin = true,
},
null,
+ null,
cancellationToken);
}
else
diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
index 94f3fcccb7..cdee07bb4a 100644
--- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
+++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj
@@ -45,16 +45,33 @@
-
+
<_Parameter1>$(TgsConfigVersion)
<_Parameter2>$(TgsInteropVersion)
<_Parameter3>$(TgsWebpanelVersion)
<_Parameter4>$(TgsHostWatchdogVersion)
<_Parameter5>$(TgsMariaDBRedistVersion)
-
+
+
+
+
+
+
-
+
+
+
+
+
+
+ <_Parameter1>@(SerializedTelemetryKey)
+
+
+
diff --git a/src/Tgstation.Server.Host/appsettings.yml b/src/Tgstation.Server.Host/appsettings.yml
index 526f38ab38..68ab2bf729 100644
--- a/src/Tgstation.Server.Host/appsettings.yml
+++ b/src/Tgstation.Server.Host/appsettings.yml
@@ -78,3 +78,7 @@ Swarm: # Should be left empty if using swarm mode is not desired
# PublicAddress: # The public address of the swarm node
# ControllerAddress: # Required on non-controller nodes. The internal address of the swarm controller's API'. Should be left empty on the controller itself
# UpdateRequiredNodeCount: # The number of nodes expected to be in the swarm before initiating an update. This should count every server irrespective of whether or not they are the controller MINUS 1
+Telemetry:
+ DisableVersionReporting: false # Prevents you installation and the version you're using from being reported on the source repository's deployments list
+ ServerFriendlyName: null # Sets a friendly name for your server in reported telemetry. Must be unique. First come first serve
+ VersionReportingRepositoryId: 841149827 # GitHub repostiory ID where the tgs_version_telemetry workflow can be found
diff --git a/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs b/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs
index 823036a10b..cd6e5c86a0 100644
--- a/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs
+++ b/tests/Tgstation.Server.Host.Tests/Setup/TestSetupWizard.cs
@@ -191,6 +191,8 @@ namespace Tgstation.Server.Host.Setup.Tests
"y",
// swarm config
"n",
+ // telemetry config
+ "n",
//saved, now for second run
//this time use defaults amap
String.Empty,
@@ -230,6 +232,9 @@ namespace Tgstation.Server.Host.Setup.Tests
"privatekey",
"n",
"http://controller.com",
+ // telemetry config
+ "y",
+ "telemetry name",
//third run, we already hit all the code coverage so just get through it
String.Empty,
nameof(DatabaseType.MariaDB),
@@ -267,7 +272,9 @@ namespace Tgstation.Server.Host.Setup.Tests
"https://controllerinternal.com",
"https://controllerpublic.com",
"privatekey",
- "y"
+ "y",
+ // telemetry config
+ "n",
};
var inputPos = 0;
diff --git a/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs b/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs
index 645edac147..f9ed0b926a 100644
--- a/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs
+++ b/tests/Tgstation.Server.Tests/Live/LiveTestingServer.cs
@@ -155,6 +155,7 @@ namespace Tgstation.Server.Tests.Live
$"General:OpenDreamGitUrl={OpenDreamUrl}",
$"Security:TokenExpiryMinutes=120", // timeouts are useless for us
$"General:OpenDreamSuppressInstallOutput={TestingUtils.RunningInGitHubActions}",
+ "Telemetry:DisableVersionReporting=true",
};
swarmArgs = new List();