Contextual information about where GitVersion is being run
示例#1
0
        public VersionPoint Execute(GitVersionContext context, DateTimeOffset olderThan)
        {
            var masterBranch = context.Repository.FindBranch("master");
            foreach (var commit in masterBranch.CommitsPriorToThan(olderThan))
            {
                foreach (var tag in context.Repository.TagsByDate(commit))
                {
                    SemanticVersion semanticVersion;
                    if (SemanticVersion.TryParse(tag.Name, context.Configuration.TagPrefix, out semanticVersion))
                    {
                        return new VersionPoint
                        {
                            Major = semanticVersion.Major,
                            Minor = semanticVersion.Minor,
                        };
                    }
                }

                SemanticVersion semanticVersionFromMergeMessage;
                if (MergeMessageParser.TryParse(commit, context.Configuration, out semanticVersionFromMergeMessage))
                {
                    return new VersionPoint
                    {
                        Major = semanticVersionFromMergeMessage.Major,
                        Minor = semanticVersionFromMergeMessage.Minor,
                    };
                }
            }
            return new VersionPoint
            {
                Major = 0,
                Minor = 1,
            };
        }
        private static VersionField? FindCommitMessageIncrement(GitVersionContext context, BaseVersion baseVersion)
        {
            if (context.Configuration.CommitMessageIncrementing == CommitMessageIncrementMode.Disabled)
            {
                return null;
            }

            var commits = GetIntermediateCommits(context.Repository, baseVersion.BaseVersionSource, context.CurrentCommit);

            if (context.Configuration.CommitMessageIncrementing == CommitMessageIncrementMode.MergeMessageOnly)
            {
                commits = commits.Where(c => c.Parents.Count() > 1);
            }

            var majorRegex = CreateRegex(context.Configuration.MajorVersionBumpMessage ?? DefaultMajorPattern);
            var minorRegex = CreateRegex(context.Configuration.MinorVersionBumpMessage ?? DefaultMinorPattern);
            var patchRegex = CreateRegex(context.Configuration.PatchVersionBumpMessage ?? DefaultPatchPattern);

            var increments = commits
                .Select(c => FindIncrementFromMessage(c.Message, majorRegex, minorRegex, patchRegex))
                .Where(v => v != null)
                .Select(v => v.Value)
                .ToList();

            if (increments.Any())
            {
                return increments.Max();
            }

            return null;
        }
示例#3
0
    public static Tuple<CachedVersion, GitVersionContext> GetVersion(string gitDirectory, Config configuration)
    {
        using (var repo = RepositoryLoader.GetRepo(gitDirectory))
        {
            var versionFinder = new GitVersionFinder();
            var context = new GitVersionContext(repo, configuration);
            var ticks = DirectoryDateFinder.GetLastDirectoryWrite(gitDirectory);
            var key = string.Format("{0}:{1}:{2}", repo.Head.CanonicalName, repo.Head.Tip.Sha, ticks);

            Tuple<CachedVersion, GitVersionContext> result;
            if (versionCacheVersions.TryGetValue(key, out result))
            {
                if (result.Item1.Timestamp != ticks)
                {
                    Logger.WriteInfo("Change detected. flushing cache.");
                    result.Item1.SemanticVersion = versionFinder.FindVersion(context);
                }
                return result;
            }
            Logger.WriteInfo("Version not in cache. Calculating version.");

            return versionCacheVersions[key] = Tuple.Create(new CachedVersion
            {
                SemanticVersion = versionFinder.FindVersion(context),
                Timestamp = ticks
            }, context);
        }
    }
        protected SemanticVersion FindVersion(
            GitVersionContext context,
            BranchType branchType)
        {
            var ancestor = FindCommonAncestorWithDevelop(context.Repository, context.CurrentBranch, branchType);

            if (!IsThereAnyCommitOnTheBranch(context.Repository, context.CurrentBranch))
            {
                var developVersionFinder = new DevelopVersionFinder();
                return developVersionFinder.FindVersion(context);
            }

            var versionOnMasterFinder = new VersionOnMasterFinder();
            var versionFromMaster = versionOnMasterFinder.Execute(context, context.CurrentBranch.Tip.Committer.When);

            var numberOfCommitsOnBranchSinceCommit = NumberOfCommitsOnBranchSinceCommit(context, ancestor);
            var sha = context.CurrentBranch.Tip.Sha;
            var releaseDate = ReleaseDateFinder.Execute(context.Repository, sha, 0);
            var semanticVersion = new SemanticVersion
            {
                Major = versionFromMaster.Major,
                Minor = versionFromMaster.Minor + 1,
                Patch = 0,
                PreReleaseTag = "unstable0",
                BuildMetaData = new SemanticVersionBuildMetaData(
                    numberOfCommitsOnBranchSinceCommit,
                    context.CurrentBranch.Name, releaseDate)
            };

            return semanticVersion;
        }
        protected SemanticVersion FindVersion(
            GitVersionContext context,
            BranchType branchType)
        {
            var ancestor = FindCommonAncestorWithDevelop(context.Repository, context.CurrentBranch, branchType);

            if (!IsThereAnyCommitOnTheBranch(context.Repository, context.CurrentBranch))
            {
                var developVersionFinder = new DevelopVersionFinder();
                return developVersionFinder.FindVersion(context);
            }

            var versionOnMasterFinder = new VersionOnMasterFinder();
            var versionFromMaster = versionOnMasterFinder.Execute(context, context.CurrentCommit.When());

            var numberOfCommitsOnBranchSinceCommit = NumberOfCommitsOnBranchSinceCommit(context, ancestor);
            var preReleaseTag = context.CurrentBranch.Name
                .TrimStart(branchType.ToString() + '-')
                .TrimStart(branchType.ToString() + '/');
            var semanticVersion = new SemanticVersion
            {
                Major = versionFromMaster.Major,
                Minor = versionFromMaster.Minor + 1,
                Patch = 0,
                PreReleaseTag = preReleaseTag,
                BuildMetaData = new SemanticVersionBuildMetaData(
                    numberOfCommitsOnBranchSinceCommit,
                    context.CurrentBranch.Name, context.CurrentCommit.Sha, context.CurrentCommit.When())
            };

            semanticVersion.OverrideVersionManuallyIfNeeded(context.Repository, context.Configuration);

            return semanticVersion;
        }
        /// <summary>
        /// Gets the <see cref="BranchConfig"/> for the current commit.
        /// </summary>
        public static BranchConfig GetBranchConfiguration(GitVersionContext context, Branch targetBranch, IList<Branch> excludedInheritBranches = null)
        {
            var matchingBranches = LookupBranchConfiguration(context.FullConfiguration, targetBranch).ToArray();

            BranchConfig branchConfiguration;
            if (matchingBranches.Length > 0)
            {
                branchConfiguration = matchingBranches[0];

                if (matchingBranches.Length > 1)
                {
                    Logger.WriteWarning(string.Format(
                        "Multiple branch configurations match the current branch branchName of '{0}'. Using the first matching configuration, '{1}'. Matching configurations include: '{2}'",
                        targetBranch.FriendlyName,
                        branchConfiguration.Name,
                        string.Join("', '", matchingBranches.Select(b => b.Name))));
                }
            }
            else
            {
                Logger.WriteInfo(string.Format(
                    "No branch configuration found for branch {0}, falling back to default configuration",
                    targetBranch.FriendlyName));

                branchConfiguration = new BranchConfig { Name = string.Empty };
                ConfigurationProvider.ApplyBranchDefaults(context.FullConfiguration, branchConfiguration, "");
            }

            return branchConfiguration.Increment == IncrementStrategy.Inherit ?
                InheritBranchConfiguration(context, targetBranch, branchConfiguration, excludedInheritBranches) :
                branchConfiguration;
        }
