Skip to content

Commit

Permalink
feat: add issue link support and templates for plain links (#109)
Browse files Browse the repository at this point in the history
* feat: add issue link support and templates for plain links

* fix by Codacy Static Code Analysis

* fix at CreateFor
  • Loading branch information
nigma143 committed Nov 3, 2023
1 parent 808f2aa commit 0f030ec
Show file tree
Hide file tree
Showing 20 changed files with 340 additions and 11 deletions.
18 changes: 18 additions & 0 deletions Versionize.Tests/Changelog/AzureLinkBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@ public void ShouldBuildAHTTPSCommitLink()
link.ShouldBe("https://dosse@dev.azure.com/dosse/DosSE.ERP.Cloud/_git/ERP/commit/734713bc047d87bf7eac9674765ae793478c50d3");
}

[Fact]
public void ShouldBuildASSHIssueLink()
{
var linkBuilder = new AzureLinkBuilder("git@ssh.dev.azure.com:v3/dosse/DosSE.ERP.Cloud/ERP.git");
var link = linkBuilder.BuildIssueLink("123");

link.ShouldBe("https://v3@dev.azure.com/v3/dosse/DosSE.ERP.Cloud/ERP/_workitems/edit/123");
}

[Fact]
public void ShouldBuildAHTTPSIssueLink()
{
var linkBuilder = new AzureLinkBuilder("https://dosse@dev.azure.com/dosse/DosSE.ERP.Cloud/_git/ERP.git");
var link = linkBuilder.BuildIssueLink("123");

link.ShouldBe("https://dosse@dev.azure.com/dosse/DosSE.ERP.Cloud/_git/ERP/_workitems/edit/123");
}

[Fact]
public void ShouldCreateAnAzureUrlBuilderForSSHPushUrlsEvenWithoutGitSuffix()
{
Expand Down
18 changes: 18 additions & 0 deletions Versionize.Tests/Changelog/BitbucketLinkBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,24 @@ public void ShouldBuildAComSSHCommitLink()
link.ShouldBe("https://bitbucket.com/mobiloitteinc/dotnet-codebase/commits/734713bc047d87bf7eac9674765ae793478c50d3");
}

[Fact]
public void ShouldBuildAnOrgSSHIssueLink()
{
var linkBuilder = new BitbucketLinkBuilder(sshOrgPushUrl);
var link = linkBuilder.BuildIssueLink("123");

link.ShouldBe("https://bitbucket.org/mobiloitteinc/dotnet-codebase/issues/123");
}

[Fact]
public void ShouldBuildAComSSHIssueLink()
{
var linkBuilder = new BitbucketLinkBuilder(sshComPushUrl);
var link = linkBuilder.BuildIssueLink("321");

link.ShouldBe("https://bitbucket.com/mobiloitteinc/dotnet-codebase/issues/321");
}

[Fact]
public void ShouldBuildAnOrgHTTPSCommitLink()
{
Expand Down
42 changes: 42 additions & 0 deletions Versionize.Tests/Changelog/ChangelogBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,48 @@ public void ShouldGenerateAChangelogForFixFeatAndBreakingCommits()
Assert.Equal(sb.Build(), changelogContents);
}

