/// <summary> /// Runs the given Build Stage /// </summary> /// <returns></returns> public bool Execute() { try { // Start stage timer _stopwatch = Stopwatch.StartNew(); Console.ForegroundColor = Color.WhiteSmoke; Misc.WriteMainHeader("SlugCI:: " + Name); // Set log level to std. Let the process override if necessary. Logger.LogLevel = LogLevel.Normal; if (ShouldSkip) { AOT_Warning("Stage skipped due to skip stage setting being set."); CompletionStatus = StageCompletionStatusEnum.Skipped; _stopwatch.Stop(); return(true); } CompletionStatus = StageCompletionStatusEnum.InProcess; Finished(ExecuteProcess()); string finalMsg = String.Format("Stage Result: {0}", CompletionStatus.ToString()); Color lineColor = CompletionStatus switch { StageCompletionStatusEnum.Success => Color.Green, StageCompletionStatusEnum.Skipped => Color.Cyan, StageCompletionStatusEnum.Warning => Color.Yellow, _ => Color.Red, }; AOT_Normal(finalMsg, lineColor); // Return success / Failure result if (CompletionStatus >= StageCompletionStatusEnum.Warning) { return(true); } } catch (ProcessException p) { CompletionStatus = StageCompletionStatusEnum.Failure; AOT_Error(p); //Logger.Error(p,true); } catch (Exception e) { CompletionStatus = StageCompletionStatusEnum.Failure; AOT_Error(e); //Logger.Error(e); } return(false); }
/// <summary> /// Writes all the lineout to the console. /// </summary> public void WriteLines() { Misc.WriteMainHeader("SlugCI Initialization of Repository"); foreach (LineOutColored lineOut in LineOutput) { lineOut.WriteToConsole(); } }
/// <summary> /// Validate all required dependencies are installed. /// </summary> /// <returns></returns> public bool Validate() { Misc.WriteMainHeader("Validate:", new List <string>() { "Confirm dependencies are installed and working" }); // TODO - Check for Typewriter and NPM bool success = true; return(success); }
/// <summary> /// Constructor /// </summary> public SlugBuilder(CISession ciSession) { Misc.WriteMainHeader("SlugBuilder:: Startup"); CISession = ciSession; GitProcessorStartup(); // Setup Build Execution Plan based upon caller's Final Build Request Target // Pretend it was compile Console.ForegroundColor = Color.WhiteSmoke; LoadBuildStages(); // TODO Remove or comment this out, this is for speeding up testing. #if DEBUG bool calcVersionSkipped = false; foreach (BuildStage stage in _executionPlan.KnownStages) { /* * //if ( stage.Name != BuildStageStatic.STAGE_TYPEWRITER_PUBLISH && stage.Name != BuildStageStatic.STAGE_TYPEWRITER_VER) stage.ShouldSkip = true; * if ( stage.Name != BuildStageStatic.STAGE_PUBLISH ) stage.ShouldSkip = true; * if ( stage.Name != BuildStageStatic.STAGE_TYPEWRITER_PUBLISH && * stage.Name != BuildStageStatic.STAGE_TYPEWRITER_VER && * stage.Name != BuildStageStatic.STAGE_PUBLISH) stage.ShouldSkip = true; * * * // Leave this in - it determines if we will have a version calculated. If not, then it manually sets one, so steps can complete. * if (stage.Name == BuildStageStatic.STAGE_CALCVERSION) * ciSession.VersionInfo = new VersionInfo(new SemVersion(3, 56, 43), "656gtg"); */ } #endif _executionPlan.BuildExecutionPlan(BuildStageStatic.STAGE_FINAL); // Anything less than skipped indicates an error situation. StageCompletionStatusEnum planStatus = _executionPlan.Execute(); WriteSummary(_executionPlan, CISession.IsInteractiveRun, ciSession); // TODO Move this somewhere... // BuildStage_TypeWriterPublish tw = (BuildStage_TypeWriterPublish) _executionPlan.GetBuildStage(BuildStageStatic.STAGE_TYPEWRITER_PUBLISH); // foreach ( LineOut output in tw.StageOutput ) { Console.WriteLine(output); } }
/// <summary> /// Displays information about the solution, its projects, git repo, etc. /// </summary> public void DisplayInfo() { List <string> info = new List <string>() { "SlugCI Version: " + GetType().Assembly.GetName().Version.ToString() }; Misc.WriteMainHeader(CISession.Solution.Name + ":: SlugCI / Repository Info", info); Console.Write(" {0,-25}", "Project Root:", Color.WhiteSmoke); Console.WriteLine(CISession.RootDirectory, Color.Cyan); Console.Write(" {0,-25}", "Source Folder:", Color.WhiteSmoke); Console.WriteLine(CISession.SourceDirectory, Color.Cyan); Console.Write(" {0,-25}", "Tests Folder:", Color.WhiteSmoke); Console.WriteLine(CISession.TestsDirectory, Color.Cyan); Console.Write(" {0,-25}", "Output Folder:", Color.WhiteSmoke); Console.WriteLine(CISession.OutputDirectory, Color.Cyan); Console.Write(" {0,-25}", "Solution At:", Color.WhiteSmoke); Console.WriteLine(CISession.Solution.Path, Color.Cyan); Console.Write(" {0,-25}", "Nuget API Key:", Color.WhiteSmoke); Console.WriteLine(CISession.NugetAPIKey, Color.Cyan); Console.Write(" {0,-25}", "Nuget Repo URL:", Color.WhiteSmoke); Console.WriteLine(CISession.NugetRepoURL, Color.Cyan); Console.WriteLine(); Console.WriteLine("-------------------------------------------------------------", Color.DarkCyan); Console.WriteLine(" GIT Information", Color.DarkCyan); Console.WriteLine("-------------------------------------------------------------", Color.DarkCyan); Console.Write(" {0,-25}", "Main Branch Name:", Color.WhiteSmoke); Console.WriteLine(CISession.GitProcessor.MainBranchName, Color.Cyan); Console.Write(" {0,-25}", "Current Branch Name:", Color.WhiteSmoke); Console.WriteLine(CISession.GitProcessor.CurrentBranch, Color.Cyan); Console.Write(" {0,-25}", "Git CommandLine Version:", Color.WhiteSmoke); Console.WriteLine(CISession.GitProcessor.GitCommandVersion, Color.Cyan); Console.WriteLine(); Console.WriteLine("-------------------------------------------------------------", Color.DarkCyan); Console.WriteLine(" Environment Variables", Color.DarkCyan); Console.WriteLine("-------------------------------------------------------------", Color.DarkCyan); Console.WriteLine(" Required: ", Color.Green); foreach (KeyValuePair <string, string> envVar in CISession.EnvironmentVariables) { Console.Write(" {0,-35} | ", envVar.Key, Color.WhiteSmoke); Console.WriteLine("{0,-60}", envVar.Value, Color.DarkCyan); } Console.WriteLine(Environment.NewLine + " Missing Required:", Color.Red); foreach (string envVar in CISession.MissingEnvironmentVariables) { Console.WriteLine(" {0,-35}", envVar, Color.WhiteSmoke); } Console.WriteLine(); Console.WriteLine("-------------------------------------------------------------", Color.DarkCyan); Console.WriteLine(" Project Info", Color.DarkCyan); Console.WriteLine("-------------------------------------------------------------", Color.DarkCyan); Console.WriteLine(" {0,-60}{1,-10} {2,-18} {3,-30}", "Project", "How Deployed", "Framework", "Assembly Name", Color.Magenta); foreach (SlugCIProject project in CISession.Projects) { foreach (string projectFramework in project.Frameworks) { Console.WriteLine(" {0,-60} {1,-10} {2,-18} {3,-30}", project.Name, project.Deploy.ToString(), projectFramework, project.AssemblyName, Color.WhiteSmoke); } } if (CISession.IsInteractiveRun) { while (Console.KeyAvailable) { Console.ReadKey(true); } Console.WriteLine("{0}Press Any key to continue", Environment.NewLine, Color.WhiteSmoke); Console.ReadKey(); } }
/// <summary> /// Allow user to choose where they are deploying too. /// </summary> /// <param name="ciSession"></param> private static void PromptForDeployTarget(CISession ciSession) { Console.WriteLine(Environment.NewLine); Color lineColor = Color.WhiteSmoke; ConsoleKey defaultChoice = ConsoleKey.Enter; List <string> help = new List <string>() { "Where you are deploying the build" }; Misc.WriteMainHeader("Deploy Target", help); // Production lineColor = Color.WhiteSmoke; if (ciSession.PublishTarget == PublishTargetEnum.Production) { lineColor = Color.Green; defaultChoice = ConsoleKey.P; } else { lineColor = Color.WhiteSmoke; } Console.WriteLine("(P) Production or main / master", lineColor); // Alpha lineColor = Color.WhiteSmoke; if (ciSession.PublishTarget == PublishTargetEnum.Alpha) { lineColor = Color.Green; defaultChoice = ConsoleKey.A; } else { lineColor = Color.WhiteSmoke; } Console.WriteLine("(A) Alpha or Test", lineColor); // Beta lineColor = Color.WhiteSmoke; if (ciSession.PublishTarget == PublishTargetEnum.Beta) { lineColor = Color.Green; defaultChoice = ConsoleKey.B; } else { lineColor = Color.WhiteSmoke; } Console.WriteLine("(B) Beta / Test", lineColor); // Set Valid Keys List <ConsoleKey> validKeys = new List <ConsoleKey>() { ConsoleKey.A, ConsoleKey.B, ConsoleKey.P }; ConsoleKey choice = PromptAndGetResponse(defaultChoice, validKeys); if (choice == ConsoleKey.A) { ciSession.PublishTarget = PublishTargetEnum.Alpha; } else if (choice == ConsoleKey.B) { ciSession.PublishTarget = PublishTargetEnum.Beta; } else { ciSession.PublishTarget = PublishTargetEnum.Production; } }
/// <summary> /// Allow user to choose where they are deploying too. /// </summary> /// <param name="ciSession"></param> private static void PromptForConfiguration(CISession ciSession) { Console.Clear(); Console.WriteLine(Environment.NewLine); Color lineColor = Color.WhiteSmoke; ConsoleKey defaultChoice = ConsoleKey.Enter; List <string> help = new List <string>() { "Usually Release or Debug" }; Misc.WriteMainHeader("Configuration to Compile", help); // Release lineColor = Color.WhiteSmoke; if (ciSession.CompileConfig == "Release") { lineColor = Color.Green; defaultChoice = ConsoleKey.R; } else { lineColor = Color.WhiteSmoke; } Console.WriteLine("(R) Release", lineColor); // Debug lineColor = Color.WhiteSmoke; if (ciSession.CompileConfig == "Debug") { lineColor = Color.Green; defaultChoice = ConsoleKey.D; } else { lineColor = Color.WhiteSmoke; } Console.WriteLine("(D) Debug", lineColor); // Other lineColor = Color.WhiteSmoke; if (ciSession.CompileConfig != "Debug" && ciSession.CompileConfig != "Release") { lineColor = Color.Green; defaultChoice = ConsoleKey.O; Console.WriteLine("(O) Other - " + ciSession.CompileConfig, lineColor); } // Set Valid Keys List <ConsoleKey> validKeys = new List <ConsoleKey>() { ConsoleKey.R, ConsoleKey.D, ConsoleKey.O }; ConsoleKey choice = PromptAndGetResponse(defaultChoice, validKeys); if (choice == ConsoleKey.R) { ciSession.CompileConfig = "Release"; } else if (choice == ConsoleKey.D) { ciSession.CompileConfig = "Debug"; } else { ciSession.CompileConfig = ciSession.CompileConfig; } }
/// <summary> /// Allows user to change the next version of the app - manually. /// </summary> /// <param name="ciSession"></param> /// <param name="slugCi"></param> private static void ManualVersionPrompts(CISession ciSession, SlugCI slugCi) { Misc.WriteMainHeader("Set Version Override"); Console.ForegroundColor = Color.WhiteSmoke; Console.WriteLine(); Console.WriteLine("This allows you to manually set the primary version numbers of the application for the branch being deployed to."); Console.WriteLine(); Console.WriteLine("You are currently targeting a build to: {0}", ciSession.PublishTarget.ToString()); bool continueLooping = true; PublishTargetEnum target = ciSession.PublishTarget; string branchName = target switch { PublishTargetEnum.Alpha => "alpha", PublishTargetEnum.Beta => "beta", PublishTargetEnum.Production => ciSession.GitProcessor.MainBranchName, }; SemVersion currentMaxVersion = ciSession.GitProcessor.GetMostRecentVersionTagOfBranch(branchName); SemVersion newManualVersion = new SemVersion(0, 0, 0); Console.WriteLine("{0}The latest version on this Branch is: {1}", Environment.NewLine, currentMaxVersion); if (target == PublishTargetEnum.Production) { Console.WriteLine(" (1) To bump the Major version number from {0} to {1}", currentMaxVersion.Major, currentMaxVersion.Major + 1); Console.WriteLine(" (2) To bump the Minor version number from {0} to {1}", currentMaxVersion.Minor, currentMaxVersion.Minor + 1); Console.WriteLine(" (3) To bump the Patch number from {0} to {1}", currentMaxVersion.Patch, currentMaxVersion.Patch + 1); Console.WriteLine(" (9) To change all 3 components at once."); while (continueLooping) { ConsoleKeyInfo keyInfo = Console.ReadKey(); if (keyInfo.Key == ConsoleKey.D3) { newManualVersion = new SemVersion(currentMaxVersion.Major, currentMaxVersion.Minor, currentMaxVersion.Patch + 1); } else if (keyInfo.Key == ConsoleKey.D2) { newManualVersion = new SemVersion(currentMaxVersion.Major, currentMaxVersion.Minor + 1, 0); } else if (keyInfo.Key == ConsoleKey.D1) { newManualVersion = new SemVersion(currentMaxVersion.Major + 1, 0, 0); } else if (keyInfo.Key == ConsoleKey.D9) { Console.WriteLine("Enter X to exit without changing version OR enter Version number in format #.#.#"); string manVer = Console.ReadLine(); if (manVer == "x" || manVer == "X") { return; } // Change Version if (slugCi.SetVersionManually(manVer)) { continueLooping = false; } } else { continue; } break; } Console.WriteLine("{0} Y/N? Do you want to set the version for branch {1} to version # {2}", Environment.NewLine, branchName, newManualVersion.ToString()); while (true) { while (Console.KeyAvailable) { Console.ReadKey(); } ConsoleKeyInfo keyInfoPYN = Console.ReadKey(true); if (keyInfoPYN.Key == ConsoleKey.Y) { ciSession.ManuallySetVersion = newManualVersion; return; } else if (keyInfoPYN.Key == ConsoleKey.N) { return; } } } // Alpha / Beta branch else { SemVersionPreRelease svpr; if (currentMaxVersion.Prerelease != string.Empty) { svpr = new SemVersionPreRelease(currentMaxVersion.Prerelease); } else { svpr = new SemVersionPreRelease(branchName, 0, IncrementTypeEnum.Patch); } Console.WriteLine(" (1) To bump the Major version number from {0} to {1}", currentMaxVersion.Major, currentMaxVersion.Major + 1); Console.WriteLine(" (2) To bump the Minor version number from {0} to {1}", currentMaxVersion.Minor, currentMaxVersion.Minor + 1); Console.WriteLine(" (3) To bump the Patch number from {0} to {1}", currentMaxVersion.Patch, currentMaxVersion.Patch + 1); Console.WriteLine(" (4) To bump the pre-release number from {0} to {1}", svpr.ReleaseNumber, svpr.ReleaseNumber + 1); Console.WriteLine(" (9) To change all 3 components at once."); while (continueLooping) { while (Console.KeyAvailable) { Console.ReadKey(); } ConsoleKeyInfo keyInfo = Console.ReadKey(true); if (keyInfo.Key == ConsoleKey.D3) { svpr = new SemVersionPreRelease(branchName, 0, IncrementTypeEnum.Patch); newManualVersion = new SemVersion(currentMaxVersion.Major, currentMaxVersion.Minor, currentMaxVersion.Patch + 1, svpr.Tag()); } else if (keyInfo.Key == ConsoleKey.D2) { svpr = new SemVersionPreRelease(branchName, 0, IncrementTypeEnum.Minor); newManualVersion = new SemVersion(currentMaxVersion.Major, currentMaxVersion.Minor + 1, 0, svpr.Tag()); //svpr.BumpMinor(); } else if (keyInfo.Key == ConsoleKey.D1) { svpr = new SemVersionPreRelease(branchName, 0, IncrementTypeEnum.Major); newManualVersion = new SemVersion(currentMaxVersion.Major + 1, 0, 0, svpr.Tag()); //svpr.BumpMajor(); } else if (keyInfo.Key == ConsoleKey.D4) { newManualVersion = currentMaxVersion; svpr.BumpVersion(); } else if (keyInfo.Key == ConsoleKey.D9) { Console.WriteLine("Enter X to exit without changing version OR enter Version number in format #.#.#"); string manVer = Console.ReadLine(); if (manVer == "x" || manVer == "X") { return; } if (!SemVersion.TryParse(manVer, out SemVersion newVer)) { continue; } svpr = new SemVersionPreRelease(branchName, 0, IncrementTypeEnum.None); newManualVersion = new SemVersion(newVer.Major, newVer.Minor, newVer.Patch, svpr.Tag()); } else { continue; } break; } newManualVersion = new SemVersion(newManualVersion.Major, newManualVersion.Minor, newManualVersion.Patch, svpr.Tag()); Console.WriteLine("{0}Y/N? Do you want to set the version for branch {1} to version # {2}", Environment.NewLine, branchName, newManualVersion.ToString()); while (true) { while (Console.KeyAvailable) { Console.ReadKey(); } ConsoleKeyInfo keyInfoPYN = Console.ReadKey(); if (keyInfoPYN.Key == ConsoleKey.Y) { ciSession.ManuallySetVersion = newManualVersion; return; } else if (keyInfoPYN.Key == ConsoleKey.N) { return; } } } }
/// <summary> /// Displays the Main Menu for SLUGCI /// </summary> /// <param name="ciSession"></param> /// <param name="slugCi"></param> /// <returns></returns> private static bool Menu(CISession ciSession, SlugCI slugCi) { bool keepLooping = true; // Get some variables that are expensive to get, just once. string versionAlpha = ciSession.GitProcessor.GetMostRecentVersionTagOfBranch("alpha").ToString(); string versionBeta = ciSession.GitProcessor.GetMostRecentVersionTagOfBranch("beta").ToString(); string versionMain = ciSession.GitBranches[ciSession.GitProcessor.MainBranchName].LatestSemVersionOnBranch.ToString(); while (keepLooping) { Console.WriteLine(Environment.NewLine); Color lineColor = Color.WhiteSmoke; // Display Git Info / Versions of project string versionPreReleaseName = "alpha"; // Get most recent Version Tag for the desired branch type Misc.WriteSubHeader("Git Project Information"); Console.WriteLine(" {0,-25} | {1,-34}", "Current Branch", ciSession.GitProcessor.CurrentBranch); Console.WriteLine(" {0,-25} | {1,-20}", "Main Branch Name", ciSession.GitProcessor.MainBranchName); Console.WriteLine(" {0,-25} | {1,-20}", "Main Branch Version #", versionMain); Console.WriteLine(" {0,-25} | {1,-20}", "Alpha Branch Version #", versionAlpha); Console.WriteLine(" {0,-25} | {1,-20}", "Beta Branch Version #", versionBeta); Misc.WriteMainHeader("SlugCI Interactive Menu", new List <string>() { ciSession.Solution.Name }); Console.WriteLine(" {0,-30} | {1,-35}", "Target Deploy:", ciSession.PublishTarget.ToString(), lineColor); Console.WriteLine(" {0,-30} | {1,-35}", "Compile Config:", ciSession.CompileConfig, lineColor); // Menu Item Console.WriteLine(" (I) Information about Project", Color.Yellow); // Menu Item Console.WriteLine(" (G) Display Git Command History", lineColor); // Menu Item string ver = ""; if (ciSession.ManuallySetVersion != null) { ver = ciSession.ManuallySetVersion.ToString(); } lineColor = ver != string.Empty ? Color.Yellow : Color.WhiteSmoke; Console.WriteLine(" (V) Manually Set the next version [ " + ver + " ]", lineColor); Console.WriteLine(" (9) Show Next Version #", Color.WhiteSmoke); Console.WriteLine(); // Menu Item Console.WriteLine(" (C) Cleanup Git Repo"); // Menu Item if (ciSession.SkipNuget) { lineColor = Color.Yellow; } else { lineColor = Color.WhiteSmoke; } Console.WriteLine(" (S) Skip Nuget Publish [ " + ciSession.SkipNuget + " ]", lineColor); // Menu Item if (ciSession.SkipAngularBuild) { lineColor = Color.Yellow; } else { lineColor = Color.WhiteSmoke; } Console.WriteLine(" (A) Skip Angular Build & Publish [ " + ciSession.SkipAngularBuild + " ]", lineColor); // Menu Item if (ciSession.SkipTests) { lineColor = Color.Yellow; } else { lineColor = Color.WhiteSmoke; } Console.WriteLine(" (T) Skip All Test Runs [ " + ciSession.SkipTests + " ]", lineColor); // Menu Item if (ciSession.FailedUnitTestsOkay) { lineColor = Color.Yellow; } else { lineColor = Color.WhiteSmoke; } Console.WriteLine(" (U) Failed Unit Tests are okay - continue building: {0}", ciSession.FailedUnitTestsOkay, lineColor); // Menu Item if (ciSession.GitProcessor.AreUncommitedChangesOnLocalBranch) { lineColor = Color.Red; Console.WriteLine(" (R) Refresh Git (You have uncommitted changes on branch). Commit and then issue this command", lineColor); } // Last line of Menu Console.Write(" (X) Exit", Color.Red); Console.WriteLine(); // Set Valid Keys List <ConsoleKey> validKeys = new List <ConsoleKey>() { ConsoleKey.A, ConsoleKey.I, ConsoleKey.C, ConsoleKey.G, ConsoleKey.V, ConsoleKey.R, ConsoleKey.S, ConsoleKey.T, ConsoleKey.U, ConsoleKey.X, ConsoleKey.D9, ConsoleKey.Enter, }; ConsoleKey answer = PromptAndGetResponse(ConsoleKey.Enter, validKeys, "Press Enter to start the Build Process OR Select an Item"); if (answer == ConsoleKey.I) { slugCi.DisplayInfo(); } else if (answer == ConsoleKey.Enter && !ciSession.GitProcessor.AreUncommitedChangesOnLocalBranch) { return(true); } else if (answer == ConsoleKey.V) { ManualVersionPrompts(ciSession, slugCi); } else if (answer == ConsoleKey.S) { ciSession.SkipNuget = !ciSession.SkipNuget; } else if (answer == ConsoleKey.A) { ciSession.SkipAngularBuild = !ciSession.SkipAngularBuild; } else if (answer == ConsoleKey.X) { return(false); } else if (answer == ConsoleKey.R) { ciSession.GitProcessor.RefreshUncommittedChanges(); } else if (answer == ConsoleKey.T) { ciSession.SkipTests = true; } else if (answer == ConsoleKey.U) { ciSession.FailedUnitTestsOkay = true; } else if (answer == ConsoleKey.G) { ciSession.GitProcessor.PrintGitHistory(); Console.WriteLine("Press [space] key to return to menu", Color.Yellow); while (Console.ReadKey().Key != ConsoleKey.Spacebar) { } } else if (answer == ConsoleKey.D9) { BuildStage_CalcVersion calcVersion = new BuildStage_CalcVersion(ciSession); calcVersion.Execute(); Console.WriteLine("{0}{0}", Environment.NewLine); Console.WriteLine("Next version will be: ", Color.DarkCyan); Console.WriteLine(" Assembly Version: {0}", ciSession.VersionInfo.AssemblyVersion); Console.WriteLine(" File Version: {0}", ciSession.VersionInfo.FileVersion); Console.WriteLine(" Informational Version: {0}", ciSession.VersionInfo.InformationalVersion); Console.WriteLine(" SemVersion: {0}", ciSession.VersionInfo.SemVersionAsString); Console.WriteLine(" NPM Version: {0}", ciSession.VersionInfo.NPMVersion); Console.WriteLine("{0}{0}Press any key to return to menu", Environment.NewLine); Console.ReadKey(); Console.Clear(); } else if (answer == ConsoleKey.C) { BuildStage_GitCleanup gitCleanup = new BuildStage_GitCleanup(ciSession); if (!gitCleanup.Execute()) { Console.WriteLine("Git Cleanup Failed."); } else { Console.WriteLine("Git Cleanup Success!"); } Console.WriteLine("Press any key to continue"); Console.ReadKey(); } Console.Clear(); } return(true); }