示例#7
0
    public static CachedVersion GetVersion(string gitDirectory, Config configuration)
    {
        using (var repo = RepositoryLoader.GetRepo(gitDirectory))
        {
            var versionFinder = new GitVersionFinder();
            var context = new GitVersionContext(repo, configuration);
            var ticks = DirectoryDateFinder.GetLastDirectoryWrite(gitDirectory);
            var key = string.Format("{0}:{1}:{2}", repo.Head.CanonicalName, repo.Head.Tip.Sha, ticks);
            CachedVersion cachedVersion;
            if (versionCacheVersions.TryGetValue(key, out cachedVersion))
            {
                if (cachedVersion.Timestamp != ticks)
                {
                    Logger.WriteInfo("Change detected. flushing cache.");
                    cachedVersion.SemanticVersion = versionFinder.FindVersion(context);
                    cachedVersion.MasterReleaseDate = LastMinorVersionFinder.Execute(repo, new Config(), repo.Head.Tip);
                }
                return cachedVersion;
            }
            Logger.WriteInfo("Version not in cache. Calculating version.");

            return versionCacheVersions[key] = new CachedVersion
            {
                SemanticVersion = versionFinder.FindVersion(context),
                MasterReleaseDate = LastMinorVersionFinder.Execute(repo, new Config(), repo.Head.Tip),
                Timestamp = ticks
            };

        }
    }
 public void UsesBranchSpecificConfigOverTopLevelDefaults()
 {
     var config = new Config
     {
         VersioningMode = VersioningMode.ContinuousDelivery,
         Branches =
         {
             {
                 "dev(elop)?(ment)?$", new BranchConfig
                 {
                     VersioningMode = VersioningMode.ContinuousDeployment,
                     Tag = "alpha"
                 }
             }
         }
     };
     ConfigurationProvider.ApplyDefaultsTo(config);
     var develop = new MockBranch("develop") { new MockCommit { CommitterEx = Constants.SignatureNow() } };
     var mockRepository = new MockRepository
     {
         Branches = new MockBranchCollection
         {
             new MockBranch("master") { new MockCommit { CommitterEx = Constants.SignatureNow() } },
             develop
         }
     };
     var context = new GitVersionContext(mockRepository, develop, config);
     context.Configuration.Tag.ShouldBe("alpha");
 }
        // TODO refactor to remove duplication
        string ExtractIssueNumber(GitVersionContext context)
        {
            const string prefix = "/pull/";
            var pullRequestBranch = context.CurrentBranch;

            var start = pullRequestBranch.CanonicalName.IndexOf(prefix, StringComparison.Ordinal);
            var end = pullRequestBranch.CanonicalName.LastIndexOf("/merge", pullRequestBranch.CanonicalName.Length - 1,
                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))
            {
                var message = string.Format("Unable to extract pull request number from '{0}'.", pullRequestBranch.CanonicalName);
                throw new WarningException(message);
            }

            return issueNumber;
        }
