コード例 #1
0
        string ExtractIssueNumber(GitVersionContext context)
        {
            const string prefix = "/pull/";
            var pullRequestBranch = context.CurrentBranch;

            var start = pullRequestBranch.CanonicalName.IndexOf(prefix, System.StringComparison.Ordinal);
            var end = pullRequestBranch.CanonicalName.LastIndexOf("/merge", pullRequestBranch.CanonicalName.Length - 1,
                System.StringComparison.Ordinal);

            string issueNumber = null;

            if (start != -1 && end != -1 && start + prefix.Length <= end)
            {
                start += prefix.Length;
                issueNumber = pullRequestBranch.CanonicalName.Substring(start, end - start);
            }

            if (!LooksLikeAValidPullRequestNumber(issueNumber))
            {
                throw new WarningException(string.Format("Unable to extract pull request number from '{0}'.",
                    pullRequestBranch.CanonicalName));
            }

            return issueNumber;
        }
コード例 #2
0
        public SemanticVersion FindVersion(GitVersionContext context)
        {
            // If current commit is tagged, don't do anything except add build metadata
            if (context.IsCurrentCommitTagged)
            {
                // Will always be 0, don't bother with the +0 on tags
                var semanticVersionBuildMetaData = metaDataCalculator.Create(context.CurrentCommit, context);
                semanticVersionBuildMetaData.CommitsSinceTag = null;
                var semanticVersion = new SemanticVersion(context.CurrentCommitTaggedVersion)
                {
                    BuildMetaData = semanticVersionBuildMetaData
                };
                return semanticVersion;
            }

            var baseVersion = baseVersionFinder.GetBaseVersion(context);
            var semver = baseVersion.SemanticVersion;
            var increment = IncrementStrategyFinder.DetermineIncrementedField(context, baseVersion);
            if (increment != null)
            {
                semver = semver.IncrementVersion(increment.Value);
            }
            else Logger.WriteInfo("Skipping version increment");

            if (!semver.PreReleaseTag.HasTag() && !string.IsNullOrEmpty(context.Configuration.Tag))
            {
                UpdatePreReleaseTag(context, semver, baseVersion.BranchNameOverride);
            }

            semver.BuildMetaData = metaDataCalculator.Create(baseVersion.BaseVersionSource, context);

            return semver;
        }
コード例 #3
0
        public override IEnumerable<BaseVersion> GetVersions(GitVersionContext context)
        {
            var olderThan = context.CurrentCommit.When();
            var allTags = context.Repository.Tags
                .Where(tag => ((Commit)tag.PeeledTarget()).When() <= olderThan)
                .ToList();
            var tagsOnBranch = context.CurrentBranch
                .Commits
                .SelectMany(commit =>
                {
                    return allTags.Where(t => IsValidTag(t, commit));
                })
                .Select(t =>
                {
                    SemanticVersion version;
                    if (SemanticVersion.TryParse(t.Name, context.Configuration.GitTagPrefix, out version))
                    {
                        var commit = t.PeeledTarget() as Commit;
                        if (commit != null)
                            return new VersionTaggedCommit(commit, version, t.Name);
                    }
                    return null;
                })
                .Where(a => a != null)
                .ToList();

            return tagsOnBranch.Select(t => CreateBaseVersion(context, t));
        }
コード例 #4
0
 public override IEnumerable<BaseVersion> GetVersions(GitVersionContext context)
 {
     var currentBranch = context.CurrentBranch;
     var tagPrefixRegex = context.Configuration.GitTagPrefix;
     var repository = context.Repository;
     return GetVersions(context, tagPrefixRegex, currentBranch, repository);
 }
コード例 #5
0
        public SemanticVersion FindVersion(GitVersionContext context)
        {
            if (context.CurrentBranch.IsMaster())
            {
                return new MasterVersionFinder().FindVersion(context.Repository, context.CurrentBranch.Tip);
            }

            if (context.CurrentBranch.IsHotfix())
            {
                return new HotfixVersionFinder().FindVersion(context);
            }

            if (context.CurrentBranch.IsRelease())
            {
                return new ReleaseVersionFinder().FindVersion(context);
            }

            if (context.CurrentBranch.IsDevelop())
            {
                return new DevelopVersionFinder().FindVersion(context);
            }

            if (context.CurrentBranch.IsPullRequest())
            {
                return new PullVersionFinder().FindVersion(context);
            }

            if (context.CurrentBranch.IsSupport())
            {
                return new SupportVersionFinder().FindVersion(context.Repository, context.CurrentBranch.Tip);
            }

            return new FeatureVersionFinder().FindVersion(context);
        }
