public void PerformRelease(BuildState state, AbsolutePath changeLogFile, Action <BuildType, string> buildAction) { var releaseId = Guid.NewGuid(); var releaseBranchTag = "_release-state-" + releaseId; var stagingBranchTag = "_staging-state-" + releaseId; EnsureOnReleaseStagingBranch(state); GitTools.Tag(stagingBranchTag, state.ReleaseStagingBranch); try { if (ChangeLogGenerator.TryPrepareChangeLogForRelease(state, changeLogFile, out var sectionFile)) { GitTools.Commit($"Updated change log for release {state.Version.MajorMinorPatch}"); } // record the current master branch state. // We will use that later to potentially undo any changes we made during that build. GitTools.Tag(releaseBranchTag, state.ReleaseTargetBranch); try { // this takes the current staging branch state and merges it into // the release branch (usually master). This changes the active // branch of the working copy. GitTools.MergeRelease(state.ReleaseTargetBranch, state.ReleaseStagingBranch); // attempt to build the release again. ValidateBuild(buildAction, BuildType.Release, sectionFile); } catch { Logger.Error("Error: Unable to build the release on the release branch. Attempting to roll back changes on release branch."); GitTools.Reset(GitTools.ResetType.Hard, releaseBranchTag); GitTools.Checkout(stagingBranchTag); GitTools.ResetBranch(state.ReleaseStagingBranch, stagingBranchTag); throw; } finally { GitTools.DeleteTag(releaseBranchTag); } } catch { // In case of errors, roll back all commits and restore the current state // to be back on the release-staging branch. GitTools.Checkout(stagingBranchTag); GitTools.ResetBranch(state.ReleaseStagingBranch, stagingBranchTag); throw; } finally { GitTools.DeleteTag(stagingBranchTag); } }
public void ContinueOnDevelopmentBranch(BuildState state) { EnsureNoUncommittedChanges(); GitTools.Checkout(state.DevelopmentBranch); GitTools.Merge(state.ReleaseStagingBranch); UpdateVersionNumbers?.Invoke(this, BuildType.Development); }
public void PrepareStagingBranch(BuildState state) { if (state == null) { throw new ArgumentNullException(nameof(state)); } var versionInfo = FetchVersion(); if (versionInfo.BranchName == state.ReleaseTargetBranch) { throw new Exception( $@"Cannot initiate a release from the release-target branch. Switch to a develop or release-xxx branch before continuing. Based on the current version information I expect to be on branch '{state.DevelopmentBranch}', but detected branch '{versionInfo.BranchName}' instead"); } // if on development branch, create a release branch. // if you work in a support-xx branch, treat it as your develop-branch. var stageBranchName = state.ReleaseStagingBranch; if (versionInfo.BranchName == state.DevelopmentBranch) { if (GitTools.CheckBranchExists(stageBranchName)) { Logger.Info($"Switching to existing staging branch from {versionInfo.BranchName} as branch {stageBranchName}"); GitTools.Checkout(stageBranchName); } else { Logger.Info($"Creating new staging branch from current branch {versionInfo.BranchName} as branch {stageBranchName}"); GitTools.Branch(stageBranchName); UpdateVersionNumbers?.Invoke(this, BuildType.Staging); } } else { if (versionInfo.BranchName != stageBranchName) { throw new Exception( $@"This command must be exist run from the development branch or an active release branch. Based on the current version information I expect to be on branch '{state.ReleaseStagingBranch}', but detected branch '{versionInfo.BranchName}' instead"); } } }