protected override async Task RunProcess()
            {
                if (isReadOnly)
                {
                    return;
                }

                // either:
                // 1. create new service line from release candidate
                // 2. merge --ff-only from release candidate to service line

                // if it passes:
                //   collect upstream branches
                //   push service line

                var upstreamLines = await repository.DetectShallowUpstreamServiceLines(releaseCandidateBranch).FirstOrDefaultAsync();

                var disposable = new CompositeDisposable();

                var readyToFinalize = await CreateOrFastForwardServiceLine(releaseCandidateBranch, repository, cli);

                if (!readyToFinalize)
                {
                    await AppendMessage($"{serviceLineBranch} unable to be fast-forwarded from {releaseCandidateBranch}; aborting", isError : true);
                }
                else
                {
                    if (!string.IsNullOrEmpty(tagName))
                    {
                        await AppendProcess(cli.AnnotatedTag(tagName, $"Automated release to service line {serviceLineBranch} from {releaseCandidateBranch}")).WaitUntilComplete();
                    }

                    var serviceLine = await settings.GetBranchBasicDetails(serviceLineBranch).FirstOrDefaultAsync();

                    // possible TODO for the future: give option to add missing upstream lines always
                    if (serviceLine == null)
                    {
                        // We need to set it up as a service line
                        using (var work = unitOfWorkFactory.CreateUnitOfWork())
                        {
                            settings.UpdateBranchSetting(serviceLineBranch, UpstreamMergePolicy.None, BranchGroupType.ServiceLine, work);
                            foreach (var upstreamServiceLine in upstreamLines)
                            {
                                settings.AddBranchPropagation(upstreamServiceLine, serviceLineBranch, work);
                            }

                            await work.CommitAsync();
                        }
                    }

                    if (autoConsolidate)
                    {
                        var consolidating = (await repository.GetBranchDetails(releaseCandidateBranch).FirstOrDefaultAsync()).UpstreamBranchGroups;
                        foreach (var upstreamServiceLine in upstreamLines)
                        {
                            var upstreamDetails = await repository.GetBranchDetails(upstreamServiceLine).FirstOrDefaultAsync();

                            consolidating = consolidating.Except(upstreamDetails.UpstreamBranchGroups).Except(new[] { upstreamServiceLine }).ToImmutableList();
                        }
                        var releasedCandidate = await settings.GetConfiguredBranches().Select(branches => branches.Find(branch => branchIteration.IsBranchIteration(branch.GroupName, releaseCandidateBranch)).GroupName).FirstOrDefaultAsync();

#pragma warning disable CS4014
                        orchestration.EnqueueAction(new ConsolidateMergedAction(releasedCandidate, serviceLineBranch));
#pragma warning restore
                    }

                    if (!string.IsNullOrEmpty(tagName))
                    {
                        await AppendProcess(cli.Push(tagName)).WaitUntilComplete();
                    }

                    await AppendProcess(cli.Push(serviceLineBranch)).WaitUntilComplete();
                }
            }