コード例 #6
0
 public override IEnumerable<BaseVersion> GetVersions(GitVersionContext context)
 {
     if (string.IsNullOrEmpty(context.Configuration.NextVersion) || context.IsCurrentCommitTagged)
         yield break;
     var semanticVersion = SemanticVersion.Parse(context.Configuration.NextVersion, context.Configuration.GitTagPrefix);
     yield return new BaseVersion("NextVersion in GitVersionConfig.yaml", false, semanticVersion, null, null);
 }
コード例 #7
0
        public BaseVersion GetBaseVersion(GitVersionContext context)
        {
            Logger.WriteInfo("Base Versions:");

            var baseVersion = strategies
                .Select(s => s.GetVersion(context))
                .Where(v =>
                {
                    if (v != null)
                    {
                        Logger.WriteInfo(v.ToString());
                        return true;
                    }

                    return false;
                })
                .Aggregate((v1, v2) =>
                {
                    if (v1.SemanticVersion > v2.SemanticVersion)
                    {
                        return new BaseVersion(v1.Source, v1.ShouldIncrement, v1.SemanticVersion, v1.BaseVersionSource ?? v2.BaseVersionSource, v1.BranchNameOverride);
                    }

                    return new BaseVersion(v2.Source, v2.ShouldIncrement, v2.SemanticVersion, v2.BaseVersionSource ?? v1.BaseVersionSource, v2.BranchNameOverride);
                });

            Logger.WriteInfo(string.Format("Base version used: {0}", baseVersion));

            return baseVersion;
        }
コード例 #8
0
        private IEnumerable<BaseVersion> ReleaseBranchBaseVersions(GitVersionContext context)
        {
            var releaseBranchConfig = context.FullConfiguration.Branches
                .Where(b => b.Value.IsReleaseBranch == true)
                .ToList();
            if (releaseBranchConfig.Any())
            {
                var releaseBranches = context.Repository.Branches
                    .Where(b => releaseBranchConfig.Any(c => Regex.IsMatch(b.FriendlyName, c.Key)));

                return releaseBranches
                    .SelectMany(b => GetReleaseVersion(context, b))
                    .Select(baseVersion =>
                    {
                        // Need to drop branch overrides and give a bit more context about
                        // where this version came from
                        var source1 = "Release branch exists -> " + baseVersion.Source;
                        return new BaseVersion(source1,
                            baseVersion.ShouldIncrement,
                            baseVersion.SemanticVersion,
                            baseVersion.BaseVersionSource,
                            null);
                    })
                    .ToList();
            }
            return new BaseVersion[0];
        }
コード例 #9
0
        public SemanticVersion FindVersion(GitVersionContext context)
        {
            // If current commit is tagged, don't do anything except add build metadata
            if (context.IsCurrentCommitTagged)
            {
                // Will always be 0, don't bother with the +0 on tags
                var semanticVersionBuildMetaData = metaDataCalculator.Create(context.CurrentCommit, context);
                semanticVersionBuildMetaData.CommitsSinceTag = null;
                var semanticVersion = new SemanticVersion(context.CurrentCommitTaggedVersion)
                {
                    BuildMetaData = semanticVersionBuildMetaData
                };
                return semanticVersion;
            }

            var baseVersion = baseVersionFinder.GetBaseVersion(context);

            if (baseVersion.ShouldIncrement) IncrementVersion(context, baseVersion);
            else Logger.WriteInfo("Skipping version increment");

            if (!baseVersion.SemanticVersion.PreReleaseTag.HasTag() && !string.IsNullOrEmpty(context.Configuration.Tag))
            {
                UpdatePreReleaseTag(context, baseVersion);
            }

            baseVersion.SemanticVersion.BuildMetaData = metaDataCalculator.Create(baseVersion.BaseVersionSource, context);

            return baseVersion.SemanticVersion;
        }
コード例 #10
0
 public override IEnumerable<BaseVersion> GetVersions(GitVersionContext context)
 {
     var baseVersionSource = context.Repository.Commits.QueryBy(new CommitFilter
     {
         IncludeReachableFrom = context.CurrentBranch.Tip
     }).First(c => !c.Parents.Any());
     yield return new BaseVersion("Fallback base version", false, new SemanticVersion(minor: 1), baseVersionSource, null);
 }
コード例 #11
0
 public SemanticVersion FindVersion(GitVersionContext context)
 {
     var repositoryDirectory = context.Repository.Info.WorkingDirectory;
     var lastTaggedReleaseFinder = new LastTaggedReleaseFinder(context);
     var nextVersionTxtFileFinder = new NextVersionTxtFileFinder(repositoryDirectory);
     var nextSemverCalculator = new NextSemverCalculator(nextVersionTxtFileFinder, lastTaggedReleaseFinder, context);
     return new BuildNumberCalculator(nextSemverCalculator, lastTaggedReleaseFinder, context.Repository).GetBuildNumber(context);
 }
