Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions src/DemaConsulting.BuildMark/RepoConnectors/GitHubRepoConnector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public override async Task<BuildInformation> GetBuildInformationAsync(Version? v
: null;

// Generate full changelog link for GitHub
var changelogLink = GenerateGitHubChangelogLink(owner, repo, fromVersion?.Tag, toVersion.Tag);
var changelogLink = GenerateGitHubChangelogLink(owner, repo, fromVersion?.Tag, toVersion.Tag, lookupData.BranchTagNames);

// Create and return build information with all collected data
return new BuildInformation(
Expand Down Expand Up @@ -135,7 +135,8 @@ internal sealed record LookupData(
List<Release> BranchReleases,
Dictionary<string, RepositoryTag> TagsByName,
Dictionary<string, Release> TagToRelease,
List<Version> ReleaseVersions);
List<Version> ReleaseVersions,
HashSet<string> BranchTagNames);

/// <summary>
/// Fetches all required data from GitHub API in parallel.
Expand Down Expand Up @@ -222,7 +223,8 @@ internal static LookupData BuildLookupData(GitHubData data)
branchReleases,
tagsByName,
tagToRelease,
releaseVersions);
releaseVersions,
branchTagNames);
}

/// <summary>
Expand Down Expand Up @@ -731,15 +733,22 @@ internal static (string owner, string repo) ParseOwnerRepo(string path)
/// <param name="repo">Repository name.</param>
/// <param name="oldTag">Old tag name (null if from beginning).</param>
/// <param name="newTag">New tag name.</param>
/// <returns>WebLink to GitHub compare page, or null if no baseline tag.</returns>
internal static WebLink? GenerateGitHubChangelogLink(string owner, string repo, string? oldTag, string newTag)
/// <param name="branchTagNames">Set of tag names on the current branch.</param>
/// <returns>WebLink to GitHub compare page, or null if no baseline tag or if tags not found in branch.</returns>
internal static WebLink? GenerateGitHubChangelogLink(string owner, string repo, string? oldTag, string newTag, HashSet<string> branchTagNames)
{
// Cannot generate comparison link without a baseline tag
if (oldTag == null)
{
return null;
}

// Suppress changelog link if either tag is not in the branch
if (!branchTagNames.Contains(oldTag) || !branchTagNames.Contains(newTag))
{
return null;
}

// Build comparison label and URL
var comparisonLabel = $"{oldTag}...{newTag}";
var comparisonUrl = $"https://github.com/{owner}/{repo}/compare/{comparisonLabel}";
Expand Down
61 changes: 59 additions & 2 deletions test/DemaConsulting.BuildMark.Tests/GitHubRepoConnectorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,11 @@ public void GitHubRepoConnector_GetCommitsInRange_ToHashNotFound_ReturnsEmptyLis
[TestMethod]
public void GitHubRepoConnector_GenerateGitHubChangelogLink_ValidTags_ReturnsWebLink()
{
// Arrange
var branchTagNames = new HashSet<string> { "v1.0.0", "v2.0.0" };

// Act
var link = GitHubRepoConnector.GenerateGitHubChangelogLink("owner", "repo", "v1.0.0", "v2.0.0");
var link = GitHubRepoConnector.GenerateGitHubChangelogLink("owner", "repo", "v1.0.0", "v2.0.0", branchTagNames);

// Assert
Assert.IsNotNull(link);
Expand All @@ -303,8 +306,59 @@ public void GitHubRepoConnector_GenerateGitHubChangelogLink_ValidTags_ReturnsWeb
[TestMethod]
public void GitHubRepoConnector_GenerateGitHubChangelogLink_NullOldTag_ReturnsNull()
{
// Arrange
var branchTagNames = new HashSet<string> { "v2.0.0" };

// Act
var link = GitHubRepoConnector.GenerateGitHubChangelogLink("owner", "repo", null, "v2.0.0", branchTagNames);

// Assert
Assert.IsNull(link);
}

/// <summary>
/// Test that GenerateGitHubChangelogLink returns null when oldTag is not in branch tags.
/// </summary>
[TestMethod]
public void GitHubRepoConnector_GenerateGitHubChangelogLink_OldTagNotInBranch_ReturnsNull()
{
// Arrange
var branchTagNames = new HashSet<string> { "v2.0.0" };

// Act
var link = GitHubRepoConnector.GenerateGitHubChangelogLink("owner", "repo", null, "v2.0.0");
var link = GitHubRepoConnector.GenerateGitHubChangelogLink("owner", "repo", "v1.0.0", "v2.0.0", branchTagNames);

// Assert
Assert.IsNull(link);
}

/// <summary>
/// Test that GenerateGitHubChangelogLink returns null when newTag is not in branch tags.
/// </summary>
[TestMethod]
public void GitHubRepoConnector_GenerateGitHubChangelogLink_NewTagNotInBranch_ReturnsNull()
{
// Arrange
var branchTagNames = new HashSet<string> { "v1.0.0" };

// Act
var link = GitHubRepoConnector.GenerateGitHubChangelogLink("owner", "repo", "v1.0.0", "v2.0.0", branchTagNames);

// Assert
Assert.IsNull(link);
}

/// <summary>
/// Test that GenerateGitHubChangelogLink returns null when neither tag is in branch tags.
/// </summary>
[TestMethod]
public void GitHubRepoConnector_GenerateGitHubChangelogLink_NoTagsInBranch_ReturnsNull()
{
// Arrange
var branchTagNames = new HashSet<string>();

// Act
var link = GitHubRepoConnector.GenerateGitHubChangelogLink("owner", "repo", "v1.0.0", "v2.0.0", branchTagNames);

// Assert
Assert.IsNull(link);
Expand All @@ -325,6 +379,7 @@ public void GitHubRepoConnector_DetermineTargetVersion_ProvidedVersion_ReturnsPr
[],
[],
[],
[],
[]);

// Act
Expand All @@ -349,6 +404,7 @@ public void GitHubRepoConnector_DetermineTargetVersion_NoVersionNoReleases_Throw
[],
[],
[],
[],
[]);

InvalidOperationException? caughtException = null;
Expand Down Expand Up @@ -386,6 +442,7 @@ public void GitHubRepoConnector_DetermineBaselineVersion_NoReleases_ReturnsNull(
[],
[],
[],
[],
[]);

// Act
Expand Down