/// <summary> /// Creates release notes of issues linked in commits added since the latest /// git tag. /// </summary> /// <remarks> /// If no git tag is found, the commit traversal starts from the first commit /// in the repository. /// <para> /// If you tag quite often, e.g. once per build, and want to traverse commits /// from the latest tag of a specific format, you can supply a /// <see cref="Regex"/> that will be used when looking up the latest tag. /// </para> /// </remarks> /// <param name="latestTagRegex"> /// An optional regex to find the latest tag of a specific format. /// </param> /// <param name="cancellationToken"> /// An optional token to monitor for cancellation requests. /// </param> /// <returns>The release notes.</returns> public async Task <ReleaseNotes> CreateReleaseNotesAsync( Regex?latestTagRegex = null, CancellationToken cancellationToken = default) { var commitsWithIssueLinks = await GetCommitsWithIssueLinks(latestTagRegex) .ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var distinctIssueNumbers = commitsWithIssueLinks.Select(pair => pair.IssueNumber).Distinct(); var distinctIssues = await _gitHubApi .GetIssuesAsync(distinctIssueNumbers, cancellationToken) .ConfigureAwait(false); var gitHubIssues = distinctIssues .Where(issue => issue.Labels.Any(label => _configuration.Labels.ShouldIncludeLabel(label.Name))) .Select(issue => new GitHubIssue( issue.Number, issue.Title, issue.HtmlUrl, issue.Labels .Where(label => _configuration.Labels.ShouldIncludeLabel(label.Name)) .Select(label => label.Name).ToList(), contributor: commitsWithIssueLinks .Where(pair => pair.IssueNumber == issue.Number && pair.Commit.Author != null && ( _configuration.ShouldGiveCreditToRepositoryOwner || !pair.Commit.Author.Login.Equals( _gitHubRepository.Owner, StringComparison.OrdinalIgnoreCase) )) .Select(pair => new GitHubContributor( pair.Commit.Author.Login, pair.Commit.Author.HtmlUrl)) .FirstOrDefault())) .ToList() .AsReadOnly(); return(new ReleaseNotes(gitHubIssues, _configuration.Labels)); }