internal IEnumerable <BaseVersion> GetVersions(string tagPrefixRegex, IBranch currentBranch) { if (!Context.FullConfiguration.IsReleaseBranch(NameWithoutOrigin(currentBranch))) { yield break; } var branchName = currentBranch.Name.Friendly; var versionInBranch = GetVersionInBranch(branchName, tagPrefixRegex); if (versionInBranch != null) { var commitBranchWasBranchedFrom = repositoryStore.FindCommitBranchWasBranchedFrom(currentBranch, Context.FullConfiguration); var branchNameOverride = branchName.RegexReplace("[-/]" + versionInBranch.Item1, string.Empty); yield return(new BaseVersion("Version in branch name", false, versionInBranch.Item2, commitBranchWasBranchedFrom.Commit, branchNameOverride)); } }
// 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 ??= repositoryStore.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 = repositoryStore.ExcludingBranches(excludedInheritBranches).ToList(); var branchPoint = repositoryStore .FindCommitBranchWasBranchedFrom(targetBranch, configuration, excludedInheritBranches.ToArray()); List <IBranch> possibleParents; if (branchPoint == BranchCommit.Empty) { possibleParents = repositoryStore.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 = repositoryStore.GetBranchesContainingCommit(branchPoint.Commit, branchesToEvaluate).ToList(); if (branches.Count > 1) { var currentTipBranches = repositoryStore.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 main 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 = repositoryStore.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 'main' 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 developOrMainConfig = ChooseMainOrDevelopIncrementStrategyIfTheChosenBranchIsOneOfThem( chosenBranch, branchConfiguration, configuration); if (developOrMainConfig != null) { return(developOrMainConfig); } 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 }); } }