コード例 #1
0
        public void Build(out IRepository repo, out IIssueTracker issueTracker)
        {
            var commits      = new List <Commit>();
            var tags         = new List <Tag>();
            var closedIssues = new List <Issue>();

            repo         = Substitute.For <IRepository>();
            issueTracker = Substitute.For <IIssueTracker>();

            commits.Add(CreateCommit(_initialCommitTime));
            var currentDate = _initialCommitTime.AddDays(1);

            foreach (var release in _releases)
            {
                // Create a commit, which *fixes* all the closed issues in the release
                commits.Add(CreateCommit(currentDate));

                // Create closed issues
                foreach (var issue in release.Item2)
                {
                    issue.DateClosed = currentDate;
                    closedIssues.Add(issue);
                }

                // Create commit which completes the release, and tag that commit
                currentDate = currentDate.AddDays(1);
                var commit = CreateCommit(currentDate);
                commits.Add(commit);
                tags.Add(CreateTag(commit, release.Item1));
                currentDate = currentDate.AddDays(1);
            }
            foreach (var additionalIssue in _additionalIssues)
            {
                closedIssues.Add(new Issue(GetNextId())
                {
                    DateCreated = currentDate,
                    Title       = additionalIssue,
                    IssueType   = IssueType.Issue
                });
                var commit = CreateCommit(currentDate);
                commits.Add(commit);
            }

            SubstituteCommitLog(repo, commits, tags);

            var filter = new IssueTrackerFilter
            {
                IncludeClosed = true
            };

            var issuesTask = issueTracker.GetIssuesAsync(filter);
            var issues     = issuesTask.Result;

            issues.Returns(c => closedIssues.Where(i => c.Arg <DateTimeOffset?>() == null || i.DateClosed > c.Arg <DateTimeOffset?>()));
        }
コード例 #2
0
        public async Task ReturnsIssuesUsingRest()
        {
            var issueTracker = new JiraIssueTracker("https://catelproject.atlassian.net/", "CTL", null);
            var issueFilter = new IssueTrackerFilter
            {
                IncludeClosed = true,
                Since = new DateTimeOffset(DateTime.Today.AddMonths(-1))
            };

            var issues = await issueTracker.GetIssuesAsync(issueFilter);
            var issuesList = issues.ToList();

            issuesList.ShouldNotBeEmpty();
        }
コード例 #3
0
        public async Task ReturnsIssuesUsingRest()
        {
            var issueTracker = new JiraIssueTracker("https://catelproject.atlassian.net/", "CTL", null);
            var issueFilter  = new IssueTrackerFilter
            {
                IncludeClosed = true,
                Since         = new DateTimeOffset(DateTime.Today.AddMonths(-1))
            };

            var issues = await issueTracker.GetIssuesAsync(issueFilter);

            var issuesList = issues.ToList();

            issuesList.ShouldNotBeEmpty();
        }
コード例 #4
0
        public async Task <IEnumerable <Issue> > GetIssuesAsync(IssueTrackerFilter filter)
        {
            var repositoryIssueRequest = PrepareFilter(filter);
            var forRepository          = await _gitHubClient.Issue.GetAllForRepository(Organisation, Repository, repositoryIssueRequest);

            var readOnlyList = forRepository.Where(i => i.ClosedAt > filter.Since);

            return(readOnlyList.Select(i => new Issue("#" + i.Number.ToString(CultureInfo.InvariantCulture))
            {
                DateClosed = i.ClosedAt,
                Url = i.HtmlUrl.ToString(),
                Title = i.Title,
                IssueType = i.PullRequest == null ? IssueType.Issue : IssueType.PullRequest,
                Labels = i.Labels.Select(l => l.Name).ToArray(),
                Contributors = i.PullRequest == null ? new Contributor[0] : new[]
                {
                    new Contributor(GetUserName(_gitHubClient, i.User), i.User.Login, i.User.HtmlUrl)
                }
            }));
        }
コード例 #5
0
        private string PrepareFilter(IssueTrackerFilter filter, IEnumerable <Jira.IssueStatus> openedStatuses,
                                     IEnumerable <Jira.IssueStatus> closedStatuses, IEnumerable <Jira.IssueResolution> acceptedResolutions)
        {
            var finalFilter = string.Empty;

            if (!string.IsNullOrWhiteSpace(filter.Filter))
            {
                finalFilter = filter.Filter;
            }

            if (filter.IncludeOpen && filter.IncludeClosed)
            {
                // no need to filter anything
            }
            else if (!filter.IncludeOpen && !filter.IncludeClosed)
            {
                throw new Exception("Cannot exclude both open and closed issues, nothing will be returned");
            }
            else if (filter.IncludeOpen)
            {
                finalFilter = finalFilter.AddJiraFilter(string.Format("status in ({0})", string.Join(", ", openedStatuses.Select(x => string.Format("\"{0}\"", x)))));
            }
            else if (filter.IncludeClosed)
            {
                finalFilter = finalFilter.AddJiraFilter(string.Format("status in ({0})", string.Join(", ", closedStatuses.Select(x => string.Format("\"{0}\"", x)))));
            }

            if (filter.Since.HasValue)
            {
                finalFilter = finalFilter.AddJiraFilter(string.Format("resolutiondate >= '{0}'", filter.Since.Value.ToString("yyyy-MM-dd")));
            }

            if (acceptedResolutions.Any())
            {
                finalFilter = finalFilter.AddJiraFilter(string.Format("resolution in ({0})", string.Join(", ", acceptedResolutions.Select(x => string.Format("\"{0}\"", x)))));
            }

            finalFilter = finalFilter.AddJiraFilter(string.Format("project = {0}", _project));

            return(finalFilter);
        }
