private BaseVersion CreateBaseVersion(GitVersionContext context, VersionTaggedCommit version) { var shouldUpdateVersion = version.Commit.Sha != context.CurrentCommit.Sha; var baseVersion = new BaseVersion(FormatSource(version), shouldUpdateVersion, version.SemVer, version.Commit, null); return(baseVersion); }
public BaseVersion GetBaseVersion(GitVersionContext context) { using (Logger.IndentLog("Calculating base versions")) { var baseVersions = strategies .SelectMany(s => s.GetVersions(context)) .Where(v => { if (v != null) { Logger.WriteInfo(v.ToString()); return(true); } return(false); }) .Select(v => new { IncrementedVersion = MaybeIncrement(context, v), Version = v }) .ToList(); var maxVersion = baseVersions.Aggregate((v1, v2) => v1.IncrementedVersion > v2.IncrementedVersion ? v1 : v2); var matchingVersionsOnceIncremented = baseVersions .Where(b => b != maxVersion && b.Version.BaseVersionSource != null && b.IncrementedVersion == maxVersion.IncrementedVersion) .ToList(); BaseVersion baseVersionWithOldestSource; if (matchingVersionsOnceIncremented.Any()) { baseVersionWithOldestSource = matchingVersionsOnceIncremented.Aggregate((v1, v2) => v1.Version.BaseVersionSource.Committer.When < v2.Version.BaseVersionSource.Committer.When ? v1 : v2).Version; Logger.WriteInfo(string.Format( "Found multiple base versions which will produce the same SemVer ({0}), taking oldest source for commit counting ({1})", maxVersion.IncrementedVersion, baseVersionWithOldestSource.Source)); } else { baseVersionWithOldestSource = baseVersions .Where(v => v.Version.BaseVersionSource != null) .OrderByDescending(v => v.IncrementedVersion) .ThenByDescending(v => v.Version.BaseVersionSource.Committer.When) .First() .Version; } if (baseVersionWithOldestSource.BaseVersionSource == null) { throw new Exception("Base version should not be null"); } var calculatedBase = new BaseVersion( maxVersion.Version.Source, maxVersion.Version.ShouldIncrement, maxVersion.Version.SemanticVersion, baseVersionWithOldestSource.BaseVersionSource, maxVersion.Version.BranchNameOverride); Logger.WriteInfo(string.Format("Base version used: {0}", calculatedBase)); return(calculatedBase); } }
public SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion) { if (baseVersion.SemanticVersion.PreReleaseTag.HasTag()) { throw new NotSupportedException("Mainline development mode doesn't yet support pre-release tags on master"); } using (log.IndentLog("Using mainline development mode to calculate current version")) { var mainlineVersion = baseVersion.SemanticVersion; // Forward merge / PR // * feature/foo // / | // master * * // var mergeBase = baseVersion.BaseVersionSource; var mainline = GetMainline(baseVersion.BaseVersionSource); var mainlineTip = mainline.Tip; // when the current branch is not mainline, find the effective mainline tip for versioning the branch if (!context.CurrentBranch.IsSameBranch(mainline)) { mergeBase = FindMergeBaseBeforeForwardMerge(baseVersion.BaseVersionSource, mainline, out mainlineTip); log.Info($"Current branch ({context.CurrentBranch.FriendlyName}) was branch from {mergeBase}"); } var mainlineCommitLog = repositoryMetadataProvider.GetMainlineCommitLog(baseVersion.BaseVersionSource, mainlineTip); var directCommits = new List <Commit>(mainlineCommitLog.Count); if (string.IsNullOrEmpty(context.Configuration.NextVersion)) { // Scans commit log in reverse, aggregating merge commits foreach (var commit in mainlineCommitLog) { directCommits.Add(commit); if (commit.Parents.Count() > 1) { mainlineVersion = AggregateMergeCommitIncrement(commit, directCommits, mainlineVersion, mainline); } } // This will increment for any direct commits on mainline mainlineVersion = IncrementForEachCommit(directCommits, mainlineVersion, mainline); } mainlineVersion.BuildMetaData = CreateVersionBuildMetaData(mergeBase); // branches other than master always get a bump for the act of branching if ((!context.CurrentBranch.IsSameBranch(mainline)) && (string.IsNullOrEmpty(context.Configuration.NextVersion))) { var branchIncrement = FindMessageIncrement(null, context.CurrentCommit, mergeBase, mainlineCommitLog); log.Info($"Performing {branchIncrement} increment for current branch "); mainlineVersion = mainlineVersion.IncrementVersion(branchIncrement); } return(mainlineVersion); } }
static SemanticVersion MaybeIncrement(GitVersionContext context, BaseVersion version) { var increment = IncrementStrategyFinder.DetermineIncrementedField(context, version); if (increment != null) { return(version.SemanticVersion.IncrementVersion(increment.Value)); } return(version.SemanticVersion); }
private bool IncludeVersion(BaseVersion version) { foreach (var filter in context.Configuration.VersionFilters) { if (filter.Exclude(version, out var reason)) { log.Info(reason); return(false); } } return(true); }
private SemanticVersion PerformIncrement(GitVersionContext context, BaseVersion baseVersion) { var semver = baseVersion.SemanticVersion; var increment = IncrementStrategyFinder.DetermineIncrementedField(context, baseVersion); if (increment != null) { semver = semver.IncrementVersion(increment.Value); } else { log.Info("Skipping version increment"); } return(semver); }
private SemanticVersion PerformIncrement(BaseVersion baseVersion) { var semver = baseVersion.SemanticVersion; var increment = repositoryMetadataProvider.DetermineIncrementedField(baseVersion, context); if (increment != null) { semver = semver.IncrementVersion(increment.Value); } else { log.Info("Skipping version increment"); } return(semver); }
public bool Exclude(BaseVersion version, out string reason) { if (version == null) { throw new ArgumentNullException(nameof(version)); } reason = null; if (version.BaseVersionSource != null && shas.Any(sha => version.BaseVersionSource.Sha.StartsWith(sha, StringComparison.OrdinalIgnoreCase))) { reason = $"Sha {version.BaseVersionSource.Sha} was ignored due to commit having been excluded by configuration"; return(true); } return(false); }
public bool Exclude(BaseVersion version, out string reason) { if (version == null) { throw new ArgumentNullException(nameof(version)); } reason = null; if (version.BaseVersionSource != null && version.BaseVersionSource.When < minimum) { reason = "Source was ignored due to commit date being outside of configured range"; return(true); } return(false); }
static void IncrementVersion(GitVersionContext context, BaseVersion baseVersion) { if (!baseVersion.SemanticVersion.PreReleaseTag.HasTag()) { switch (context.Configuration.Increment) { case IncrementStrategy.None: Logger.WriteInfo("Skipping version increment"); break; case IncrementStrategy.Major: Logger.WriteInfo("Incrementing Major Version"); baseVersion.SemanticVersion.Major++; baseVersion.SemanticVersion.Minor = 0; baseVersion.SemanticVersion.Patch = 0; break; case IncrementStrategy.Minor: baseVersion.SemanticVersion.Minor++; baseVersion.SemanticVersion.Patch = 0; Logger.WriteInfo("Incrementing Minor Version"); break; case IncrementStrategy.Patch: baseVersion.SemanticVersion.Patch++; Logger.WriteInfo("Incrementing Patch Version"); break; default: throw new ArgumentOutOfRangeException(); } } else { if (baseVersion.SemanticVersion.PreReleaseTag.Number != null) { baseVersion.SemanticVersion.PreReleaseTag.Number = baseVersion.SemanticVersion.PreReleaseTag.Number; baseVersion.SemanticVersion.PreReleaseTag.Number++; } } }
void UpdatePreReleaseTag(GitVersionContext context, BaseVersion baseVersion) { var tagToUse = context.Configuration.Tag; if (tagToUse == "useBranchName") { Logger.WriteInfo("Using branch name to calculate version tag"); var name = baseVersion.BranchNameOverride ?? context.CurrentBranch.Name; tagToUse = name.RegexReplace(context.Configuration.BranchPrefixToTrim, string.Empty, RegexOptions.IgnoreCase); } int?number = null; if (!string.IsNullOrEmpty(context.Configuration.TagNumberPattern)) { var match = Regex.Match(context.CurrentBranch.CanonicalName, context.Configuration.TagNumberPattern); var numberGroup = match.Groups["number"]; if (numberGroup.Success) { number = int.Parse(numberGroup.Value); } } var lastTag = highestTagBaseVersionStrategy.GetVersion(context); if (number == null && lastTag != null && MajorMinorPatchEqual(lastTag.SemanticVersion, baseVersion.SemanticVersion) && lastTag.SemanticVersion.PreReleaseTag.HasTag()) { number = lastTag.SemanticVersion.PreReleaseTag.Number + 1; } if (number == null) { number = 1; } baseVersion.SemanticVersion.PreReleaseTag = new SemanticVersionPreReleaseTag(tagToUse, number); }
public SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion, GitVersionContext context) { if (baseVersion.SemanticVersion.PreReleaseTag.HasTag()) { throw new NotSupportedException("Mainline development mode doesn't yet support pre-release tags on master"); } using (Logger.IndentLog("Using mainline development mode to calculate current version")) { var mainlineVersion = baseVersion.SemanticVersion; // Forward merge / PR // * feature/foo // / | // master * * // var mainlineTip = GetMainlineTip(context); var commitsNotOnMainline = context.Repository.Commits.QueryByPath(context.PathFilter, new CommitFilter { IncludeReachableFrom = context.CurrentBranch, ExcludeReachableFrom = mainlineTip, SortBy = CommitSortStrategies.Time, FirstParentOnly = true }).Where(c => c.Sha != baseVersion.BaseVersionSource.Sha && c.Parents.Count() == 1).ToList(); var commitLog = context.Repository.Commits.QueryByPath(context.PathFilter, new CommitFilter { IncludeReachableFrom = context.CurrentBranch, ExcludeReachableFrom = baseVersion.BaseVersionSource, SortBy = CommitSortStrategies.Time, FirstParentOnly = true }) .Where(c => c.Sha != baseVersion.BaseVersionSource.Sha) .Except(commitsNotOnMainline) .ToList(); commitLog.Reverse(); var directCommits = new List <Commit>(); // Scans commit log in reverse, aggregating merge commits foreach (var commit in commitLog) { directCommits.Add(commit); if (commit.Parents.Count() > 1) { mainlineVersion = AggregateMergeCommitIncrement(context, commit, directCommits, mainlineVersion); } } if (context.CurrentBranch.FriendlyName != "master") { var mergedHead = context.CurrentCommit; var findMergeBase = context.Repository.ObjectDatabase.FindMergeBase(context.CurrentCommit, mainlineTip); Logger.WriteInfo(string.Format("Current branch ({0}) was branch from {1}", context.CurrentBranch.FriendlyName, findMergeBase)); var branchIncrement = FindMessageIncrement(context, null, mergedHead, findMergeBase, directCommits); // This will increment for any direct commits on master mainlineVersion = IncrementForEachCommit(context, directCommits, mainlineVersion, "master"); mainlineVersion.BuildMetaData = metaDataCalculator.Create(findMergeBase, context); // Don't increment if the merge commit is a merge into mainline // this ensures PR's and forward merges end up correct. if (mergedHead.Parents.Count() == 1 || mergedHead.Parents.First() != mainlineTip) { Logger.WriteInfo(string.Format("Performing {0} increment for current branch ", branchIncrement)); mainlineVersion = mainlineVersion.IncrementVersion(branchIncrement); } } else { // If we are on master, make sure no commits get left behind mainlineVersion = IncrementForEachCommit(context, directCommits, mainlineVersion); mainlineVersion.BuildMetaData = metaDataCalculator.Create(baseVersion.BaseVersionSource, context); } return(mainlineVersion); } }
public BaseVersion GetBaseVersion(GitVersionContext context) { using (Logger.IndentLog("Calculating base versions")) { var baseVersions = strategies .SelectMany(s => s.GetVersions(context)) .Where(v => { if (v == null) { return(false); } Logger.WriteInfo(v.ToString()); foreach (var filter in context.Configuration.VersionFilters) { string reason; if (filter.Exclude(v, out reason)) { Logger.WriteInfo(reason); return(false); } } return(true); }) .Select(v => new Versions { IncrementedVersion = MaybeIncrement(context, v), Version = v }) .ToList(); if (!baseVersions.Any()) { var defaultBaseVersions = DefaultStrategy.GetVersions(context) .Where(v => { if (v == null) { return(false); } Logger.WriteInfo(v.ToString()); foreach (var filter in context.Configuration.VersionFilters) { string reason; if (filter.Exclude(v, out reason)) { Logger.WriteInfo(reason); return(false); } } return(true); }) .Select(v => new Versions { IncrementedVersion = MaybeIncrement(context, v), Version = v }) .ToList(); baseVersions.AddRange(defaultBaseVersions); } FixTheBaseVersionSourceOfMergeMessageStrategyIfReleaseBranchWasMergedAndDeleted (context, baseVersions); var maxVersion = baseVersions.Aggregate((v1, v2) => v1.IncrementedVersion > v2.IncrementedVersion ? v1 : v2); var matchingVersionsOnceIncremented = baseVersions .Where(b => b.Version.BaseVersionSource != null && b.IncrementedVersion == maxVersion.IncrementedVersion) .ToList(); BaseVersion baseVersionWithOldestSource; if (matchingVersionsOnceIncremented.Any()) { var oldest = matchingVersionsOnceIncremented.Aggregate((v1, v2) => v1.Version.BaseVersionSource.Committer.When < v2.Version.BaseVersionSource.Committer.When ? v1 : v2); baseVersionWithOldestSource = oldest.Version; maxVersion = oldest; Logger.WriteInfo(string.Format( "Found multiple base versions which will produce the same SemVer ({0}), taking oldest source for commit counting ({1})", maxVersion.IncrementedVersion, baseVersionWithOldestSource.Source)); } else { baseVersionWithOldestSource = baseVersions .Where(v => v.Version.BaseVersionSource != null) .OrderByDescending(v => v.IncrementedVersion) .ThenByDescending(v => v.Version.BaseVersionSource.Committer.When) .First() .Version; } if (baseVersionWithOldestSource.BaseVersionSource == null) { throw new Exception("Base version should not be null"); } var calculatedBase = new BaseVersion( context, maxVersion.Version.Source, maxVersion.Version.ShouldIncrement, maxVersion.Version.SemanticVersion, baseVersionWithOldestSource.BaseVersionSource, maxVersion.Version.BranchNameOverride); Logger.WriteInfo(string.Format("Base version used: {0}", calculatedBase)); return(calculatedBase); } }
public SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion, GitVersionContext context) { if (baseVersion.SemanticVersion.PreReleaseTag.HasTag()) { throw new NotSupportedException("Mainline development mode doesn't yet support pre-release tags on master"); } using (Logger.IndentLog("Using mainline development mode to calculate current version")) { var mainlineVersion = baseVersion.SemanticVersion; // Forward merge / PR // * feature/foo // / | // master * * // var mergeBase = baseVersion.BaseVersionSource; var mainline = GetMainline(context, baseVersion.BaseVersionSource); var mainlineTip = mainline.Tip; // when the current branch is not mainline, find the effective mainline tip for versioning the branch if (!context.CurrentBranch.IsSameBranch(mainline)) { mergeBase = FindMergeBaseBeforeForwardMerge(context, baseVersion.BaseVersionSource, mainline, out mainlineTip); Logger.WriteInfo($"Current branch ({context.CurrentBranch.FriendlyName}) was branch from {mergeBase}"); } var mainlineCommitLog = context.Repository.Commits.QueryBy(new CommitFilter { IncludeReachableFrom = mainlineTip, ExcludeReachableFrom = baseVersion.BaseVersionSource, SortBy = CommitSortStrategies.Reverse, FirstParentOnly = true }) .ToList(); var directCommits = new List <Commit>(mainlineCommitLog.Count); // Scans commit log in reverse, aggregating merge commits foreach (var commit in mainlineCommitLog) { directCommits.Add(commit); if (commit.Parents.Count() > 1) { mainlineVersion = AggregateMergeCommitIncrement(context, commit, directCommits, mainlineVersion, mainline); } } // This will increment for any direct commits on mainline mainlineVersion = IncrementForEachCommit(context, directCommits, mainlineVersion, mainline); mainlineVersion.BuildMetaData = metaDataCalculator.Create(mergeBase, context); // branches other than master always get a bump for the act of branching if (context.CurrentBranch.FriendlyName != "master") { var branchIncrement = FindMessageIncrement(context, null, context.CurrentCommit, mergeBase, mainlineCommitLog); Logger.WriteInfo($"Performing {branchIncrement} increment for current branch "); mainlineVersion = mainlineVersion.IncrementVersion(branchIncrement); } return(mainlineVersion); } }
private SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion, GitVersionContext context) { if (baseVersion.SemanticVersion.PreReleaseTag.HasTag()) { throw new NotSupportedException("Mainline development mode doesn't yet support pre-release tags on master"); } using (Logger.IndentLog("Using mainline development mode to calculate current version")) { var mainlineVersion = baseVersion.SemanticVersion; var commitLog = context.Repository.Commits.QueryBy(new CommitFilter { IncludeReachableFrom = context.CurrentBranch, ExcludeReachableFrom = baseVersion.BaseVersionSource, SortBy = CommitSortStrategies.Reverse }).Where(c => c.Sha != baseVersion.BaseVersionSource.Sha).ToList(); var directCommits = new List <Commit>(); foreach (var commit in commitLog) { directCommits.Add(commit); if (commit.Parents.Count() > 1) { // Merge commit, process all merged commits as a batch var mergeCommit = commit; var mergedHead = GetMergedHead(mergeCommit); var findMergeBase = context.Repository.ObjectDatabase.FindMergeBase(mergeCommit.Parents.First(), mergedHead); var findMessageIncrement = FindMessageIncrement(context, mergeCommit, mergedHead, findMergeBase, directCommits); // If this collection is not empty there has been some direct commits against master // Treat each commit as it's own 'release', we need to do this before we increment the branch mainlineVersion = IncrementForEachCommit(context, directCommits, mainlineVersion); directCommits.Clear(); // Finally increment for the branch mainlineVersion = mainlineVersion.IncrementVersion(findMessageIncrement); Logger.WriteInfo(string.Format("Merge commit {0} incremented base versions {1}, now {2}", mergeCommit.Sha, findMessageIncrement, mainlineVersion)); } } if (context.CurrentBranch.FriendlyName != "master") { var mergedHead = context.CurrentCommit; var findMergeBase = context.Repository.ObjectDatabase.FindMergeBase(context.CurrentCommit, context.Repository.FindBranch("master").Tip); Logger.WriteInfo(string.Format("Current branch ({0}) was branch from {1}", context.CurrentBranch.FriendlyName, findMergeBase)); var branchIncrement = FindMessageIncrement(context, findMergeBase, mergedHead, findMergeBase, directCommits); mainlineVersion = IncrementForEachCommit(context, directCommits, mainlineVersion); Logger.WriteInfo(string.Format("Performing {0} increment for current branch ", branchIncrement)); mainlineVersion = mainlineVersion.IncrementVersion(branchIncrement); } else { // If we are on master, make sure no commits get left behind mainlineVersion = IncrementForEachCommit(context, directCommits, mainlineVersion); } return(mainlineVersion); } }
static SemanticVersion MaybeIncrement(GitVersionContext context, BaseVersion version) { return(version.ShouldIncrement ? version.SemanticVersion.IncrementVersion(context.Configuration.Increment) : version.SemanticVersion); }
public BaseVersion GetBaseVersion() { using (log.IndentLog("Calculating base versions")) { var baseVersions = strategies .SelectMany(s => s.GetVersions()) .Where(v => { if (v == null) { return(false); } log.Info(v.ToString()); foreach (var filter in context.Configuration.VersionFilters) { if (filter.Exclude(v, out var reason)) { log.Info(reason); return(false); } } return(true); }) .Select(v => new Versions { IncrementedVersion = repositoryMetadataProvider.MaybeIncrement(v, context), Version = v }) .ToList(); FixTheBaseVersionSourceOfMergeMessageStrategyIfReleaseBranchWasMergedAndDeleted(baseVersions); var maxVersion = baseVersions.Aggregate((v1, v2) => v1.IncrementedVersion > v2.IncrementedVersion ? v1 : v2); var matchingVersionsOnceIncremented = baseVersions .Where(b => b.Version.BaseVersionSource != null && b.IncrementedVersion == maxVersion.IncrementedVersion) .ToList(); BaseVersion baseVersionWithOldestSource; if (matchingVersionsOnceIncremented.Any()) { var oldest = matchingVersionsOnceIncremented.Aggregate((v1, v2) => v1.Version.BaseVersionSource.Committer.When < v2.Version.BaseVersionSource.Committer.When ? v1 : v2); baseVersionWithOldestSource = oldest.Version; maxVersion = oldest; log.Info($"Found multiple base versions which will produce the same SemVer ({maxVersion.IncrementedVersion}), taking oldest source for commit counting ({baseVersionWithOldestSource.Source})"); } else { baseVersionWithOldestSource = baseVersions .Where(v => v.Version.BaseVersionSource != null) .OrderByDescending(v => v.IncrementedVersion) .ThenByDescending(v => v.Version.BaseVersionSource.Committer.When) .First() .Version; } if (baseVersionWithOldestSource.BaseVersionSource == null) { throw new Exception("Base version should not be null"); } var calculatedBase = new BaseVersion( maxVersion.Version.Source, maxVersion.Version.ShouldIncrement, maxVersion.Version.SemanticVersion, baseVersionWithOldestSource.BaseVersionSource, maxVersion.Version.BranchNameOverride); log.Info($"Base version used: {calculatedBase}"); return(calculatedBase); } }
public BaseVersion GetBaseVersion() { using (log.IndentLog("Calculating base versions")) { var allVersions = new List <BaseVersion>(); foreach (var strategy in strategies) { var baseVersions = GetBaseVersions(strategy).ToList(); allVersions.AddRange(baseVersions); } var versions = allVersions .Select(baseVersion => new Versions { IncrementedVersion = repositoryMetadataProvider.MaybeIncrement(baseVersion, context), Version = baseVersion }) .ToList(); FixTheBaseVersionSourceOfMergeMessageStrategyIfReleaseBranchWasMergedAndDeleted(versions); if (context.Configuration.VersioningMode == VersioningMode.Mainline) { versions = versions .Where(b => !b.IncrementedVersion.PreReleaseTag.HasTag()) .ToList(); } var maxVersion = versions.Aggregate((v1, v2) => v1.IncrementedVersion > v2.IncrementedVersion ? v1 : v2); var matchingVersionsOnceIncremented = versions .Where(b => b.Version.BaseVersionSource != null && b.IncrementedVersion == maxVersion.IncrementedVersion) .ToList(); BaseVersion baseVersionWithOldestSource; if (matchingVersionsOnceIncremented.Any()) { var oldest = matchingVersionsOnceIncremented.Aggregate((v1, v2) => v1.Version.BaseVersionSource.When < v2.Version.BaseVersionSource.When ? v1 : v2); baseVersionWithOldestSource = oldest.Version; maxVersion = oldest; log.Info($"Found multiple base versions which will produce the same SemVer ({maxVersion.IncrementedVersion}), taking oldest source for commit counting ({baseVersionWithOldestSource.Source})"); } else { baseVersionWithOldestSource = versions .Where(v => v.Version.BaseVersionSource != null) .OrderByDescending(v => v.IncrementedVersion) .ThenByDescending(v => v.Version.BaseVersionSource.When) .First() .Version; } if (baseVersionWithOldestSource.BaseVersionSource == null) { throw new Exception("Base version should not be null"); } var calculatedBase = new BaseVersion( maxVersion.Version.Source, maxVersion.Version.ShouldIncrement, maxVersion.Version.SemanticVersion, baseVersionWithOldestSource.BaseVersionSource, maxVersion.Version.BranchNameOverride); log.Info($"Base version used: {calculatedBase}"); return(calculatedBase); } }