public void ShouldHideFixSectionWhenHideIsTrue() { var plainLinkBuilder = new PlainLinkBuilder(); var changelog = ChangelogBuilder.CreateForPath(_testDirectory); changelog.Write( new Version(1, 1, 0), new DateTimeOffset(), plainLinkBuilder, new List <ConventionalCommit> { ConventionalCommitParser.Parse(new TestCommit("a360d6a307909c6e571b29d4a329fd786c5d4543", "fix: a fix")), ConventionalCommitParser.Parse(new TestCommit("b360d6a307909c6e571b29d4a329fd786c5d4543", "feat: a feature")), }, ChangelogOptions.Default with { Sections = new[] { new ChangelogSection { Type = "feat", Hidden = false, Section = "Features" }, new ChangelogSection { Type = "fix", Hidden = true, Section = "Bug Fixes" }, } });
public void ShouldGenerateAChangelogForFixFeatAndBreakingCommits() { var plainLinkBuilder = new PlainLinkBuilder(); var changelog = ChangelogBuilder.CreateForPath(_testDirectory); changelog.Write( new Version(1, 1, 0), new DateTimeOffset(), plainLinkBuilder, new List <ConventionalCommit> { ConventionalCommitParser.Parse(new TestCommit("a360d6a307909c6e571b29d4a329fd786c5d4543", "fix: a fix")), ConventionalCommitParser.Parse(new TestCommit("b360d6a307909c6e571b29d4a329fd786c5d4543", "feat: a feature")), ConventionalCommitParser.Parse( new TestCommit("c360d6a307909c6e571b29d4a329fd786c5d4543", "feat: a breaking change feature\nBREAKING CHANGE: this will break everything")), }, ChangelogOptions.Default); var changelogContents = File.ReadAllText(changelog.FilePath); var sb = new ChangelogStringBuilder(); sb.Append(ChangelogOptions.Preamble); sb.Append("<a name=\"1.1.0\"></a>"); sb.Append("## 1.1.0 (1-1-1)", 2); sb.Append("### Features", 2); sb.Append("* a breaking change feature"); sb.Append("* a feature", 2); sb.Append("### Bug Fixes", 2); sb.Append("* a fix", 2); sb.Append("### Breaking Changes", 2); sb.Append("* a breaking change feature", 2); Assert.Equal(sb.Build(), changelogContents); }
private Changelog SetUpUpdateChangelogWhenImageIsDeleted() { var changelog = new ChangelogBuilder() .SetTitle(It.IsNotNull <string>()) .SetContent(It.IsNotNull <string>()) .SetImageUrl("url") .Build(); database.Setup(d => d.ChangelogRepository.FindById(updateRequest.ChangelogId)) .ReturnsAsync(changelog); mapper.Setup(m => m.Map(updateRequest, changelog)).Returns(changelog); database.Setup(d => d.ChangelogRepository.Update(changelog)).ReturnsAsync(true); return(changelog); }
public void ShouldGenerateAChangelogEvenForEmptyCommits() { var plainLinkBuilder = new PlainLinkBuilder(); var changelog = ChangelogBuilder.CreateForPath(_testDirectory); changelog.Write( new Version(1, 1, 0), new DateTimeOffset(), plainLinkBuilder, new List <ConventionalCommit>(), ChangelogOptions.Default); var wasChangelogWritten = File.Exists(Path.Join(_testDirectory, "CHANGELOG.md")); Assert.True(wasChangelogWritten); }
private Changelog SetUpUpdateChangelogWhenImageIsChanged(bool imageInserted) { var changelog = new ChangelogBuilder() .SetTitle(It.IsNotNull <string>()) .SetContent(It.IsNotNull <string>()) .SetImageUrl(It.IsAny <string>()) .Build(); database.Setup(d => d.ChangelogRepository.FindById(updateRequest.ChangelogId)) .ReturnsAsync(changelog); mapper.Setup(m => m.Map(updateRequest, changelog)).Returns(changelog); filesManager.Setup(fm => fm.Upload(It.IsNotNull <IFormFile>(), It.IsNotNull <string>())) .ReturnsAsync(new FileModel("path", "url", 1)); database.Setup(d => d.ChangelogImageRepository.Insert(It.IsNotNull <ChangelogImage>(), false)) .ReturnsAsync(imageInserted); database.Setup(d => d.ChangelogRepository.Update(changelog)).ReturnsAsync(true); return(changelog); }
public void ShouldGenerateWithoutLiteralLineBreakCharacters() { var plainLinkBuilder = new PlainLinkBuilder(); var changelog = ChangelogBuilder.CreateForPath(_testDirectory); changelog.Write( new Version(1, 1, 0), new DateTimeOffset(), plainLinkBuilder, new List <ConventionalCommit> { ConventionalCommitParser.Parse(new TestCommit("a360d6a307909c6e571b29d4a329fd786c5d4543", "fix: a fix")), }, ChangelogOptions.Default); var contents = File.ReadAllText(Path.Join(_testDirectory, "CHANGELOG.md")); contents.ShouldNotContain("\\n"); }
public async Task <Changelog> CreateChangelog(CreateChangelogRequest request) { var changelog = new ChangelogBuilder() .SetTitle(request.Title) .SetContent(request.Content) .Build(); if (!await database.ChangelogRepository.Insert(changelog, false)) { throw new DatabaseException(); } if (request.Image != null) { await UploadImage(request.Image, changelog); await database.ChangelogRepository.Update(changelog); } return(changelog); }
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); }