コード例 #6
0
        private Octokit.RepositoryIssueRequest PrepareFilter(IssueTrackerFilter filter)
        {
            var repositoryIssueRequest = new Octokit.RepositoryIssueRequest
            {
                Filter = Octokit.IssueFilter.All,
                Since  = filter.Since,
            };

            if (filter.IncludeOpen && filter.IncludeClosed)
            {
                repositoryIssueRequest.State = Octokit.ItemState.All;
            }
            else if (filter.IncludeOpen)
            {
                repositoryIssueRequest.State = Octokit.ItemState.Open;
            }
            else if (filter.IncludeClosed)
            {
                repositoryIssueRequest.State = Octokit.ItemState.Closed;
            }

            return(repositoryIssueRequest);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        public async Task <IEnumerable <Issue> > GetIssuesAsync(IssueTrackerFilter filter)
        {
            Log.DebugFormat("Connecting to Jira server '{0}'", _server);

            var jira = Atlassian.Jira.Jira.CreateRestClient(_server, _authenticationInfo.Username,
                                                            _authenticationInfo.Password, new Jira.JiraRestClientSettings());

            var jiraRestClient = jira.RestClient;

            Log.Debug("Retrieving statuses");

            var statuses    = (await jiraRestClient.GetIssueStatusesAsync(CancellationToken.None)).ToList();
            var resolutions = (await jiraRestClient.GetIssueResolutionsAsync(CancellationToken.None)).ToList();

            var openedStatuses      = GetOpenedStatuses(statuses);
            var closedStatuses      = GetClosedStatuses(statuses);
            var acceptedResolutions = GetAcceptedResolutions(resolutions);

            var finalFilter = PrepareFilter(filter, openedStatuses, closedStatuses, acceptedResolutions);

            var issues = new List <Issue>();

            Log.DebugFormat("Searching for issues using filter '{0}'", filter);

            const int MaxIssues = 200;

            // TODO: Once the Atlassian.Sdk issue type contains all info, remove custom JiraIssue
            var retrievedIssues = jiraRestClient.GetIssues(finalFilter, 0, MaxIssues);
            //var retrievedIssues = await jiraRestClient.GetIssuesFromJqlAsync(finalFilter, MaxIssues, 0, CancellationToken.None);

            int lastRetrievedIssuesCount = retrievedIssues.Count;

            while (lastRetrievedIssuesCount % MaxIssues == 0)
            {
                var newlyRetrievedIssues = jiraRestClient.GetIssues(finalFilter, lastRetrievedIssuesCount, MaxIssues);
                //var newlyRetrievedIssues = await jiraRestClient.GetIssuesFromJqlAsync(finalFilter, MaxIssues, lastRetrievedIssuesCount, CancellationToken.None);
                if (newlyRetrievedIssues.Count == 0)
                {
                    break;
                }

                retrievedIssues.AddRange(newlyRetrievedIssues);

                lastRetrievedIssuesCount = retrievedIssues.Count;
            }

            foreach (var issue in retrievedIssues)
            {
                var gitIssue = new Issue(issue.key)
                {
                    IssueType   = IssueType.Issue,
                    Title       = issue.summary,
                    Description = issue.description,
                    DateCreated = issue.created,
                    Labels      = issue.labels.ToArray()
                };

                if (closedStatuses.Any(x => string.Equals(x.Id, issue.status)))
                {
                    gitIssue.DateClosed = issue.resolutionDate;
                }

                foreach (var fixVersion in issue.fixVersions)
                {
                    gitIssue.FixVersions.Add(new Version
                    {
                        Name        = fixVersion.name,
                        ReleaseDate = fixVersion.releaseDate,
                        IsReleased  = fixVersion.released
                    });
                }

                var uri = new Uri(new Uri(_server), string.Format("/browse/{0}", issue.key));
                gitIssue.Url = uri.ToString();

                issues.Add(gitIssue);
            }

            Log.DebugFormat("Found '{0}' issues using filter '{1}'", issues.Count, filter);

            return(issues.AsEnumerable());
        }
コード例 #9
0
        public async Task<IEnumerable<Issue>> GetIssuesAsync(IssueTrackerFilter filter)
        {
            Log.DebugFormat("Connecting to Jira server '{0}'", _server);

            var jira = Atlassian.Jira.Jira.CreateRestClient(_server, _authenticationInfo.Username,
                _authenticationInfo.Password, new Jira.JiraRestClientSettings());

            var jiraRestClient = jira.RestClient;

            Log.Debug("Retrieving statuses");

            var statuses = (await jiraRestClient.GetIssueStatusesAsync(CancellationToken.None)).ToList();
            var resolutions = (await jiraRestClient.GetIssueResolutionsAsync(CancellationToken.None)).ToList();

            var openedStatuses = GetOpenedStatuses(statuses);
            var closedStatuses = GetClosedStatuses(statuses);
            var acceptedResolutions = GetAcceptedResolutions(resolutions);

            var finalFilter = PrepareFilter(filter, openedStatuses, closedStatuses, acceptedResolutions);

            var issues = new List<Issue>();

            Log.DebugFormat("Searching for issues using filter '{0}'", filter);

            const int MaxIssues = 200;

            // TODO: Once the Atlassian.Sdk issue type contains all info, remove custom JiraIssue
            var retrievedIssues = jiraRestClient.GetIssues(finalFilter, 0, MaxIssues);
            //var retrievedIssues = await jiraRestClient.GetIssuesFromJqlAsync(finalFilter, MaxIssues, 0, CancellationToken.None);

            int lastRetrievedIssuesCount = retrievedIssues.Count;

            while (lastRetrievedIssuesCount % MaxIssues == 0)
            {
                var newlyRetrievedIssues = jiraRestClient.GetIssues(finalFilter, lastRetrievedIssuesCount, MaxIssues);
                //var newlyRetrievedIssues = await jiraRestClient.GetIssuesFromJqlAsync(finalFilter, MaxIssues, lastRetrievedIssuesCount, CancellationToken.None);
                if (newlyRetrievedIssues.Count == 0)
                {
                    break;
                }

                retrievedIssues.AddRange(newlyRetrievedIssues);

                lastRetrievedIssuesCount = retrievedIssues.Count;
            }

            foreach (var issue in retrievedIssues)
            {
                var gitIssue = new Issue(issue.key)
                {
                    IssueType = IssueType.Issue,
                    Title = issue.summary,
                    Description = issue.description,
                    DateCreated = issue.created,
                    Labels = issue.labels.ToArray()
                };

                if (closedStatuses.Any(x => string.Equals(x.Id, issue.status)))
                {
                    gitIssue.DateClosed = issue.resolutionDate;
                }

                foreach (var fixVersion in issue.fixVersions)
                {
                    gitIssue.FixVersions.Add(new Version
                    {
                        Name = fixVersion.name,
                        ReleaseDate = fixVersion.releaseDate,
                        IsReleased = fixVersion.released
                    });
                }

                var uri = new Uri(new Uri(_server), string.Format("/browse/{0}", issue.key));
                gitIssue.Url = uri.ToString();

                issues.Add(gitIssue);
            }

            Log.DebugFormat("Found '{0}' issues using filter '{1}'", issues.Count, filter);

            return issues.AsEnumerable();
        }
コード例 #10
0
        private string PrepareFilter(IssueTrackerFilter filter, IEnumerable<Jira.IssueStatus> openedStatuses, 
            IEnumerable<Jira.IssueStatus> closedStatuses, IEnumerable<Jira.IssueResolution> acceptedResolutions)
        {
            var finalFilter = string.Empty;
            if (!string.IsNullOrWhiteSpace(filter.Filter))
            {
                finalFilter = filter.Filter;
            }

            if (filter.IncludeOpen && filter.IncludeClosed)
            {
                // no need to filter anything
            }
            else if (!filter.IncludeOpen && !filter.IncludeClosed)
            {
                throw new Exception("Cannot exclude both open and closed issues, nothing will be returned");
            }
            else if (filter.IncludeOpen)
            {
                finalFilter = finalFilter.AddJiraFilter(string.Format("status in ({0})", string.Join(", ", openedStatuses.Select(x => string.Format("\"{0}\"", x)))));
            }
            else if (filter.IncludeClosed)
            {
                finalFilter = finalFilter.AddJiraFilter(string.Format("status in ({0})", string.Join(", ", closedStatuses.Select(x => string.Format("\"{0}\"", x)))));
            }

            if (filter.Since.HasValue)
            {
                finalFilter = finalFilter.AddJiraFilter(string.Format("resolutiondate >= '{0}'", filter.Since.Value.ToString("yyyy-MM-dd")));
            }

            if (acceptedResolutions.Any())
            {
                finalFilter = finalFilter.AddJiraFilter(string.Format("resolution in ({0})", string.Join(", ", acceptedResolutions.Select(x => string.Format("\"{0}\"", x)))));
            }

            finalFilter = finalFilter.AddJiraFilter(string.Format("project = {0}", _project));

            return finalFilter;
        }