public void UpdateGitHubIssues(PerformContext context) { var gitHubService = new GitHubService(); var repository = new Community.Models.Repository("umbraco-cms", "umbraco", "Umbraco-CMS", "Umbraco CMS"); RecurringJob.AddOrUpdate(() => gitHubService.UpdateIssues(context, repository), Cron.MinuteInterval(5)); }
public void UpdateIssues(PerformContext context, Community.Models.Repository repository) { // Accept newer versions of the TLS protocol ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; try { var options = new GitHubGetRepositoryIssuesOptions { Owner = repository.Owner, Repository = repository.Alias, Sort = GitHubIssueSortField.Updated, Direction = GitHubSortDirection.Descending, State = GitHubIssueState.All, PerPage = 100, Page = 1 }; while (true) { var localCount = 0; // Make the initial request to the API context.WriteLine($"Fetching page issues for repo {repository.Alias} (page {options.Page})"); GitHubGetIssuesResponse issuesResponse; try { issuesResponse = GitHubApi.Issues.GetIssues(options); } catch (GitHubHttpException ex) { throw new Exception($"Failed fetching page {options.Page}\r\n\r\n{ex.Response.Response.ResponseUri}", ex); } catch (Exception ex) { throw new Exception($"Failed fetching page {options.Page}", ex); } foreach (var response in issuesResponse.Body) { // Local flag used later to determine whether new data was fetched for this issue var updated = false; var gitHubResponse = JsonConvert.DeserializeObject <GitHubResponse>(response.JObject.ToString()); var responseIsIssue = gitHubResponse.pull_request == null; string issuesFile; string issuesCommentFile; string issuesEventsFile; string issuesCombinedFile; if (responseIsIssue) { issuesFile = HostingEnvironment.MapPath($"{repository.IssuesStorageDirectory()}/{response.Number}.issue.json"); issuesCommentFile = HostingEnvironment.MapPath($"{repository.IssuesStorageDirectory()}/{response.Number}.issue.comments.json"); issuesEventsFile = HostingEnvironment.MapPath($"{repository.IssuesStorageDirectory()}/{response.Number}.issue.events.json"); issuesCombinedFile = HostingEnvironment.MapPath($"{repository.IssuesStorageDirectory()}/{response.Number}.issue.combined.json"); } else { issuesFile = HostingEnvironment.MapPath($"{repository.IssuesStorageDirectory()}/pulls/{response.Number}.pull.json"); issuesCommentFile = HostingEnvironment.MapPath($"{repository.IssuesStorageDirectory()}/pulls/{response.Number}.pull.comments.json"); issuesEventsFile = HostingEnvironment.MapPath($"{repository.IssuesStorageDirectory()}/pulls/{response.Number}.pull.events.json"); issuesCombinedFile = HostingEnvironment.MapPath($"{repository.IssuesStorageDirectory()}/pulls/{response.Number}.pull.combined.json"); } // Make sure we have a directory Directory.CreateDirectory(Path.GetDirectoryName(issuesFile)); JsonUtils.SaveJsonObject(issuesFile, response); // Fetch comments and events if the local JSON file is older than the last update time of the issue JArray comments; JArray events; if (File.Exists(issuesCommentFile) && File.GetLastWriteTimeUtc(issuesCommentFile) > response.UpdatedAt.DateTime.ToUniversalTime()) { comments = JsonUtils.LoadJsonArray(issuesCommentFile); } else { context.WriteLine($"Fetching comments for issue {response.Number} {response.Title}"); var issueCommentsResponse = GitHubApi.Client.DoHttpGetRequest($"/repos/{repository.Owner}/{repository.Alias}/issues/{response.Number}/comments"); if (issueCommentsResponse.StatusCode != HttpStatusCode.OK) { throw new Exception($"Failed fetching comments for issue #{response.Number} ({issueCommentsResponse.StatusCode})"); } comments = JsonUtils.ParseJsonArray(issueCommentsResponse.Body); JsonUtils.SaveJsonArray(issuesCommentFile, comments); updated = true; } if (File.Exists(issuesEventsFile) && File.GetLastWriteTimeUtc(issuesEventsFile) > response.UpdatedAt.DateTime.ToUniversalTime()) { events = JsonUtils.LoadJsonArray(issuesEventsFile); } else { context.WriteLine($"Fetching events for issue {response.Number} {response.Title}"); var issueEventssResponse = GitHubApi.Client.DoHttpGetRequest($"/repos/{repository.Owner}/{repository.Alias}/issues/{response.Number}/events"); if (issueEventssResponse.StatusCode != HttpStatusCode.OK) { throw new Exception($"Failed fetching events for issue #{response.Number} ({issueEventssResponse.StatusCode})"); } events = JsonUtils.ParseJsonArray(issueEventssResponse.Body); JsonUtils.SaveJsonArray(issuesEventsFile, events); } // Save a JSON file with all the combined data we have for the issue response.JObject.Add("_comments", comments); response.JObject.Add("events", events); JsonUtils.SaveJsonObject(issuesCombinedFile, response); if (updated) { localCount++; } } context.WriteLine($"Updated {localCount} issues on page {options.Page}"); // Break the loop if not all issues on the page were updated if (localCount < options.PerPage) { break; } // Increment the page count options.Page++; } } catch (Exception ex) { context.WriteLine("Error while fetching issues", ex); context.WriteLine("Error:" + ex.Message + " - Stack trace: " + ex.StackTrace); } }