Exemple #1
0
        public static IEnumerable <Issue> SearchForGitHubIssues(this GitHubClient s_gitHub, SearchIssuesRequest issueQuery)
        {
            List <Issue> totalIssues = new List <Issue>();
            int          totalPages = -1, currentPage = 0;

            do
            {
                currentPage++;
                issueQuery.Page = currentPage;

                SearchIssuesResult searchresults = null;

                searchresults = s_gitHub.Search.SearchIssues(issueQuery).Result;

                foreach (var item in searchresults.Items)
                {
                    totalIssues.Add(item);
                    Colorizer.WriteLine($"Found issue '[Cyan!{item.HtmlUrl}]' in GitHub.");
                    Colorizer.WriteLine($"   Labels: '[Green!{string.Join(",", item.Labels.Select(x => x.Name).OrderBy(s => s))}]'.");
                }

                // if this is the first call, setup the totalpages stuff
                if (totalPages == -1)
                {
                    totalPages = (searchresults.TotalCount / 100) + 1;
                }
            } while (totalPages > currentPage);

            return(totalIssues);
        }
Exemple #2
0
        private async Task <Issue> GetExistingIssueAsync(IGitHubClient client, GrafanaNotification notification)
        {
            string id = GetUniqueIdentifier(notification);

            var searchedLabels = new List <string>
            {
                NotificationIdLabel
            };

            searchedLabels.AddRange(_githubOptions.Value.EnvironmentLabels.OrEmpty());

            string automationId = string.Format(BodyLabelTextFormat, id);
            var    request      = new SearchIssuesRequest(automationId)
            {
                Labels    = searchedLabels,
                Order     = SortDirection.Descending,
                SortField = IssueSearchSort.Created,
                Type      = IssueTypeQualifier.Issue,
                In        = new[] { IssueInQualifier.Body },
                State     = ItemState.Open,
            };

            SearchIssuesResult issues = await client.Search.SearchIssues(request);

            return(issues.Items.FirstOrDefault());
        }