コード例 #12
0
        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;
            }
        }
コード例 #13
0
        public SemanticVersion FindVersion(GitVersionContext context)
        {
            var issueNumber = ExtractIssueNumber(context);

            var version = FindVersion(context, BranchType.PullRequest);
            version.PreReleaseTag = new SemanticVersionPreReleaseTag("PullRequest", int.Parse(issueNumber));
            //TODO version.Version.BuildMetaData = NumberOfCommitsOnBranchSinceCommit(context.CurrentBranch, commonAncestor);
            return version;
        }
コード例 #14
0
        public override IEnumerable<BaseVersion> GetVersions(GitVersionContext context)
        {
            if (context.Configuration.IsCurrentBranchDevelop)
            {
                return ReleaseBranchBaseVersions(context).Union(MasterTagsVersions(context));
            }

            return new BaseVersion[0];
        }
コード例 #15
0
 IEnumerable<BaseVersion> GetReleaseVersion(GitVersionContext context, Branch releaseBranch)
 {
     var tagPrefixRegex = context.Configuration.GitTagPrefix;
     var repository = context.Repository;
     var baseSource = releaseBranch.FindMergeBase(context.CurrentBranch, repository);
     return releaseVersionStrategy
         .GetVersions(tagPrefixRegex, releaseBranch, repository)
         .Select(b => new BaseVersion(b.Source, true, b.SemanticVersion, baseSource, b.BranchNameOverride));
 }
コード例 #16
0
ファイル: BaseVersion.cs プロジェクト: asbjornu/GitVersion
 public BaseVersion(GitVersionContext context, string source, bool shouldIncrement, SemanticVersion semanticVersion, Commit baseVersionSource, string branchNameOverride)
 {
     Source = source;
     ShouldIncrement = shouldIncrement;
     SemanticVersion = semanticVersion;
     BaseVersionSource = baseVersionSource;
     BranchNameOverride = branchNameOverride;
     _context = context;
 }
コード例 #17
0
 public override IEnumerable<BaseVersion> GetVersions(GitVersionContext context)
 {
     var versionInBranch = GetVersionInBranch(context);
     if (versionInBranch != null)
     {
         var commitBranchWasBranchedFrom = context.CurrentBranch.FindCommitBranchWasBranchedFrom(context.Repository);
         var branchNameOverride = context.CurrentBranch.Name.RegexReplace("[-/]" + versionInBranch.Item1, string.Empty);
         yield return new BaseVersion("Version in branch name", false, versionInBranch.Item2, commitBranchWasBranchedFrom, branchNameOverride);
     }
 }
コード例 #18
0
        private IEnumerable<BaseVersion> MasterTagsVersions(GitVersionContext context)
        {
            var master = context.Repository.FindBranch("master");
            if (master != null)
            {
                return taggedCommitVersionStrategy.GetTaggedVersions(context, master, null);
            }

            return new BaseVersion[0];
        }
コード例 #19
0
        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;
        }
コード例 #20
0
 public IEnumerable<BaseVersion> GetVersions(GitVersionContext context, string tagPrefixRegex, Branch currentBranch, IRepository repository)
 {
     var branchName = currentBranch.FriendlyName;
     var versionInBranch = GetVersionInBranch(branchName, tagPrefixRegex);
     if (versionInBranch != null)
     {
         var commitBranchWasBranchedFrom = currentBranch.FindCommitBranchWasBranchedFrom(repository);
         var branchNameOverride = branchName.RegexReplace("[-/]" + versionInBranch.Item1, string.Empty);
         yield return new BaseVersion(context, "Version in branch name", false, versionInBranch.Item2, commitBranchWasBranchedFrom.Commit, branchNameOverride);
     }
 }
コード例 #21
0
        public override BaseVersion GetVersion(GitVersionContext context)
        {
            VersionTaggedCommit version;
            if (GetVersion(context, out version))
            {
                var shouldUpdateVersion = version.Commit.Sha != context.CurrentCommit.Sha;
                return new BaseVersion(string.Format("Git tag '{0}'", version.Tag), shouldUpdateVersion, version.SemVer, version.Commit, null);
            }

            return null;
        }
コード例 #22
0
 private static 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 Logger.WriteInfo("Skipping version increment");
     return semver;
 }