示例#10
0
        public bool FindVersion(GitVersionContext context, out SemanticVersion semanticVersion)
        {
            var versionString = GetUnknownBranchSuffix(context.CurrentBranch);
            if (!versionString.Contains("."))
            {
                semanticVersion = null;
                return false;
            }
            var shortVersion = SemanticVersion.Parse(versionString, context.Configuration.TagPrefix);

            var applicableTagsInDescendingOrder = context.Repository.SemVerTagsRelatedToVersion(context.Configuration, shortVersion).OrderByDescending(tag => SemanticVersion.Parse(tag.Name, context.Configuration.TagPrefix)).ToList();
            var nbHotfixCommits = BranchCommitDifferenceFinder.NumberOfCommitsSinceLastTagOrBranchPoint(context, applicableTagsInDescendingOrder, BranchType.Unknown, "master");
            var semanticVersionPreReleaseTag = RecentTagVersionExtractor.RetrieveMostRecentOptionalTagVersion(context, applicableTagsInDescendingOrder) ?? CreateDefaultPreReleaseTag(context, versionString);

            if (semanticVersionPreReleaseTag.Name == "release")
            {
                semanticVersionPreReleaseTag.Name = context.Configuration.ReleaseBranchTag;
            }

            semanticVersion = new SemanticVersion
            {
                Major = shortVersion.Major,
                Minor = shortVersion.Minor,
                Patch = shortVersion.Patch,
                PreReleaseTag = semanticVersionPreReleaseTag,
                BuildMetaData = new SemanticVersionBuildMetaData(nbHotfixCommits, context.CurrentBranch.Name, context.CurrentCommit.Sha, context.CurrentCommit.When())
            };
            return true;
        }
示例#11
0
        public static VersionVariables ExecuteGitVersion(IFileSystem fileSystem, string targetUrl, string dynamicRepositoryLocation, Authentication authentication, string targetBranch, bool noFetch, string workingDirectory, string commitId)
        {
            // Normalise if we are running on build server
            var gitPreparer = new GitPreparer(targetUrl, dynamicRepositoryLocation, authentication, noFetch, workingDirectory);
            var applicableBuildServers = BuildServerList.GetApplicableBuildServers();
            var buildServer = applicableBuildServers.FirstOrDefault();
            var currentBranch = buildServer == null ? null : buildServer.GetCurrentBranch();
            if (!string.IsNullOrEmpty(currentBranch))
            {
                Logger.WriteInfo("Branch from build environment: " + currentBranch);
            }
            gitPreparer.Initialise(buildServer != null, currentBranch ?? targetBranch);
            var dotGitDirectory = gitPreparer.GetDotGitDirectory();
            var projectRoot = gitPreparer.GetProjectRootDirectory();
            Logger.WriteInfo(string.Format("Project root is: " + projectRoot));
            if (string.IsNullOrEmpty(dotGitDirectory) || string.IsNullOrEmpty(projectRoot))
            {
                // TODO Link to wiki article
                throw new Exception(string.Format("Failed to prepare or find the .git directory in path '{0}'.", workingDirectory));
            }
            VersionVariables variables;
            var versionFinder = new GitVersionFinder();
            var configuration = ConfigurationProvider.Provide(projectRoot, fileSystem);

            using (var repo = RepositoryLoader.GetRepo(dotGitDirectory))
            {
                var gitVersionContext = new GitVersionContext(repo, configuration, commitId: commitId);
                var semanticVersion = versionFinder.FindVersion(gitVersionContext);
                var config = gitVersionContext.Configuration;
                variables = VariableProvider.GetVariablesFor(semanticVersion, config.AssemblyVersioningScheme, config.VersioningMode, config.ContinuousDeploymentFallbackTag, gitVersionContext.IsCurrentCommitTagged);
            }

            return variables;
        }
        public static VersionField? DetermineIncrementedField(GitVersionContext context, BaseVersion baseVersion)
        {
            var commitMessageIncrement = FindCommitMessageIncrement(context, baseVersion);
            var defaultIncrement = context.Configuration.Increment.ToVersionField();

            // use the default branch config increment strategy if there are no commit message overrides
            if (commitMessageIncrement == null)
            {
                return baseVersion.ShouldIncrement ? defaultIncrement : (VersionField?)null;
            }

            // cap the commit message severity to minor for alpha versions
            if (baseVersion.SemanticVersion < new SemanticVersion(1) && commitMessageIncrement > VersionField.Minor)
            {
                commitMessageIncrement = VersionField.Minor;
            }

            // don't increment for less than the branch config increment, if the absence of commit messages would have
            // still resulted in an increment of configuration.Increment
            if (baseVersion.ShouldIncrement && commitMessageIncrement < defaultIncrement)
            {
                return defaultIncrement;
            }

            return commitMessageIncrement;
        }
        public SemanticVersion FindVersion(GitVersionContext context)
        {
            var versionOnMasterFinder = new VersionOnMasterFinder();
            var tip = context.CurrentBranch.Tip;
            var versionFromMaster = versionOnMasterFinder.Execute(context, tip.When());

            var f = new CommitFilter
            {
                Since = tip,
                Until = context.Repository.FindBranch("master").Tip,
                SortBy = CommitSortStrategies.Topological | CommitSortStrategies.Time
            };

            var c = context.Repository.Commits.QueryBy(f);
            var numberOfCommitsSinceRelease = c.Count();

            var releaseDate = ReleaseDateFinder.Execute(context.Repository, tip.Sha, 0);
            var semanticVersion = new SemanticVersion
            {
                Major = versionFromMaster.Major,
                Minor = versionFromMaster.Minor + 1,
                Patch = 0,
                PreReleaseTag = "unstable" + numberOfCommitsSinceRelease,
                BuildMetaData = new SemanticVersionBuildMetaData(numberOfCommitsSinceRelease, context.CurrentBranch.Name, releaseDate),
            };
            return semanticVersion;
        }
