Exemple #1
0
        /// <summary>
        /// Writes End of slugBuilder Summary info.
        /// </summary>
        internal virtual void WriteSummary(ExecutionPlan plan, bool isInteractive, CISession ciSession)
        {
            Console.WriteLine();
            Misc.WriteFinalHeader(plan.PlanStatus, ciSession);

            // Build dictionary of each Build Stage in order, assigning a letter to each stage.  The letter will allow user to see detailed info
            // about the stage.
            Dictionary <char, BuildStage> stageInfo = new Dictionary <char, BuildStage>();
            char letter = 'A';

            foreach (BuildStage buildStage in plan.Plan)
            {
                stageInfo.Add(letter, buildStage);
                letter++;
            }


            bool continueLooping = true;

            while (continueLooping)
            {
                // Print info for non interactive sessions
                if (!isInteractive)
                {
                    if (Logger.OutputSink.SevereMessages.Count > 0)
                    {
                        CISession.OutputSink.WriteNormal("");
                        WriteSevereMessages();
                        WriteStageStats(plan, stageInfo);
                    }
                }
                else
                {
                    CISession.OutputSink.WriteNormal("");
                    WriteStageStats(plan, stageInfo);
                    CISession.OutputSink.WriteNormal("");
                }


                // Write Version info if successful build
                if (plan.WasSuccessful)
                {
                    CISession.OutputSink.WriteSuccess($"Build succeeded on {DateTime.Now.ToString(CultureInfo.CurrentCulture)}");
                    Console.WriteLine();
                    Console.WriteLine("Version Built was: ", Color.Yellow);
                    Console.WriteLine("    Semantic Version:   " + ciSession.VersionInfo.SemVersionAsString, Color.Yellow);
                    Console.WriteLine("    Assembly Version:   " + ciSession.VersionInfo.AssemblyVersion, Color.Yellow);
                    Console.WriteLine("    File Version:       " + ciSession.VersionInfo.FileVersion, Color.Yellow);
                    Console.WriteLine("    Info Version:       " + ciSession.VersionInfo.InformationalVersion, Color.Yellow);
                }
                else
                {
                    CISession.OutputSink.WriteError($"Build failed on {DateTime.Now.ToString(CultureInfo.CurrentCulture)}");
                }


                // Exit if non-interactive as rest is user prompting and responding
                if (!isInteractive)
                {
                    return;
                }

                Console.WriteLine("Press (x) to exit, (1) to display git history  (9) to view detailed error information  OR");
                Console.WriteLine("  Press letter from above build stage to see detailed output of that build stage.");
                ConsoleKeyInfo keyInfo = Console.ReadKey();
                if (keyInfo.Key == ConsoleKey.X)
                {
                    return;
                }

                // Detailed error info
                if (keyInfo.Key == ConsoleKey.D9)
                {
                    CISession.OutputSink.WriteNormal("");
                    WriteSevereMessages();
                }

                // Git history
                if (keyInfo.Key == ConsoleKey.D1)
                {
                    ciSession.GitProcessor.PrintGitHistory();
                    Console.WriteLine("Press [space] key to return to menu", Color.Yellow);
                    while (Console.ReadKey().Key != ConsoleKey.Spacebar)
                    {
                    }
                }

                // Check to see if letter is in StageInfo Dictionary.
                char keyPress = keyInfo.KeyChar;
                if (keyPress > 96)
                {
                    keyPress = (char)(keyPress - 32);
                }


                // Display detailed info about a specific stage...
                if (stageInfo.ContainsKey(keyPress))
                {
                    // Display detailed info
                    BuildStage stage = stageInfo [keyPress];

                    Console.WriteLine();
                    Misc.WriteSubHeader(stage.Name, new List <string>()
                    {
                        "Detailed Output"
                    });
                    Color lineColor = Color.WhiteSmoke;
                    foreach (LineOutColored output in stage.StageOutput)
                    {
                        output.WriteToConsole();
                    }

                    Console.WriteLine();
                    Console.WriteLine("Press [space] key to return to menu", Color.Yellow);
                    while (Console.ReadKey().Key != ConsoleKey.Spacebar)
                    {
                    }
                }
            }
        }
Exemple #2
0
        /// <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;
            }
        }
Exemple #3
0
        /// <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;
            }
        }
