/// <summary> /// Populates the milestone tableo to be equivalent to the current set of milestones on GitHub. /// </summary> public async Task PopulateMilestones(RoachRepoId repoId, CancellationToken cancellationtoken = default(CancellationToken)) { var milestones = await _storageQueryUtil.GetMilestones(repoId, RoachItemFilter.All, cancellationtoken); var map = milestones.ToDictionary(x => x.Number); var list = new List <RoachMilestoneEntity>(); foreach (var milestone in await _githubQueryUtil.GetMilestones(repoId)) { var isOpen = milestone.State == ItemState.Open; RoachMilestone r; if (!map.TryGetValue(milestone.Number, out r) || r.Title != milestone.Title || r.IsOpen != isOpen) { r = new RoachMilestone(repoId, milestone.Number, milestone.Title, isOpen); list.Add(new RoachMilestoneEntity(r)); } } if (list.Count > 0) { // TODO: Need to thread through the CancellationToken here. await AzureUtil.InsertBatchUnordered(_milestoneTable, list); } }
public async Task <List <Issue> > GetIssues(RoachRepoId repo, RepositoryIssueRequest request, int pageSize = DefaultPageSize) { var list = new List <Issue>(); var options = new ApiOptions() { PageCount = 1, StartPage = 1, PageSize = pageSize }; var done = false; var issues = _client.Issue; do { var pageIssues = request != null ? await issues.GetAllForRepository(repo.Owner, repo.Name, request, options) : await issues.GetAllForRepository(repo.Owner, repo.Name, options); list.AddRange(pageIssues); if (pageIssues.Count < pageSize) { done = true; } else { options.StartPage++; } } while (!done); return(list); }
/// <summary> /// Get all issues in the specified label which don't have an assignee and / or a milestone. /// </summary> public async Task <List <RoachIssue> > GetTriageIssues(RoachRepoId repoId, string label, CancellationToken cancellationToken) { var unassignedFilter = TableQuery.CombineFilters( TableQuery.GenerateFilterCondition(nameof(TableEntity.PartitionKey), QueryComparisons.Equal, EntityKeyUtil.ToKey(repoId)), TableOperators.And, TableQuery.GenerateFilterCondition(nameof(RoachIssueEntity.Assignee), QueryComparisons.Equal, TheBugsConstants.UnassignedName)); var unassignedList = await AzureUtil.QueryAsync(_issueTable, new TableQuery <RoachIssueEntity>().Where(unassignedFilter), cancellationToken); var unknownMilestoneFilter = TableQuery.CombineFilters( TableQuery.GenerateFilterCondition(nameof(TableEntity.PartitionKey), QueryComparisons.Equal, EntityKeyUtil.ToKey(repoId)), TableOperators.And, TableQuery.GenerateFilterConditionForInt(nameof(RoachIssueEntity.MilestoneNumber), QueryComparisons.Equal, RoachMilestoneId.NoneNumber)); var unknownMilestoneList = await AzureUtil.QueryAsync(_issueTable, new TableQuery <RoachIssueEntity>().Where(unknownMilestoneFilter), cancellationToken); var list = new List <RoachIssue>(); var hashSet = new HashSet <int>(); foreach (var entity in unassignedList.Concat(unknownMilestoneList)) { if (hashSet.Add(entity.Number) && entity.Labels.Contains(label) && entity.IssueType == IssueType.Issue) { list.Add(entity.Issue); } } return(list); }
public async Task <List <RoachMilestone> > GetMilestones(RoachRepoId repoId, RoachItemFilter filter = RoachItemFilter.All, CancellationToken cancellationToken = default(CancellationToken)) { var util = FilterUtil.PartitionKey(RoachMilestoneEntity.GetPartitionKey(repoId)); switch (filter) { case RoachItemFilter.All: // Nothing to do: break; case RoachItemFilter.Closed: util = util.And(FilterUtil.Column(nameof(RoachMilestoneEntity.IsOpen), false)); break; case RoachItemFilter.Open: util = util.And(FilterUtil.Column(nameof(RoachMilestoneEntity.IsOpen), true)); break; default: throw new Exception($"Bad enum value {filter}"); } var list = await AzureUtil.QueryAsync <RoachMilestoneEntity>( _milestoneTable, util, cancellationToken); return(list.Select(x => x.Milestone).OrderBy(x => x.Title).ToList()); }
private async Task <List <RoachIssueEntity> > GetIssuesInMilestone(RoachRepoId repoId, int milestone, CancellationToken cancellationToken) { var filter = FilterUtil .PartitionKey(RoachIssueEntity.GetPartitionKey(repoId)) .And(FilterUtil.Column(nameof(RoachIssueEntity.MilestoneNumber), milestone)); return(await AzureUtil.QueryAsync <RoachIssueEntity>(_issueTable, filter, cancellationToken)); }
private RepoInitUtil(RoachRepoId id, GitHubClient githubClient, CloudTableClient client) { _repoId = id; _client = githubClient; _issueTable = client.GetTableReference(TableNames.RoachIssueTable); _milestoneTable = client.GetTableReference(TableNames.RoachMilestoneTable); _statusTable = client.GetTableReference(TableNames.RoachStatusTable); }
public async Task <IReadOnlyList <Milestone> > GetMilestones(RoachRepoId repoId) { var request = new MilestoneRequest() { State = ItemStateFilter.All }; return(await _client.Issue.Milestone.GetAllForRepository(repoId.Owner, repoId.Name, request)); }
public async Task <IReadOnlyList <Issue> > GetIssuesChangedSince(RoachRepoId repoId, DateTimeOffset since) { var request = new RepositoryIssueRequest() { Since = since, State = ItemStateFilter.All, }; return(await _client.Issue.GetAllForRepository(repoId.Owner, repoId.Name, request)); }
public async Task <List <RoachIssue> > GetIssues(RoachRepoId repoId, string assignee, List <int> milestones, CancellationToken cancellationToken) { IEnumerable <RoachIssueEntity> list = await GetIssuesInMilestones(repoId, milestones, cancellationToken); if (assignee != null) { list = list.Where(x => x.Assignee == assignee); } return(list.Select(x => x.Issue).ToList()); }
/// <summary> /// Populates the issues tables to reflect changes that occured since the see cref="since"/> parameter. /// </summary> public async Task PopulateIssuesSince(RoachRepoId repoId, DateTimeOffset since, CancellationToken cancellationtoken = default(CancellationToken)) { var changedIssues = await _githubQueryUtil.GetIssuesChangedSince(repoId, since); var issueList = new List <RoachIssueEntity>(capacity: changedIssues.Count); foreach (var changedIssue in changedIssues) { var issue = new RoachIssue(repoId, changedIssue); issueList.Add(new RoachIssueEntity(issue)); } // TODO: Need to thread through the CancellationToken here. await AzureUtil.InsertBatchUnordered(_issueTable, issueList); }
private async Task <List <RoachIssueEntity> > GetIssuesInMilestones(RoachRepoId repoId, List <int> milestones, CancellationToken cancellationToken) { if (milestones == null || milestones.Count == 0) { // Return all of the issues return(await AzureUtil.QueryAsync <RoachIssueEntity>(_issueTable, FilterUtil.PartitionKey(RoachIssueEntity.GetPartitionKey(repoId)), cancellationToken)); } var list = new List <RoachIssueEntity>(); foreach (var milestone in milestones) { list.AddRange(await GetIssuesInMilestone(repoId, milestone, cancellationToken)); } return(list); }
public static async Task GitHubIssueChanged( [QueueTrigger(QueueNames.IssueChanged)] string rawMessage, [Table(TableNames.RoachIssueTable)] CloudTable table, CancellationToken cancellationToken) { var issueMessage = JsonConvert.DeserializeObject <IssueMessage>(rawMessage); var repoId = RoachRepoId.ParseFullName(issueMessage.RepoFullName); var issueId = new RoachIssueId(repoId, issueMessage.Number); var milestoneId = new RoachMilestoneId(repoId, issueMessage.MilestoneNumber); var isOpen = issueMessage.State == "open"; var updatedAt = issueMessage.UpdatedAt != null ? DateTimeOffset.Parse(issueMessage.UpdatedAt) : (DateTimeOffset?)null; var roachIssue = new RoachIssue(issueId, issueMessage.Assignee ?? TheBugsConstants.UnassignedName, milestoneId, issueMessage.Title, isOpen, issueMessage.Labels, updatedAt); var issueEntity = new RoachIssueEntity(roachIssue); var operation = TableOperation.InsertOrReplace(issueEntity); await table.ExecuteAsync(TableOperation.InsertOrReplace(issueEntity), cancellationToken); }
public static EntityKey GetEntityKey(RoachRepoId id) => new EntityKey(id.Owner, id.Name);
public async Task <IEnumerable <Milestone> > GetMilestones(RoachRepoId repoId, IEnumerable <string> milestoneTitles) { var all = await GetMilestones(repoId); return(all.Where(x => milestoneTitles.Contains(x.Title))); }
private static async Task InitRepo(GitHubClient client, CloudStorageAccount account, RoachRepoId id) { await RepoInitUtil.Initialize(id, client, account, Console.Out); }
internal IssueStatus(RoachRepoId repoId, int number, DateTimeOffset?updatedAt) { RepoId = repoId; Number = number; UpdatedAt = updatedAt; }
public async Task <IEnumerable <Milestone> > GetMilestones(RoachRepoId repoId, IEnumerable <int> milestoneNumbers) { var all = await GetMilestones(repoId); return(all.Where(x => milestoneNumbers.Contains(x.Number))); }
public RoachStatusEntity(RoachRepoId repoId, DateTimeOffset lastBulkUpdate) { this.SetEntityKey(GetEntityKey(repoId)); SetLastBulkUpdate(lastBulkUpdate); }
public static async Task Initialize(RoachRepoId id, GitHubClient githubClient, CloudStorageAccount account, TextWriter logger) { var util = new RepoInitUtil(id, githubClient, account.CreateCloudTableClient()); await util.Go(logger); }
public static string GetPartitionKey(RoachRepoId repoId) => EntityKeyUtil.ToKey(repoId);
public static string ToKey(RoachRepoId id) { return($"{id.Owner}-{id.Name}"); }