示例#14
0
        public SemanticVersion FindVersion(GitVersionContext context)
        {
            var versionOnMasterFinder = new VersionOnMasterFinder();
            var tip = context.CurrentCommit;
            var versionFromMaster = versionOnMasterFinder.Execute(context, tip.When());

            var f = new CommitFilter
            {
                Since = tip,
                Until = context.Repository.FindBranch("master").Tip,
                SortBy = CommitSortStrategies.Topological | CommitSortStrategies.Time
            };

            var c = context.Repository.Commits.QueryBy(f);
            var numberOfCommitsSinceRelease = c.Count();

            var semanticVersion = new SemanticVersion
            {
                Major = versionFromMaster.Major,
                Minor = versionFromMaster.Minor + 1,
                Patch = 0,
                PreReleaseTag = context.Configuration.DevelopBranchTag + numberOfCommitsSinceRelease,
                BuildMetaData = new SemanticVersionBuildMetaData(numberOfCommitsSinceRelease, context.CurrentBranch.Name,tip.Sha,tip.When()),
            };

            semanticVersion.OverrideVersionManuallyIfNeeded(context.Repository, context.Configuration);

            return semanticVersion;
        }
示例#15
0
 static SemanticVersion GetSemanticVersion(Repository repository)
 {
     var versionForRepositoryFinder = new GitVersionFinder();
     var gitVersionContext = new GitVersionContext(repository);
     Logger.WriteInfo("Running against branch: " + gitVersionContext.CurrentBranch.Name);
     return versionForRepositoryFinder.FindVersion(gitVersionContext);
 }
        void EnsureHeadIsNotDetached(GitVersionContext context)
        {
            if (!context.CurrentBranch.CanonicalName.Equals("(no branch)", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            var message = string.Format("It looks like the branch being examined is a detached Head pointing to commit '{0}'. Without a proper branch name GitVersion cannot determine the build version.", context.CurrentBranch.Tip.Id.ToString(7));
            throw new ErrorException(message);
        }
示例#17
0
        void EnsureHeadIsNotDetached(GitVersionContext context)
        {
            if (!context.CurrentBranch.IsDetachedHead())
            {
                return;
            }

            var message = string.Format("It looks like the branch being examined is a detached Head pointing to commit '{0}'. Without a proper branch name GitVersion cannot determine the build version.", context.CurrentCommit.Id.ToString(7));
            throw new WarningException(message);
        }
示例#18
0
 public SemanticVersion FindVersion(GitVersionContext context)
 {
     try
     {
         return FindVersion(context, BranchType.Unknown, "master");
     }
     catch (Exception)
     {
         return new SemanticVersion();
     }
 }
 public NextSemverCalculator(
     NextVersionTxtFileFinder nextVersionTxtFileFinder,
     LastTaggedReleaseFinder lastTaggedReleaseFinder,
     GitVersionContext context)
 {
     this.nextVersionTxtFileFinder = nextVersionTxtFileFinder;
     this.lastTaggedReleaseFinder = lastTaggedReleaseFinder;
     mergedBranchesWithVersionFinder = new MergedBranchesWithVersionFinder(context);
     unknownBranchFinder = new OtherBranchVersionFinder();
     this.context = context;
 }
示例#20
0
        int NumberOfCommitsOnBranchSinceCommit(GitVersionContext context, Commit commit)
        {
            var qf = new CommitFilter
            {
                Since = context.CurrentCommit,
                Until = commit,
                SortBy = CommitSortStrategies.Topological | CommitSortStrategies.Time
            };

            return context.Repository.Commits.QueryBy(qf).Count();
        }
示例#21
0
        string ExtractIssueNumber(GitVersionContext context)
        {
            var issueNumber = GitHelper.ExtractIssueNumber(context.CurrentBranch.CanonicalName);

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

            return issueNumber;
        }
示例#22
0
        VersionVariables ExecuteInternal(string targetBranch, string commitId, IRepository repo, GitPreparer gitPreparer, string projectRoot, IBuildServer buildServer)
        {
            gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, gitPreparer.IsDynamicGitRepository));

            var versionFinder = new GitVersionFinder();
            var configuration = ConfigurationProvider.Provide(projectRoot, fileSystem);

            var gitVersionContext = new GitVersionContext(repo, configuration, commitId : commitId);
            var semanticVersion = versionFinder.FindVersion(gitVersionContext);

            return VariableProvider.GetVariablesFor(semanticVersion, gitVersionContext.Configuration, gitVersionContext.IsCurrentCommitTagged);
        }
