diff --git a/.codecov.yml b/.codecov.yml
new file mode 100644
index 0000000000..b9a9d80675
--- /dev/null
+++ b/.codecov.yml
@@ -0,0 +1,17 @@
+codecov:
+ strict_yaml_branch: master
+coverage:
+ status:
+ project:
+ default:
+ threshold: 0
+ if_no_uploads: failure
+ if_ci_failed: failure
+ patch: off
+ changes:
+ default:
+ if_no_uploads: failure
+ if_ci_failed: failure
+ only_pulls: yes
+comment:
+ layout: "header, diff, changes"
diff --git a/.gitignore b/.gitignore
index 5dee86e7ae..90b3b65a9c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ packages/*
*.user
*.dmb
*.int
+/TestResults
diff --git a/TGServiceInterface/ChatSetupInfo.cs b/TGServiceInterface/ChatSetupInfo.cs
index c34d6aea8e..20e522cba4 100644
--- a/TGServiceInterface/ChatSetupInfo.cs
+++ b/TGServiceInterface/ChatSetupInfo.cs
@@ -1,235 +1,235 @@
-using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Web.Script.Serialization;
-
-namespace TGServiceInterface
-{
- ///
- /// For setting up authentication no matter the chat provider
- ///
- [DataContract]
- [KnownType(typeof(IRCSetupInfo))]
- [KnownType(typeof(DiscordSetupInfo))]
- public class ChatSetupInfo
- {
- const int AdminListIndex = 0;
- const int AdminModeIndex = 1;
- const int AdminChannelIndex = 2;
- const int DevChannelIndex = 3;
- const int WDChannelIndex = 4;
- const int GameChannelIndex = 5;
- const int ProviderIndex = 6;
- const int EnabledIndex = 7;
- ///
- /// Starting index of which child classes should use to write their custom data to
- ///
- protected const int BaseIndex = 8;
- ///
- /// Set to if a child constructor should use the baseInfo parameter of to initialize it's property fields, otherwise
- ///
- protected readonly bool InitializeFields;
-
- ///
- /// Raw access to the underlying data
- ///
- [DataMember]
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Web.Script.Serialization;
+
+namespace TGServiceInterface
+{
+ ///
+ /// For setting up authentication no matter the chat provider
+ ///
+ [DataContract]
+ [KnownType(typeof(IRCSetupInfo))]
+ [KnownType(typeof(DiscordSetupInfo))]
+ public class ChatSetupInfo
+ {
+ const int AdminListIndex = 0;
+ const int AdminModeIndex = 1;
+ const int AdminChannelIndex = 2;
+ const int DevChannelIndex = 3;
+ const int WDChannelIndex = 4;
+ const int GameChannelIndex = 5;
+ const int ProviderIndex = 6;
+ const int EnabledIndex = 7;
+ ///
+ /// Starting index of which child classes should use to write their custom data to
+ ///
+ protected const int BaseIndex = 8;
+ ///
+ /// Set to if a child constructor should use the baseInfo parameter of to initialize it's property fields, otherwise
+ ///
+ protected readonly bool InitializeFields;
+
+ ///
+ /// Raw access to the underlying data
+ ///
+ [DataMember]
public IList DataFields { get; protected set; }
- ///
- /// Constructs a from optional
- ///
- /// The that this is for
- /// Optional past data
- /// The number of fields in this chat provider
- protected internal ChatSetupInfo(ChatProvider provider, ChatSetupInfo baseInfo, int numFields)
- {
- numFields += BaseIndex;
- InitializeFields = baseInfo == null || baseInfo.DataFields.Count != numFields;
-
- if (InitializeFields)
- {
- DataFields = new List(numFields);
- for (var I = 0; I < numFields; ++I)
- DataFields.Add(null);
-
- AdminList = new List();
- AdminChannels = new List();
- DevChannels = new List();
- GameChannels = new List();
- WatchdogChannels = new List();
- AdminsAreSpecial = false;
- Enabled = false;
- }
- else
- DataFields = baseInfo.DataFields;
- Provider = provider;
+ ///
+ /// Constructs a from optional
+ ///
+ /// The that this is for
+ /// Optional past data
+ /// The number of fields in this chat provider
+ protected internal ChatSetupInfo(ChatProvider provider, ChatSetupInfo baseInfo, int numFields)
+ {
+ numFields += BaseIndex;
+ InitializeFields = baseInfo == null || baseInfo.DataFields.Count != numFields;
+
+ if (InitializeFields)
+ {
+ DataFields = new List(numFields);
+ for (var I = 0; I < numFields; ++I)
+ DataFields.Add(null);
+
+ AdminList = new List();
+ AdminChannels = new List();
+ DevChannels = new List();
+ GameChannels = new List();
+ WatchdogChannels = new List();
+ AdminsAreSpecial = false;
+ Enabled = false;
+ }
+ else
+ DataFields = baseInfo.DataFields;
+ Provider = provider;
Specialize(true); //to check we have a valid provider
- }
-
- ///
- /// Recreates as the correct child
- ///
- /// If , is returned provided is a valid
- /// A new based on the type
- ChatSetupInfo Specialize(bool checkOnly)
- {
- switch (Provider)
- {
- case ChatProvider.IRC:
- if (!checkOnly)
- return new IRCSetupInfo(this);
- break;
- case ChatProvider.Discord:
+ }
+
+ ///
+ /// Recreates as the correct child
+ ///
+ /// If , is returned provided is a valid
+ /// A new based on the type
+ ChatSetupInfo Specialize(bool checkOnly)
+ {
+ switch (Provider)
+ {
+ case ChatProvider.IRC:
if (!checkOnly)
- return new DiscordSetupInfo(this);
- break;
- default:
- throw new Exception("Invalid provider!");
- }
- return null;
- }
-
- ///
- /// Properly formats a name for the
- ///
- /// The to format
- /// The formatted
- protected virtual string SanitizeChannelName(string channel)
- {
- return Specialize(false).SanitizeChannelName(channel);
- }
-
- ///
- /// Sanitizes a list of
- ///
- /// An of strings
- void SanitizeChannelNames(IList channelnames)
- {
- for (var I = 0; I < channelnames.Count; ++I)
-
- if (String.IsNullOrWhiteSpace(channelnames[I]))
- {
- channelnames.RemoveAt(I);
- --I;
- }
- else
- channelnames[I] = SanitizeChannelName(channelnames[I].Trim());
- }
-
- ///
- /// Constructs a from a data list
- ///
- /// The data
- public ChatSetupInfo(IList DeserializedData)
- {
- DataFields = DeserializedData;
- Specialize(false); //ensure provider type is valid
- }
- ///
- /// The list of admin entries
- ///
- public IList AdminList
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminListIndex]); }
- set { DataFields[AdminListIndex] = new JavaScriptSerializer().Serialize(value); }
- }
- ///
- /// If AdminList corresponds to a Provider specific recognization method
- ///
- public bool AdminsAreSpecial
- {
- get { return Convert.ToBoolean(DataFields[AdminModeIndex]); }
- set { DataFields[AdminModeIndex] = Convert.ToString(value); }
- }
- ///
- /// The channels from which admin commands/messages can be sent/received
- ///
- public IList AdminChannels
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminChannelIndex]); }
- set
- {
- SanitizeChannelNames(value);
- DataFields[AdminChannelIndex] = new JavaScriptSerializer().Serialize(value);
- }
- }
- ///
- /// The channels to which repo and compile messages are sent
- ///
- public IList DevChannels
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[DevChannelIndex]); }
- set
- {
- SanitizeChannelNames(value);
- DataFields[DevChannelIndex] = new JavaScriptSerializer().Serialize(value);
- }
- }
- ///
- /// The channels to which watchdog messages are sent
- ///
- public IList WatchdogChannels
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[WDChannelIndex]); }
- set
- {
- SanitizeChannelNames(value);
- DataFields[WDChannelIndex] = new JavaScriptSerializer().Serialize(value);
- }
- }
- ///
- /// The channels to which game messages are sent
- ///
- public IList GameChannels
- {
- get { return new JavaScriptSerializer().Deserialize>(DataFields[GameChannelIndex]); }
- set
- {
- SanitizeChannelNames(value);
- DataFields[GameChannelIndex] = new JavaScriptSerializer().Serialize(value);
- }
- }
- ///
- /// If this chat provider is enabled
- ///
- public bool Enabled
- {
- get { return Convert.ToBoolean(DataFields[EnabledIndex]); }
- set { DataFields[EnabledIndex] = Convert.ToString(value); }
- }
-
- ///
- /// The type of provider
- ///
- public ChatProvider Provider
- {
- get { return (ChatProvider)Convert.ToInt32(DataFields[ProviderIndex]); }
- set { DataFields[ProviderIndex] = Convert.ToString((int)value); }
- }
- }
-
- ///
- /// Chat provider for IRC. Admin entries should be user nicknames in normal mode or required channel flags in special mode
- ///
- [DataContract]
- public sealed class IRCSetupInfo : ChatSetupInfo
- {
- const int URLIndex = 0;
- const int PortIndex = 1;
- const int NickIndex = 2;
- const int AuthTargetIndex = 3;
- const int AuthMessageIndex = 4;
- const int AuthLevelIndex = 5;
+ return new IRCSetupInfo(this);
+ break;
+ case ChatProvider.Discord:
+ if (!checkOnly)
+ return new DiscordSetupInfo(this);
+ break;
+ default:
+ throw new Exception("Invalid provider!");
+ }
+ return null;
+ }
+
+ ///
+ /// Properly formats a name for the
+ ///
+ /// The to format
+ /// The formatted
+ protected virtual string SanitizeChannelName(string channel)
+ {
+ return Specialize(false).SanitizeChannelName(channel);
+ }
+
+ ///
+ /// Sanitizes a list of
+ ///
+ /// An of strings
+ void SanitizeChannelNames(IList channelnames)
+ {
+ for (var I = 0; I < channelnames.Count; ++I)
+
+ if (String.IsNullOrWhiteSpace(channelnames[I]))
+ {
+ channelnames.RemoveAt(I);
+ --I;
+ }
+ else
+ channelnames[I] = SanitizeChannelName(channelnames[I].Trim());
+ }
+
+ ///
+ /// Constructs a from a data list
+ ///
+ /// The data
+ public ChatSetupInfo(IList DeserializedData)
+ {
+ DataFields = DeserializedData;
+ Specialize(false); //ensure provider type is valid
+ }
+ ///
+ /// The list of admin entries
+ ///
+ public IList AdminList
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminListIndex]); }
+ set { DataFields[AdminListIndex] = new JavaScriptSerializer().Serialize(value); }
+ }
+ ///
+ /// If AdminList corresponds to a Provider specific recognization method
+ ///
+ public bool AdminsAreSpecial
+ {
+ get { return Convert.ToBoolean(DataFields[AdminModeIndex]); }
+ set { DataFields[AdminModeIndex] = Convert.ToString(value); }
+ }
+ ///
+ /// The channels from which admin commands/messages can be sent/received
+ ///
+ public IList AdminChannels
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[AdminChannelIndex]); }
+ set
+ {
+ SanitizeChannelNames(value);
+ DataFields[AdminChannelIndex] = new JavaScriptSerializer().Serialize(value);
+ }
+ }
+ ///
+ /// The channels to which repo and compile messages are sent
+ ///
+ public IList DevChannels
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[DevChannelIndex]); }
+ set
+ {
+ SanitizeChannelNames(value);
+ DataFields[DevChannelIndex] = new JavaScriptSerializer().Serialize(value);
+ }
+ }
+ ///
+ /// The channels to which watchdog messages are sent
+ ///
+ public IList WatchdogChannels
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[WDChannelIndex]); }
+ set
+ {
+ SanitizeChannelNames(value);
+ DataFields[WDChannelIndex] = new JavaScriptSerializer().Serialize(value);
+ }
+ }
+ ///
+ /// The channels to which game messages are sent
+ ///
+ public IList GameChannels
+ {
+ get { return new JavaScriptSerializer().Deserialize>(DataFields[GameChannelIndex]); }
+ set
+ {
+ SanitizeChannelNames(value);
+ DataFields[GameChannelIndex] = new JavaScriptSerializer().Serialize(value);
+ }
+ }
+ ///
+ /// If this chat provider is enabled
+ ///
+ public bool Enabled
+ {
+ get { return Convert.ToBoolean(DataFields[EnabledIndex]); }
+ set { DataFields[EnabledIndex] = Convert.ToString(value); }
+ }
+
+ ///
+ /// The type of provider
+ ///
+ public ChatProvider Provider
+ {
+ get { return (ChatProvider)Convert.ToInt32(DataFields[ProviderIndex]); }
+ set { DataFields[ProviderIndex] = Convert.ToString((int)value); }
+ }
+ }
+
+ ///
+ /// Chat provider for IRC. Admin entries should be user nicknames in normal mode or required channel flags in special mode
+ ///
+ [DataContract]
+ public sealed class IRCSetupInfo : ChatSetupInfo
+ {
+ const int URLIndex = 0;
+ const int PortIndex = 1;
+ const int NickIndex = 2;
+ const int AuthTargetIndex = 3;
+ const int AuthMessageIndex = 4;
+ const int AuthLevelIndex = 5;
const int FieldsLen = 6;
- ///
- /// Construct IRC setup info from optional generic info. Defaults to TGS3 on rizons IRC server
- ///
- /// Optional generic info
- public IRCSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.IRC, baseInfo, FieldsLen)
- {
- if (!InitializeFields)
+ ///
+ /// Construct IRC setup info from optional generic info. Defaults to TGS3 on rizons IRC server
+ ///
+ /// Optional generic info
+ public IRCSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.IRC, baseInfo, FieldsLen)
+ {
+ if (!InitializeFields)
return;
Nickname = "TGS3";
@@ -239,106 +239,106 @@ namespace TGServiceInterface
AuthMessage = "";
AdminsAreSpecial = true;
AuthLevel = IRCMode.Op;
- }
-
- ///
- protected override string SanitizeChannelName(string working)
- {
- if (working[0] != '#')
- return "#" + working;
- return working;
- }
-
- ///
- /// The port of the IRC server
- ///
- public ushort Port
- {
- get { return Convert.ToUInt16(DataFields[BaseIndex + PortIndex]); }
- set { DataFields[BaseIndex + PortIndex] = value.ToString(); }
- }
- ///
- /// The URL of the IRC server
- ///
- public string URL
- {
- get { return DataFields[BaseIndex + URLIndex]; }
- set { DataFields[BaseIndex + URLIndex] = value; }
- }
- ///
- /// The nickname of the IRC bot
- ///
- public string Nickname
- {
- get { return DataFields[BaseIndex + NickIndex]; }
- set { DataFields[BaseIndex + NickIndex] = value; }
- }
- ///
- /// The target for sending authentication messages
- ///
- public string AuthTarget
- {
- get { return DataFields[BaseIndex + AuthTargetIndex]; }
- set { DataFields[BaseIndex + AuthTargetIndex] = value; }
- }
- ///
- /// The authentication message
- ///
- public string AuthMessage
- {
- get { return DataFields[BaseIndex + AuthMessageIndex]; }
- set { DataFields[BaseIndex + AuthMessageIndex] = value; }
- }
- ///
- /// The minimum mode required to use admin bot commands when in special auth mode
- ///
- public IRCMode AuthLevel
- {
- get { return (IRCMode)Convert.ToInt32(DataFields[BaseIndex + AuthLevelIndex]); }
- set { DataFields[BaseIndex + AuthLevelIndex] = Convert.ToString((int)value); }
- }
- }
-
- ///
- /// Chat provider for Discord. Admin entires should be user ids in normal mode or group ids in special mode
- ///
- [DataContract]
- public sealed class DiscordSetupInfo : ChatSetupInfo
- {
- const int BotTokenIndex = 0;
+ }
+
+ ///
+ protected override string SanitizeChannelName(string working)
+ {
+ if (working[0] != '#')
+ return "#" + working;
+ return working;
+ }
+
+ ///
+ /// The port of the IRC server
+ ///
+ public ushort Port
+ {
+ get { return Convert.ToUInt16(DataFields[BaseIndex + PortIndex]); }
+ set { DataFields[BaseIndex + PortIndex] = value.ToString(); }
+ }
+ ///
+ /// The URL of the IRC server
+ ///
+ public string URL
+ {
+ get { return DataFields[BaseIndex + URLIndex]; }
+ set { DataFields[BaseIndex + URLIndex] = value; }
+ }
+ ///
+ /// The nickname of the IRC bot
+ ///
+ public string Nickname
+ {
+ get { return DataFields[BaseIndex + NickIndex]; }
+ set { DataFields[BaseIndex + NickIndex] = value; }
+ }
+ ///
+ /// The target for sending authentication messages
+ ///
+ public string AuthTarget
+ {
+ get { return DataFields[BaseIndex + AuthTargetIndex]; }
+ set { DataFields[BaseIndex + AuthTargetIndex] = value; }
+ }
+ ///
+ /// The authentication message
+ ///
+ public string AuthMessage
+ {
+ get { return DataFields[BaseIndex + AuthMessageIndex]; }
+ set { DataFields[BaseIndex + AuthMessageIndex] = value; }
+ }
+ ///
+ /// The minimum mode required to use admin bot commands when in special auth mode
+ ///
+ public IRCMode AuthLevel
+ {
+ get { return (IRCMode)Convert.ToInt32(DataFields[BaseIndex + AuthLevelIndex]); }
+ set { DataFields[BaseIndex + AuthLevelIndex] = Convert.ToString((int)value); }
+ }
+ }
+
+ ///
+ /// Chat provider for Discord. Admin entires should be user ids in normal mode or group ids in special mode
+ ///
+ [DataContract]
+ public sealed class DiscordSetupInfo : ChatSetupInfo
+ {
+ const int BotTokenIndex = 0;
const int FieldsLen = 1;
- ///
- /// Construct Discord setup info from optional generic info. Default is not a valid discord bot tokent
- ///
- /// Optional generic info
- public DiscordSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.Discord, baseInfo, FieldsLen)
- {
- if (!InitializeFields)
- return;
- BotToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; //needless to say, this is fake
- }
- ///
- protected override string SanitizeChannelName(string working)
- {
- working = working.Replace("<", "").Replace(">", "").Replace("&", ""); //filter out some stuff that can come in the copypasta
- try
- {
- Convert.ToUInt64(working);
- }
- catch
- {
- throw new Exception("Invalid Discord channel ID!");
- }
- return working;
- }
-
- ///
- /// The Discord bot token to use. See https://discordapp.com/developers/applications/me for registering bot accounts
- ///
- public string BotToken
- {
- get { return DataFields[BaseIndex + BotTokenIndex]; }
- set { DataFields[BaseIndex + BotTokenIndex] = value; }
- }
- }
-}
+ ///
+ /// Construct Discord setup info from optional generic info. Default is not a valid discord bot tokent
+ ///
+ /// Optional generic info
+ public DiscordSetupInfo(ChatSetupInfo baseInfo = null) : base(ChatProvider.Discord, baseInfo, FieldsLen)
+ {
+ if (!InitializeFields)
+ return;
+ BotToken = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; //needless to say, this is fake
+ }
+ ///
+ protected override string SanitizeChannelName(string working)
+ {
+ working = working.Replace("<", "").Replace(">", "").Replace("&", ""); //filter out some stuff that can come in the copypasta
+ try
+ {
+ Convert.ToUInt64(working);
+ }
+ catch
+ {
+ throw new Exception("Invalid Discord channel ID!");
+ }
+ return working;
+ }
+
+ ///
+ /// The Discord bot token to use. See https://discordapp.com/developers/applications/me for registering bot accounts
+ ///
+ public string BotToken
+ {
+ get { return DataFields[BaseIndex + BotTokenIndex]; }
+ set { DataFields[BaseIndex + BotTokenIndex] = value; }
+ }
+ }
+}
diff --git a/TGServiceTests/TempDirectoryRequiredTest.cs b/TGServiceTests/TempDirectoryRequiredTest.cs
index a4ef44cf09..f3dcacd255 100644
--- a/TGServiceTests/TempDirectoryRequiredTest.cs
+++ b/TGServiceTests/TempDirectoryRequiredTest.cs
@@ -6,6 +6,7 @@ namespace TGServiceTests
///
/// To be the parent of test classes that required a temporary directory
///
+ [TestClass]
public class TempDirectoryRequiredTest
{
///
diff --git a/TGStationServer3.sln b/TGStationServer3.sln
index 5e501864f6..2999ef57e4 100644
--- a/TGStationServer3.sln
+++ b/TGStationServer3.sln
@@ -75,8 +75,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{081BB0BB
ProjectSection(SolutionItems) = preProject
Tools\build_byond.sh = Tools\build_byond.sh
Tools\Config.dm = Tools\Config.dm
+ Tools\CoverageExclusions.runsettings = Tools\CoverageExclusions.runsettings
Tools\DMAPITravisTester.dme = Tools\DMAPITravisTester.dme
Tools\Doxyfile = Tools\Doxyfile
+ Tools\GenCodeCovXML.ps1 = Tools\GenCodeCovXML.ps1
Tools\install_byond.sh = Tools\install_byond.sh
Tools\Test.dm = Tools\Test.dm
Tools\TGS3Build.ps1 = Tools\TGS3Build.ps1
diff --git a/Tools/CoverageExclusions.runsettings b/Tools/CoverageExclusions.runsettings
new file mode 100644
index 0000000000..92eee55060
--- /dev/null
+++ b/Tools/CoverageExclusions.runsettings
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ .*\\TGServiceTests\\.*
+
+
+
+
+ True
+ True
+ True
+ False
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Tools/GenCodeCovXML.ps1 b/Tools/GenCodeCovXML.ps1
new file mode 100644
index 0000000000..b0403e8f48
--- /dev/null
+++ b/Tools/GenCodeCovXML.ps1
@@ -0,0 +1,15 @@
+$coverageFilePath = Resolve-Path -path "TestResults\*\*.coverage"
+
+$coverageFilePath = $coverageFilePath.ToString()
+
+Write-Host "Running CodeCoverage.exe..."
+&"C:\Program Files (x86)\Microsoft Visual Studio\Community\Team Tools\Dynamic Code Coverage Tools\CodeCoverage.exe" analyze /output:coverage.coveragexml "$coverageFilePath"
+
+rm -r TestResults
+
+Write-Host "Downloading PathCapitalizationCorrector v0.1.4..."
+appveyor DownloadFile https://github.com/Cyberboss/PathCapitalizationCorrector/releases/download/0.1.4/PathCapitalizationCorrector.exe
+
+Write-Host "Fixing Window's terrible case ignorance..."
+&"./PathCapitalizationCorrector.exe" coverage.coveragexml
+codecov -f coverage.coveragexml
diff --git a/appveyor.yml b/appveyor.yml
index 261a73153e..0ad02e2883 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -34,8 +34,8 @@ after_build:
- ps: if($env:APPVEYOR_REPO_COMMIT_MESSAGE -match "\[TGSDeploy\]"){$env:TGSDeploy = "Do it."}
- ps: $env:TGSVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$env:APPVEYOR_BUILD_FOLDER/TGServerService/bin/Release/TGServerService.exe").FileVersion
test_script:
- - OpenCover.Console.exe -register:user -target:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\MSTest.exe" -targetargs:"/testcontainer:"".\TGServiceTests\bin\Release\TGServiceTests.dll" -filter:"+[TG*]* -[TGServiceTests*]*" -output:".\TGSCoverage.xml"
- - codecov -f "TGSCoverage.xml"
+ - vstest.console /logger:Appveyor "TGServiceTests\bin\Release\TGServiceTests.dll" /Enablecodecoverage /Settings:"Tools/CoverageExclusions.runsettings" /inIsolation /Platform:x64
+ - powershell -Command "Tools/GenCodeCovXML.ps1"
deploy:
- provider: GitHub
release: "tgstation-server-v$(TGSVersion)"