Exemple #1
0
        // TODO I think we need to take a fresh approach to this.. it's getting really complex with heaps of edge cases
        private BranchConfig InheritBranchConfiguration(IBranch targetBranch, BranchConfig branchConfiguration, ICommit currentCommit, Config configuration, IList <IBranch> excludedInheritBranches)
        {
            using (log.IndentLog("Attempting to inherit branch configuration from parent branch"))
            {
                var excludedBranches = new[] { targetBranch };
                // Check if we are a merge commit. If so likely we are a pull request
                var parentCount = currentCommit.Parents.Count();
                if (parentCount == 2)
                {
                    excludedBranches = CalculateWhenMultipleParents(currentCommit, ref targetBranch, excludedBranches);
                }

                excludedInheritBranches ??= repositoryMetadataProvider.GetExcludedInheritBranches(configuration).ToList();

                excludedBranches = excludedBranches.Where(b => excludedInheritBranches.All(bte => !b.Equals(bte))).ToArray();
                // Add new excluded branches.
                foreach (var excludedBranch in excludedBranches)
                {
                    excludedInheritBranches.Add(excludedBranch);
                }
                var branchesToEvaluate = repositoryMetadataProvider.ExcludingBranches(excludedInheritBranches).ToList();

                var branchPoint = repositoryMetadataProvider
                                  .FindCommitBranchWasBranchedFrom(targetBranch, configuration, excludedInheritBranches.ToArray());
                List <IBranch> possibleParents;
                if (branchPoint == BranchCommit.Empty)
                {
                    possibleParents = repositoryMetadataProvider.GetBranchesContainingCommit(targetBranch.Tip, branchesToEvaluate)
                                      // It fails to inherit Increment branch configuration if more than 1 parent;
                                      // therefore no point to get more than 2 parents
                                      .Take(2)
                                      .ToList();
                }
                else
                {
                    var branches = repositoryMetadataProvider.GetBranchesContainingCommit(branchPoint.Commit, branchesToEvaluate).ToList();
                    if (branches.Count > 1)
                    {
                        var currentTipBranches = repositoryMetadataProvider.GetBranchesContainingCommit(currentCommit, branchesToEvaluate).ToList();
                        possibleParents = branches.Except(currentTipBranches).ToList();
                    }
                    else
                    {
                        possibleParents = branches;
                    }
                }

                log.Info("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.ToString())));

                if (possibleParents.Count == 1)
                {
                    var branchConfig = GetBranchConfiguration(possibleParents[0], currentCommit, configuration, excludedInheritBranches);
                    // If we have resolved a fallback config we should not return that we have got config
                    if (branchConfig.Name != FallbackConfigName)
                    {
                        return(new BranchConfig(branchConfiguration)
                        {
                            Increment = branchConfig.Increment,
                            PreventIncrementOfMergedBranchVersion = branchConfig.PreventIncrementOfMergedBranchVersion,
                            // If we are inheriting from develop then we should behave like develop
                            TracksReleaseBranches = branchConfig.TracksReleaseBranches
                        });
                    }
                }

                // If we fail to inherit it is probably because the branch has been merged and we can't do much. So we will fall back to develop's config
                // if develop exists and master if not
                var errorMessage = possibleParents.Count == 0
                    ? "Failed to inherit Increment branch configuration, no branches found."
                    : "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.ToString()));

                var chosenBranch = repositoryMetadataProvider.GetChosenBranch(configuration);
                if (chosenBranch == null)
                {
                    // TODO We should call the build server to generate this exception, each build server works differently
                    // for fetch issues and we could give better warnings.
                    throw new InvalidOperationException("Could not find a 'develop' or 'master' branch, neither locally nor remotely.");
                }

                log.Warning($"{errorMessage}{System.Environment.NewLine}Falling back to {chosenBranch} branch config");

                // To prevent infinite loops, make sure that a new branch was chosen.
                if (targetBranch.Equals(chosenBranch))
                {
                    var developOrMasterConfig =
                        ChooseMasterOrDevelopIncrementStrategyIfTheChosenBranchIsOneOfThem(
                            chosenBranch, branchConfiguration, configuration);
                    if (developOrMasterConfig != null)
                    {
                        return(developOrMasterConfig);
                    }

                    log.Warning("Fallback branch wants to inherit Increment branch configuration from itself. Using patch increment instead.");
                    return(new BranchConfig(branchConfiguration)
                    {
                        Increment = IncrementStrategy.Patch
                    });
                }

                var inheritingBranchConfig = GetBranchConfiguration(chosenBranch, currentCommit, configuration, excludedInheritBranches);
                var configIncrement        = inheritingBranchConfig.Increment;
                if (inheritingBranchConfig.Name.IsEquivalentTo(FallbackConfigName) && configIncrement == IncrementStrategy.Inherit)
                {
                    log.Warning("Fallback config inherits by default, dropping to patch increment");
                    configIncrement = IncrementStrategy.Patch;
                }
                return(new BranchConfig(branchConfiguration)
                {
                    Increment = configIncrement,
                    PreventIncrementOfMergedBranchVersion = inheritingBranchConfig.PreventIncrementOfMergedBranchVersion,
                    // If we are inheriting from develop then we should behave like develop
                    TracksReleaseBranches = inheritingBranchConfig.TracksReleaseBranches
                });
            }
        }