internal static bool TryMergeToShelve( RestApi restApi, Branch branch, string destinationBranch, MergeReport mergeReport, string comment, string taskNumber, TrunkBotConfiguration botConfig, string codeReviewsStorageFile, out int shelveId) { shelveId = -1; MergeToResponse result = TrunkMergebotApi.MergeBranchTo( restApi, branch.Repository, branch.FullName, destinationBranch, comment, TrunkMergebotApi.MergeToOptions.CreateShelve); if (result.Status == MergeToResultStatus.MergeNotNeeded) { ChangeTaskStatus.SetTaskAsMerged( restApi, branch, taskNumber, string.Format( "Branch {0} was already merged to {1} (MergeNotNeeded).", branch.FullName, botConfig.TrunkBranch), botConfig, codeReviewsStorageFile); return(false); } if (result.Status == MergeToResultStatus.AncestorNotFound || result.Status == MergeToResultStatus.Conflicts || result.Status == MergeToResultStatus.Error || result.ChangesetNumber == 0) { BuildMergeReport.AddFailedMergeProperty(mergeReport, result.Status, result.Message); ChangeTaskStatus.SetTaskAsFailed( restApi, branch, taskNumber, string.Format( "Can't merge branch {0}. Reason: {1}", branch.FullName, result.Message), botConfig, codeReviewsStorageFile); return(false); } shelveId = result.ChangesetNumber; BuildMergeReport.AddSucceededMergeProperty(mergeReport, result.Status); return(true); }
internal static bool TryApplyShelve( RestApi restApi, Branch branch, string destinationBranch, MergeReport mergeReport, string comment, string taskNumber, int shelveId, TrunkBotConfiguration botConfig, string codeReviewsStorageFile, out int csetId) { MergeToResponse mergeResult = TrunkMergebotApi.MergeShelveTo( restApi, branch.Repository, shelveId, destinationBranch, comment, TrunkMergebotApi.MergeToOptions.EnsureNoDstChanges); csetId = mergeResult.ChangesetNumber; BuildMergeReport.UpdateMergeProperty(mergeReport, mergeResult.Status, csetId); if (mergeResult.Status == MergeToResultStatus.OK) { return(true); } if (mergeResult.Status == MergeToResultStatus.DestinationChanges) { // it should checkin the shelve only on the exact parent shelve cset. // if there are new changes in the trunk branch enqueue againg the task return(false); } ChangeTaskStatus.SetTaskAsFailed( restApi, branch, taskNumber, string.Format( "Can't merge branch {0}. Reason: {1}", branch.FullName, mergeResult.Message), botConfig, codeReviewsStorageFile); return(false); }
internal static Result TryProcessBranch( RestApi restApi, Branch branch, TrunkBotConfiguration botConfig, string botName, string codeReviewsStorageFile) { int shelveId = -1; string taskNumber = null; MergeReport mergeReport = null; try { mLog.InfoFormat("Getting task number of branch {0} ...", branch.FullName); taskNumber = GetTaskNumber(branch.FullName, botConfig.BranchPrefix); if (!IsTaskReady( restApi, taskNumber, botConfig.Issues, botConfig.Plastic.IsApprovedCodeReviewFilterEnabled, branch.Repository, branch.Id, codeReviewsStorageFile)) { return(Result.NotReady); } if (!IsMergeAllowed(restApi, branch, botConfig.TrunkBranch)) { mLog.WarnFormat( "Branch {0} is not yet ready to be merged. " + "Jumping to next branch in the queue...", branch.FullName); return(Result.NotReady); } mLog.InfoFormat("Building the merge report of task {0} ...", taskNumber); mergeReport = BuildMergeReport.Build(TrunkMergebotApi.GetBranch( restApi, branch.Repository, branch.FullName)); string taskTittle; string taskUrl; if (GetIssueInfo(restApi, taskNumber, botConfig.Issues, out taskTittle, out taskUrl)) { BuildMergeReport.AddIssueProperty(mergeReport, taskTittle, taskUrl); } string comment = GetComment(branch.FullName, taskTittle, botName); mLog.InfoFormat("Trying to shelve server-side-merge from {0} to {1}", branch.FullName, botConfig.TrunkBranch); if (!MergeToOperations.TryMergeToShelve( restApi, branch, botConfig.TrunkBranch, mergeReport, comment, taskNumber, botConfig, codeReviewsStorageFile, out shelveId)) { return(Result.Failed); } mLog.InfoFormat("Testing branch {0} ...", branch.FullName); if (!TryBuildTask(restApi, branch, mergeReport, taskNumber, shelveId, botConfig, codeReviewsStorageFile)) { return(Result.Failed); } mLog.InfoFormat("Checking-in shelved merged {0} from {1} to {2}", shelveId, branch.FullName, botConfig.TrunkBranch); int csetId = -1; if (!MergeToOperations.TryApplyShelve( restApi, branch, botConfig.TrunkBranch, mergeReport, comment, taskNumber, shelveId, botConfig, codeReviewsStorageFile, out csetId)) { return(Result.Failed); } mLog.InfoFormat("Checkin: Created changeset {0} in branch {1}", csetId, botConfig.TrunkBranch); mLog.InfoFormat("Setting branch {0} as 'integrated'...", branch.FullName); ChangeTaskStatus.SetTaskAsMerged( restApi, branch, taskNumber, string.Format( "Branch {0} was correctly merged to {1}.", branch.FullName, botConfig.TrunkBranch), botConfig, codeReviewsStorageFile); string labelName = string.Empty; if (!CreateLabel( restApi, csetId, branch.FullName, botConfig.TrunkBranch, botConfig.Repository, botConfig.Plastic.IsAutoLabelEnabled, botConfig.Plastic.AutomaticLabelPattern, mergeReport, branch.Owner, botConfig.Notifications, out labelName)) { return(Result.Failed); } if (!HasToRunPlanAfterTaskMerged(botConfig.CI)) { return(Result.Ok); } if (!TryRunAfterCheckinPlan( restApi, branch, mergeReport, taskNumber, csetId, labelName, botConfig)) { return(Result.Failed); } } catch (Exception ex) { mLog.ErrorFormat( "The attempt to process task {0} failed for branch {1}: {2}", taskNumber, branch.FullName, ex.Message); mLog.DebugFormat( "StackTrace:{0}{1}", Environment.NewLine, ex.StackTrace); ChangeTaskStatus.SetTaskAsFailed( restApi, branch, taskNumber, string.Format( "Can't process branch {0} because of an unexpected error: {1}.", branch.FullName, ex.Message), botConfig, codeReviewsStorageFile); BuildMergeReport.SetUnexpectedExceptionProperty(mergeReport, ex.Message); return(Result.Failed); } finally { ReportMerge(restApi, branch.Repository, branch.FullName, botName, mergeReport); SafeDeleteShelve(restApi, branch.Repository, shelveId); } return(Result.Ok); }
static bool TryBuildTask( RestApi restApi, Branch branch, MergeReport mergeReport, string taskNumber, int shelveId, TrunkBotConfiguration botConfig, string codeReviewsStorageFile) { if (botConfig.CI == null) { string message = "No CI plug was set for this mergebot. Therefore, no " + "build actions for task " + taskNumber + " will be performed."; mLog.Info(message); Notifier.NotifyTaskStatus( restApi, branch.Owner, message, botConfig.Notifications); return(true); } ChangeTaskStatus.SetTaskAsTesting(restApi, branch, taskNumber, string.Format( "Starting to test branch {0}.", branch.FullName), botConfig); string repSpec = string.Format("{0}@{1}", branch.Repository, botConfig.Server); string scmSpecToSwitchTo = string.Format("sh:{0}@{1}", shelveId, repSpec); string comment = string.Format( "Building branch {0}", branch.FullName); BuildProperties properties = CreateBuildProperties( restApi, taskNumber, branch.FullName, string.Empty, BuildProperties.StageValues.PRE_CHECKIN, botConfig); int iniTime = Environment.TickCount; TrunkMergebotApi.CI.PlanResult buildResult = TrunkMergebotApi.CI.Build( restApi, botConfig.CI.Plug, botConfig.CI.PlanBranch, scmSpecToSwitchTo, comment, properties); BuildMergeReport.AddBuildTimeProperty(mergeReport, Environment.TickCount - iniTime); if (buildResult.Succeeded) { BuildMergeReport.AddSucceededBuildProperty(mergeReport, botConfig.CI.PlanBranch); return(true); } BuildMergeReport.AddFailedBuildProperty(mergeReport, botConfig.CI.PlanBranch, buildResult.Explanation); ChangeTaskStatus.SetTaskAsFailed( restApi, branch, taskNumber, string.Format( "Branch {0} build failed. \nReason: {1}", branch.FullName, buildResult.Explanation), botConfig, codeReviewsStorageFile); return(false); }