Esempio n. 1
0
        public void ShouldNotIncrementPatchVersionForEmptyCommitsIfIgnoreInsignificantIsGiven()
        {
            var strategy = VersionIncrementStrategy.CreateFrom(new List <ConventionalCommit>());

            strategy.NextVersion(new Version(1, 1, 1), true)
            .ShouldBe(new Version(1, 1, 1));
        }
Esempio n. 2
0
        public void ShouldIncrementPatchVersionForEmptyCommits()
        {
            var strategy = VersionIncrementStrategy.CreateFrom(new List <ConventionalCommit>());

            strategy.NextVersion(new Version(1, 1, 1))
            .ShouldBe(new Version(1, 1, 2));
        }
    public void ShouldIncrementVersionFromPrereleaseToStable(TestScenario testScenario)
    {
        var strategy = new VersionIncrementStrategy(testScenario.Commits);

        var nextVersion = strategy.NextVersion(testScenario.FromVersion, testScenario.PrereleaseLabel);

        nextVersion.ShouldBe(testScenario.ExpectedVersion);
    }
        public void ShouldIncrementPatchVersionForFixCommitsIfIgnoreInsignificantIsGiven()
        {
            var strategy = VersionIncrementStrategy.CreateFrom(new List<ConventionalCommit>()
            {
                new ConventionalCommit() { Type = "fix"}
            });

            strategy.NextVersion(new Version(1, 1, 1), true)
                .ShouldBe(new Version(1, 1, 2));
        }
    public void ShouldIncrementMinorVersionForFeatures()
    {
        var strategy = new VersionIncrementStrategy(new List <ConventionalCommit>
        {
            new ConventionalCommit {
                Type = "feat"
            }
        });

        strategy.NextVersion(new SemanticVersion(1, 1, 1)).ShouldBe(new SemanticVersion(1, 2, 0));
    }
    public void ShouldIncrementPatchVersionForFixCommitsIfIgnoreInsignificantIsGiven()
    {
        var strategy = new VersionIncrementStrategy(new List <ConventionalCommit>
        {
            new ConventionalCommit {
                Type = "fix"
            }
        });

        strategy.NextVersion(new SemanticVersion(1, 1, 1)).ShouldBe(new SemanticVersion(1, 1, 2));
    }
        public void ShouldIncrementMinorVersionForFeatures()
        {
            var strategy = VersionIncrementStrategy.CreateFrom(new List<ConventionalCommit>()
            {
                new ConventionalCommit()
                {
                    Type = "feat"
                }
            });

            strategy.NextVersion(new Version(1, 1, 1))
                .ShouldBe(new Version(1, 2, 0));
        }
        public void ShouldIncrementMajorVersionForBreakingChanges()
        {
            var strategy = VersionIncrementStrategy.CreateFrom(new List<ConventionalCommit>()
            {
                new ConventionalCommit()
                {
                    Type = "chore",
                    Notes = new List<ConventionalCommitNote>()
                    {
                        new ConventionalCommitNote() { Title = "BREAKING CHANGE"}
                    }
                }
            });

            strategy.NextVersion(new Version(1, 1, 1))
                .ShouldBe(new Version(2, 0, 0));
        }