示例#23
0
        public SemanticVersion FindVersion(GitVersionContext context)
        {
            EnsureMainTopologyConstraints(context);

            if (ShouldGitHubFlowVersioningSchemeApply(context.Repository))
            {
                Logger.WriteInfo("GitHubFlow version strategy will be used");
                return new GitHubFlowVersionFinder().FindVersion(context);
            }

            Logger.WriteInfo("GitFlow version strategy will be used");
            return new GitFlowVersionFinder().FindVersion(context);
        }
示例#24
0
        public SemanticVersion FindVersion(GitVersionContext context)
        {
            Logger.WriteInfo(string.Format("Running against branch: {0} ({1})", context.CurrentBranch.Name, context.CurrentCommit.Sha));
            EnsureMainTopologyConstraints(context);

            var filePath = Path.Combine(context.Repository.GetRepositoryDirectory(), "NextVersion.txt");
            if (File.Exists(filePath))
            {
                throw new Exception("NextVersion.txt has been depreciated. See https://github.com/ParticularLabs/GitVersion/wiki/GitVersionConfig.yaml-Configuration-File for replacement");
            }

            return new NextVersionCalculator().FindVersion(context);
        }
示例#25
0
        public SemanticVersion FindVersion(GitVersionContext context)
        {
            Logger.WriteInfo(string.Format("Running against branch: {0} ({1})", context.CurrentBranch.Name, context.CurrentCommit.Sha));
            EnsureMainTopologyConstraints(context);

            var filePath = Path.Combine(context.Repository.GetRepositoryDirectory(), "NextVersion.txt");
            if (File.Exists(filePath))
            {
                throw new WarningException("NextVersion.txt has been depreciated. See http://gitversion.readthedocs.org/en/latest/configuration/ for replacement");
            }

            return new NextVersionCalculator().FindVersion(context);
        }
示例#26
0
        private static VersionField? FindCommitMessageIncrement(GitVersionContext context, BaseVersion baseVersion)
        {
            if (context.Configuration.CommitMessageIncrementing == CommitMessageIncrementMode.Disabled)
            {
                return null;
            }
            
            var commits = GetIntermediateCommits(context.Repository, baseVersion.BaseVersionSource, context.CurrentCommit);

            if (context.Configuration.CommitMessageIncrementing == CommitMessageIncrementMode.MergeMessageOnly)
            {
                commits = commits.Where(c => c.Parents.Count() > 1);
            }

            return GetIncrementForCommits(context, commits);
        }
 SemanticVersion GetVersion(GitVersionContext context)
 {
     return context.CurrentBranch.Commits.Where(c =>
         {
             string versionPart;
             SemanticVersion semanticVersion;
             return MergeMessageParser.TryParse(c, out versionPart) && SemanticVersion.TryParse(versionPart, out semanticVersion);
         })
         .Select(c =>
         {
             string versionPart;
             MergeMessageParser.TryParse(c, out versionPart);
             return SemanticVersion.Parse(versionPart);
         })
         .Max();
 }
        protected SemanticVersion FindVersion(
            GitVersionContext context,
            BranchType branchType,
            string baseBranchName)
        {
            var nbHotfixCommits = NumberOfCommitsInBranchNotKnownFromBaseBranch(context.Repository, context.CurrentBranch, branchType, baseBranchName);

            var versionString = context.CurrentBranch.GetSuffix(branchType);
            if (!versionString.Contains("."))
                return new SemanticVersion();
            var version = SemanticVersion.Parse(versionString);

            EnsureVersionIsValid(version, context.CurrentBranch, branchType);

            if (branchType == BranchType.Hotfix)
                version.PreReleaseTag = "beta.1";
            if (branchType == BranchType.Release)
                version.PreReleaseTag = "beta.1";
            if (branchType == BranchType.Unknown)
                version.PreReleaseTag = context.CurrentBranch.Name.Replace("-" + versionString, string.Empty) + ".1";

            var tagVersion = RetrieveMostRecentOptionalTagVersion(context.Repository, version, context.CurrentBranch.Commits.Take(nbHotfixCommits + 1));

            var sha = context.CurrentCommit.Sha;
            var releaseDate = ReleaseDateFinder.Execute(context.Repository, sha, version.Patch);
            var semanticVersion = new SemanticVersion
            {
                Major = version.Major,
                Minor = version.Minor,
                Patch = version.Patch,
                PreReleaseTag = version.PreReleaseTag,
                BuildMetaData = new SemanticVersionBuildMetaData(
                    nbHotfixCommits, context.CurrentBranch.Name, releaseDate)
            };

            if (tagVersion != null)
            {
                //If the tag is on the eact commit then dont bump the PreReleaseTag
                if (context.CurrentCommit.Sha != tagVersion.Commit.Sha)
                {
                    tagVersion.SemVer.PreReleaseTag.Number++;
                }
                semanticVersion.PreReleaseTag = tagVersion.SemVer.PreReleaseTag;
            }

            return semanticVersion;
        }
 public static VersionVariables GetVersion(this RepositoryFixtureBase fixture, Config configuration, IRepository repository = null, string commitId = null, bool isForTrackedBranchOnly = true)
 {
     ConfigurationProvider.ApplyDefaultsTo(configuration);
     var gitVersionContext = new GitVersionContext(repository ?? fixture.Repository, configuration, isForTrackedBranchOnly, commitId);
     var executeGitVersion = ExecuteGitVersion(gitVersionContext);
     var variables = VariableProvider.GetVariablesFor(executeGitVersion, gitVersionContext.Configuration, gitVersionContext.IsCurrentCommitTagged);
     try
     {
         return variables;
     }
     catch (Exception)
     {
         Console.WriteLine("Test failing, dumping repository graph");
         gitVersionContext.Repository.DumpGraph();
         throw;
     }
 }
