Beispiel #1
0
		public static void PerformNightlyBuild(ConfigFile config)
		{
			string packagePath = Path.Combine(config.PackageDir, config.PackageName);
			FileVersionInfo versionCore = null;
			FileVersionInfo versionEditor = null;
			FileVersionInfo versionLauncher = null;

			// Build the target Solution
			Console.WriteLine("================================ Build Solution ===============================");
			{
				var buildProperties = new Dictionary<string,string>(){ { "Configuration", "Release"} };
				var buildRequest = new BuildRequestData(config.SolutionPath, buildProperties, null, new string[] { "Build" }, null);
				var buildParameters = new BuildParameters();
				//buildParameters.Loggers = new[] { new ConsoleLogger(LoggerVerbosity.Minimal) };
				var buildResult = BuildManager.DefaultBuildManager.Build(buildParameters, buildRequest);
				if (buildResult.OverallResult != BuildResultCode.Success)
					throw new ApplicationException("The project doesn't compile properly. Cannot proceed in this state.");

				versionCore = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "Duality.dll"));
				versionEditor = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "DualityEditor.exe"));
				versionLauncher = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "DualityLauncher.exe"));

				Console.WriteLine("Build Successful");
				Console.WriteLine("  Core Version:     {0}", versionCore.FileVersion);
				Console.WriteLine("  Editor Version:   {0}", versionEditor.FileVersion);
				Console.WriteLine("  Launcher Version: {0}", versionLauncher.FileVersion);
			}
			Console.WriteLine("===============================================================================");
			Console.WriteLine();
			Console.WriteLine();

			// Perform unit testing
			Console.WriteLine("================================= Unit Testing ================================");
			{
				foreach (string nunitProjectFile in Directory.EnumerateFiles(config.UnitTestProjectDir, "*.nunit", SearchOption.TopDirectoryOnly))
				{
					Console.Write("Testing '{0}'... ", Path.GetFileName(nunitProjectFile));

					// Don't use /timeout, as it will execute tests from a different thread,
					// which will break a lot of graphics-related Duality stuff!
					string resultFile = "UnitTestResult.xml";
					ExecuteCommand(
						string.Format("{0} {1} /result={2}", 
							Path.Combine(config.NUnitBinDir, "nunit-console.exe"), 
							nunitProjectFile,
							resultFile), 
						verbose: false);

					if (File.Exists(resultFile))
					{
						bool unitTestFailed = false;
						XmlDocument resultDoc = new XmlDocument();
						resultDoc.Load(resultFile);

						Stack<XmlElement> elementStack = new Stack<XmlElement>();
						elementStack.Push(resultDoc["test-results"]);
						do
						{
							XmlElement currentElement = elementStack.Pop();
							XmlAttribute successAttribute = currentElement.Attributes["success"];

							if (successAttribute == null)
							{
								foreach (XmlElement child in currentElement.OfType<XmlElement>().Reverse())
								{
									elementStack.Push(child);
								}
							}
							else
							{
								bool success = (successAttribute == null) || XmlConvert.ToBoolean(successAttribute.Value.ToLower());
								if (!success)
								{
									unitTestFailed = true;
									break;
								}
							}
						} while (elementStack.Count > 0);

						if (unitTestFailed)
						{
							ExecuteBackgroundCommand(resultFile);
							ExecuteBackgroundCommand(
								string.Format("{0} {1}", 
									Path.Combine(config.NUnitBinDir, "nunit.exe"), 
									nunitProjectFile));
							throw new ApplicationException(string.Format("At least one unit test has failed. See {0} for more information.", resultFile));
						}
						else
						{
							Console.WriteLine("success!");
							File.Delete(resultFile);
						}
					}
					else
					{
						throw new ApplicationException("Something appears to have failed during unit testing, because no result file was found.");
					}
				}
			}
			Console.WriteLine("===============================================================================");
			Console.WriteLine();
			Console.WriteLine();

			// Build the documentation
			if (!config.NoDocs)
			{
				Console.WriteLine("================================== Build Docs =================================");
				{
					var buildProperties = new Dictionary<string,string>(){ { "Configuration", "Release"} };
					var buildRequest = new BuildRequestData(config.DocSolutionPath, buildProperties, null, new string[] { "Build" }, null);
					var buildParameters = new BuildParameters();
					buildParameters.Loggers = new[] { new ConsoleLogger(LoggerVerbosity.Minimal) };
					var buildResult = BuildManager.DefaultBuildManager.Build(buildParameters, buildRequest);
					if (buildResult.OverallResult != BuildResultCode.Success)
						throw new ApplicationException("Documentation Build Failure");
					File.Copy(
						Path.Combine(config.DocBuildResultDir, config.DocBuildResultFile), 
						Path.Combine(config.BuildResultDir, config.DocBuildResultFile),
						true);
					Console.WriteLine("Documentation Build Successful");
				}
				Console.WriteLine("===============================================================================");
				Console.WriteLine();
				Console.WriteLine();
			}
			else if (File.Exists(Path.Combine(config.DocBuildResultDir, config.DocBuildResultFile)))
			{
				Console.WriteLine("============================== Copy existing Docs =============================");
				{
					File.Copy(
						Path.Combine(config.DocBuildResultDir, config.DocBuildResultFile), 
						Path.Combine(config.BuildResultDir, config.DocBuildResultFile),
						true);
				}
				Console.WriteLine("===============================================================================");
				Console.WriteLine();
				Console.WriteLine();
			}

			// Copy the results to the target directory
			Console.WriteLine("================================ Copy to Target ===============================");
			{
				Console.WriteLine("Creating target directory '{0}'", config.IntermediateTargetDir);
				if (Directory.Exists(config.IntermediateTargetDir))
					Directory.Delete(config.IntermediateTargetDir, true);
				CopyDirectory(config.BuildResultDir, config.IntermediateTargetDir, true, path => 
					{
						string fileName = Path.GetFileName(path);
						foreach (string blackListEntry in config.FileCopyBlackList)
						{
							if (Regex.IsMatch(fileName, WildcardToRegex(blackListEntry), RegexOptions.IgnoreCase))
							{
								Console.ForegroundColor = ConsoleColor.DarkGray;
								Console.WriteLine("Ignore {0}", path);
								Console.ForegroundColor = ConsoleColor.Gray;
								return false;
							}
						}
						Console.WriteLine("Copy   {0}", path);
						return true;
					});
				if (!string.IsNullOrEmpty(config.AdditionalFileDir) && Directory.Exists(config.AdditionalFileDir))
				{
					CopyDirectory(config.AdditionalFileDir, config.IntermediateTargetDir, true);
				}
			}
			Console.WriteLine("===============================================================================");
			Console.WriteLine();
			Console.WriteLine();

			// Create the ZIP package
			Console.WriteLine("============================== Create ZIP Package =============================");
			{
				Console.WriteLine("Package Path: {0}", packagePath);
				if (!Directory.Exists(config.PackageDir))
					Directory.CreateDirectory(config.PackageDir);

				ZipFile package = new ZipFile();
				string[] files = Directory.GetFiles(config.IntermediateTargetDir, "*", SearchOption.AllDirectories);
				package.AddFiles(files);
				package.Save(packagePath);
			}
			Console.WriteLine("===============================================================================");
			Console.WriteLine();
			Console.WriteLine();
			
			// Cleanup
			Console.WriteLine("=================================== Cleanup ===================================");
			{
				Console.WriteLine("Deleting target directory '{0}'", config.IntermediateTargetDir);
				if (Directory.Exists(config.IntermediateTargetDir))
					Directory.Delete(config.IntermediateTargetDir, true);
			}
			Console.WriteLine("===============================================================================");
			Console.WriteLine();
			Console.WriteLine();
			
			// Build all NuGet Packages
			Console.WriteLine("============================= Build NuGet Packages ============================");
			{
				bool nugetFound = File.Exists(config.NuGetPath);
				bool nugetSpecsFound = Directory.Exists(config.NuGetPackageSpecsDir);
				if (nugetFound && nugetSpecsFound)
				{
					if (!Directory.Exists(config.NuGetPackageTargetDir))
						Directory.CreateDirectory(config.NuGetPackageTargetDir);

					Console.WriteLine("Deleting old package files in '{0}'...", config.NuGetPackageTargetDir);
					foreach (string file in Directory.EnumerateFiles(config.NuGetPackageTargetDir, "*.nupkg", SearchOption.TopDirectoryOnly))
					{
						File.Delete(file);
					}

					Console.WriteLine("Creating packages from '{0}'...", config.NuGetPackageSpecsDir);
					foreach (string file in Directory.EnumerateFiles(config.NuGetPackageSpecsDir, "*.nuspec", SearchOption.AllDirectories))
					{
						string fileAbs = Path.GetFullPath(file);
						ExecuteCommand(Path.GetFullPath(config.NuGetPath) + " pack " + fileAbs, config.NuGetPackageTargetDir, false);
					}
				}
				else if (!nugetFound)
				{
					throw new ApplicationException(string.Format("Can't find NuGet command line tool '{0}'.", config.NuGetPath));
				}
				else if (!nugetSpecsFound)
				{
					throw new ApplicationException(string.Format("Can't find NuGet package specs directory '{0}'.", config.NuGetPackageSpecsDir));
				}
			}
			Console.WriteLine("===============================================================================");
			Console.WriteLine();
			Console.WriteLine();
			
			// Copy ZIP Package
			if (!string.IsNullOrWhiteSpace(config.CopyPackageTo))
			{
				Console.WriteLine("=============================== Copy ZIP Package ==============================");
				{
					Console.WriteLine("Copying package to '{0}'", config.CopyPackageTo);
					if (!Directory.Exists(config.CopyPackageTo))
						Directory.CreateDirectory(config.CopyPackageTo);
					File.Copy(packagePath, Path.Combine(config.CopyPackageTo, config.PackageName), true);
				}
				Console.WriteLine("===============================================================================");
				Console.WriteLine();
				Console.WriteLine();
			}
		}