Esempio n. 9
0
    public SemanticVersion Versionize(VersionizeOptions options)
    {
        var workingDirectory = _directory.FullName;

        using var repo = new Repository(workingDirectory);

        var isDirty = repo.RetrieveStatus(new StatusOptions()).IsDirty;

        if (!options.SkipDirty && isDirty)
        {
            Exit($"Repository {workingDirectory} is dirty. Please commit your changes.", 1);
        }

        var projects = Projects.Discover(workingDirectory);

        if (projects.IsEmpty())
        {
            Exit($"Could not find any projects files in {workingDirectory} that have a <Version> defined in their csproj file.", 1);
        }

        if (projects.HasInconsistentVersioning())
        {
            Exit($"Some projects in {workingDirectory} have an inconsistent <Version> defined in their csproj file. Please update all versions to be consistent or remove the <Version> elements from projects that should not be versioned", 1);
        }

        Information($"Discovered {projects.GetProjectFiles().Count()} versionable projects");
        foreach (var project in projects.GetProjectFiles())
        {
            Information($"  * {project}");
        }

        var versionTag       = repo.SelectVersionTag(projects.Version);
        var isInitialRelease = versionTag == null;
        var commitsInVersion = repo.GetCommitsSinceLastVersion(versionTag);

        var conventionalCommits = ConventionalCommitParser.Parse(commitsInVersion);

        var versionIncrement = new VersionIncrementStrategy(conventionalCommits);

        var nextVersion = isInitialRelease ? projects.Version : versionIncrement.NextVersion(projects.Version, options.Prerelease);

        // For non initial releases: for insignificant commits such as chore increment the patch version if IgnoreInsignificantCommits is not set
        if (!isInitialRelease && nextVersion == projects.Version)
        {
            if (options.IgnoreInsignificantCommits || options.ExitInsignificantCommits)
            {
                var exitCode = options.ExitInsignificantCommits ? 1 : 0;
                Exit($"Version was not affected by commits since last release ({projects.Version})", exitCode);
            }
            else
            {
                nextVersion = nextVersion.IncrementPatchVersion();
            }
        }

        if (!string.IsNullOrWhiteSpace(options.ReleaseAs))
        {
            try
            {
                nextVersion = SemanticVersion.Parse(options.ReleaseAs);
            }
            catch (Exception)
            {
                Exit($"Could not parse the specified release version {options.ReleaseAs} as valid version", 1);
            }
        }

        if (nextVersion < projects.Version)
        {
            Exit($"Semantic versioning conflict: the next version {nextVersion} would be lower than the current version {projects.Version}. This can be caused by using a wrong pre-release label or release as version", 1);
        }

        if (!options.DryRun && !options.SkipCommit && repo.VersionTagsExists(nextVersion))
        {
            Exit($"Version {nextVersion} already exists. Please use a different version.", 1);
        }

        var versionTime = DateTimeOffset.Now;

        // Commit changelog and version source
        if (!options.DryRun && (nextVersion != projects.Version))
        {
            projects.WriteVersion(nextVersion);

            foreach (var projectFile in projects.GetProjectFiles())
            {
                Commands.Stage(repo, projectFile);
            }
        }

        Step($"bumping version from {projects.Version} to {nextVersion} in projects");

        var changelog            = ChangelogBuilder.CreateForPath(workingDirectory);
        var changelogLinkBuilder = LinkBuilderFactory.CreateFor(repo);

        if (options.DryRun)
        {
            string markdown = ChangelogBuilder.GenerateMarkdown(nextVersion, versionTime, changelogLinkBuilder, conventionalCommits, options.Changelog);
            DryRun(markdown.TrimEnd('\n'));
        }
        else
        {
            changelog.Write(nextVersion, versionTime, changelogLinkBuilder, conventionalCommits, options.Changelog);
        }

        Step("updated CHANGELOG.md");

        if (!options.DryRun && !options.SkipCommit)
        {
            if (!repo.IsConfiguredForCommits())
            {
                Exit(@"Warning: Git configuration is missing. Please configure git before running versionize:
git config --global user.name ""John Doe""
$ git config --global user.email [email protected]", 1);
            }

            Commands.Stage(repo, changelog.FilePath);

            foreach (var projectFile in projects.GetProjectFiles())
            {
                Commands.Stage(repo, projectFile);
            }

            var author    = repo.Config.BuildSignature(versionTime);
            var committer = author;

            var releaseCommitMessage = $"chore(release): {nextVersion} {options.CommitSuffix}".TrimEnd();
            var versionCommit        = repo.Commit(releaseCommitMessage, author, committer);
            Step("committed changes in projects and CHANGELOG.md");

            repo.Tags.Add($"v{nextVersion}", versionCommit, author, $"{nextVersion}");
            Step($"tagged release as {nextVersion}");

            Information("");
            Information("i Run `git push --follow-tags origin master` to push all changes including tags");
        }
        else if (options.SkipCommit)
        {
            Information("");
            Information($"i Commit and tagging of release was skipped. Tag this release as `v{nextVersion}` to make versionize detect the release");
        }

        return(nextVersion);
    }