Release CreateNewRelease(Project project, List<PackageVersion> latestVersions)
        {
            var version = VersionNumber;
            var releaseNotes = ReleaseNotes;
            if (string.IsNullOrWhiteSpace(version))
            {
                version = latestVersions.Select(p => SemanticVersion.Parse(p.Version)).OrderByDescending(v => v).First().ToString();
                Log.Warn("A --version parameter was not specified, so we will infer the version number from the packages. The highest version number is: " + version);
            }

            var release = new Release();
            release.Assembled = DateTime.UtcNow;
            release.AssembledBy = Environment.UserName;
            release.Version = version;
            release.ReleaseNotes = releaseNotes;
            release.PackageVersions = latestVersions.ToArray();

            Log.Debug("Creating release: " + version);

            var result = Client.Create(project.Link("Releases"), release).Execute();

            Log.Info("Release created successfully!");

            return result;
        }
        /// <summary>
        /// Parse version based on mask tokens:
        /// i - Increment based on lastest version
        /// c - Use the lastest version current value
        /// </summary>
        /// <param name="versionNumberMask"></param>
        /// <param name="project"></param>
        /// <returns></returns>
        private string ParseVersionMask(string versionNumberMask, Project project)
        {
            var semanticVersionTokens = versionNumberMask.ToLower().Split('-');
            var versionTokens = semanticVersionTokens[0].Split('.');

            string specialVersionToken = null;
            if (semanticVersionTokens.Length > 1)
            {
                specialVersionToken = semanticVersionTokens[1];
            }

            var releases = Session.List<Release>(project.Link("Releases"));
            var lastestReleaseVersion = releases.Select(p => SemanticVersion.Parse(p.Version)).OrderByDescending(v => v).FirstOrDefault();

            var parsedVersionBuilder = new StringBuilder();

            for (int i = 0; i < versionTokens.Length; i++)
            {
                var versionToken = versionTokens[i];

                int versionComponent;

                if (!int.TryParse(versionToken, out versionComponent))
                {
                    int lastestVersionComponent = 0;

                    if (lastestReleaseVersion != null)
                    {
                        switch (i)
                        {
                            case 0:
                                lastestVersionComponent = lastestReleaseVersion.Version.Major;
                                break;
                            case 1:
                                lastestVersionComponent = lastestReleaseVersion.Version.Minor;
                                break;
                            case 2:
                                lastestVersionComponent = lastestReleaseVersion.Version.Build;
                                break;
                            case 3:
                                lastestVersionComponent = lastestReleaseVersion.Version.Revision;
                                break;
                        }
                    }

                    if (versionToken.Equals("c"))
                    {
                        // Current version
                        versionComponent = lastestVersionComponent;

                    }
                    else if (versionToken.Equals("i"))
                    {
                        // Incremented version
                        versionComponent = lastestVersionComponent + 1;
                    }
                    else
                    {
                        // Invalid token, puts 0 on that part
                        versionComponent = 0;
                    }
                }

                parsedVersionBuilder.Append(versionComponent);
                if (i + 1 < versionTokens.Length)
                {
                    parsedVersionBuilder.Append(".");
                }
            }

            // Parses SemVer special version token
            if (!string.IsNullOrWhiteSpace(specialVersionToken))
            {
                string parsedSpecialVersionToken = null;

                if (specialVersionToken.Equals("c") &&
                    lastestReleaseVersion != null)
                {
                    parsedSpecialVersionToken = lastestReleaseVersion.SpecialVersion;
                }
                else if (specialVersionToken.Equals("i") &&
                         lastestReleaseVersion != null &&
                         !string.IsNullOrWhiteSpace(lastestReleaseVersion.SpecialVersion))
                {
                    int subVersionNumber = 0;

                    var lastestSpecialVersionTokens = lastestReleaseVersion.SpecialVersion.Split('.');

                    if (lastestSpecialVersionTokens.Length > 1)
                    {
                        int.TryParse(lastestSpecialVersionTokens[1], out subVersionNumber);
                    }

                    parsedSpecialVersionToken = string.Format("{0}.{1}", lastestSpecialVersionTokens[0], subVersionNumber + 1);
                }
                else
                {
                    parsedSpecialVersionToken = specialVersionToken;
                }

                if (!string.IsNullOrWhiteSpace(parsedSpecialVersionToken))
                {
                    parsedVersionBuilder.AppendFormat("-{0}", parsedSpecialVersionToken);
                }
            }

            versionNumberMask = parsedVersionBuilder.ToString();
            return versionNumberMask;
        }
        IEnumerable<Step> FindStepsForProject(Project project)
        {
            Log.Debug("Getting project steps...");

            var steps = Client.List<Step>(project.Link("Steps")).Execute();

            Log.DebugFormat("Found {0} steps", steps.Count);

            return steps;
        }
        Release FindRelease(Project project)
        {
            Log.DebugFormat("Searching for release '{0}'", VersionNumber);

            var releases = Client.List<Release>(project.Link("Releases")).Execute();

            var release = releases.FirstOrDefault(x => string.Equals(x.Version, VersionNumber, StringComparison.InvariantCultureIgnoreCase));
            if (release == null)
            {
                throw new ArgumentException(string.Format("A release named '{0}' could not be found.", VersionNumber));
            }

            Log.InfoFormat("Found release: {0} [{1}]", release.Version, release.Id);

            return release;
        }