private static bool TryRemote(Repository gitRepository, string name, ReleaseNotesGenerationParameters context, out IIssueTracker issueTracker) { var upstream = gitRepository.Network.Remotes[name]; if (upstream == null) { issueTracker = null; return false; } return IssueTrackerFactory.TryCreateIssueTrackerFromUrl( upstream.Url, context.IssueTracker.Authentication.ToIssueTrackerSettings(), out issueTracker); }
private static bool TryRemote(Repository gitRepository, string name, ReleaseNotesGenerationParameters context, out IIssueTracker issueTracker) { var upstream = gitRepository.Network.Remotes[name]; if (upstream == null) { issueTracker = null; return(false); } return(IssueTrackerFactory.TryCreateIssueTrackerFromUrl( upstream.Url, context.IssueTracker.Authentication.ToIssueTrackerSettings(), out issueTracker)); }
public static Task <SemanticReleaseNotes> GenerateReleaseNotesAsync(ReleaseNotesGenerationParameters generationParameters, IRepository gitRepo, SemanticReleaseNotes previousReleaseNotes, Categories categories, TaggedCommit tagToStartFrom, ReleaseInfo currentReleaseInfo) { var issuenumberregex = new Regex(@"#\s?(\d+)", RegexOptions.Compiled); var semanticReleases = new Dictionary <string, SemanticRelease>(); var releases = ReleaseFinder.FindReleases(gitRepo, tagToStartFrom, currentReleaseInfo); foreach (var release in releases) { if (!semanticReleases.ContainsKey(release.Name)) { var beginningSha = release.FirstCommit != null?release.FirstCommit.Substring(0, 10) : null; var endSha = release.LastCommit != null?release.LastCommit.Substring(0, 10) : null; semanticReleases.Add(release.Name, new SemanticRelease(release.Name, release.When, new ReleaseDiffInfo { BeginningSha = beginningSha, EndSha = endSha, // TODO DiffUrlFormat = context.Repository.DiffUrlFormat })); } var semanticRelease = semanticReleases[release.Name]; var commits = gitRepo.Commits.Where(x => x.Author.When >= release.PreviousReleaseDate && x.Author.When <= release.When); foreach (Commit commit in commits) { var match = issuenumberregex.Match(commit.Message); var releaseNoteItem = new ReleaseNoteItem(match.Success ? commit.Message.Replace(match.Groups[0].Value, "") :commit.Message, match.Success ? match.Groups[0].Value : string.Empty, match.Success? string.Format(generationParameters.IssueTracker.Server, match.Groups[0].Value): string.Empty, null, commit.Author.When, new[] { new Contributor(commit.Author.Name, commit.Author.Email, string.Empty) }); semanticRelease.ReleaseNoteLines.Add(releaseNoteItem); } } var semanticReleaseNotes = new SemanticReleaseNotes(semanticReleases.Values, categories); var mergedReleaseNotes = semanticReleaseNotes.Merge(previousReleaseNotes); return(Task.FromResult(mergedReleaseNotes)); }
public ReleaseNotesGenerator(ReleaseNotesGenerationParameters generationParameters) { _generationParameters = generationParameters; }
public static async Task <SemanticReleaseNotes> GenerateReleaseNotesAsync(ReleaseNotesGenerationParameters generationParameters, IRepository gitRepo, IIssueTracker issueTracker, SemanticReleaseNotes previousReleaseNotes, Categories categories, TaggedCommit tagToStartFrom, ReleaseInfo currentReleaseInfo) { var releases = ReleaseFinder.FindReleases(gitRepo, tagToStartFrom, currentReleaseInfo); var findIssuesSince = IssueStartDateBasedOnPreviousReleaseNotes(gitRepo, previousReleaseNotes) ?? tagToStartFrom.Commit.Author.When; var filter = new IssueTrackerFilter { Since = findIssuesSince, IncludeOpen = false }; var closedIssues = (await issueTracker.GetIssuesAsync(filter)).ToArray(); // As discussed here: https://github.com/GitTools/GitReleaseNotes/issues/85 var semanticReleases = new Dictionary <string, SemanticRelease>(); foreach (var issue in closedIssues) { // 1) Include all issues from the issue tracker that are assigned to this release foreach (var fixVersion in issue.FixVersions) { if (!fixVersion.IsReleased) { continue; } if (!semanticReleases.ContainsKey(fixVersion.Name)) { semanticReleases.Add(fixVersion.Name, new SemanticRelease(fixVersion.Name, fixVersion.ReleaseDate)); } var semanticRelease = semanticReleases[fixVersion.Name]; var releaseNoteItem = new ReleaseNoteItem(issue.Title, issue.Id, issue.Url, issue.Labels, issue.DateClosed, new Contributor[] { /*TODO: implement*/ }); semanticRelease.ReleaseNoteLines.Add(releaseNoteItem); } // 2) Get closed issues from the issue tracker that have no fixversion but are closed between the last release and this release if (issue.FixVersions.Count == 0) { foreach (var release in releases) { if (issue.DateClosed.HasValue && issue.DateClosed.Value > release.PreviousReleaseDate && (release.When == null || issue.DateClosed <= release.When)) { if (!semanticReleases.ContainsKey(release.Name)) { var beginningSha = release.FirstCommit != null?release.FirstCommit.Substring(0, 10) : null; var endSha = release.LastCommit != null?release.LastCommit.Substring(0, 10) : null; semanticReleases.Add(release.Name, new SemanticRelease(release.Name, release.When, new ReleaseDiffInfo { BeginningSha = beginningSha, EndSha = endSha, // TODO DiffUrlFormat = context.Repository.DiffUrlFormat })); } var semanticRelease = semanticReleases[release.Name]; var releaseNoteItem = new ReleaseNoteItem(issue.Title, issue.Id, issue.Url, issue.Labels, issue.DateClosed, issue.Contributors); semanticRelease.ReleaseNoteLines.Add(releaseNoteItem); } } } } // 3) Remove any duplicates foreach (var semanticRelease in semanticReleases.Values) { var handledIssues = new HashSet <string>(); for (var i = 0; i < semanticRelease.ReleaseNoteLines.Count; i++) { var releaseNoteLine = semanticRelease.ReleaseNoteLines[i] as ReleaseNoteItem; if (releaseNoteLine == null) { continue; } if (handledIssues.Contains(releaseNoteLine.IssueNumber)) { semanticRelease.ReleaseNoteLines.RemoveAt(i--); continue; } handledIssues.Add(releaseNoteLine.IssueNumber); } } var semanticReleaseNotes = new SemanticReleaseNotes(semanticReleases.Values, categories); var mergedReleaseNotes = semanticReleaseNotes.Merge(previousReleaseNotes); return(mergedReleaseNotes); }
public static async Task<SemanticReleaseNotes> GenerateReleaseNotesAsync(ReleaseNotesGenerationParameters generationParameters, IRepository gitRepo, IIssueTracker issueTracker, SemanticReleaseNotes previousReleaseNotes, Categories categories, TaggedCommit tagToStartFrom, ReleaseInfo currentReleaseInfo) { var releases = ReleaseFinder.FindReleases(gitRepo, tagToStartFrom, currentReleaseInfo); var findIssuesSince = IssueStartDateBasedOnPreviousReleaseNotes(gitRepo, previousReleaseNotes) ?? tagToStartFrom.Commit.Author.When; var filter = new IssueTrackerFilter { Since = findIssuesSince, IncludeOpen = false }; var closedIssues = (await issueTracker.GetIssuesAsync(filter)).ToArray(); // As discussed here: https://github.com/GitTools/GitReleaseNotes/issues/85 var semanticReleases = new Dictionary<string, SemanticRelease>(); foreach (var issue in closedIssues) { // 1) Include all issues from the issue tracker that are assigned to this release foreach (var fixVersion in issue.FixVersions) { if (!fixVersion.IsReleased) { continue; } if (!semanticReleases.ContainsKey(fixVersion.Name)) { semanticReleases.Add(fixVersion.Name, new SemanticRelease(fixVersion.Name, fixVersion.ReleaseDate)); } var semanticRelease = semanticReleases[fixVersion.Name]; var releaseNoteItem = new ReleaseNoteItem(issue.Title, issue.Id, issue.Url, issue.Labels, issue.DateClosed, new Contributor[] { /*TODO: implement*/ }); semanticRelease.ReleaseNoteLines.Add(releaseNoteItem); } // 2) Get closed issues from the issue tracker that have no fixversion but are closed between the last release and this release if (issue.FixVersions.Count == 0) { foreach (var release in releases) { if (issue.DateClosed.HasValue && issue.DateClosed.Value > release.PreviousReleaseDate && (release.When == null || issue.DateClosed <= release.When)) { if (!semanticReleases.ContainsKey(release.Name)) { var beginningSha = release.FirstCommit != null ? release.FirstCommit.Substring(0, 10) : null; var endSha = release.LastCommit != null ? release.LastCommit.Substring(0, 10) : null; semanticReleases.Add(release.Name, new SemanticRelease(release.Name, release.When, new ReleaseDiffInfo { BeginningSha = beginningSha, EndSha = endSha, // TODO DiffUrlFormat = context.Repository.DiffUrlFormat })); } var semanticRelease = semanticReleases[release.Name]; var releaseNoteItem = new ReleaseNoteItem(issue.Title, issue.Id, issue.Url, issue.Labels, issue.DateClosed, issue.Contributors); semanticRelease.ReleaseNoteLines.Add(releaseNoteItem); } } } } // 3) Remove any duplicates foreach (var semanticRelease in semanticReleases.Values) { var handledIssues = new HashSet<string>(); for (var i = 0; i < semanticRelease.ReleaseNoteLines.Count; i++) { var releaseNoteLine = semanticRelease.ReleaseNoteLines[i] as ReleaseNoteItem; if (releaseNoteLine == null) { continue; } if (handledIssues.Contains(releaseNoteLine.IssueNumber)) { semanticRelease.ReleaseNoteLines.RemoveAt(i--); continue; } handledIssues.Add(releaseNoteLine.IssueNumber); } } var semanticReleaseNotes = new SemanticReleaseNotes(semanticReleases.Values, categories); var mergedReleaseNotes = semanticReleaseNotes.Merge(previousReleaseNotes); return mergedReleaseNotes; }