示例#30
0
        public VersionPoint Execute(GitVersionContext context, DateTimeOffset olderThan)
        {
            var masterBranch = context.Repository.FindBranch("master");
            foreach (var commit in masterBranch.CommitsPriorToThan(olderThan))
            {
                foreach (var tag in context.Repository.TagsByDate(commit))
                {
                    int major;
                    int minor;
                    if (ShortVersionParser.TryParseMajorMinor(tag.Name, out major, out minor))
                    {
                        return new VersionPoint
                        {
                            Major = major,
                            Minor = minor,
                            Timestamp = commit.When(),
                            CommitSha = commit.Sha,
                        };
                    }
                }
                string versionString;
                if (MergeMessageParser.TryParse(commit, out versionString))
                {
                    int major;
                    int minor;
                    if (ShortVersionParser.TryParseMajorMinor(versionString, out major, out minor))
                    {
                        return new VersionPoint
                        {
                            Major = major,
                            Minor = minor,
                            Timestamp = commit.When(),
                            CommitSha = commit.Sha,
                        };
                    }
                }

            }
            return new VersionPoint
            {
                Major = 0,
                Minor = 1,
                Timestamp = DateTimeOffset.MinValue,
                CommitSha = null,
            };
        }
        private static VersionField?FindCommitMessageIncrement(IRepository repository, GitVersionContext context, BaseVersion baseVersion)
        {
            if (context.Configuration.CommitMessageIncrementing == CommitMessageIncrementMode.Disabled)
            {
                return(null);
            }

            var commits = GetIntermediateCommits(repository, baseVersion.BaseVersionSource, context.CurrentCommit);

            if (context.Configuration.CommitMessageIncrementing == CommitMessageIncrementMode.MergeMessageOnly)
            {
                commits = commits.Where(c => c.Parents.Count() > 1);
            }

            return(GetIncrementForCommits(context, commits));
        }