Exemple #3
0
        /// <summary>
        /// Loops through paginated search results to get all issues
        /// </summary>
        /// <param name="searchIssuesRequest">A SearchIssuesRequest object representing the GitHub issue search</param>
        /// <returns>All the issues in the given search</returns>
        public async Task <List <Issue> > GetAllIssuesFromSearchAsync(SearchIssuesRequest searchIssuesRequest)
        {
            SearchIssuesResult searchIssuesResult = await _githubClient.Search.SearchIssues(searchIssuesRequest);

            List <Issue> issues = new List <Issue>();

            issues.AddRange(searchIssuesResult.Items);

            // Loop through the pagination starting at page 2 since we've already done page 1 above
            for (int page = 2; issues.Count < searchIssuesResult.TotalCount; page++)
            {
                try
                {
                    searchIssuesRequest.Page = page;
                    searchIssuesResult       = await _githubClient.Search.SearchIssues(searchIssuesRequest);

                    issues.AddRange(searchIssuesResult.Items);
                }
                catch (Exception e)
                {
                    Utilities.WriteWarning($"An exception occurred while attempting to paginate through the GitHub issues search API.", Log);
                    Utilities.WriteWarning($"Attempting to access page {page} of search; currently read {issues.Count} of {searchIssuesResult.TotalCount}'", Log);
                    Utilities.WriteWarning($"Exception: ${e.Message}", Log);
                    break;
                }
            }

            return(issues);
        }
        private async Task <Issue> GetCorrespondingIssueAsync(int workItemId)
        {
            var searchIssuesRequest = new SearchIssuesRequest(term: TextUtilities.GetFormattedWorkItemId(workItemId))
            {
                Type = IssueTypeQualifier.Issue,
                In   = new[] { IssueInQualifier.Body },
            };

            searchIssuesRequest.Repos.Add(owner: repoOwner, name: repo);

            SearchIssuesResult searchIssuesResult = await search.SearchIssues(searchIssuesRequest);

            int searchResultCount = searchIssuesResult.Items.Count;

            if (searchResultCount == 0)
            {
                throw new WorkItemIdentificationException(string.Format(Resources.NoIssueFoundInGitHubRepoWithWorkItemIdX, workItemId));
            }

            if (searchResultCount > 1)
            {
                throw new WorkItemIdentificationException(string.Format(Resources.MultipleIssuesFoundInGitHubRepoWithWorkItemIdX, workItemId));
            }

            return(searchIssuesResult.Items[0]);
        }
        private async Task <Issue> GetExistingIssueAsync(IGitHubClient client, GrafanaNotification notification)
        {
            string id = GetUniqueIdentifier(notification);

            var searchedLabels = new List <string>
            {
                NotificationIdLabel
            };

            searchedLabels.AddRange(_githubOptions.Value.EnvironmentLabels.OrEmpty());

            string automationId = string.Format(BodyLabelTextFormat, id);
            var    request      = new SearchIssuesRequest(automationId)
            {
                // We need to manually quote the label here, because of
                // https://github.com/octokit/octokit.net/issues/2044
                Labels    = searchedLabels.Select(label => '"' + label + '"'),
                Order     = SortDirection.Descending,
                SortField = IssueSearchSort.Created,
                Type      = IssueTypeQualifier.Issue,
                In        = new[] { IssueInQualifier.Body },
                State     = ItemState.Open,
            };

            SearchIssuesResult issues = await client.Search.SearchIssues(request);

            return(issues.Items.FirstOrDefault());
        }
        public static IEnumerable <Issue> SearchForGitHubIssues(this GitHubClient s_gitHub, SearchIssuesRequest issueQuery)
        {
            List <Issue> totalIssues = new List <Issue>();
            int          totalPages = -1, currentPage = 0;

            do
            {
                currentPage++;
                issueQuery.Page = currentPage;

                SearchIssuesResult searchresults = null;

                searchresults = s_gitHub.Search.SearchIssues(issueQuery).Result;

                foreach (Issue item in searchresults.Items)
                {
                    totalIssues.Add(item);
                }

                // if this is the first call, setup the totalpages stuff
                if (totalPages == -1)
                {
                    totalPages = (searchresults.TotalCount / 100) + 1;
                }
            } while (totalPages > currentPage);

            return(totalIssues);
        }