Exemple #4
0
        /// <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;
                    }
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// SlugCI - An extremely opinionated Git Versioning and CI tool.
        /// </summary>
        /// <param name="rootdir">(Optional) The folder that contains the GIT Repository for the solution.</param>
        /// <param name="deployto">Where you are wanting to deploy this to.  Valid values are (dev, alpha, beta, prod)</param>
        /// <param name="compileconfig">The visual Studio Configuration value.  Standard values are Debug and Release.  But you can define your own also.
        /// <para>   If not specified then it will be set to Debug if the deployto is not production and set to Release if deployto is Production.</para></param>
        /// <param name="faststart">Skips checking the config file and updating it.  Generally should only be used when testing.</param>
        /// <param name="interactive">If True (Default) will prompt you for values.</param>
        /// <param name="skipnuget">Does not publish to nuget.  Still builds the .nupkg however.</param>
        /// <param name="info">Displays detailed information about the Solution and Environment</param>
        /// <param name="failedtestsok">If true, unit tests that fail do not stop the build from continuing</param>
        /// <param name="verbosity">Sets the verbosity of command output.  You can set value for all commands or just certain commands.  Be careful with all, it can generate a LOT of output on debug level
        /// <param name="setup">Perform initial setup of a repository</param>
        /// <param name="skipangular">Skips the Angular Build</param>
        /// <param name="skiptests">Will skip unit testing completely</param>
        /// <para>  The best is set to specific methods via:   method:value|method:value|method:value.</para>
        /// <para>  Valid methods are:</para>
        /// <para>    compile, pack, gitversion</para>
        /// <para>  Valid values are:</para>
        /// <para>    debug, warn, info</para></param>
        /// <returns></returns>
        public static async Task <int> Main(string rootdir       = "",
                                            string deployto      = "test",
                                            string compileconfig = "",
                                            bool faststart       = false,
                                            string verbosity     = "",
                                            bool interactive     = true,
                                            bool skipnuget       = false,
                                            bool failedtestsok   = false,
                                            bool info            = false,
                                            bool setup           = false,
                                            bool skipangular     = false,
                                            bool skiptests       = false)
        {
            CISession ciSession = new CISession();

            Logger.SetOutputSink(CISession.OutputSink);

            try {
                Console.SetWindowSize(130, 34);
                string slugCIVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
                Misc.WriteAppHeader(new List <string>()
                {
                    "SlugCI Version: " + slugCIVersion
                });


                // We process thru defaults, at the end if interactive is on, then we
                // prompt user for changes / confirmation

                // If no RootDir specified, then set to current directory.
                if (rootdir == string.Empty)
                {
                    ciSession.RootDirectory = (AbsolutePath)Directory.GetCurrentDirectory();
                }
                else
                {
                    ciSession.RootDirectory = (AbsolutePath)rootdir;
                }


                // Determine Deployment Target
                deployto = deployto.ToLower();
                ciSession.PublishTarget = deployto switch
                {
                    "alpha" => PublishTargetEnum.Alpha,
                    "beta" => PublishTargetEnum.Beta,
                    "dev" => PublishTargetEnum.Development,
                    "prod" => PublishTargetEnum.Production,
                    _ => PublishTargetEnum.Development,
                };


                // Set Compile Configuration.  If not specified, then we base it upon PublishTarget.  This ensure production does not have Debug code, unless specifically requested.
                if (compileconfig == string.Empty)
                {
                    DetermineCompileConfiguration(ciSession);
                }
                else
                {
                    ciSession.CompileConfig = compileconfig;
                }


                // Set the Verbosity of components
                SetVerbosity(verbosity, ciSession);


                // Set Faststart
                if (faststart == true)
                {
                    ciSession.IsFastStart = true;
                }


                // Interactive mode
                ciSession.IsInteractiveRun = interactive;


                // Skip Nuget
                ciSession.SkipNuget = skipnuget;


                // Skip Angular Web Build
                ciSession.SkipAngularBuild = skipangular;


                // Failed Unit tests are ok?
                ciSession.FailedUnitTestsOkay = failedtestsok;


                // Setup mode
                ciSession.IsInSetupMode = setup;

                // Skip unit tests
                ciSession.SkipTests = skiptests;


                // Perform Validation
                ValidateDependencies validation = new ValidateDependencies(ciSession);
                if (!validation.Validate())
                {
                    throw new ApplicationException("One or more required features is missing from this pc.");
                }

                // Create the SlugCI which is main processing class.
                SlugCI slugCI     = new SlugCI(ciSession);
                Task   slugCITask = Task.Run(slugCI.StartupAsync);

                slugCITask.Wait();

                if (!slugCI.IsReady)
                {
                    Colorful.Console.WriteLine("SlugCI Initializer is not ready to continue processing the solution.  Exiting...", Color.Red);
                    return(1);
                }


                // Interactive mode....
                if (interactive)
                {
                    UserPrompting(ciSession);
                }



                slugCI.WriteLines();

                if (interactive)
                {
                    if (!Menu(ciSession, slugCI))
                    {
                        return(1);
                    }
                }


                // If user wanted info then display it and exit.
                if (info && !interactive)
                {
                    slugCI.DisplayInfo();
                    return(0);
                }


                // Begin Executing
                slugCI.Execute();

                return(0);
            }
            catch (Exception e) {
                if (ciSession.GitProcessor != null)
                {
                    if (ciSession.GitProcessor.HasErrored)
                    {
                        ciSession.GitProcessor.PrintGitHistory();
                    }
                }
                Logger.Error(e);
            }

            return(0);
        }
Exemple #6
0
        /// <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);
        }