コード例 #23
0
ファイル: PullVersionFinder.cs プロジェクト: hbre/GitVersion
        string ExtractIssueNumber(GitVersionContext context)
        {
            var issueNumber = GitHelper.ExtractIssueNumber(context.CurrentBranch.CanonicalName);

            if (!GitHelper.LooksLikeAValidPullRequestNumber(issueNumber))
            {
                throw new WarningException(string.Format("Unable to extract pull request number from '{0}'.", context.CurrentBranch.CanonicalName));
            }

            return issueNumber;
        }
コード例 #24
0
        public override BaseVersion GetVersion(GitVersionContext context)
        {
            var versionInBranch = GetVersionInBranch(context);
            if (versionInBranch != null)
            {
                var commitBranchWasBranchedFrom = context.CurrentBranch.FindCommitBranchWasBranchedFrom(context.Repository, context.OnlyEvaluateTrackedBranches);
                var branchNameOverride = context.CurrentBranch.Name.RegexReplace("[-/]" + versionInBranch.Item1, string.Empty);
                return new BaseVersion("Version in branch name", false, versionInBranch.Item2, commitBranchWasBranchedFrom, branchNameOverride);
            }

            return null;
        }
コード例 #25
0
        protected override bool IsValidTag(GitVersionContext context, string branchName, Tag tag, Commit commit)
        {
            if (!string.IsNullOrWhiteSpace(branchName))
            {
                if (context.Configuration.TrackMergeTarget)
                {
                    return IsDirectMergeFromCommit(tag, commit);
                }
            }

            return base.IsValidTag(context, branchName, tag, commit);
        }
コード例 #26
0
        void UpdatePreReleaseTag(GitVersionContext context, SemanticVersion semanticVersion, string branchNameOverride)
        {
            var tagToUse = context.Configuration.Tag;
            if (tagToUse == "useBranchName")
            {
                tagToUse = "{BranchName}";
            }
            if (tagToUse.Contains("{BranchName}"))
            {
                Logger.WriteInfo("Using branch name to calculate version tag");

                var branchName = branchNameOverride ?? context.CurrentBranch.FriendlyName;
                if (!string.IsNullOrWhiteSpace(context.Configuration.BranchPrefixToTrim))
                {
                    branchName = branchName.RegexReplace(context.Configuration.BranchPrefixToTrim, string.Empty, RegexOptions.IgnoreCase);
                }
                branchName = branchName.RegexReplace("[^a-zA-Z0-9-]", "-");

                tagToUse = tagToUse.Replace("{BranchName}", branchName);
            }

            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 = context.CurrentBranch
                .GetVersionTagsOnBranch(context.Repository, context.Configuration.GitTagPrefix)
                .FirstOrDefault(v => v.PreReleaseTag.Name == tagToUse);

            if (number == null &&
                lastTag != null &&
                MajorMinorPatchEqual(lastTag, semanticVersion) &&
                lastTag.PreReleaseTag.HasTag())
            {
                number = lastTag.PreReleaseTag.Number + 1;
            }

            if (number == null)
            {
                number = 1;
            }

            semanticVersion.PreReleaseTag = new SemanticVersionPreReleaseTag(tagToUse, number);
        }
コード例 #27
0
        Tuple<string, SemanticVersion> GetVersionInBranch(GitVersionContext context)
        {
            var branchParts = context.CurrentBranch.Name.Split('/', '-');
            foreach (var part in branchParts)
            {
                SemanticVersion semanticVersion;
                if (SemanticVersion.TryParse(part, context.Configuration.GitTagPrefix, out semanticVersion))
                {
                    return Tuple.Create(part, semanticVersion);
                }
            }

            return null;
        }
コード例 #28
0
        public override IEnumerable<BaseVersion> GetVersions(GitVersionContext context)
        {
            string currentBranchName = null;
            var head = context.Repository.Head;
            if (head != null)
            {
                currentBranchName = head.CanonicalName;
            }

            var olderThan = context.CurrentCommit.When();
            var allTags = context.Repository.Tags
                .Where(tag => ((Commit)tag.PeeledTarget()).When() <= olderThan)
                .ToList();
            var tagsOnBranch = context.CurrentBranch
                .Commits
                .SelectMany(commit =>
                {
                    return allTags.Where(t => IsValidTag(context, currentBranchName, t, commit));
                })
                .Select(t =>
                {
                    SemanticVersion version;
                    if (SemanticVersion.TryParse(t.Name, context.Configuration.GitTagPrefix, out version))
                    {
                        var commit = t.PeeledTarget() as Commit;
                        if (commit != null)
                            return new VersionTaggedCommit(commit, version, t.Name);
                    }
                    return null;
                })
                .Where(a => a != null)
                .ToList();

            if (tagsOnBranch.Count == 0)
            {
                yield break;
            }
            if (tagsOnBranch.Count == 1)
            {
                yield return CreateBaseVersion(context, tagsOnBranch[0]);
            }

            foreach (var result in tagsOnBranch.Select(t => CreateBaseVersion(context, t)))
            {
                yield return result;
            }
        }