Exemple #7
0
        public IReadOnlyList <Issue> GetAllEffortRelatedIssues(string searchTerm, string involvedPerson)
        {
            var relevantIssuesRequest = new SearchIssuesRequest(searchTerm)
            {
                Involves = involvedPerson,
                Type     = IssueTypeQualifier.Issue,
                In       = new[] { IssueInQualifier.Comment },
            };

            SearchIssuesResult potentialEffortIssues = searchClient.SearchIssues(relevantIssuesRequest).GetAwaiter().GetResult();

            return(potentialEffortIssues.Items);
        }
        private async Task <IReadOnlyList <int> > GetWorkItemIdsByLabel(string label)
        {
            var result = new List <int>();

            // Search for all issues marked with CodePlex migration labels sorted in ascending fashion by creation date.
            var searchIssuesRequest = new SearchIssuesRequest
            {
                Type      = IssueTypeQualifier.Issue,
                Labels    = new[] { label },
                Order     = SortDirection.Ascending,
                SortField = IssueSearchSort.Created,
                Page      = 1,
            };

            searchIssuesRequest.Repos.Add(owner: repoOwner, name: repo);

            int resultCount = 0;
            SearchIssuesResult searchIssuesResult = await search.SearchIssues(searchIssuesRequest);

            int totalResultCount = searchIssuesResult.TotalCount;

            // Extract CodePlex work item ID from issue body, migration state from from assigned labels.
            while (searchIssuesResult.Items.Count > 0)
            {
                foreach (Issue issue in searchIssuesResult.Items)
                {
                    try
                    {
                        int codePlexWorkItemId = TextUtilities.GetCodePlexWorkItemId(issue.Body);
                        result.Add(codePlexWorkItemId);
                    }
                    catch (Exception ex)
                    {
                        throw new WorkItemIdentificationException(
                                  string.Format(Resources.ErrorExtractingCodePlexWorkItemIdFromGitHubIssue, issue.Number, ex.Message), ex);
                    }
                }

                resultCount += searchIssuesResult.Items.Count;
                if (resultCount >= totalResultCount)
                {
                    break;
                }

                searchIssuesRequest.Page += 1;
                searchIssuesResult        = await search.SearchIssues(searchIssuesRequest);
            }

            return(result);
        }
        private async Task RequestAsync()
        {
            SearchIssuesRequest request = new SearchIssuesRequest();

            request.Repos.Add("angular/angular");
            request.Created = new DateRange(DateTime.Now.Subtract(TimeSpan.FromDays(7)), SearchQualifierOperator.GreaterThan);

            request.SortField = IssueSearchSort.Created;
            request.Order     = SortDirection.Descending;

            searchResults = await client.Search.SearchIssues(request);

            LastUpdate = DateTime.Now;
        }
        public static async Task <IEnumerable <Models.Objects.Issue> > ListIssuesAsync(this GitHubClient s_gitHub, RepositoryInfo repo, SearchIssuesRequest issueQuery)
        {
            TimeLimiter rateLimiter = TimeLimiter.GetFromMaxCountByInterval(1, TimeSpan.FromSeconds(1));

            List <Models.Objects.Issue> issuesFound = new List <Models.Objects.Issue>();

            int totalPages = -1, currentPage = 0;

            issueQuery.Repos.Add(repo.Owner, repo.Name);

            do
            {
                currentPage++;
                issueQuery.Page = currentPage;

                SearchIssuesResult searchresults = null;

                // make sure the rate limit is met
                await rateLimiter;
                searchresults = await s_gitHub.Search.SearchIssues(issueQuery);

                Colorizer.WriteLine("Found [Yellow!{0}] issues in [Magenta!{1}].", searchresults.TotalCount, $"{repo.Owner}\\{repo.Name}");

                foreach (Issue item in searchresults.Items)
                {
                    Models.Objects.Issue issueFound = new Models.Objects.Issue(item)
                    {
                        // set the repo on the item
                        RepositoryName   = repo.Name,
                        OrganizationName = repo.Owner
                    };
                    issuesFound.Add(issueFound);
                }

                // if this is the first call, setup the totalpages stuff
                if (totalPages == -1)
                {
                    totalPages = (searchresults.TotalCount / 100) + 1;
                }
                Colorizer.WriteLine("Retrieved [Yellow!{0}]/[Yellow!{1}] issues.", issuesFound.Count, searchresults.TotalCount);
            } while (totalPages > currentPage);

            return(issuesFound);
        }
Exemple #11
0
        private static async Task IssueExamples(GitHubClient client)
        {
            Issue issue = await client.Issue.Get("octokit", "octokit.net", 1);

            Console.WriteLine($"Issue.Get: Id={issue.Id}, Title={issue.Title}");

            SearchIssuesResult result = await client.Search.SearchIssues(
                new SearchIssuesRequest("bug")
            {
                In    = new IssueInQualifier[] { IssueInQualifier.Title },
                Repos = new RepositoryCollection {
                    "octokit/octokit.net"
                }
            });

            Console.WriteLine($"Search.SearchIssues (Simple Search): TotalCount={result.TotalCount}");

            await IssueAllFieldsExample(client);
        }
