Example #1
0
        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);
        }
Example #3
0
        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);
        }