public bool PublishTestRun(Configuration configuration) { if (configuration.TestSuiteId == null) throw new ArgumentException("/testSuiteId must be specified when publishing test results"); if (configuration.TestConfigId == null) throw new ArgumentException("/testConfigId must be specified when publishing test results"); string trxPath = Path.Combine( Path.GetDirectoryName(configuration.TestResults), Path.GetFileNameWithoutExtension(configuration.TestResults) + "_TestRunPublish.trx"); Console.WriteLine("Taken copy of results file to update for publish ({0})", trxPath); File.Copy(configuration.TestResults, trxPath); if (configuration.FixTestIds) TrxFileCorrector.FixTestIdsInTrx(trxPath); var fixedFile = Regex.Replace(File.ReadAllText(trxPath), "TestRun id=\".{36}\"", string.Format("TestRun id=\"{0}\"", Guid.NewGuid())); File.WriteAllText(trxPath, fixedFile); var paths = new[] { @"C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\TCM.exe", @"C:\Program Files\Microsoft Visual Studio 11.0\Common7\IDE\TCM.exe" }; var tcm = File.Exists(paths[0]) ? paths[0] : paths[1]; const string argsFormat = "run /publish /suiteid:{0} /configid:{1} " + "/resultsfile:\"{2}\" " + "/collection:\"{3}\" /teamproject:\"{4}\" " + "/build:\"{5}\" /builddefinition:\"{6}\" /resultowner:\"{7}\""; var args = string.Format(argsFormat, configuration.TestSuiteId, configuration.TestConfigId, trxPath, configuration.Collection, configuration.Project, configuration.BuildNumber, configuration.BuildDefinition, configuration.TestRunResultOwner ?? Environment.UserName); //Optionally override title if (!string.IsNullOrEmpty(configuration.TestRunTitle)) args += " /title:\"" + configuration.TestRunTitle + "\""; Console.WriteLine("Launching tcm.exe {0}", args); string stdOut; string stdErr; var processStartInfo = new ProcessStartInfo(tcm, args) { UseShellExecute = false, RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true }; var process = Process.Start(processStartInfo); process.InputAndOutputToEnd(string.Empty, out stdOut, out stdErr); Console.Write(stdOut); Console.Write(stdErr); return process.ExitCode == 0; }
private void ApplyDefaults(Configuration configuration) { configuration.BuildFlavor = configuration.BuildFlavor ?? "Debug"; configuration.LocalPath = configuration.LocalPath ?? "Solution.sln"; configuration.BuildPlatform = configuration.BuildPlatform ?? "AnyCPU"; configuration.ServerPath = configuration.ServerPath ?? "$/Solution.sln"; configuration.BuildTarget = configuration.BuildTarget ?? "default"; configuration.DropPath = configuration.DropPath ?? @"\\server\drops\"; configuration.BuildStatus = configuration.BuildStatus ?? "Succeeded"; }
public void UpdateConfigurationFromTeamCityBuild(Configuration configuration) { ServicePointManager.ServerCertificateValidationCallback = ((sender, certificate, chain, sslPolicyErrors) => true); using (var handler = new HttpClientHandler { Credentials = new NetworkCredential(configuration.TeamCityUserId, configuration.TeamCityPassword) }) using (var client = new HttpClient(handler)) { client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); HttpResponseMessage response = null; try { response = client.GetAsync(string.Format("{0}/httpAuth/app/rest/builds/id:{1}", configuration.TeamCityServerAddress, configuration.TeamCityBuildId)).Result; var result = response.Content.ReadAsAsync<dynamic>().Result; configuration.BuildNumber = configuration.BuildNumber ?? (string)result.number; configuration.BuildStatus = configuration.BuildStatus ?? ToTfsStatus((string)result.status); configuration.BuildDefinition = configuration.BuildDefinition ?? (string)result.buildType.name; } catch (Exception ex) { if (response != null) { Console.WriteLine("Unable to fetch build information from TeamCity"); Console.WriteLine(); Console.WriteLine("Exception:"); Console.WriteLine(ex.ToString()); Console.WriteLine(); Console.WriteLine("Content:"); Console.WriteLine(response.Content.ReadAsStringAsync().Result); Console.WriteLine(); throw; } } } }
public bool TryProvide(string[] args, out Configuration configuration) { var localConfiguration = new Configuration(); var p = new OptionSet { {"c|collection=", "The collection", v => localConfiguration.Collection = v}, {"p|project=", "The team project", v => localConfiguration.Project = v}, {"b|builddefinition=", "The build definition", v => localConfiguration.BuildDefinition = v}, {"n|buildnumber=", "The build number to assign the build", v => localConfiguration.BuildNumber = v}, {"teamcityBuildId=", "The TeamCity build id to take startTime, endTime, buildnumber from", v => localConfiguration.TeamCityBuildId = v}, {"teamcityServer=", "Url of your teamcity server", v => localConfiguration.TeamCityServerAddress = v}, {"teamcityUserId=", "Username to connect with (if in teamcity build use system.teamcity.auth.userId)", v => localConfiguration.TeamCityUserId = v}, {"teamcityPassword="******"Password to connect with (if in teamcity build use system.teamcity.auth.password)", v => localConfiguration.TeamCityPassword = v}, {"s|status=", "Status of the build (Succeeded, Failed, Stopped, PartiallySucceeded, default: Succeeded)", v => localConfiguration.BuildStatus = v}, {"f|flavor=", "Flavor of the build (to track test results against, default: Debug)", v => localConfiguration.BuildFlavor = v}, {"l|platform=", "Platform of the build (to track test results against, AnyCPU)", v => localConfiguration.BuildPlatform = v}, {"t|target=", "Target of the build (shown on build report, default: default)", v => localConfiguration.BuildTarget = v}, {"localpath=", "Local path of solution file. (default: Solution.sln)", v => localConfiguration.LocalPath = v}, {"serverpath=", "Version Control path for solution file. (e.g. $/Solution.sln)", v => localConfiguration.ServerPath = v}, {"droplocation=", @"Location where builds are dropped (default: \\server\drops\)", v => localConfiguration.DropPath = v}, {"buildlog=", @"Location of build log file. (e.g. \\server\folder\build.log)", v => localConfiguration.BuildLog = v }, {"testResults=", @"Test results file to publish (*.trx, requires MSTest installed)", v => localConfiguration.TestResults = v}, {"create", "Should the build definition be created if it does not exist", v => localConfiguration.CreateBuildDefinitionIfNotExists = (v != null)}, {"trigger", "Instead of creating a manual build, we should trigger the build", v=>localConfiguration.TriggerBuild = (v != null)}, {"keepForever", "Does the build participates in the retention policy of the build definition or to keep the build forever", v=>localConfiguration.KeepForever = (v != null)}, {"buildController=", @"The name of the build controller to use when creating the build definition (default, first controller)", v => localConfiguration.BuildController = v}, {"publishTestRun", @"Creates a test run in Test Manager (requires tcm.exe installed)", v => localConfiguration.PublishTestRun = (v != null)}, {"fixTestIds", @"If the .trx file comes from VSTest.Console.exe, the testId's will not be recognised by Test Runs (for associated automation)", v => localConfiguration.FixTestIds = (v != null)}, {"testSuiteId=", @"The Test Suite to publish the results of the test run to [tcm /suiteId]", v => localConfiguration.TestSuiteId = int.Parse(v)}, {"testConfigid=", @"The Test Configuration to publish the results of the test run to [tcm /configId]", v => localConfiguration.TestConfigId = int.Parse(v)}, {"testRunTitle=", @"The title of the test run [tcm /title]", v => localConfiguration.TestRunTitle = v}, {"testRunResultOwner=", @"The result owner of the test run [tcm /resultOwner]", v => localConfiguration.TestRunResultOwner = v}, }; try { p.Parse(args); } catch (OptionException) { ShowHelp(p); configuration = null; return false; } if (!string.IsNullOrEmpty(localConfiguration.TeamCityBuildId)) _teamCityBuildInfoFetcher.UpdateConfigurationFromTeamCityBuild(localConfiguration); if (string.IsNullOrEmpty(localConfiguration.Collection) || string.IsNullOrEmpty(localConfiguration.Project) || string.IsNullOrEmpty(localConfiguration.BuildDefinition) || (string.IsNullOrEmpty(localConfiguration.BuildNumber) && !localConfiguration.TriggerBuild)) { ShowMissingArgsIfNeeded(localConfiguration); ShowHelp(p); configuration = null; return false; } ApplyDefaults(localConfiguration); configuration = localConfiguration; return true; }
private void ShowMissingArgsIfNeeded(Configuration localConfiguration) { if (string.IsNullOrEmpty(localConfiguration.Collection) && string.IsNullOrEmpty(localConfiguration.Project) && string.IsNullOrEmpty(localConfiguration.BuildDefinition) && string.IsNullOrEmpty(localConfiguration.BuildNumber)) return; if (string.IsNullOrEmpty(localConfiguration.Collection)) Console.WriteLine("collection not specified"); if (string.IsNullOrEmpty(localConfiguration.Project)) Console.WriteLine("project not specified"); if (string.IsNullOrEmpty(localConfiguration.BuildDefinition)) Console.WriteLine("buildDefinition not specified"); if (string.IsNullOrEmpty(localConfiguration.BuildNumber) && !localConfiguration.TriggerBuild) Console.WriteLine("buildNumber not specified"); }