示例#32
0
        static int Run()
        {
            try
            {
                Arguments arguments;
                var       argumentsWithoutExeName = GetArgumentsWithoutExeName();
                try
                {
                    arguments = ArgumentParser.ParseArguments(argumentsWithoutExeName);
                }
                catch (Exception)
                {
                    Console.WriteLine("Failed to parse arguments: {0}", string.Join(" ", argumentsWithoutExeName));

                    HelpWriter.Write();
                    return(1);
                }

                if (arguments.IsHelp)
                {
                    HelpWriter.Write();
                    return(0);
                }

                if (!string.IsNullOrEmpty(arguments.Proj) || !string.IsNullOrEmpty(arguments.Exec))
                {
                    arguments.Output = OutputType.BuildServer;
                }

                ConfigureLogging(arguments);

                var gitPreparer  = new GitPreparer(arguments);
                var gitDirectory = gitPreparer.Prepare();
                if (string.IsNullOrEmpty(gitDirectory))
                {
                    Console.Error.WriteLine("Failed to prepare or find the .git directory in path '{0}'", arguments.TargetPath);
                    return(1);
                }

                var fileSystem = new FileSystem();
                if (arguments.Init)
                {
                    ConfigurationProvider.WriteSample(gitDirectory, fileSystem);
                    return(0);
                }

                var workingDirectory = Directory.GetParent(gitDirectory).FullName;
                Logger.WriteInfo("Working directory: " + workingDirectory);
                var applicableBuildServers = GetApplicableBuildServers(arguments.Authentication).ToList();

                foreach (var buildServer in applicableBuildServers)
                {
                    buildServer.PerformPreProcessingSteps(gitDirectory);
                }
                SemanticVersion semanticVersion;
                var             versionFinder = new GitVersionFinder();
                var             configuration = ConfigurationProvider.Provide(gitDirectory, fileSystem);
                using (var repo = RepositoryLoader.GetRepo(gitDirectory))
                {
                    var gitVersionContext = new GitVersionContext(repo, configuration);
                    semanticVersion = versionFinder.FindVersion(gitVersionContext);
                }

                if (arguments.Output == OutputType.BuildServer)
                {
                    foreach (var buildServer in applicableBuildServers)
                    {
                        buildServer.WriteIntegration(semanticVersion, Console.WriteLine);
                    }
                }

                var variables = VariableProvider.GetVariablesFor(semanticVersion, configuration);
                if (arguments.Output == OutputType.Json)
                {
                    switch (arguments.VersionPart)
                    {
                    case null:
                        Console.WriteLine(JsonOutputFormatter.ToJson(variables));
                        break;

                    default:
                        string part;
                        if (!variables.TryGetValue(arguments.VersionPart, out part))
                        {
                            throw new WarningException(string.Format("Could not extract '{0}' from the available parts.", arguments.VersionPart));
                        }
                        Console.WriteLine(part);
                        break;
                    }
                }

                if (!string.IsNullOrWhiteSpace(arguments.AssemblyVersionFormat) && !variables.ContainsKey(arguments.AssemblyVersionFormat))
                {
                    Console.WriteLine("Unrecognised AssemblyVersionFormat argument. Valid values for this argument are: {0}", string.Join(" ", variables.Keys.OrderBy(a => a)));
                    HelpWriter.Write();
                    return(1);
                }


                using (var assemblyInfoUpdate = new AssemblyInfoFileUpdate(arguments, workingDirectory, variables, fileSystem))
                {
                    var execRun    = RunExecCommandIfNeeded(arguments, workingDirectory, variables);
                    var msbuildRun = RunMsBuildIfNeeded(arguments, workingDirectory, variables);
                    if (!execRun && !msbuildRun)
                    {
                        assemblyInfoUpdate.DoNotRestoreAssemblyInfo();
                        //TODO Put warning back
                        //if (!context.CurrentBuildServer.IsRunningInBuildAgent())
                        //{
                        //    Console.WriteLine("WARNING: Not running in build server and /ProjectFile or /Exec arguments not passed");
                        //    Console.WriteLine();
                        //    Console.WriteLine("Run GitVersion.exe /? for help");
                        //}
                    }
                }

                if (gitPreparer.IsDynamicGitRepository)
                {
                    DeleteHelper.DeleteGitRepository(gitPreparer.DynamicGitRepositoryPath);
                }
            }
            catch (WarningException exception)
            {
                var error = string.Format("An error occurred:\r\n{0}", exception.Message);
                Logger.WriteWarning(error);
                return(1);
            }
            catch (Exception exception)
            {
                var error = string.Format("An unexpected error occurred:\r\n{0}", exception);
                Logger.WriteError(error);
                return(1);
            }

            return(0);
        }
 public MergedBranchesWithVersionFinder(GitVersionContext context)
 {
     lastMergedBranchWithVersion = new Lazy <SemanticVersion>(() => GetVersion(context));
 }
示例#34
0
        public static void Run(Arguments arguments, IFileSystem fileSystem)
        {
            var gitPreparer = new GitPreparer(arguments);

            gitPreparer.InitialiseDynamicRepositoryIfNeeded();
            var dotGitDirectory = gitPreparer.GetDotGitDirectory();

            if (string.IsNullOrEmpty(dotGitDirectory))
            {
                throw new Exception(string.Format("Failed to prepare or find the .git directory in path '{0}'", arguments.TargetPath));
            }
            var applicableBuildServers = GetApplicableBuildServers(arguments.Authentication).ToList();

            foreach (var buildServer in applicableBuildServers)
            {
                buildServer.PerformPreProcessingSteps(dotGitDirectory, arguments.NoFetch);
            }
            VersionVariables variables;
            var versionFinder = new GitVersionFinder();
            var configuration = ConfigurationProvider.Provide(dotGitDirectory, fileSystem);

            using (var repo = RepositoryLoader.GetRepo(dotGitDirectory))
            {
                var gitVersionContext = new GitVersionContext(repo, configuration, commitId: arguments.CommitId);
                var semanticVersion   = versionFinder.FindVersion(gitVersionContext);
                var config            = gitVersionContext.Configuration;
                variables = VariableProvider.GetVariablesFor(semanticVersion, config.AssemblyVersioningScheme, config.VersioningMode, config.ContinuousDeploymentFallbackTag, gitVersionContext.IsCurrentCommitTagged);
            }

            if (arguments.Output == OutputType.BuildServer)
            {
                foreach (var buildServer in applicableBuildServers)
                {
                    buildServer.WriteIntegration(Console.WriteLine, variables);
                }
            }

            if (arguments.Output == OutputType.Json)
            {
                switch (arguments.ShowVariable)
                {
                case null:
                    Console.WriteLine(JsonOutputFormatter.ToJson(variables));
                    break;

                default:
                    string part;
                    if (!variables.TryGetValue(arguments.ShowVariable, out part))
                    {
                        throw new WarningException(string.Format("'{0}' variable does not exist", arguments.ShowVariable));
                    }
                    Console.WriteLine(part);
                    break;
                }
            }

            using (var assemblyInfoUpdate = new AssemblyInfoFileUpdate(arguments, arguments.TargetPath, variables, fileSystem))
            {
                var execRun    = RunExecCommandIfNeeded(arguments, arguments.TargetPath, variables);
                var msbuildRun = RunMsBuildIfNeeded(arguments, arguments.TargetPath, variables);
                if (!execRun && !msbuildRun)
                {
                    assemblyInfoUpdate.DoNotRestoreAssemblyInfo();
                    //TODO Put warning back
                    //if (!context.CurrentBuildServer.IsRunningInBuildAgent())
                    //{
                    //    Console.WriteLine("WARNING: Not running in build server and /ProjectFile or /Exec arguments not passed");
                    //    Console.WriteLine();
                    //    Console.WriteLine("Run GitVersion.exe /? for help");
                    //}
                }
            }
        }
        public static VersionField?DetermineIncrementedField(IGitRepository repository, GitVersionContext context, BaseVersion baseVersion)
        {
            var commitMessageIncrement = FindCommitMessageIncrement(repository, context, baseVersion);
            var defaultIncrement       = context.Configuration.Increment.ToVersionField();

            // use the default branch config increment strategy if there are no commit message overrides
            if (commitMessageIncrement == null)
            {
                return(baseVersion.ShouldIncrement ? defaultIncrement : (VersionField?)null);
            }

            // cap the commit message severity to minor for alpha versions
            if (baseVersion.SemanticVersion < new SemanticVersion(1) && commitMessageIncrement > VersionField.Minor)
            {
                commitMessageIncrement = VersionField.Minor;
            }

            // don't increment for less than the branch config increment, if the absence of commit messages would have
            // still resulted in an increment of configuration.Increment
            if (baseVersion.ShouldIncrement && commitMessageIncrement < defaultIncrement)
            {
                return(defaultIncrement);
            }

            return(commitMessageIncrement);
        }
