コード例 #1
0
        private async Task ProcessNotifications(IssuesHookData issueEvent)
        {
            string         repo     = issueEvent.Repository.Owner.Login + "/" + issueEvent.Repository.Name;
            int            number   = issueEvent.Issue.Number;
            string         title    = issueEvent.Issue.Title;
            string         uri      = issueEvent.Issue.HtmlUrl;
            string         username = issueEvent.Issue.User.Login;
            DateTimeOffset date     = issueEvent.Issue.UpdatedAt ?? _systemClock.UtcNow;

            using IDisposable scope = _logger.BeginScope("Handling issue {repo}#{issueNumber}", repo, number);
            switch (issueEvent.Action)
            {
            case "opened":
                await _teamMentionForwarder.HandleMentions(repo, null, issueEvent.Issue.Body, title, uri, username,
                                                           date);

                break;

            case "edited":
                await _teamMentionForwarder.HandleMentions(repo, issueEvent.Changes.Body.From,
                                                           issueEvent.Issue.Body, title, uri, username, date);

                break;
            }
        }
コード例 #2
0
        public async Task <IActionResult> IssuesHook(IssuesHookData data)
        {
            string action = data.Action;

            _logger.LogInformation("Processing issues action '{action}' for issue {repo}/{number}", data.Action, data.Repository.Name, data.Issue.Number);

            await ProcessRcaRulesAsync(data, action);

            return(NoContent());
        }
コード例 #3
0
        private bool ShouldOpenRcaIssue(IssuesHookData data, string action, out string triggeringLabel)
        {
            triggeringLabel = null;
            GitHubConnectionOptions options = _githubOptions.Value;

            if (options.RcaRequestedLabels == null || options.RcaRequestedLabels.Length == 0)
            {
                return(false);
            }

            switch (action)
            {
            case "closed":
                HashSet <string> names = data.Issue.Labels.Select(l => l.Name).ToHashSet();
                names.IntersectWith(options.RcaRequestedLabels);
                triggeringLabel = names.FirstOrDefault();
                if (names.Count == 0)
                {
                    _logger.LogTrace("Issue {repo}/{number} is closed by has no RCA label, taking no RCA action", data.Repository.Name, data.Issue.Number);
                    return(false);
                }

                _logger.LogInformation("Issue closed with label '{label}', RCA required", triggeringLabel);
                return(true);

            case "labeled":

                triggeringLabel = data.Label.Name;
                if (data.Issue.State == ItemState.Open)
                {
                    _logger.LogInformation("Issue {repo}/{number} is labeled with {label} but still open, taking no RCA action", data.Repository.Name, data.Issue.Number, triggeringLabel);
                    return(false);
                }

                if (!options.RcaRequestedLabels.Contains(data.Label.Name, StringComparer.OrdinalIgnoreCase))
                {
                    _logger.LogTrace("Label '{label}' irrelevant, taking no RCA action", triggeringLabel);
                    return(false);
                }

                _logger.LogInformation("Previously closed labeled with '{label}', RCA required", triggeringLabel);
                return(true);

            default:
                _logger.LogTrace("Issues hook with '{action}' action, no RCA action taken", action);
                return(false);
            }
        }
コード例 #4
0
        private async Task ProcessRcaRulesAsync(IssuesHookData data, string action)
        {
            if (!ShouldOpenRcaIssue(data, action, out string triggeringLabel))
            {
                return;
            }

            GitHubConnectionOptions options = _githubOptions.Value;

            int    issueNumber = data.Issue.Number;
            string issueTitle  = data.Issue.Title;
            string assignee    = data.Issue.Assignee?.Login;

            string[] copiedLabels = Array.Empty <string>();

            if (options.RcaCopyLabelPrefixes != null && options.RcaCopyLabelPrefixes.Length > 0)
            {
                copiedLabels = data.Issue
                               .Labels
                               .Select(l => l.Name)
                               .Where(n => options.RcaCopyLabelPrefixes.Any(o =>
                                                                            n.StartsWith(o, StringComparison.OrdinalIgnoreCase)))
                               .ToArray();

                _logger.LogInformation($"Copying labels: '{string.Join("', '", copiedLabels)}'");
            }

            if (string.IsNullOrEmpty(assignee))
            {
                _logger.LogInformation("Issue was not assigned, using event sender");
                assignee = data.Sender.Login;
            }

            string issueRepo = data.Repository.Name;
            string issueOrg  = data.Repository.Owner.Login;

            _logger.LogInformation("Opening connection to open issue to {org}/{repo}", options.Organization, options.Repository);
            IGitHubClient client = await _gitHubClientFactory.CreateGitHubClientAsync(options.Organization, options.Repository);

            var issue = new NewIssue($"RCA: {issueTitle} ({issueNumber})")
            {
                Body =
                    $@"An issue, {issueOrg}/{issueRepo}#{issueNumber}, that was marked with the '{triggeringLabel}' label was recently closed.

Please fill out the following root cause analysis, and then close the issue.

Filling it out promptly after resolving an issue ensures things are fresh in your mind.

For help filling out this form, see the [Root Cause Analysis](https://github.com/dotnet/core-eng/wiki/Root-Cause-Analysis).

## Describe the scope of the problem

## Brief description of root cause of the problem

## Diagnostic / Monitoring
### Links to any queries or metrics used for diagnosis

### What additional diagnostics would have reduced the time to fix the issue?

### What additional [telemetry](https://github.com/dotnet/core-eng/blob/master/Documentation/Alerting.md) would have allowed us to catch the issue sooner?

### What additional [testing or validation](https://github.com/dotnet/core-eng/tree/master/Documentation/Validation) would have caught this error before rollout?

",
            };

            if (!string.IsNullOrEmpty(assignee))
            {
                _logger.LogInformation("Setting assignee");
                issue.Assignees.Add(assignee);
            }

            await _ensureLabels.Value;

            if (options.RcaLabel != null)
            {
                _logger.LogTrace("Adding label '{label}'", options.RcaLabel);
                issue.Labels.Add(options.RcaLabel);
            }

            foreach (string toCopy in copiedLabels)
            {
                issue.Labels.Add(toCopy);
            }

            _logger.LogInformation("Sending issue create request...");
            Issue createdIssue = await client.Issue.Create(options.Organization, options.Repository, issue);

            _logger.LogInformation("Created RCA issue {number}", createdIssue.Number);
        }
コード例 #5
0
 private async Task ProcessTimelineIssueTriageAsync(IssuesHookData data, string action)
 {
     await _timelineIssueTriage.ProcessIssueEvent(data);
 }