public void ExecutionPlan_2Stages_Success() { // A. Setup ExecutionPlan executionPlan = new ExecutionPlan(); CISession ciSession = new CISession(); const string stage_01 = "st01"; const string stage_02 = "st02"; const string stage_03 = "st03"; const string stage_04 = "st04"; // B. Build some Build Stages to test with testStageClass stage01 = new testStageClass(stage_01, ciSession); testStageClass stage02 = new testStageClass(stage_02, ciSession); // Setup predecessors stage02.AddPredecessor(stage_01); // B3 - Add to Execution plan executionPlan.AddKnownStage(stage01); executionPlan.AddKnownStage(stage02); // Test //Should be 2 steps in the plan and known stages executionPlan.BuildExecutionPlan(stage_02); // Validate Assert.AreEqual(2, executionPlan.KnownStages.Count, "A10: "); Assert.AreEqual(2, executionPlan.Plan.Count, "A20: "); // Validate the plan sequence Assert.AreEqual(stage01, executionPlan.Plan.First.Value, "A30:"); Assert.AreEqual(stage02, executionPlan.Plan.First.Next.Value, "A40:"); }
/// <summary> /// Constructor /// </summary> public BuildStage_Publish(CISession ciSession) : base(BuildStageStatic.STAGE_PUBLISH, ciSession) { // TODO Need to figure out what to do here... It could be PUBLISH OR PUBLISH TEST or do we do a post processing Execution plan...? PredecessorList.Add(BuildStageStatic.STAGE_PACK); PredecessorList.Add(BuildStageStatic.STAGE_ANGULAR); }
/// <summary> /// Prompt user for information and confirm... /// </summary> private static bool UserPrompting(CISession ciSession) { PromptForDeployTarget(ciSession); DetermineCompileConfiguration(ciSession); PromptForConfiguration(ciSession); return(true); }
/// <summary> /// Sets Compile Configuration if none specified on command line, based upon the publishing target. /// </summary> /// <param name="ciSession"></param> private static void DetermineCompileConfiguration(CISession ciSession) { if (ciSession.PublishTarget == PublishTargetEnum.Production) { ciSession.CompileConfig = "Release"; } else { ciSession.CompileConfig = "Debug"; } }
/// <summary> /// Writes The Final Status information /// </summary> public static void WriteFinalHeader(StageCompletionStatusEnum status, CISession ciSession) { Color color; Color lineColor = Color.DarkViolet; if (status == StageCompletionStatusEnum.Success) { color = Color.LimeGreen; } else if (status == StageCompletionStatusEnum.Failure || status == StageCompletionStatusEnum.Aborted) { color = Color.Red; } else { color = Color.Yellow; } Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(apphdr, lineColor); Console.WriteLine(apphdr, lineColor); Console.WriteLine("| " + "Overall Build Status: " + status, color); Console.WriteLine(apphdr, lineColor); Console.WriteLine(apphdr, lineColor); Console.WriteLine(); Console.WriteLine(hdrSep, lineColor); Console.WriteLine("| " + "Project Step Status: ", lineColor); Console.WriteLine(hdrSep, lineColor); Console.WriteLine(""); Console.WriteLine(" {0,-30} {1,-8} {2,-8} {3,-8} {4,-8}", "Project", "Deploy", "Compile", "Pack", "Publish"); foreach (SlugCIProject project in ciSession.Projects) { Console.Write(" {0,-30}", project.Name, Color.WhiteSmoke); Console.Write(" {0,-8}", project.Deploy.ToString(), Color.WhiteSmoke); string text; (text, lineColor) = WriteProjectStageStatus(project.Results.CompileSuccess); Console.Write(" {0,-8}", text, lineColor); (text, lineColor) = WriteProjectStageStatus(project.Results.PackedSuccess); Console.Write(" {0,-8}", text, lineColor); (text, lineColor) = WriteProjectStageStatus(project.Results.PublishedSuccess); Console.Write(" {0,-8}", text, lineColor); Console.ForegroundColor = Color.WhiteSmoke; Console.WriteLine(); } }
/// <summary> /// Constructor /// </summary> public PreStage_ConvertToSlugCI(CISession ciSession) : base(BuildStageStatic.PRESTAGE_CONVERT_TO_SLUGCI, ciSession) { // Set expected directories. ExpectedSolutionPath = CISession.SourceDirectory; DotNetPath = ToolPathResolver.GetPathExecutable("dotnet"); if (ciSession.IsFastStart) { // TODO - Need to restore this at some point, but needs to write to a AddOutputStage instead of screen. It interferes with prompting. // Misc.WriteSubHeader("FastStart: Skipping normal checks and validations"); } }
public void ExecutionPlan_MultiDependency_Success() { // A. Setup ExecutionPlan executionPlan = new ExecutionPlan(); CISession ciSession = new CISession(); const string stage_01 = "st01"; const string stage_02 = "st02"; const string stage_03 = "st03"; const string stage_04 = "st04"; // B. Build some Build Stages to test with testStageClass stage01 = new testStageClass(stage_01, ciSession); testStageClass stage02 = new testStageClass(stage_02, ciSession); testStageClass stage03 = new testStageClass(stage_03, ciSession); testStageClass stage04 = new testStageClass(stage_04, ciSession); // Setup predecessors stage02.AddPredecessor(stage_01); stage03.AddPredecessor(stage_02); stage04.AddPredecessor(stage_02); stage04.AddPredecessor(stage_03); // B3 - Add to Execution plan executionPlan.AddKnownStage(stage01); executionPlan.AddKnownStage(stage02); executionPlan.AddKnownStage(stage03); executionPlan.AddKnownStage(stage04); // Test //Should be 2 steps in the plan and known stages executionPlan.BuildExecutionPlan(stage_04); // Validate Assert.AreEqual(4, executionPlan.KnownStages.Count, "A10: "); Assert.AreEqual(4, executionPlan.Plan.Count, "A20: "); // Validate the plan sequence LinkedListNode <BuildStage> node = executionPlan.Plan.First; Assert.AreEqual(stage01, node.Value, "A30:"); node = node.Next; Assert.AreEqual(stage02, node.Value, "A40:"); node = node.Next; Assert.AreEqual(stage03, node.Value, "A50:"); node = node.Next; Assert.AreEqual(stage04, node.Value, "A60:"); }
/// <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> /// Constructor /// </summary> /// <param name="ciSession">The SlugCI Session object</param> public SlugCI(CISession ciSession) { LineOutput.Add(LineOutColored.NewLine()); Color lineColor = Color.WhiteSmoke; CISession = ciSession; CISession.SlugCIPath = CISession.RootDirectory / ".slugci"; CISession.SourceDirectory = CISession.RootDirectory / "src"; CISession.TestsDirectory = CISession.RootDirectory / "tests"; CISession.OutputDirectory = CISession.RootDirectory / "artifacts"; CISession.SlugCIFileName = CISession.SlugCIPath / SLUG_CI_CONFIG_FILE; CISession.AngularDirectory = CISession.RootDirectory / "angular"; CISession.CoveragePath = CISession.OutputDirectory / "Coverage"; CISession.TestOutputPath = CISession.OutputDirectory / "Tests"; ciSession.GitProcessor = new GitProcessor(ciSession); }
/// <summary> /// Constructor /// </summary> /// <param name="ciSession"></param> public GitProcessor(CISession ciSession) { CISession = ciSession; if (CISession.VerbosityGitVersion == ProcessVerbosity.Nothing) { logInvocationLogging = false; logOutputLogging = false; } else if (ciSession.VerbosityGitVersion == ProcessVerbosity.Commands) { logInvocationLogging = true; logOutputLogging = false; } else { logInvocationLogging = true; logOutputLogging = true; } }
/// <summary> /// Constructor /// </summary> public BuildStage_Clean(CISession ciSession) : base(BuildStageStatic.STAGE_CLEAN, ciSession) { }
/// <summary> /// Constructor /// </summary> public BuildStage_CalcVersion(CISession ciSession) : base(BuildStageStatic.STAGE_CALCVERSION, ciSession) { PredecessorList.Add(BuildStageStatic.STAGE_RESTORE); }
/// <summary> /// Constructor /// </summary> public BuildStage_Test(CISession ciSession) : base(BuildStageStatic.STAGE_TEST, ciSession) { PredecessorList.Add(BuildStageStatic.STAGE_COMPILE); }
/// <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); }
/// <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); }
/// <summary> /// Constructor /// </summary> public BuildStage_TypeWriterVersioning(CISession ciSession) : base(BuildStageStatic.STAGE_TYPEWRITER_VER, ciSession) { PredecessorList.Add(BuildStageStatic.STAGE_TEST); }
/// <summary> /// Constructor /// </summary> public PreStage_Initialization(CISession ciSession) : base(BuildStageStatic.PRESTAGE_INITIALIZATION, ciSession) { }
/// <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; } } } }
internal testStageClass(string name, CISession ciSession) : base(name, ciSession) { }
/// <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> /// Constructor /// </summary> public BuildStage_Compile(CISession ciSession) : base(BuildStageStatic.STAGE_COMPILE, ciSession) { PredecessorList.Add(BuildStageStatic.STAGE_CALCVERSION); }
/// <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> /// Constructor /// </summary> public BuildStage_Final(CISession ciSession) : base(BuildStageStatic.STAGE_FINAL, ciSession) { AddPredecessor(BuildStageStatic.STAGE_TYPEWRITER_PUBLISH); }
/// <summary> /// Sets verbosity of components based upon verbosity setting. /// </summary> /// <param name="verbosity"></param> /// <param name="ciSession"></param> private static void SetVerbosity(string verbosity, CISession ciSession) { if (String.IsNullOrEmpty(verbosity)) { return; } List <string> methods = verbosity.Split('|').ToList(); foreach (string method in methods) { string [] splits = method.Split(':'); if (splits.Length != 2) { throw new ArgumentException("Verbosity setting has invalid method:value combination of: " + method); } // Validate the possible values if (splits[1] != "debug" && splits[1] != "info" && splits[1] != "warn") { throw new ArgumentException("Verbosity setting has invalid value for the method: " + method); } switch (splits [0]) { case "compile": if (splits[1] == "debug") { ciSession.VerbosityCompile = DotNetVerbosity.Diagnostic; } else if (splits [1] == "info") { ciSession.VerbosityCompile = DotNetVerbosity.Normal; } else { ciSession.VerbosityCompile = DotNetVerbosity.Detailed; } break; case "pack": if (splits[1] == "debug") { ciSession.VerbosityPack = DotNetVerbosity.Diagnostic; } else if (splits[1] == "info") { ciSession.VerbosityPack = DotNetVerbosity.Normal; } else { ciSession.VerbosityPack = DotNetVerbosity.Detailed; } break; case "gitversion": if (splits[1] == "debug") { ciSession.VerbosityGitVersion = ProcessVerbosity.All; } else if (splits [1] == "info") { ciSession.VerbosityGitVersion = ProcessVerbosity.Commands; } else { ciSession.VerbosityGitVersion = ProcessVerbosity.Nothing; } break; case "calcversion": if (splits [1] == "debug") { ciSession.VerbosityCalcVersion = Verbosity.Verbose; } else { ciSession.VerbosityCalcVersion = Verbosity.Normal; } break; } } }
/// <summary> /// Constructor /// </summary> public BuildStage_GitCleanup(CISession ciSession) : base(BuildStageStatic.STAGE_GITCLEAN, ciSession) { }
/// <summary> /// Constructor /// </summary> public BuildStage_GitCommit(CISession ciSession) : base(BuildStageStatic.STAGE_GITCOMMIT, ciSession) { PredecessorList.Add(BuildStageStatic.STAGE_TEST); PredecessorList.Add(BuildStageStatic.STAGE_TYPEWRITER_VER); }
public ValidateDependencies(CISession ciSession) { CISession = ciSession; }
/// <summary> /// Constructor /// </summary> public BuildStage_TypeWriterPublish(CISession ciSession) : base(BuildStageStatic.STAGE_TYPEWRITER_PUBLISH, ciSession) { PredecessorList.Add(BuildStageStatic.STAGE_PUBLISH); }
/// <summary> /// Constructor /// </summary> /// <param name="ciSession"></param> public BuildStage_Restore(CISession ciSession) : base(BuildStageStatic.STAGE_RESTORE, ciSession) { PredecessorList.Add(BuildStageStatic.STAGE_CLEAN); }
/// <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) { } } } }