Exemple #12
0
        private async Task <IReadOnlyList <PullRequestEntry> > GetMergedPullRequestsBetween2Refs(string owner, string repository, string fromRef, string toRef, int batchSize)
        {
            // Get commits for the from/to range
            this.logger.LogInformation($"Get commits from {owner}/{repository} in specified range ({fromRef} - {toRef})");


            GitHubCommit fromCommit = await this.GitHubClient.Repository.Commit.Get(owner, repository, fromRef).ConfigureAwait(false);

            GitHubCommit toCommit = await this.GitHubClient.Repository.Commit.Get(owner, repository, toRef).ConfigureAwait(false);

            // Offset minimum date to ensure commit from last tag is not included.
            DateTime from       = fromCommit.Commit.Committer.Date.UtcDateTime.AddMinutes(1);
            DateTime to         = toCommit.Commit.Committer.Date.UtcDateTime;
            var      fromOffset = new DateTimeOffset(from);
            var      toOffset   = new DateTimeOffset(to);

            // First load the Pull Requests for the date range of our commits
            this.logger.LogInformation($"Find Pull Requests merged in this date range {from.ToLocalTime()} - {to.ToLocalTime()}");

            var pullRequestRequest = new PullRequestRequest
            {
                State = ItemStateFilter.Closed,
            };

            // It's faster than using "PullRequest.GetAllForRepository" to do a search issues query and query each PR
            // individually. Search results max at 100 items so we request in batches.
            List <PullRequest> mergedPullRequests = new List <PullRequest>();
            DateTimeOffset     tempFromOffset     = fromOffset;

            while (true)
            {
                var prRequest = new SearchIssuesRequest()
                {
                    Type   = IssueTypeQualifier.PullRequest,
                    Closed = new DateRange(tempFromOffset, toOffset),
                    State  = ItemState.Closed,
                    Repos  = new RepositoryCollection {
                        $"{owner}/{repository}"
                    }
                };

                SearchIssuesResult issues = await this.GitHubClient
                                            .Search
                                            .SearchIssues(prRequest)
                                            .ConfigureAwait(false);

                if (issues.Items?.Count == 0)
                {
                    break;
                }

                // The returned issues do not actually contain the PR information we require so we grab each one.
                foreach (Issue issue in issues.Items)
                {
                    PullRequest pr = await this.GitHubClient
                                     .PullRequest
                                     .Get(owner, repository, issue.Number)
                                     .ConfigureAwait(false);

                    if (pr?.Merged != true)
                    {
                        continue;
                    }

                    // Update the date to get the latest for subsequest queries.
                    if (tempFromOffset < pr.MergedAt.Value)
                    {
                        tempFromOffset = pr.MergedAt.Value;
                    }

                    mergedPullRequests.Add(pr);
                }

                if (issues.Items.Count == issues.TotalCount)
                {
                    break;
                }
            }

            this.logger.LogInformation($"Found {mergedPullRequests.Count} Pull Requests merged in this date range");
            this.logger.LogInformation("Getting details for each Pull Request");

            // Now load details about the PullRequests using parallel async tasks
            var result = new List <PullRequestEntry>();

            for (int i = 0; i < mergedPullRequests.Count; i += batchSize)
            {
                IEnumerable <PullRequest> batchPullRequests = mergedPullRequests
                                                              .Skip(i)
                                                              .Take(batchSize);

                List <Task <PullRequestEntry> > tasks = batchPullRequests.Select(async pull =>
                {
                    // Load the commits.
                    IReadOnlyList <PullRequestCommit> pullRequestCommits = await this.GitHubClient
                                                                           .PullRequest
                                                                           .Commits(owner, repository, pull.Number)
                                                                           .ConfigureAwait(false);

                    // Need to load commits individually to get the full author details.
                    // Using ToList runs the queries in parallel.
                    List <Task <GitHubCommit> > pullRequestFullCommitsTask = pullRequestCommits
                                                                             .Select(async x => await this.GitHubClient
                                                                                     .Repository.Commit.Get(owner, repository, x.Sha)
                                                                                     .ConfigureAwait(false))
                                                                             .ToList();

                    GitHubCommit[] pullRequestFullCommits = await Task.WhenAll(pullRequestFullCommitsTask).ConfigureAwait(false);

                    // Extract the distinct users who have commits in the PR
                    IEnumerable <Author> contributorUsers = pullRequestFullCommits
                                                            .Where(x => x.Author != null && x.Author.Id != 0)
                                                            .Select(x => x.Author)
                                                            .DistinctBy(x => x.Login);

                    // Gather everything into a CachedPullRequest object
                    return(new PullRequestEntry()
                    {
                        PullRequest = pull,
                        Commits = pullRequestCommits,
                        Contributors = contributorUsers.ToList(),
                        Labels = pull.Labels.Select(x => x.Name).ToList()
                    });
                }).ToList();

                // Collect the results
                result.AddRange(await Task.WhenAll(tasks).ConfigureAwait(false));

                this.logger.LogInformation($"Loaded {result.Count} Pull Requests");
            }

            return(result);
        }