コード例 #29
0
 static SemanticVersionPreReleaseTag RetrieveMostRecentOptionalTagVersion(GitVersionContext context, List<Tag> applicableTagsInDescendingOrder)
 {
     if (applicableTagsInDescendingOrder.Any())
     {
         var taggedCommit = applicableTagsInDescendingOrder.First().PeeledTarget();
         var preReleaseVersion = applicableTagsInDescendingOrder.Select(tag => SemanticVersion.Parse(tag.FriendlyName, context.Configuration.GitTagPrefix)).FirstOrDefault();
         if (preReleaseVersion != null)
         {
             if (taggedCommit != context.CurrentCommit)
             {
                 preReleaseVersion.PreReleaseTag.Number++;
             }
             return preReleaseVersion.PreReleaseTag;
         }
     }
     return null;
 }
コード例 #30
0
        IEnumerable<BaseVersion> GetReleaseVersion(GitVersionContext context, Branch releaseBranch)
        {
            var tagPrefixRegex = context.Configuration.GitTagPrefix;
            var repository = context.Repository;

            // Find the commit where the child branch was created.
            var baseSource = context.RepositoryMetadataProvider.FindMergeBase(releaseBranch, context.CurrentBranch);
            if (baseSource == context.CurrentCommit)
            {
                // Ignore the branch if it has no commits.
                return new BaseVersion[0];
            }

            return releaseVersionStrategy
                .GetVersions(context, tagPrefixRegex, releaseBranch, repository)
                .Select(b => new BaseVersion(context, b.Source, true, b.SemanticVersion, baseSource, b.BranchNameOverride));
        }
コード例 #31
0
 private void FixTheBaseVersionSourceOfMergeMessageStrategyIfReleaseBranchWasMergedAndDeleted(
     GitVersionContext context, List <Versions> baseVersions)
 {
     if (!ReleaseBranchExistsInRepo(context))
     {
         foreach (var baseVersion in baseVersions)
         {
             if (baseVersion.Version.Source.Contains(
                     MergeMessageBaseVersionStrategy.MergeMessageStrategyPrefix) &&
                 baseVersion.Version.Source.Contains("Merge branch") &&
                 baseVersion.Version.Source.Contains("release"))
             {
                 var parents = baseVersion.Version.BaseVersionSource.Parents.ToList();
                 baseVersion.Version = new BaseVersion(
                     context,
                     baseVersion.Version.Source,
                     baseVersion.Version.ShouldIncrement,
                     baseVersion.Version.SemanticVersion,
                     context.Repository.ObjectDatabase.FindMergeBase(parents[0], parents[1]),
                     baseVersion.Version.BranchNameOverride);
             }
         }
     }
 }
コード例 #32
0
        public SemanticVersionBuildMetaData Create(Commit baseVersionSource, GitVersionContext context)
        {
            var qf = new CommitFilter
            {
                IncludeReachableFrom = context.CurrentCommit,
                ExcludeReachableFrom = baseVersionSource,
                SortBy = CommitSortStrategies.Topological | CommitSortStrategies.Time
            };

            var commitLog       = context.Repository.Commits.QueryBy(qf);
            var commitsSinceTag = commitLog.Count();

            context.Log.Info($"{commitsSinceTag} commits found between {baseVersionSource.Sha} and {context.CurrentCommit.Sha}");

            var shortSha = context.Repository.ObjectDatabase.ShortenObjectId(context.CurrentCommit);

            return(new SemanticVersionBuildMetaData(
                       baseVersionSource.Sha,
                       commitsSinceTag,
                       context.CurrentBranch.FriendlyName,
                       context.CurrentCommit.Sha,
                       shortSha,
                       context.CurrentCommit.When()));
        }
コード例 #33
0
        void UpdatePreReleaseTag(GitVersionContext context, SemanticVersion semanticVersion, string branchNameOverride)
        {
            var tagToUse = GetBranchSpecificTag(context.Configuration, context.CurrentBranch.FriendlyName, branchNameOverride);

            int?number = null;

            var lastTag = context.RepositoryMetadataProvider
                          .GetVersionTagsOnBranch(context.CurrentBranch, context.Configuration.GitTagPrefix)
                          .FirstOrDefault(v => v.PreReleaseTag.Name == tagToUse);

            if (lastTag != null &&
                MajorMinorPatchEqual(lastTag, semanticVersion) &&
                lastTag.PreReleaseTag.HasTag())
            {
                number = lastTag.PreReleaseTag.Number + 1;
            }

            if (number == null)
            {
                number = 1;
            }

            semanticVersion.PreReleaseTag = new SemanticVersionPreReleaseTag(tagToUse, number);
        }