示例#36
0
 public GitVersionContext(IRepository repository, string targetBranch, Config configuration, bool onlyEvaluateTrackedBranches = true, string commitId = null)
     : this(repository, GitVersionContext.GetTargetBranch(repository, targetBranch), configuration, onlyEvaluateTrackedBranches, commitId)
 {
 }
示例#37
0
 public LastTaggedReleaseFinder(GitVersionContext context)
 {
     this.context = context;
 }
        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.FriendlyName);

                        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.Except(excludedInheritBranches).ToList();

                var branchPoint = context.RepositoryMetadataProvider
                                  .FindCommitBranchWasBranchedFrom(targetBranch, excludedInheritBranches.ToArray());
                List <Branch> possibleParents;
                if (branchPoint == BranchCommit.Empty)
                {
                    possibleParents = context.RepositoryMetadataProvider.GetBranchesContainingCommit(context.CurrentCommit, 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);
                    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))
                {
                    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);
                return(new BranchConfig(branchConfiguration)
                {
                    Increment = inheritingBranchConfig.Increment,
                    PreventIncrementOfMergedBranchVersion = inheritingBranchConfig.PreventIncrementOfMergedBranchVersion,
                    // If we are inheriting from develop then we should behave like develop
                    TracksReleaseBranches = inheritingBranchConfig.TracksReleaseBranches
                });
            }
        }
示例#39
0
 void EnsureMainTopologyConstraints(GitVersionContext context)
 {
     EnsureHeadIsNotDetached(context);
 }
示例#40
0
 SemanticVersionPreReleaseTag CreateDefaultPreReleaseTag(GitVersionContext context, string versionString)
 {
     return(context.CurrentBranch.Name
            .Replace("/" + versionString, string.Empty)
            .Replace("-" + versionString, string.Empty) + ".1");
 }
 public LastTaggedReleaseFinder(GitVersionContext context)
 {
     lastTaggedRelease = new Lazy <VersionTaggedCommit>(() => GetVersion(context));
 }
 internal static SemanticVersionPreReleaseTag RetrieveMostRecentOptionalTagVersion(GitVersionContext context, List <Tag> applicableTagsInDescendingOrder)
 {
     if (applicableTagsInDescendingOrder.Any())
     {
         var taggedCommit      = applicableTagsInDescendingOrder.First().Target;
         var preReleaseVersion = applicableTagsInDescendingOrder.Select(tag => SemanticVersion.Parse(tag.Name, context.Configuration.TagPrefix)).FirstOrDefault();
         if (preReleaseVersion != null)
         {
             if (taggedCommit != context.CurrentCommit)
             {
                 preReleaseVersion.PreReleaseTag.Number++;
             }
             return(preReleaseVersion.PreReleaseTag);
         }
     }
     return(null);
 }
示例#43
0
 void EnsureMainTopologyConstraints(GitVersionContext context)
 {
     EnsureLocalBranchExists(context.Repository, "master");
     // TODO somehow enforce this? EnsureLocalBranchExists(context.Repository, "develop");
     EnsureHeadIsNotDetached(context);
 }
示例#44
0
 public MergedBranchesWithVersionFinder(GitVersionContext context)
 {
     this.context = context;
 }
        internal static SemanticVersionPreReleaseTag RetrieveMostRecentOptionalTagVersion(GitVersionContext context, SemanticVersion matchVersion)
        {
            var tagsInDescendingOrder = context.Repository.SemVerTagsRelatedToVersion(context.Configuration, matchVersion).OrderByDescending(tag => SemanticVersion.Parse(tag.Name, context.Configuration.TagPrefix));

            return(RetrieveMostRecentOptionalTagVersion(context, tagsInDescendingOrder.ToList()));
        }
 void EnsureMainTopologyConstraints(GitVersionContext context)
 {
     EnsureLocalBranchExists(context.Repository, "master");
     EnsureHeadIsNotDetached(context);
 }