Beispiel #2
0
        public static void PerformNightlyBuild(ConfigFile config)
        {
            string packagePath = Path.Combine(config.PackageDir, config.PackageName);
            FileVersionInfo versionCore = null;
            FileVersionInfo versionEditor = null;
            FileVersionInfo versionLauncher = null;

            // Build the target Solution
            Console.WriteLine("================================ Build Solution ===============================");
            {
                bool buildSuccess = BuildVisualStudioSolution(config.SolutionPath, "Release");
                if (!buildSuccess)
                    throw new ApplicationException("The project doesn't compile properly. Cannot proceed in this state.");

                versionCore = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "Duality.dll"));
                versionEditor = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "DualityEditor.exe"));
                versionLauncher = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "DualityLauncher.exe"));

                Console.WriteLine("Build Successful");
                Console.WriteLine("  Core Version:     {0}", versionCore.FileVersion);
                Console.WriteLine("  Editor Version:   {0}", versionEditor.FileVersion);
                Console.WriteLine("  Launcher Version: {0}", versionLauncher.FileVersion);
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Perform unit testing
            Console.WriteLine("================================= Unit Testing ================================");
            {
                foreach (string nunitProjectFile in Directory.EnumerateFiles(config.UnitTestProjectDir, "*.nunit", SearchOption.TopDirectoryOnly))
                {
                    Console.Write("Testing '{0}'... ", Path.GetFileName(nunitProjectFile));

                    // Don't use /timeout, as it will execute tests from a different thread,
                    // which will break a lot of graphics-related Duality stuff!
                    string resultFile = "UnitTestResult.xml";
                    ExecuteCommand(
                        string.Format("{0} {1} /result={2}",
                            Path.Combine(config.NUnitBinDir, "nunit-console.exe"),
                            nunitProjectFile,
                            resultFile),
                        verbose: false);

                    if (File.Exists(resultFile))
                    {
                        bool unitTestFailed = false;
                        XmlDocument resultDoc = new XmlDocument();
                        resultDoc.Load(resultFile);

                        Stack<XmlElement> elementStack = new Stack<XmlElement>();
                        elementStack.Push(resultDoc["test-results"]);
                        do
                        {
                            XmlElement currentElement = elementStack.Pop();
                            XmlAttribute successAttribute = currentElement.Attributes["success"];

                            if (successAttribute == null)
                            {
                                foreach (XmlElement child in currentElement.OfType<XmlElement>().Reverse())
                                {
                                    elementStack.Push(child);
                                }
                            }
                            else
                            {
                                bool success = (successAttribute == null) || XmlConvert.ToBoolean(successAttribute.Value.ToLower());
                                if (!success)
                                {
                                    unitTestFailed = true;
                                    break;
                                }
                            }
                        } while (elementStack.Count > 0);

                        if (unitTestFailed)
                        {
                            ExecuteBackgroundCommand(resultFile);
                            ExecuteBackgroundCommand(
                                string.Format("{0} {1}",
                                    Path.Combine(config.NUnitBinDir, "nunit.exe"),
                                    nunitProjectFile));
                            throw new ApplicationException(string.Format("At least one unit test has failed. See {0} for more information.", resultFile));
                        }
                        else
                        {
                            Console.WriteLine("success!");
                            File.Delete(resultFile);
                        }
                    }
                    else
                    {
                        throw new ApplicationException("Something appears to have failed during unit testing, because no result file was found.");
                    }
                }
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Build the documentation
            bool includeDocs =
                !string.IsNullOrWhiteSpace(config.DocBuildResultDir) &&
                !string.IsNullOrWhiteSpace(config.DocBuildResultFile);
            if (!config.NoDocs)
            {
                Console.WriteLine("================================== Build Docs =================================");
                {
                    bool buildSuccess = BuildVisualStudioSolution(config.DocSolutionPath, "Release");
                    if (!buildSuccess)
                        throw new ApplicationException("Documentation Build Failure");

                    Console.WriteLine("Documentation Build Successful");

                    if (includeDocs)
                    {
                        File.Copy(
                            Path.Combine(config.DocBuildResultDir, config.DocBuildResultFile),
                            Path.Combine(config.BuildResultDir, config.DocBuildResultFile),
                            true);
                        Console.WriteLine("Documentation copied to build directory");
                    }
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }
            else if (includeDocs && File.Exists(Path.Combine(config.DocBuildResultDir, config.DocBuildResultFile)))
            {
                Console.WriteLine("============================== Copy existing Docs =============================");
                {
                    File.Copy(
                        Path.Combine(config.DocBuildResultDir, config.DocBuildResultFile),
                        Path.Combine(config.BuildResultDir, config.DocBuildResultFile),
                        true);
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }

            // Copy the results to the target directory
            Console.WriteLine("================================ Copy to Target ===============================");
            {
                Console.WriteLine("Creating target directory '{0}'", config.IntermediateTargetDir);
                if (Directory.Exists(config.IntermediateTargetDir))
                    Directory.Delete(config.IntermediateTargetDir, true);
                CopyDirectory(config.BuildResultDir, config.IntermediateTargetDir, true, path =>
                    {
                        string fileName = Path.GetFileName(path);
                        foreach (string blackListEntry in config.FileCopyBlackList)
                        {
                            if (Regex.IsMatch(fileName, WildcardToRegex(blackListEntry), RegexOptions.IgnoreCase))
                            {
                                Console.ForegroundColor = ConsoleColor.DarkGray;
                                Console.WriteLine("Ignore {0}", path);
                                Console.ForegroundColor = ConsoleColor.Gray;
                                return false;
                            }
                        }
                        Console.WriteLine("Copy   {0}", path);
                        return true;
                    });
                if (!string.IsNullOrEmpty(config.AdditionalFileDir) && Directory.Exists(config.AdditionalFileDir))
                {
                    CopyDirectory(config.AdditionalFileDir, config.IntermediateTargetDir, true);
                }
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Create the ZIP package
            Console.WriteLine("============================== Create ZIP Package =============================");
            {
                Console.WriteLine("Package Path: {0}", packagePath);
                if (!Directory.Exists(config.PackageDir))
                    Directory.CreateDirectory(config.PackageDir);

                ZipFile package = new ZipFile();
                string[] files = Directory.GetFiles(config.IntermediateTargetDir, "*", SearchOption.AllDirectories);
                package.AddFiles(files);
                package.Save(packagePath);
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Cleanup
            Console.WriteLine("=================================== Cleanup ===================================");
            {
                Console.WriteLine("Deleting target directory '{0}'", config.IntermediateTargetDir);
                if (Directory.Exists(config.IntermediateTargetDir))
                    Directory.Delete(config.IntermediateTargetDir, true);
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Build all NuGet Packages
            Console.WriteLine("============================= Build NuGet Packages ============================");
            {
                bool nugetFound = File.Exists(config.NuGetPath);
                bool nugetSpecsFound = Directory.Exists(config.NuGetPackageSpecsDir);
                if (nugetFound && nugetSpecsFound)
                {
                    if (!Directory.Exists(config.NuGetPackageTargetDir))
                        Directory.CreateDirectory(config.NuGetPackageTargetDir);

                    Console.WriteLine("Deleting old package files in '{0}'...", config.NuGetPackageTargetDir);
                    foreach (string file in Directory.EnumerateFiles(config.NuGetPackageTargetDir, "*.nupkg", SearchOption.TopDirectoryOnly))
                    {
                        File.Delete(file);
                    }

                    Console.WriteLine("Determining package data from '{0}'...", config.NuGetPackageSpecsDir);
                    Dictionary<string,Version> packageVersions = new Dictionary<string,Version>();
                    foreach (string file in Directory.EnumerateFiles(config.NuGetPackageSpecsDir, "*.nuspec", SearchOption.AllDirectories))
                    {
                        Console.Write("  {0}: ", Path.GetFileName(file));

                        string fileAbs = Path.GetFullPath(file);
                        XDocument doc = XDocument.Load(fileAbs);
                        XElement elemId = doc.Descendants("id").FirstOrDefault();
                        XElement elemVersion = doc.Descendants("version").FirstOrDefault();

                        string id = elemId.Value.Trim();
                        Version version = Version.Parse(elemVersion.Value.Trim());
                        packageVersions[id] = version;

                        Console.WriteLine("{0}", version);
                    }

                    Console.WriteLine();
                    Console.WriteLine("Creating packages from '{0}'...", config.NuGetPackageSpecsDir);
                    foreach (string file in Directory.EnumerateFiles(config.NuGetPackageSpecsDir, "*.nuspec", SearchOption.AllDirectories))
                    {
                        Console.Write("  {0}... ", Path.GetFileName(file));

                        string fileAbs = Path.GetFullPath(file);
                        XDocument doc = XDocument.Load(fileAbs);

                        bool skip = false;
                        foreach (XElement elemDependency in doc.Descendants("dependency"))
                        {
                            string id = elemDependency.Attribute("id").Value.Trim();
                            Version version = Version.Parse(elemDependency.Attribute("version").Value.Trim());
                            Version developedAgainstVersion;
                            if (packageVersions.TryGetValue(id, out developedAgainstVersion))
                            {
                                if (version != developedAgainstVersion)
                                {
                                    skip = true;
                                    break;
                                }
                            }
                        }

                        if (skip)
                        {
                            Console.ForegroundColor = ConsoleColor.Yellow;
                            Console.WriteLine("dependency mismatch (skip)");
                            Console.ResetColor();
                            continue;
                        }

                        XElement elemId = doc.Descendants("id").FirstOrDefault();
                        XElement elemVersion = doc.Descendants("version").FirstOrDefault();
                        string targetFileName = string.Format("{0}.{1}.nupkg", elemId.Value.Trim(), elemVersion.Value.Trim());
                        ExecuteCommand(Path.GetFullPath(config.NuGetPath) + " pack " + fileAbs, config.NuGetPackageTargetDir, false);

                        if (!File.Exists(Path.Combine(config.NuGetPackageTargetDir, targetFileName)))
                        {
                            throw new ApplicationException(string.Format("Failed to create NuGet Package {0}", Path.GetFileName(file)));
                        }
                        else
                        {
                            Console.WriteLine("done");
                        }
                    }
                }
                else if (!nugetFound)
                {
                    throw new ApplicationException(string.Format("Can't find NuGet command line tool '{0}'.", config.NuGetPath));
                }
                else if (!nugetSpecsFound)
                {
                    throw new ApplicationException(string.Format("Can't find NuGet package specs directory '{0}'.", config.NuGetPackageSpecsDir));
                }
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Copy ZIP Package
            if (!string.IsNullOrWhiteSpace(config.CopyPackageTo))
            {
                Console.WriteLine("=============================== Copy ZIP Package ==============================");
                {
                    Console.WriteLine("Copying package to '{0}'", config.CopyPackageTo);
                    if (!Directory.Exists(config.CopyPackageTo))
                        Directory.CreateDirectory(config.CopyPackageTo);
                    File.Copy(packagePath, Path.Combine(config.CopyPackageTo, config.PackageName), true);
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }

            Console.WriteLine("Finished Build.");
            Console.ReadLine();
        }
Beispiel #3
0
        public static void PerformNightlyBuild(ConfigFile config)
        {
            if (!config.NoCleanNugetPackageTargetDir)
            {
                Console.WriteLine("============================= Clean NuGet Packages ============================");
                if (Directory.Exists(config.NuGetPackageTargetDir))
                {
                    Console.WriteLine("Deleting old package files in '{0}'...", config.NuGetPackageTargetDir);
                    foreach (string file in Directory.EnumerateFiles(config.NuGetPackageTargetDir, "*.nupkg",
                                                                     SearchOption.TopDirectoryOnly))
                    {
                        File.Delete(file);
                    }
                }

                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }

            // Build the target Solution
            if (!config.NoBuild)
            {
                Console.WriteLine("================================ Build Solution ===============================");
                {
                    bool buildSuccess = BuildVisualStudioSolution(config.SolutionPath, "Release");
                    if (!buildSuccess)
                    {
                        throw new ApplicationException("The project doesn't compile properly. Cannot proceed in this state.");
                    }

                    FileVersionInfo versionCore     = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "Duality.dll"));
                    FileVersionInfo versionEditor   = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "DualityEditor.exe"));
                    FileVersionInfo versionLauncher = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "DualityLauncher.exe"));

                    Console.WriteLine("Build Successful");
                    Console.WriteLine("  Core Version:     {0}", versionCore.FileVersion);
                    Console.WriteLine("  Editor Version:   {0}", versionEditor.FileVersion);
                    Console.WriteLine("  Launcher Version: {0}", versionLauncher.FileVersion);
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }

            // Perform unit testing
            if (!config.NoTests)
            {
                Console.WriteLine("================================= Unit Testing ================================");
                foreach (string nunitProjectFile in Directory.EnumerateFiles(config.UnitTestProjectDir, "*.nunit", SearchOption.TopDirectoryOnly))
                {
                    Console.Write("Testing '{0}'... ", Path.GetFileName(nunitProjectFile));

                    // Don't use /timeout, as it will execute tests from a different thread,
                    // which will break a lot of graphics-related Duality stuff!
                    string resultFile = "UnitTestResult.xml";
                    ExecuteCommand(
                        string.Format("{0} {1} /result={2}",
                                      Path.Combine(config.NUnitBinDir, "nunit3-console.exe"),
                                      nunitProjectFile,
                                      resultFile),
                        verbose: true);

                    if (File.Exists(resultFile))
                    {
                        XmlDocument resultDoc = new XmlDocument();
                        resultDoc.Load(resultFile);

                        XmlElement   testRunElement  = resultDoc["test-run"];
                        XmlAttribute failedAttribute = testRunElement.Attributes["failed"];
                        int          failedCount     = int.Parse(failedAttribute.Value);

                        if (failedCount > 0)
                        {
                            ExecuteBackgroundCommand(resultFile);
                            ExecuteBackgroundCommand(
                                string.Format("{0} {1}",
                                              Path.Combine(config.NUnitBinDir, "nunit3-console.exe"),
                                              nunitProjectFile));
                            throw new ApplicationException(string.Format("At least one unit test has failed. See {0} for more information.", resultFile));
                        }
                        else
                        {
                            Console.WriteLine("success!");
                            File.Delete(resultFile);
                        }
                    }
                    else
                    {
                        throw new ApplicationException("Something appears to have failed during unit testing, because no result file was found.");
                    }
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }

            if (!config.NoDocs)
            {
                Console.WriteLine("================================== Build Docs =================================");
                {
                    bool buildSuccess = BuildVisualStudioSolution(config.DocSolutionPath, "Release");
                    if (!buildSuccess)
                    {
                        throw new ApplicationException("Documentation Build Failure");
                    }

                    Console.WriteLine("Documentation Build Successful");
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }

            // Build all NuGet Packages
            Console.WriteLine("============================= Build NuGet Packages ============================");
            {
                bool nugetFound      = File.Exists(config.NuGetPath);
                bool nugetSpecsFound = Directory.Exists(config.NuGetPackageSpecsDir);
                if (nugetFound && nugetSpecsFound)
                {
                    if (!Directory.Exists(config.NuGetPackageTargetDir))
                    {
                        Directory.CreateDirectory(config.NuGetPackageTargetDir);
                    }

                    Console.WriteLine("Determining package data from '{0}'...", config.NuGetPackageSpecsDir);
                    Dictionary <string, string> packageVersions = new Dictionary <string, string>();
                    foreach (string file in Directory.EnumerateFiles(config.NuGetPackageSpecsDir, "*.nuspec", SearchOption.AllDirectories))
                    {
                        Console.Write("  {0}: ", Path.GetFileName(file));

                        string    fileAbs     = Path.GetFullPath(file);
                        XDocument doc         = XDocument.Load(fileAbs);
                        XElement  elemId      = doc.Descendants("id").FirstOrDefault();
                        XElement  elemVersion = doc.Descendants("version").FirstOrDefault();

                        string id      = elemId.Value.Trim();
                        string version = elemVersion.Value.Trim();
                        packageVersions[id] = version;

                        Console.WriteLine("{0}", version);
                    }

                    Console.WriteLine();
                    Console.WriteLine("Creating packages from '{0}'...", config.NuGetPackageSpecsDir);
                    foreach (string file in Directory.EnumerateFiles(config.NuGetPackageSpecsDir, "*.nuspec", SearchOption.AllDirectories))
                    {
                        Console.Write("  {0}... ", Path.GetFileName(file));

                        string    fileAbs = Path.GetFullPath(file);
                        XDocument doc     = XDocument.Load(fileAbs);

                        bool skip = false;
                        foreach (XElement elemDependency in doc.Descendants("dependency"))
                        {
                            string id      = elemDependency.Attribute("id").Value.Trim();
                            string version = elemDependency.Attribute("version").Value.Trim();
                            string developedAgainstVersion;
                            if (packageVersions.TryGetValue(id, out developedAgainstVersion))
                            {
                                if (version != developedAgainstVersion)
                                {
                                    skip = true;
                                    break;
                                }
                            }
                        }

                        if (skip)
                        {
                            Console.ForegroundColor = ConsoleColor.Yellow;
                            Console.WriteLine("dependency mismatch (skip)");
                            Console.ResetColor();
                            continue;
                        }

                        XElement elemId         = doc.Descendants("id").FirstOrDefault();
                        XElement elemVersion    = doc.Descendants("version").FirstOrDefault();
                        string   targetFileName = string.Format("{0}.{1}.nupkg", elemId.Value.Trim(), elemVersion.Value.Trim());
                        string   packResult     = ExecuteCommand(Path.GetFullPath(config.NuGetPath) + " pack " + fileAbs, config.NuGetPackageTargetDir, false);

                        if (!File.Exists(Path.Combine(config.NuGetPackageTargetDir, targetFileName)))
                        {
                            string errorMessage = string.Format(
                                "Failed to create NuGet Package {0}:" + Environment.NewLine + "{1}",
                                Path.GetFileName(file),
                                packResult);

                            // If in non-interactive mode, continue to build packages even if one of them failed.
                            if (config.NonInteractive)
                            {
                                Console.ForegroundColor = ConsoleColor.Red;
                                Console.WriteLine("failed");
                                Console.WriteLine(errorMessage);
                                Console.ForegroundColor = ConsoleColor.Gray;
                            }
                            // Otherwise, stop with an exception.
                            else
                            {
                                throw new ApplicationException(errorMessage);
                            }
                        }
                        else
                        {
                            Console.WriteLine("done");
                        }
                    }
                }
                else if (!nugetFound)
                {
                    throw new ApplicationException(string.Format("Can't find NuGet command line tool '{0}'.", config.NuGetPath));
                }
                else if (!nugetSpecsFound)
                {
                    throw new ApplicationException(string.Format("Can't find NuGet package specs directory '{0}'.", config.NuGetPackageSpecsDir));
                }
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            Console.WriteLine("Finished Build.");
            if (!config.NonInteractive)
            {
                Console.ReadLine();
            }
        }
Beispiel #4
0
        public static void Main(string[] args)
        {
            ConfigFile config = ConfigFile.Load("BuildConfig.xml");

            // Parse command line arguments
            PropertyInfo[]         configProps    = typeof(ConfigFile).GetProperties();
            HashSet <PropertyInfo> configOverride = new HashSet <PropertyInfo>();

            foreach (string arg in args)
            {
                string[] token = arg.Split('=');
                if (token.Length != 2)
                {
                    continue;
                }

                PropertyInfo prop = configProps.FirstOrDefault(p => p.Name.ToLower() == token[0].Trim().ToLower());
                if (prop == null)
                {
                    continue;
                }

                object value = null;
                try
                {
                    value = Convert.ChangeType(token[1].Trim(), prop.PropertyType, System.Globalization.CultureInfo.InvariantCulture);
                }
                catch {}
                if (value == null)
                {
                    continue;
                }

                prop.SetValue(config, value, null);
                configOverride.Add(prop);
            }

            try
            {
                // Resolve tool paths
                config.NuGetPath = FindToolPath(config.NuGetPath);

                // Write some initial data
                Console.WriteLine("===================================== Init ====================================");
                {
                    Console.WriteLine("NightlyBuilder launched");
                    Console.WriteLine("Working Dir: {0}", Environment.CurrentDirectory);
                    Console.WriteLine("Command Line: {0}", args.Aggregate("", (acc, arg) => acc + " " + arg));
                    Console.WriteLine("Config:");
                    foreach (PropertyInfo prop in configProps)
                    {
                        if (configOverride.Contains(prop))
                        {
                            Console.ForegroundColor = ConsoleColor.White;
                        }
                        Console.WriteLine("  {0}: {1}", prop.Name, prop.GetValue(config, null));
                        Console.ForegroundColor = ConsoleColor.Gray;
                    }
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();

                // Run the build
                PerformNightlyBuild(config);
            }
            catch (Exception e)
            {
                Console.WriteLine();
                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("ERROR: {0}", e);
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.WriteLine();
                if (config.NonInteractive)
                {
                    Environment.Exit(1);
                }
                else
                {
                    Console.ReadLine();
                }
            }

            Environment.Exit(0);
        }
Beispiel #5
0
        public static void PerformNightlyBuild(ConfigFile config)
        {
            string          packagePath     = Path.Combine(config.PackageDir, config.PackageName);
            FileVersionInfo versionCore     = null;
            FileVersionInfo versionEditor   = null;
            FileVersionInfo versionLauncher = null;

            // Build the target Solution
            Console.WriteLine("================================ Build Solution ===============================");
            {
                bool buildSuccess = BuildVisualStudioSolution(config.SolutionPath, "Release");
                if (!buildSuccess)
                {
                    throw new ApplicationException("The project doesn't compile properly. Cannot proceed in this state.");
                }

                versionCore     = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "Duality.dll"));
                versionEditor   = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "DualityEditor.exe"));
                versionLauncher = FileVersionInfo.GetVersionInfo(Path.Combine(config.BuildResultDir, "DualityLauncher.exe"));

                Console.WriteLine("Build Successful");
                Console.WriteLine("  Core Version:     {0}", versionCore.FileVersion);
                Console.WriteLine("  Editor Version:   {0}", versionEditor.FileVersion);
                Console.WriteLine("  Launcher Version: {0}", versionLauncher.FileVersion);
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Perform unit testing
            Console.WriteLine("================================= Unit Testing ================================");
            {
                foreach (string nunitProjectFile in Directory.EnumerateFiles(config.UnitTestProjectDir, "*.nunit", SearchOption.TopDirectoryOnly))
                {
                    Console.Write("Testing '{0}'... ", Path.GetFileName(nunitProjectFile));

                    // Don't use /timeout, as it will execute tests from a different thread,
                    // which will break a lot of graphics-related Duality stuff!
                    string resultFile = "UnitTestResult.xml";
                    ExecuteCommand(
                        string.Format("{0} {1} /result={2}",
                                      Path.Combine(config.NUnitBinDir, "nunit-console.exe"),
                                      nunitProjectFile,
                                      resultFile),
                        verbose: false);

                    if (File.Exists(resultFile))
                    {
                        bool        unitTestFailed = false;
                        XmlDocument resultDoc      = new XmlDocument();
                        resultDoc.Load(resultFile);

                        Stack <XmlElement> elementStack = new Stack <XmlElement>();
                        elementStack.Push(resultDoc["test-results"]);
                        do
                        {
                            XmlElement   currentElement   = elementStack.Pop();
                            XmlAttribute successAttribute = currentElement.Attributes["success"];

                            if (successAttribute == null)
                            {
                                foreach (XmlElement child in currentElement.OfType <XmlElement>().Reverse())
                                {
                                    elementStack.Push(child);
                                }
                            }
                            else
                            {
                                bool success = (successAttribute == null) || XmlConvert.ToBoolean(successAttribute.Value.ToLower());
                                if (!success)
                                {
                                    unitTestFailed = true;
                                    break;
                                }
                            }
                        } while (elementStack.Count > 0);

                        if (unitTestFailed)
                        {
                            ExecuteBackgroundCommand(resultFile);
                            ExecuteBackgroundCommand(
                                string.Format("{0} {1}",
                                              Path.Combine(config.NUnitBinDir, "nunit.exe"),
                                              nunitProjectFile));
                            throw new ApplicationException(string.Format("At least one unit test has failed. See {0} for more information.", resultFile));
                        }
                        else
                        {
                            Console.WriteLine("success!");
                            File.Delete(resultFile);
                        }
                    }
                    else
                    {
                        throw new ApplicationException("Something appears to have failed during unit testing, because no result file was found.");
                    }
                }
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Build the documentation
            bool includeDocs =
                !string.IsNullOrWhiteSpace(config.DocBuildResultDir) &&
                !string.IsNullOrWhiteSpace(config.DocBuildResultFile);

            if (!config.NoDocs)
            {
                Console.WriteLine("================================== Build Docs =================================");
                {
                    bool buildSuccess = BuildVisualStudioSolution(config.DocSolutionPath, "Release");
                    if (!buildSuccess)
                    {
                        throw new ApplicationException("Documentation Build Failure");
                    }

                    Console.WriteLine("Documentation Build Successful");

                    if (includeDocs)
                    {
                        File.Copy(
                            Path.Combine(config.DocBuildResultDir, config.DocBuildResultFile),
                            Path.Combine(config.BuildResultDir, config.DocBuildResultFile),
                            true);
                        Console.WriteLine("Documentation copied to build directory");
                    }
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }
            else if (includeDocs && File.Exists(Path.Combine(config.DocBuildResultDir, config.DocBuildResultFile)))
            {
                Console.WriteLine("============================== Copy existing Docs =============================");
                {
                    File.Copy(
                        Path.Combine(config.DocBuildResultDir, config.DocBuildResultFile),
                        Path.Combine(config.BuildResultDir, config.DocBuildResultFile),
                        true);
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }

            // Copy the results to the target directory
            Console.WriteLine("================================ Copy to Target ===============================");
            {
                Console.WriteLine("Creating target directory '{0}'", config.IntermediateTargetDir);
                if (Directory.Exists(config.IntermediateTargetDir))
                {
                    Directory.Delete(config.IntermediateTargetDir, true);
                }
                CopyDirectory(config.BuildResultDir, config.IntermediateTargetDir, true, path =>
                {
                    string fileName = Path.GetFileName(path);
                    foreach (string blackListEntry in config.FileCopyBlackList)
                    {
                        if (Regex.IsMatch(fileName, WildcardToRegex(blackListEntry), RegexOptions.IgnoreCase))
                        {
                            Console.ForegroundColor = ConsoleColor.DarkGray;
                            Console.WriteLine("Ignore {0}", path);
                            Console.ForegroundColor = ConsoleColor.Gray;
                            return(false);
                        }
                    }
                    Console.WriteLine("Copy   {0}", path);
                    return(true);
                });
                if (!string.IsNullOrEmpty(config.AdditionalFileDir) && Directory.Exists(config.AdditionalFileDir))
                {
                    CopyDirectory(config.AdditionalFileDir, config.IntermediateTargetDir, true);
                }
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Create the ZIP package
            Console.WriteLine("============================== Create ZIP Package =============================");
            {
                Console.WriteLine("Package Path: {0}", packagePath);
                if (!Directory.Exists(config.PackageDir))
                {
                    Directory.CreateDirectory(config.PackageDir);
                }

                ZipFile  package = new ZipFile();
                string[] files   = Directory.GetFiles(config.IntermediateTargetDir, "*", SearchOption.AllDirectories);
                package.AddFiles(files);
                package.Save(packagePath);
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Cleanup
            Console.WriteLine("=================================== Cleanup ===================================");
            {
                Console.WriteLine("Deleting target directory '{0}'", config.IntermediateTargetDir);
                if (Directory.Exists(config.IntermediateTargetDir))
                {
                    Directory.Delete(config.IntermediateTargetDir, true);
                }
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Build all NuGet Packages
            Console.WriteLine("============================= Build NuGet Packages ============================");
            {
                bool nugetFound      = File.Exists(config.NuGetPath);
                bool nugetSpecsFound = Directory.Exists(config.NuGetPackageSpecsDir);
                if (nugetFound && nugetSpecsFound)
                {
                    if (!Directory.Exists(config.NuGetPackageTargetDir))
                    {
                        Directory.CreateDirectory(config.NuGetPackageTargetDir);
                    }

                    Console.WriteLine("Deleting old package files in '{0}'...", config.NuGetPackageTargetDir);
                    foreach (string file in Directory.EnumerateFiles(config.NuGetPackageTargetDir, "*.nupkg", SearchOption.TopDirectoryOnly))
                    {
                        File.Delete(file);
                    }

                    Console.WriteLine("Determining package data from '{0}'...", config.NuGetPackageSpecsDir);
                    Dictionary <string, Version> packageVersions = new Dictionary <string, Version>();
                    foreach (string file in Directory.EnumerateFiles(config.NuGetPackageSpecsDir, "*.nuspec", SearchOption.AllDirectories))
                    {
                        Console.Write("  {0}: ", Path.GetFileName(file));

                        string    fileAbs     = Path.GetFullPath(file);
                        XDocument doc         = XDocument.Load(fileAbs);
                        XElement  elemId      = doc.Descendants("id").FirstOrDefault();
                        XElement  elemVersion = doc.Descendants("version").FirstOrDefault();

                        string  id      = elemId.Value.Trim();
                        Version version = Version.Parse(elemVersion.Value.Trim());
                        packageVersions[id] = version;

                        Console.WriteLine("{0}", version);
                    }

                    Console.WriteLine();
                    Console.WriteLine("Creating packages from '{0}'...", config.NuGetPackageSpecsDir);
                    foreach (string file in Directory.EnumerateFiles(config.NuGetPackageSpecsDir, "*.nuspec", SearchOption.AllDirectories))
                    {
                        Console.Write("  {0}... ", Path.GetFileName(file));

                        string    fileAbs = Path.GetFullPath(file);
                        XDocument doc     = XDocument.Load(fileAbs);

                        bool skip = false;
                        foreach (XElement elemDependency in doc.Descendants("dependency"))
                        {
                            string  id      = elemDependency.Attribute("id").Value.Trim();
                            Version version = Version.Parse(elemDependency.Attribute("version").Value.Trim());
                            Version developedAgainstVersion;
                            if (packageVersions.TryGetValue(id, out developedAgainstVersion))
                            {
                                if (version != developedAgainstVersion)
                                {
                                    skip = true;
                                    break;
                                }
                            }
                        }

                        if (skip)
                        {
                            Console.ForegroundColor = ConsoleColor.Yellow;
                            Console.WriteLine("dependency mismatch (skip)");
                            Console.ResetColor();
                            continue;
                        }

                        XElement elemId         = doc.Descendants("id").FirstOrDefault();
                        XElement elemVersion    = doc.Descendants("version").FirstOrDefault();
                        string   targetFileName = string.Format("{0}.{1}.nupkg", elemId.Value.Trim(), elemVersion.Value.Trim());
                        ExecuteCommand(Path.GetFullPath(config.NuGetPath) + " pack " + fileAbs, config.NuGetPackageTargetDir, false);

                        if (!File.Exists(Path.Combine(config.NuGetPackageTargetDir, targetFileName)))
                        {
                            throw new ApplicationException(string.Format("Failed to create NuGet Package {0}", Path.GetFileName(file)));
                        }
                        else
                        {
                            Console.WriteLine("done");
                        }
                    }
                }
                else if (!nugetFound)
                {
                    throw new ApplicationException(string.Format("Can't find NuGet command line tool '{0}'.", config.NuGetPath));
                }
                else if (!nugetSpecsFound)
                {
                    throw new ApplicationException(string.Format("Can't find NuGet package specs directory '{0}'.", config.NuGetPackageSpecsDir));
                }
            }
            Console.WriteLine("===============================================================================");
            Console.WriteLine();
            Console.WriteLine();

            // Copy ZIP Package
            if (!string.IsNullOrWhiteSpace(config.CopyPackageTo))
            {
                Console.WriteLine("=============================== Copy ZIP Package ==============================");
                {
                    Console.WriteLine("Copying package to '{0}'", config.CopyPackageTo);
                    if (!Directory.Exists(config.CopyPackageTo))
                    {
                        Directory.CreateDirectory(config.CopyPackageTo);
                    }
                    File.Copy(packagePath, Path.Combine(config.CopyPackageTo, config.PackageName), true);
                }
                Console.WriteLine("===============================================================================");
                Console.WriteLine();
                Console.WriteLine();
            }

            Console.WriteLine("Finished Build.");
            Console.ReadLine();
        }