private async Task <bool> CreateOrFastForwardServiceLine(string latestBranchName, IRepositoryMediator repository, IGitCli cli)
            {
                var showRefResult = await repository.GetBranchRef(serviceLineBranch).Take(1);

                if (showRefResult == null)
                {
                    // create service line
                    await AppendProcess(cli.CheckoutRemote(latestBranchName)).WaitUntilComplete();

                    await AppendProcess(cli.CheckoutNew(serviceLineBranch)).WaitUntilComplete();

                    return(true);
                }
                else
                {
                    // fast-forward
                    await AppendProcess(cli.CheckoutRemote(serviceLineBranch)).WaitUntilComplete();

                    var fastForward = cli.MergeFastForward(latestBranchName);
                    await AppendProcess(fastForward).WaitUntilComplete();

                    var fastForwardResult = fastForward.ExitCode;

                    return(fastForwardResult == 0);
                }
            }
Exemplo n.º 2
0
            private async Task <(bool created, string branchName, string badReason)> CreateDownstreamBranch(IEnumerable <NeededMerge> allUpstreamBranches)
            {
                var downstreamBranch = await repository.GetNextCandidateBranch(Details).FirstOrDefaultAsync();

                var validUpstream = allUpstreamBranches.ToImmutableList();

                if (validUpstream.Count == 0 || validUpstream.Any(t => t.BranchName == null))
                {
                    if (validUpstream.Any(t => t.BranchName != null))
                    {
#pragma warning disable CS4014
                        orchestration.EnqueueAction(new MergeDownstreamAction(validUpstream.First(t => t.BranchName == null).GroupName), skipDuplicateCheck: false);
#pragma warning restore
                        await AppendMessage($"{validUpstream.First(t => t.BranchName == null).GroupName} did not have current branch; aborting", isError : true);
                    }

                    return(created : false, branchName : null, badReason : "UpstreamBranchMissing");
                }

                var badBranches = await BadBranches(validUpstream.Select(t => t.BranchName));

                if (badBranches.Any())
                {
                    await AppendMessage($"{badBranches.First().BranchName} is marked as bad; aborting", isError : true);

                    return(created : false, branchName : null, badReason : "UpstreamAlreadyBad");
                }

                // Basic process; should have checks on whether or not to create the branch
                var initialBranch = validUpstream[0];

                var checkout      = cli.CheckoutRemote(initialBranch.BranchName);
                var checkoutError = await checkout.FirstErrorMessage();
                await AppendProcess(checkout);

                if (!string.IsNullOrEmpty(checkoutError) && checkoutError.StartsWith("fatal"))
                {
                    await AppendMessage($"{downstreamBranch} unable to be branched from {initialBranch.BranchName}; aborting");

                    return(created : false, branchName : null, badReason : "FailedToBranch");
                }

                await AppendProcess(cli.CheckoutNew(downstreamBranch));

                var    shouldCancel = false;
                var    shouldRetry  = false;
                string badReason    = null;
                foreach (var upstreamBranch in validUpstream.Skip(1))
                {
                    var result = await MergeUpstreamBranch(upstreamBranch, downstreamBranch);

                    shouldCancel = shouldCancel || result.HadConflicts;
                    badReason    = badReason ?? result.BadReason;
                    shouldRetry  = shouldRetry || (result.HadConflicts && result.Resolution == MergeConflictResolution.AddIntegrationBranch);
                }
                if (shouldCancel)
                {
                    if (shouldRetry)
                    {
                        // abort, but queue another attempt
#pragma warning disable CS4014
                        orchestration.EnqueueAction(new MergeDownstreamAction(downstreamBranchGroup), skipDuplicateCheck: true);
#pragma warning restore
                        return(created : false, branchName : downstreamBranch, badReason : null);
                    }
                    return(created : false, branchName : downstreamBranch, badReason);
                }

                return(created : true, branchName : downstreamBranch, badReason);
            }