[Fact]
public void ShouldGenerateAChangelogForFixFeatAndIssueLink()
{
var githubLinkBuilder = new GithubLinkBuilder(
"https://github.com/versionize/versionize.git");
var changelog = ChangelogBuilder.CreateForPath(_testDirectory);
changelog.Write(
new Version(1, 1, 0),
DateTimeOffset.Parse("2023-10-31"),
githubLinkBuilder,
new List<ConventionalCommit>
{
ConventionalCommitParser.Parse(new TestCommit("a360d6a307909c6e571b29d4a329fd786c5d4543", "fix: a fix #107")),
ConventionalCommitParser.Parse(new TestCommit("b360d6a307909c6e571b29d4a329fd786c5d4543", "feat: a feature (#75)")),
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 expectedContent = @$"{ChangelogOptions.Preamble}
<a name=""1.1.0""></a>
## [1.1.0](https://www.github.com/versionize/versionize/releases/tag/v1.1.0) (2023-10-31)
### Features
* a breaking change feature ([c360d6a](https://www.github.com/versionize/versionize/commit/c360d6a307909c6e571b29d4a329fd786c5d4543))
* a feature ([#75](https://www.github.com/versionize/versionize/issues/75)) ([b360d6a](https://www.github.com/versionize/versionize/commit/b360d6a307909c6e571b29d4a329fd786c5d4543))
### Bug Fixes
* a fix [#107](https://www.github.com/versionize/versionize/issues/107) ([a360d6a](https://www.github.com/versionize/versionize/commit/a360d6a307909c6e571b29d4a329fd786c5d4543))
### Breaking Changes
* a breaking change feature ([c360d6a](https://www.github.com/versionize/versionize/commit/c360d6a307909c6e571b29d4a329fd786c5d4543))
";
Assert.Equal(expectedContent, changelogContents);
}

[Fact]
public void ShouldHideFixSectionWhenHideIsTrue()
{
Expand Down
37 changes: 37 additions & 0 deletions Versionize.Tests/Changelog/GithubLinkBuilderTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using LibGit2Sharp;
using NuGet.Versioning;
using Shouldly;
using Versionize.Tests.TestSupport;
using Xunit;
Expand Down Expand Up @@ -67,6 +68,42 @@ public void ShouldCreateAGithubUrlBuilderForHTTPSPushUrlsEvenWithoutGitSuffix()
linkBuilder.ShouldBeAssignableTo<GithubLinkBuilder>();
}

[Fact]
public void ShouldBuildASSHLink()
{
var linkBuilder = new GithubLinkBuilder("git@github.com:versionize/versionize");

linkBuilder.BuildIssueLink("123")
.ShouldBe("https://www.github.com/versionize/versionize/issues/123");
linkBuilder.BuildCommitLink(
new ConventionalCommit
{
Sha = "734713bc047d87bf7eac9674765ae793478c50d3"
})
.ShouldBe("https://www.github.com/versionize/versionize/commit/734713bc047d87bf7eac9674765ae793478c50d3");
linkBuilder.BuildVersionTagLink(
new SemanticVersion(1, 2, 3))
.ShouldBe("https://www.github.com/versionize/versionize/releases/tag/v1.2.3");
}

[Fact]
public void ShouldBuildAHTTPSLink()
{
var linkBuilder = new GithubLinkBuilder("https://github.com/versionize/versionize.git");

linkBuilder.BuildIssueLink("123")
.ShouldBe("https://www.github.com/versionize/versionize/issues/123");
linkBuilder.BuildCommitLink(
new ConventionalCommit
{
Sha = "734713bc047d87bf7eac9674765ae793478c50d3"
})
.ShouldBe("https://www.github.com/versionize/versionize/commit/734713bc047d87bf7eac9674765ae793478c50d3");
linkBuilder.BuildVersionTagLink(
new SemanticVersion(1, 2, 3))
.ShouldBe("https://www.github.com/versionize/versionize/releases/tag/v1.2.3");
}

private static Repository SetupRepositoryWithRemote(string remoteName, string pushUrl)
{
var workingDirectory = TempDir.Create();
Expand Down
18 changes: 18 additions & 0 deletions Versionize.Tests/Changelog/GitlabLinkBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ public void ShouldBuildAHTTPSCommitLink()
link.ShouldBe("https://gitlab.com/inkscape/inkscape/-/commit/734713bc047d87bf7eac9674765ae793478c50d3");
}

[Fact]
public void ShouldBuildASSHIssueLink()
{
var linkBuilder = new GitlabLinkBuilder(inkscapeSSH);
var link = linkBuilder.BuildIssueLink("123");

link.ShouldBe("https://gitlab.com/inkscape/inkscape/-/issues/123");
}

[Fact]
public void ShouldBuildAHTTPSIssueLink()
{
var linkBuilder = new GitlabLinkBuilder(inkscapeHTTPS);
var link = linkBuilder.BuildIssueLink("123");

link.ShouldBe("https://gitlab.com/inkscape/inkscape/-/issues/123");
}

[Fact]
public void ShouldBuildASSHTagLink()
{
Expand Down
75 changes: 75 additions & 0 deletions Versionize.Tests/Changelog/PlainLinkBuilderTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using LibGit2Sharp;
using NuGet.Versioning;
using Shouldly;
using Versionize.Changelog;
using Versionize.Tests.TestSupport;
using Xunit;

namespace Versionize.Tests.Changelog;

public class PlainLinkBuilderTest
{
[Fact]
public void ShouldCreatePlainLinkBuilder()
{
var repo = SetupRepositoryWithRemote("origin", "https://hostmeister.com/versionize/versionize.git");
var linkBuilder = LinkBuilderFactory.CreateFor(repo);

linkBuilder.ShouldBeAssignableTo<PlainLinkBuilder>();

linkBuilder.BuildIssueLink("123")
.ShouldBeEmpty();
linkBuilder.BuildCommitLink(
new ConventionalCommit
{
Sha = "734713bc047d87bf7eac9674765ae793478c50d3"
})
.ShouldBeEmpty();
linkBuilder.BuildVersionTagLink(
new SemanticVersion(1, 2, 3))
.ShouldBeEmpty();
}

[Fact]
public void ShouldBuildCustomLinks()
{
var repo = SetupRepositoryWithRemote("origin", "https://hostmeister.com/versionize/versionize.git");
var linkBuilder = LinkBuilderFactory.CreateFor(
repo,
new PlainLinkTemplates
{
IssueLink = "https://my-repo/issues/{issue}",
CommitLink = "https://my-repo/commits/{commitSha}",
VersionTagLink = "https://my-repo/tags/v{version}",
});

linkBuilder.ShouldBeAssignableTo<PlainLinkBuilder>();

linkBuilder.BuildIssueLink("123")
.ShouldBe("https://my-repo/issues/123");
linkBuilder.BuildCommitLink(
new ConventionalCommit
{
Sha = "734713bc047d87bf7eac9674765ae793478c50d3"
})
.ShouldBe("https://my-repo/commits/734713bc047d87bf7eac9674765ae793478c50d3");
linkBuilder.BuildVersionTagLink(
new SemanticVersion(1, 2, 3))
.ShouldBe("https://my-repo/tags/v1.2.3");
}

private static Repository SetupRepositoryWithRemote(string remoteName, string pushUrl)
{
var workingDirectory = TempDir.Create();
var repo = TempRepository.Create(workingDirectory);

foreach (var existingRemoteName in repo.Network.Remotes.Select(remote => remote.Name))
{
repo.Network.Remotes.Remove(existingRemoteName);
}

repo.Network.Remotes.Add(remoteName, pushUrl);

return repo;
}
}
25 changes: 24 additions & 1 deletion Versionize.Tests/ConventionalCommitParserTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using LibGit2Sharp;
using LibGit2Sharp;
using Shouldly;
using Xunit;

Expand Down Expand Up @@ -72,6 +72,29 @@ public void ShouldSupportExclamationMarkToSignifyingBreakingChanges(string commi
conventionalCommit.Notes[0].Title.ShouldBe("BREAKING CHANGE");
conventionalCommit.Notes[0].Text.ShouldBe(string.Empty);
}

[Theory]
[InlineData("fix: subject text #64", new[] {"64"})]
[InlineData("fix: subject #64 text", new[] { "64" })]
[InlineData("fix: #64 subject text", new[] { "64" })]
[InlineData("fix: subject text. #64 #65", new[] { "64", "65" })]
[InlineData("fix: subject text. (#64) (#65)", new[] { "64", "65" })]
[InlineData("fix: subject text. #64#65", new[] { "64", "65" })]
[InlineData("fix: #64 subject #65 text. (#66)", new[] { "64", "65", "66" })]
public void ShouldExtractCommitIssues(string commitMessage, string[] expectedIssues)
{
var testCommit = new TestCommit("c360d6a307909c6e571b29d4a329fd786c5d4543", commitMessage);
var conventionalCommit = ConventionalCommitParser.Parse(testCommit);

Assert.Equal(conventionalCommit.Issues.Count, expectedIssues.Length);

foreach (var expectedIssue in expectedIssues)
{
var issue = conventionalCommit.Issues.SingleOrDefault(x => x.Id == expectedIssue);
Assert.NotNull(issue);
Assert.Equal(issue.Token, $"#{expectedIssue}");
}
}
}

public class TestCommit : Commit
Expand Down
5 changes: 5 additions & 0 deletions Versionize/Changelog/AzureLinkBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public string BuildVersionTagLink(Version version)
return $"https://{_organization}@dev.azure.com/{_organization}/{_repository}/releases/tag/v{version}";
}

public string BuildIssueLink(string issueId)
{
return $"https://{_organization}@dev.azure.com/{_organization}/{_repository}/_workitems/edit/{issueId}";
}

public string BuildCommitLink(ConventionalCommit commit)
{
return $"https://{_organization}@dev.azure.com/{_organization}/{_repository}/commit/{commit.Sha}";
Expand Down
7 changes: 6 additions & 1 deletion Versionize/Changelog/BitbucketLinkBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using Version = NuGet.Versioning.SemanticVersion;

namespace Versionize.Changelog;
Expand Down Expand Up @@ -59,6 +59,11 @@ public string BuildVersionTagLink(Version version)
return $"https://bitbucket.{_domain}/{_organization}/{_repository}/src/v{version}";
}

public string BuildIssueLink(string issueId)
{
return $"https://bitbucket.{_domain}/{_organization}/{_repository}/issues/{issueId}";
}

public string BuildCommitLink(ConventionalCommit commit)
{
return $"https://bitbucket.{_domain}/{_organization}/{_repository}/commits/{commit.Sha}";
Expand Down
12 changes: 11 additions & 1 deletion Versionize/Changelog/ChangelogBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,17 @@ public static string BuildCommit(ConventionalCommit commit, IChangelogLinkBuilde
sb.Append($"**{commit.Scope}:** ");
}

sb.Append(commit.Subject);
var subject = commit.Subject;
foreach (var issue in commit.Issues)
{
var issueLink = linkBuilder.BuildIssueLink(issue.Id);
if (!string.IsNullOrEmpty(issueLink))
{
subject = subject.Replace(issue.Token, $"[{issue.Token}]({issueLink})");
}
}

sb.Append(subject);

var commitLink = linkBuilder.BuildCommitLink(commit);

Expand Down
5 changes: 5 additions & 0 deletions Versionize/Changelog/GithubLinkBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public string BuildVersionTagLink(Version version)
return $"https://www.github.com/{_organization}/{_repository}/releases/tag/v{version}";
}

public string BuildIssueLink(string issueId)
{
return $"https://www.github.com/{_organization}/{_repository}/issues/{issueId}";
}

public string BuildCommitLink(ConventionalCommit commit)
{
return $"https://www.github.com/{_organization}/{_repository}/commit/{commit.Sha}";
Expand Down
6 changes: 6 additions & 0 deletions Versionize/Changelog/GitlabLinkBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using LibGit2Sharp;
using System.Text.RegularExpressions;
using Version = NuGet.Versioning.SemanticVersion;

Expand Down Expand Up @@ -51,6 +52,11 @@ public string BuildVersionTagLink(Version version)
return $"https://gitlab.com/{_organization}/{_repository}/-/tags/v{version}";
}

public string BuildIssueLink(string issueId)
{
return $"https://gitlab.com/{_organization}/{_repository}/-/issues/{issueId}";
}

public string BuildCommitLink(ConventionalCommit commit)
{
return $"https://gitlab.com/{_organization}/{_repository}/-/commit/{commit.Sha}";
Expand Down
4 changes: 3 additions & 1 deletion Versionize/Changelog/IChangelogLinkBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using Version = NuGet.Versioning.SemanticVersion;
using Version = NuGet.Versioning.SemanticVersion;

namespace Versionize.Changelog;

public interface IChangelogLinkBuilder
{
string BuildIssueLink(string issueId);

string BuildCommitLink(ConventionalCommit commit);

string BuildVersionTagLink(Version version);
Expand Down

0 comments on commit 0f030ec

Please sign in to comment.