コード例 #34
0
 public override BaseVersion GetVersion(GitVersionContext context)
 {
     return(new BaseVersion("Source 1", false, new SemanticVersion(1), when, null));
 }
コード例 #35
0
 public override BaseVersion GetVersion(GitVersionContext context)
 {
     return(new BaseVersion("Source 2", true, new SemanticVersion(2), when, null));
 }
コード例 #36
0
 public abstract SemanticVersionPreReleaseTag GetPreReleaseTag(GitVersionContext context, List <Tag> possibleTags, int numberOfCommits);
コード例 #37
0
 public override IEnumerable <BaseVersion> GetVersions(GitVersionContext context)
 {
     return(GetTaggedVersions(context, context.CurrentBranch, context.CurrentCommit.When()));
 }
コード例 #38
0
 /// <summary>
 /// Calculates the <see cref="BaseVersion"/> values for the given <paramref name="context"/>.
 /// </summary>
 /// <param name="context">
 /// The context for calculating the <see cref="BaseVersion"/>.
 /// </param>
 /// <returns>
 /// An <see cref="IEnumerable{BaseVersion}"/> of the base version values found by the strategy.
 /// </returns>
 public abstract IEnumerable <BaseVersion> GetVersions(GitVersionContext context);
コード例 #39
0
 private static bool TryParse(Commit mergeCommit, GitVersionContext context, out MergeMessage mergeMessage)
 {
     mergeMessage = Inner(mergeCommit, context);
     return(mergeMessage != null);
 }
コード例 #40
0
        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
                {
                    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.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);
            }
        }
コード例 #41
0
        // TODO I think we need to take a fresh approach to this.. it's getting really complex with heaps of edge cases
        static BranchConfig InheritBranchConfiguration(GitVersionContext context, Branch targetBranch, BranchConfig branchConfiguration, IList <Branch> excludedInheritBranches)
        {
            var repository = context.Repository;
            var config     = context.FullConfiguration;

            using (Logger.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 = context.CurrentCommit.Parents.Count();
                if (parentCount == 2)
                {
                    excludedBranches = CalculateWhenMultipleParents(repository, context.CurrentCommit, ref targetBranch, excludedBranches);
                }

                if (excludedInheritBranches == null)
                {
                    excludedInheritBranches = repository.Branches.Where(b =>
                    {
                        var branchConfig = config.GetConfigForBranch(b.NameWithoutRemote());

                        return(branchConfig == null || branchConfig.Increment == IncrementStrategy.Inherit);
                    }).ToList();
                }
                // Add new excluded branches.
                foreach (var excludedBranch in excludedBranches.ExcludingBranches(excludedInheritBranches))
                {
                    excludedInheritBranches.Add(excludedBranch);
                }
                var branchesToEvaluate = repository.Branches.ExcludingBranches(excludedInheritBranches).ToList();

                var branchPoint = context.RepositoryMetadataProvider
                                  .FindCommitBranchWasBranchedFrom(targetBranch, excludedInheritBranches.ToArray());
                List <Branch> possibleParents;
                if (branchPoint == BranchCommit.Empty)
                {
                    possibleParents = context.RepositoryMetadataProvider.GetBranchesContainingCommit(targetBranch.Tip, branchesToEvaluate, true)
                                      // 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 = context.RepositoryMetadataProvider
                                   .GetBranchesContainingCommit(branchPoint.Commit, branchesToEvaluate, true).ToList();
                    if (branches.Count > 1)
                    {
                        var currentTipBranches = context.RepositoryMetadataProvider
                                                 .GetBranchesContainingCommit(context.CurrentCommit, branchesToEvaluate, true).ToList();
                        possibleParents = branches.Except(currentTipBranches).ToList();
                    }
                    else
                    {
                        possibleParents = branches;
                    }
                }

                Logger.WriteInfo("Found possible parent branches: " + string.Join(", ", possibleParents.Select(p => p.FriendlyName)));

                if (possibleParents.Count == 1)
                {
                    var branchConfig = GetBranchConfiguration(context, possibleParents[0], 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
                string errorMessage;
                if (possibleParents.Count == 0)
                {
                    errorMessage = "Failed to inherit Increment branch configuration, no branches found.";
                }
                else
                {
                    errorMessage = "Failed to inherit Increment branch configuration, ended up with: " + string.Join(", ", possibleParents.Select(p => p.FriendlyName));
                }

                var developBranchRegex = config.Branches[ConfigurationProvider.DevelopBranchKey].Regex;
                var masterBranchRegex  = config.Branches[ConfigurationProvider.MasterBranchKey].Regex;

                var chosenBranch = repository.Branches.FirstOrDefault(b => Regex.IsMatch(b.FriendlyName, developBranchRegex, RegexOptions.IgnoreCase) ||
                                                                      Regex.IsMatch(b.FriendlyName, masterBranchRegex, RegexOptions.IgnoreCase));
                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.");
                }

                var branchName = chosenBranch.FriendlyName;
                Logger.WriteWarning(errorMessage + Environment.NewLine + Environment.NewLine + "Falling back to " + branchName + " branch config");

                // To prevent infinite loops, make sure that a new branch was chosen.
                if (targetBranch.IsSameBranch(chosenBranch))
                {
                    BranchConfig developOrMasterConfig =
                        ChooseMasterOrDevelopIncrementStrategyIfTheChosenBranchIsOneOfThem(
                            chosenBranch, branchConfiguration, config);
                    if (developOrMasterConfig != null)
                    {
                        return(developOrMasterConfig);
                    }
                    else
                    {
                        Logger.WriteWarning("Fallback branch wants to inherit Increment branch configuration from itself. Using patch increment instead.");
                        return(new BranchConfig(branchConfiguration)
                        {
                            Increment = IncrementStrategy.Patch
                        });
                    }
                }

                var inheritingBranchConfig = GetBranchConfiguration(context, chosenBranch, excludedInheritBranches);
                var configIncrement        = inheritingBranchConfig.Increment;
                if (inheritingBranchConfig.Name == FallbackConfigName && configIncrement == IncrementStrategy.Inherit)
                {
                    Logger.WriteWarning("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
                });
            }
        }
コード例 #42
0
 public override SemanticVersionPreReleaseTag GetPreReleaseTag(GitVersionContext context, List <Tag> possibleTags, int numberOfCommits)
 {
     return(context.Configuration.Tag + "." + numberOfCommits);
 }
コード例 #43
0
        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);
            }
        }