Exemple #13
0
        private static async Task IssueAllFieldsExample(GitHubClient client)
        {
            var fromDate = new DateTime(2018, 3, 17);
            var toDate   = new DateTime(2019, 3, 17);

            int fromNumber = 1;
            int toNumber   = 10;

            string branch            = "master";
            string excludedBranch    = "other";
            string excludedLabel     = "wth";
            string excludedMilestone = "Nothing Done";
            string excludedUser      = "******";
            string label             = "up-for-grabs";
            string milestone         = "API Cleanup";
            string repository        = "octokit/octokit.net";
            string term = "bug";
            string user = "******";

            var request = new SearchIssuesRequest(term)
            {
                Archived   = true,
                Assignee   = user,
                Author     = user,
                Base       = branch,
                Closed     = new DateRange(fromDate, toDate),
                Commenter  = user,
                Comments   = new Range(fromNumber, toNumber),
                Created    = new DateRange(fromDate, SearchQualifierOperator.GreaterThan),
                Exclusions = new SearchIssuesRequestExclusions
                {
                    Assignee  = excludedUser,
                    Author    = excludedUser,
                    Base      = excludedBranch,
                    Commenter = excludedUser,
                    Head      = branch,
                    Involves  = excludedUser,
                    Labels    = new string[] { excludedLabel },
                    Language  = Language.Ada,
                    Mentions  = excludedUser,
                    Milestone = excludedMilestone,
                    State     = ItemState.Open,
                    Status    = CommitState.Error
                },
                Head      = branch,
                In        = new IssueInQualifier[] { IssueInQualifier.Title },
                Involves  = user,
                Is        = new IssueIsQualifier[] { IssueIsQualifier.Public },
                Labels    = new string[] { label },
                Language  = Language.CSharp,
                Mentions  = user,
                Merged    = new DateRange(toDate, SearchQualifierOperator.LessThan),
                Milestone = milestone,
                No        = IssueNoMetadataQualifier.Assignee,
                Order     = SortDirection.Descending,
                Repos     = new RepositoryCollection()
                {
                    repository
                },
                SortField = IssueSearchSort.Created,
                State     = ItemState.Closed,
                Status    = CommitState.Success,
                Type      = IssueTypeQualifier.Issue,
                Updated   = new DateRange(toDate, SearchQualifierOperator.LessThanOrEqualTo),
                User      = user
            };

            SearchIssuesResult result = await client.Search.SearchIssues(request);

            Console.WriteLine($"Search.SearchIssues (All Fields): TotalCount={result.TotalCount}");
        }
Exemple #14
0
 public CreateIssueCommentResponse CreateIssueComment(SearchIssuesResult issue, string body)
 {
     return(Request(new CreateIssueCommentRequest(_repo, issue.Number, body)));
 }
 public ErrorReportResultUpdated(SearchIssuesResult issue, CreateIssueCommentResponse comment)
     : base(issue.Number, comment.HtmlUrl)
 {
 }