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; }
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; }
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; }
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; }
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; }
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; }
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); }
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); }
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; }
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(); }
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; }
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); }
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); }
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); }
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); }
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; } }
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)); }
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)); }
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); }
public GitVersionContext(IRepository repository, string targetBranch, Config configuration, bool onlyEvaluateTrackedBranches = true, string commitId = null) : this(repository, GitVersionContext.GetTargetBranch(repository, targetBranch), configuration, onlyEvaluateTrackedBranches, commitId) { }
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 }); } }
void EnsureMainTopologyConstraints(GitVersionContext context) { EnsureHeadIsNotDetached(context); }
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); }
void EnsureMainTopologyConstraints(GitVersionContext context) { EnsureLocalBranchExists(context.Repository, "master"); // TODO somehow enforce this? EnsureLocalBranchExists(context.Repository, "develop"); EnsureHeadIsNotDetached(context); }
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); }