コード例 #44
0
        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);
            }
        }
コード例 #45
0
 public BranchConfigurationCalculator(ILog log, GitVersionContext context)
 {
     this.log     = log ?? throw new ArgumentNullException(nameof(log));
     this.context = context;
 }
コード例 #46
0
 public override IEnumerable <BaseVersion> GetVersions(GitVersionContext context)
 {
     return(versions);
 }
コード例 #47
0
 public override IEnumerable <BaseVersion> GetVersions(GitVersionContext context)
 {
     yield return(new BaseVersion(context, "Source 2", true, new SemanticVersion(2), when, null));
 }
コード例 #48
0
 public override IEnumerable <BaseVersion> GetVersions(GitVersionContext context)
 {
     yield return(new BaseVersion("Source 1", false, new SemanticVersion(1), when, null));
 }
コード例 #49
0
 public BaseVersion GetBaseVersion(GitVersionContext context)
 {
     return(new BaseVersion(context, "Test source", shouldIncrement, semanticVersion, source, null));
 }
コード例 #50
0
 public virtual IEnumerable <BaseVersion> GetVersions(GitVersionContext context)
 {
     return(versions);
 }
コード例 #51
0
 public SemanticVersion FindVersion(GitVersionContext context)
 {
     return(FindVersion(context, BranchType.Hotfix, "master"));
 }
コード例 #52
0
 static SemanticVersion MaybeIncrement(GitVersionContext context, BaseVersion version)
 {
     return(version.ShouldIncrement ? version.SemanticVersion.IncrementVersion(context.Configuration.Increment) : version.SemanticVersion);
 }
コード例 #53
0
 protected virtual bool IsValidTag(GitVersionContext context, string branchName, Tag tag, Commit commit)
 {
     return(tag.PeeledTarget() == commit);
 }
コード例 #54
0
        static SemanticVersion ExecuteGitVersion(GitVersionContext context)
        {
            var vf = new GitVersionFinder();

            return(vf.FindVersion(context));
        }
コード例 #55
0
 public SemanticVersionBuildMetaData Create(Commit baseVersionSource, GitVersionContext context)
 {
     return(metaData);
 }
コード例 #56
0
 public override BaseVersion GetVersion(GitVersionContext context)
 {
     return(new BaseVersion("Fallback base version", false, new SemanticVersion(minor: 1), context.CurrentBranch.Commits.Last(), null));
 }
