internal static CIReleaseInfo Create(Commit commit, CIBranchVersionMode ciVersionMode, string ciBuildName, StringBuilder errors, CommitVersionInfo info) { var actualBaseTag = info.PreviousMaxTag; ReleaseTagVersion ciBaseTag = actualBaseTag ?? ReleaseTagVersion.VeryFirstVersion; string ciBuildVersionNuGet = null, ciBuildVersion = null; // If there is no base release found, we fall back to ZeroTimedBased mode. if (ciVersionMode == CIBranchVersionMode.ZeroTimed || actualBaseTag == null) { DateTime timeRelease = commit.Committer.When.ToUniversalTime().UtcDateTime; ciBuildVersion = CreateSemVerZeroTimed(ciBuildName, timeRelease, actualBaseTag?.ToString()); ciBuildVersionNuGet = CreateNuGetZeroTimed(ciBuildName, timeRelease); } else { Debug.Assert(ciVersionMode == CIBranchVersionMode.LastReleaseBased && actualBaseTag != null); CIBuildDescriptor ci = new CIBuildDescriptor { BranchName = ciBuildName, BuildIndex = info.PreviousMaxCommitDepth }; if (!ci.IsValidForNuGetV2) { errors.AppendLine("Due to NuGet V2 limitation, the branch name must not be longer than 8 characters. "); errors.Append("Adds a VersionName attribute to the branch element in RepositoryInfo.xml with a shorter name: ") .AppendFormat(@"<Branch Name=""{0}"" VersionName=""{1}"" ... />.", ci.BranchName, ci.BranchName.Substring(0, 8)) .AppendLine(); } else { ciBuildVersion = actualBaseTag.ToString(ReleaseTagFormat.SemVer, ci); ciBuildVersionNuGet = actualBaseTag.ToString(ReleaseTagFormat.NuGetPackage, ci); } } Debug.Assert(ciBuildVersion == null || errors.Length == 0); return(ciBuildVersion != null ? new CIReleaseInfo(ciBaseTag, info.PreviousMaxCommitDepth, ciBuildVersion, ciBuildVersionNuGet) : null); }
internal static CIReleaseInfo Create( Commit commit, CIBranchVersionMode ciVersionMode, string ciBuildName, StringBuilder errors, BasicCommitInfo info) { var actualBaseTag = info?.MaxCommit.ThisTag; CSVersion ciBaseTag = actualBaseTag ?? CSVersion.VeryFirstVersion; SVersion ciBuildVersionNuGet = null, ciBuildVersion = null; // If there is no base release found, we fall back to ZeroTimedBased mode. if (ciVersionMode == CIBranchVersionMode.ZeroTimed || actualBaseTag == null) { DateTime timeRelease = commit.Committer.When.ToUniversalTime().UtcDateTime; string vS = CIBuildDescriptor.CreateSemVerZeroTimed(ciBuildName, timeRelease); string vN = CIBuildDescriptor.CreateShortFormZeroTimed(ciBuildName, timeRelease); if (actualBaseTag != null) { string buildMetaData = "+v" + actualBaseTag; vS += buildMetaData; vN += buildMetaData; } ciBuildVersion = SVersion.Parse(vS); ciBuildVersionNuGet = SVersion.Parse(vN, false); return(new CIReleaseInfo(ciBaseTag, 0, ciBuildVersion, ciBuildVersionNuGet, true)); } Debug.Assert(ciVersionMode == CIBranchVersionMode.LastReleaseBased && actualBaseTag != null); CIBuildDescriptor ci = new CIBuildDescriptor { BranchName = ciBuildName, BuildIndex = info.BelowDepth }; if (!ci.IsValidForShortForm) { errors.AppendLine("Due to ShortForm (NuGet V2 compliance) limitation, the branch name must not be longer than 8 characters. "); errors.Append("Adds a VersionName attribute to the branch element in RepositoryInfo.xml with a shorter name: ") .AppendLine() .Append($@"<Branch Name=""{ci.BranchName}"" VersionName=""{ci.BranchName.Substring( 0, 8 )}"" ... />.") .AppendLine(); } else { ciBuildVersion = SVersion.Parse(actualBaseTag.ToString(CSVersionFormat.Normalized, ci)); ciBuildVersionNuGet = SVersion.Parse(actualBaseTag.ToString(CSVersionFormat.NuGetPackage, ci), false); } Debug.Assert(ciBuildVersion == null || errors.Length == 0); return(ciBuildVersion != null ? new CIReleaseInfo(ciBaseTag, info.BelowDepth, ciBuildVersion, ciBuildVersionNuGet, false) : null); }
internal static CIReleaseInfo Create( Commit commit, CIBranchVersionMode ciVersionMode, string ciVersionName, StringBuilder errors, CommitVersionInfo info ) { var actualBaseTag = info.PreviousMaxTag; ReleaseTagVersion ciBaseTag = actualBaseTag ?? ReleaseTagVersion.VeryFirstVersion; string ciBuildVersionNuGet = null, ciBuildVersion = null; // If there is no base release found, we fall back to ZeroTimedBased mode. if( ciVersionMode == CIBranchVersionMode.ZeroTimed || actualBaseTag == null ) { string suffix = actualBaseTag != null ? '+' + actualBaseTag.ToString() : null; var name = string.Format( "0.0.0--ci-{0}.{1:yyyy-MM-ddTHH-mm-ss-ff}", ciVersionName, commit.Committer.When ); ciBuildVersion = name + suffix; TimeSpan delta200 = commit.Committer.When.ToUniversalTime() - new DateTime( 2015, 1, 1, 0, 0, 0, DateTimeKind.Utc ); Debug.Assert( Math.Log( 1000 * 366 * 24 * 60 * (long)60, 62 ) < 7, "Using Base62: 1000 years in seconds on 7 chars!" ); long second = (long)delta200.TotalSeconds; string b62 = ToBase62( second ); string ver = new string( '0', 7 - b62.Length ) + b62; ciBuildVersionNuGet = string.Format( "0.0.0-C{0}-{1}", ciVersionName, ver ); } else { Debug.Assert( ciVersionMode == CIBranchVersionMode.LastReleaseBased && actualBaseTag != null ); CIBuildDescriptor ci = new CIBuildDescriptor { BranchName = ciVersionName, BuildIndex = info.PreviousMaxCommitDepth }; if( !ci.IsValidForNuGetV2 ) { errors.AppendLine( "Due to NuGet V2 limitation, the branch name must not be longer than 8 characters. " ); errors.Append( "Adds a VersionName attribute to the branch element in RepositoryInfo.xml with a shorter name: " ) .AppendFormat( @"<Branch Name=""{0}"" VersionName=""{1}"" ... />.", ci.BranchName, ci.BranchName.Substring( 0, 8 ) ) .AppendLine(); } else { ciBuildVersion = actualBaseTag.ToString( ReleaseTagFormat.SemVer, ci ); ciBuildVersionNuGet = actualBaseTag.ToString( ReleaseTagFormat.NuGetPackage, ci ); } } Debug.Assert( ciBuildVersion == null || errors.Length == 0 ); return ciBuildVersion != null ? new CIReleaseInfo( ciBaseTag, info.PreviousMaxCommitDepth, ciBuildVersion, ciBuildVersionNuGet ) : null; }
internal static CIReleaseInfo Create( Commit commit, CIBranchVersionMode ciVersionMode, string ciBuildName, StringBuilder errors, CommitVersionInfo info ) { var actualBaseTag = info.PreviousMaxTag; ReleaseTagVersion ciBaseTag = actualBaseTag ?? ReleaseTagVersion.VeryFirstVersion; string ciBuildVersionNuGet = null, ciBuildVersion = null; // If there is no base release found, we fall back to ZeroTimedBased mode. if( ciVersionMode == CIBranchVersionMode.ZeroTimed || actualBaseTag == null ) { DateTime timeRelease = commit.Committer.When.ToUniversalTime().UtcDateTime; ciBuildVersion = CreateSemVerZeroTimed( ciBuildName, timeRelease, actualBaseTag?.ToString() ); ciBuildVersionNuGet = CreateNuGetZeroTimed( ciBuildName, timeRelease ); } else { Debug.Assert( ciVersionMode == CIBranchVersionMode.LastReleaseBased && actualBaseTag != null ); CIBuildDescriptor ci = new CIBuildDescriptor { BranchName = ciBuildName, BuildIndex = info.PreviousMaxCommitDepth }; if( !ci.IsValidForNuGetV2 ) { errors.AppendLine( "Due to NuGet V2 limitation, the branch name must not be longer than 8 characters. " ); errors.Append( "Adds a VersionName attribute to the branch element in RepositoryInfo.xml with a shorter name: " ) .AppendFormat( @"<Branch Name=""{0}"" VersionName=""{1}"" ... />.", ci.BranchName, ci.BranchName.Substring( 0, 8 ) ) .AppendLine(); } else { ciBuildVersion = actualBaseTag.ToString( ReleaseTagFormat.SemVer, ci ); ciBuildVersionNuGet = actualBaseTag.ToString( ReleaseTagFormat.NuGetPackage, ci ); } } Debug.Assert( ciBuildVersion == null || errors.Length == 0 ); return ciBuildVersion != null ? new CIReleaseInfo( ciBaseTag, info.PreviousMaxCommitDepth, ciBuildVersion, ciBuildVersionNuGet ) : null; }
string TryFindCommit( RepositoryInfoOptions options, Repository r, out Commit commit, out CIBranchVersionMode ciVersionMode, out string branchNameForCIVersion ) { ciVersionMode = CIBranchVersionMode.None; commit = null; branchNameForCIVersion = null; string commitSha = options.StartingCommitSha; // Find current commit (the head) if none is provided. if( string.IsNullOrWhiteSpace( commitSha ) ) { IEnumerable<string> branchNames; if( string.IsNullOrWhiteSpace( options.StartingBranchName ) ) { // locCommit is here because one cannot use an out parameter inside a lambda. var locCommit = commit = r.Head.Tip; if( locCommit == null ) return "Unitialized Git repository."; // Save the branches! // By doing this, when we are in 'Detached Head' state (the head of the repository is on a commit and not on a branch: git checkout <sha>), // we can detect that it is the head of a branch and hence apply possible options (mainly CI) for it. // We take into account only the branches from options.RemoteName remote here. string branchName = r.Head.FriendlyName; if( branchName == "(no branch)" ) { string remotePrefix = options.RemoteName + '/'; branchNames = r.Branches .Where( b => b.Tip == locCommit && (!b.IsRemote || b.FriendlyName.StartsWith( remotePrefix )) ) .Select( b => b.IsRemote ? b.FriendlyName.Substring( remotePrefix.Length ) : b.FriendlyName ); } else branchNames = new[] { branchName }; } else { Branch br = r.Branches[options.StartingBranchName] ?? r.Branches[ options.RemoteName + '/' + options.StartingBranchName]; if( br == null ) return string.Format( "Unknown StartingBranchName: '{0}' (also tested on remote '{1}/{0}').", options.StartingBranchName, options.RemoteName ); commit = br.Tip; branchNames = new[] { options.StartingBranchName }; } RepositoryInfoOptionsBranch bOpt; if( options.Branches != null && (bOpt = options.Branches.FirstOrDefault( b => branchNames.Contains( b.Name ) )) != null && bOpt.CIVersionMode != CIBranchVersionMode.None ) { ciVersionMode = bOpt.CIVersionMode; branchNameForCIVersion = string.IsNullOrWhiteSpace( bOpt.VersionName ) ? bOpt.Name : bOpt.VersionName; } } else { commit = r.Lookup<Commit>( commitSha ); if( commit == null ) return string.Format( "Commit '{0}' not found.", commitSha ); } return null; }
string TryFindCommit(RepositoryInfoOptions options, Repository r, out Commit commit, out CIBranchVersionMode ciVersionMode, out string branchNameForCIVersion) { ciVersionMode = CIBranchVersionMode.None; commit = null; branchNameForCIVersion = null; string commitSha = options.StartingCommitSha; // Find current commit (the head) if none is provided. if (string.IsNullOrWhiteSpace(commitSha)) { IEnumerable <string> branchNames; if (string.IsNullOrWhiteSpace(options.StartingBranchName)) { // locCommit is here because one cannot use an out parameter inside a lambda. var locCommit = commit = r.Head.Tip; if (locCommit == null) { return("Unitialized Git repository."); } // Save the branches! // By doing this, when we are in 'Detached Head' state (the head of the repository is on a commit and not on a branch: git checkout <sha>), // we can detect that it is the head of a branch and hence apply possible options (mainly CI) for it. // We take into account only the branches from options.RemoteName remote here. string branchName = r.Head.FriendlyName; if (branchName == "(no branch)") { string remotePrefix = options.RemoteName + '/'; branchNames = r.Branches .Where(b => b.Tip == locCommit && (!b.IsRemote || b.FriendlyName.StartsWith(remotePrefix))) .Select(b => b.IsRemote ? b.FriendlyName.Substring(remotePrefix.Length) : b.FriendlyName); } else { branchNames = new[] { branchName } }; } else { string remotePrefix = options.RemoteName + '/'; string localBranchName = options.StartingBranchName.StartsWith(remotePrefix) ? options.StartingBranchName.Substring(remotePrefix.Length) : options.StartingBranchName; Branch br = r.Branches[options.StartingBranchName]; if (br == null && ReferenceEquals(localBranchName, options.StartingBranchName)) { string remoteName = remotePrefix + options.StartingBranchName; br = r.Branches[remoteName]; if (br == null) { return($"Unknown StartingBranchName: '{options.StartingBranchName}' (also tested on remote '{remoteName}')."); } } if (br == null) { return($"Unknown (remote) StartingBranchName: '{options.StartingBranchName}'."); } commit = br.Tip; branchNames = new[] { localBranchName }; } RepositoryInfoOptionsBranch bOpt; if (options.Branches != null && (bOpt = options.Branches.FirstOrDefault(b => branchNames.Contains(b.Name))) != null && bOpt.CIVersionMode != CIBranchVersionMode.None) { ciVersionMode = bOpt.CIVersionMode; branchNameForCIVersion = string.IsNullOrWhiteSpace(bOpt.VersionName) ? bOpt.Name : bOpt.VersionName; } } else { commit = r.Lookup <Commit>(commitSha); if (commit == null) { return($"Commit '{commitSha}' not found."); } } return(null); }