コード例 #57
0
        static Branch GetMainline(GitVersionContext context, Commit baseVersionSource)
        {
            var mainlineBranchConfigs = context.FullConfiguration.Branches.Where(b => b.Value.IsMainline == true).ToList();
            var mainlineBranches      = context.Repository.Branches
                                        .Where(b =>
            {
                return(mainlineBranchConfigs.Any(c => Regex.IsMatch(b.FriendlyName, c.Value.Regex)));
            })
                                        .Select(b => new
            {
                MergeBase = context.Repository.ObjectDatabase.FindMergeBase(b.Tip, context.CurrentCommit),
                Branch    = b
            })
                                        .Where(a => a.MergeBase != null)
                                        .GroupBy(b => b.MergeBase.Sha, b => b.Branch)
                                        .ToDictionary(b => b.Key, b => b.ToList());

            var allMainlines = mainlineBranches.Values.SelectMany(branches => branches.Select(b => b.FriendlyName));

            Logger.WriteInfo("Found possible mainline branches: " + string.Join(", ", allMainlines));

            // Find closest mainline branch
            var firstMatchingCommit      = context.CurrentBranch.Commits.First(c => mainlineBranches.ContainsKey(c.Sha));
            var possibleMainlineBranches = mainlineBranches[firstMatchingCommit.Sha];

            if (possibleMainlineBranches.Count == 1)
            {
                var mainlineBranch = possibleMainlineBranches[0];
                Logger.WriteInfo("Mainline for current branch is " + mainlineBranch.FriendlyName);
                return(mainlineBranch);
            }

            // prefer current branch, if it is a mainline branch
            if (possibleMainlineBranches.Any(context.CurrentBranch.IsSameBranch))
            {
                Logger.WriteInfo($"Choosing {context.CurrentBranch.FriendlyName} as mainline because it is the current branch");
                return(context.CurrentBranch);
            }

            // prefer a branch on which the merge base was a direct commit, if there is such a branch
            var firstMatchingCommitBranch = possibleMainlineBranches
                                            .FirstOrDefault(b =>
            {
                var filter = new CommitFilter
                {
                    IncludeReachableFrom = b,
                    ExcludeReachableFrom = baseVersionSource,
                    FirstParentOnly      = true,
                };
                var query = context.Repository.Commits.QueryBy(filter);

                return(query.Contains(firstMatchingCommit));
            });

            if (firstMatchingCommitBranch != null)
            {
                var message = string.Format(
                    "Choosing {0} as mainline because {1}'s merge base was a direct commit to {0}",
                    firstMatchingCommitBranch.FriendlyName,
                    context.CurrentBranch.FriendlyName);
                Logger.WriteInfo(message);

                return(firstMatchingCommitBranch);
            }

            var chosenMainline = possibleMainlineBranches[0];

            Logger.WriteInfo($"Multiple mainlines ({string.Join(", ", possibleMainlineBranches.Select(b => b.FriendlyName))}) have the same merge base for the current branch, choosing {chosenMainline.FriendlyName} because we found that branch first...");
            return(chosenMainline);
        }
コード例 #58
0
 private static SemanticVersionPreReleaseTag RetrieveMostRecentOptionalTagVersion(GitVersionContext context, IReadOnlyCollection <Tag> applicableTagsInDescendingOrder)
 {
     if (applicableTagsInDescendingOrder.Any())
     {
         var taggedCommit      = applicableTagsInDescendingOrder.First().PeeledTarget();
         var preReleaseVersion = applicableTagsInDescendingOrder.Select(tag => SemanticVersion.Parse(tag.FriendlyName, context.Configuration.GitTagPrefix)).FirstOrDefault();
         if (preReleaseVersion != null)
         {
             if (taggedCommit != context.CurrentCommit)
             {
                 preReleaseVersion.PreReleaseTag.Number++;
             }
             return(preReleaseVersion.PreReleaseTag);
         }
     }
     return(null);
 }
コード例 #59
0
        private static VersionField TryFindIncrementFromMergeMessage(Commit mergeCommit, GitVersionContext context)
        {
            if (mergeCommit != null)
            {
                var mergeMessage = new MergeMessage(mergeCommit.Message, context.FullConfiguration);
                if (mergeMessage.MergedBranch != null)
                {
                    var config = context.FullConfiguration.GetConfigForBranch(mergeMessage.MergedBranch);
                    if (config != null && config.Increment.HasValue && config.Increment != IncrementStrategy.Inherit)
                    {
                        return(config.Increment.Value.ToVersionField());
                    }
                }
            }

            // Fallback to config increment value
            return(IncrementStrategyFinder.FindDefaultIncrementForBranch(context));
        }
コード例 #60
0
 public override SemanticVersionPreReleaseTag GetPreReleaseTag(GitVersionContext context, List <Tag> possibleCommits, int numberOfCommits)
 {
     return(RetrieveMostRecentOptionalTagVersion(context, possibleCommits) ?? context.Configuration.Tag + ".1");
 }