public static async Task InitialIssueTriage()

in tools/github-event-processor/Azure.Sdk.Tools.GitHubEventProcessor/EventProcessing/IssueProcessing.cs [97:280]


        public static async Task InitialIssueTriage(GitHubEventClient gitHubEventClient, IssueEventGitHubPayload issueEventPayload)
        {
            if (gitHubEventClient.RulesConfiguration.RuleEnabled(RulesConstants.InitialIssueTriage))
            {
                if (issueEventPayload.Action == ActionConstants.Opened)
                {
                    // If the user is not a member of the Azure Org AND the user does not have write or admin collaborator permission.
                    // This piece is executed for every issue created that doesn't have labels or owners on it at the time of creation.
                    bool isCustomerReported = false;
                    bool isMemberOfOrg = await gitHubEventClient.IsUserMemberOfOrg(OrgConstants.Azure, issueEventPayload.Issue.User.Login);
                    if (!isMemberOfOrg)
                    {
                        bool hasAdminOrWritePermission = await gitHubEventClient.DoesUserHaveAdminOrWritePermission(issueEventPayload.Repository.Id, issueEventPayload.Issue.User.Login);
                        if (!hasAdminOrWritePermission)
                        {
                            gitHubEventClient.AddLabel(TriageLabelConstants.CustomerReported);
                            gitHubEventClient.AddLabel(TriageLabelConstants.Question);
                            isCustomerReported = true;
                        }
                    }

                    // If there are no labels and no assignees
                    if ((issueEventPayload.Issue.Labels.Count == 0) && (issueEventPayload.Issue.Assignee == null))
                    {
                        // Query AI Triage and disable Answers if this is not a customer reported issue.
                        IssueTriageResponse triageOutput = await gitHubEventClient.QueryAIIssueTriageService(
                            issueEventPayload, 
                            true, 
                            !isCustomerReported);

                        if (triageOutput.Labels.Any())
                        {
                            // If labels were predicted, add them to the issue
                            foreach (string label in triageOutput.Labels)
                            {
                                gitHubEventClient.AddLabel(label);
                            }

                            // needs-team-attention needs to be added if it can be determined who this issue actually
                            // belongs to.
                            bool addNeedsTeamAttention = true;

                            CodeownersEntry codeownersEntry = CodeOwnerUtils.GetCodeownersEntryForLabelList(triageOutput.Labels);
                            bool hasValidAssignee = false;
                            if (codeownersEntry.AzureSdkOwners.Count > 0)
                            {
                                // If there's only a single owner, 
                                if (codeownersEntry.AzureSdkOwners.Count == 1)
                                {
                                    if (await gitHubEventClient.OwnerCanBeAssignedToIssuesInRepo(
                                                                    issueEventPayload.Repository.Owner.Login,
                                                                    issueEventPayload.Repository.Name,
                                                                    codeownersEntry.AzureSdkOwners[0]))
                                    {
                                        hasValidAssignee = true;
                                        gitHubEventClient.AssignOwnerToIssue(
                                                            issueEventPayload.Repository.Owner.Login,
                                                            issueEventPayload.Repository.Name,
                                                            codeownersEntry.AzureSdkOwners[0]);
                                    }
                                    // Output something into the logs pointing out that AzureSdkOwners has a user that cannot
                                    // be assigned to an issue
                                    else
                                    {
                                        Console.WriteLine($"{codeownersEntry.AzureSdkOwners[0]} is the only owner in the AzureSdkOwners for service label(s), {string.Join(",", triageOutput.Labels)}, but cannot be assigned as an issue owner in this repository.");
                                    }
                                }
                                // else there are multiple owners and a random one needs to be assigned
                                else
                                {
                                    // Create a list of AzureSdkOwners that has been randomized. The reason
                                    // the entire list is being randomed is because each person has to be
                                    // checked to see if they can be assigned to an issue in the repository.
                                    // and having the entire list being random simplifies processing if a given
                                    // owner cannot be assigned.
                                    var rnd = new Random();
                                    var randomAzureSdkOwners = codeownersEntry.AzureSdkOwners.OrderBy(item => rnd.Next(0, codeownersEntry.AzureSdkOwners.Count));
                                    foreach (string azureSdkOwner in randomAzureSdkOwners)
                                    {
                                        if (await gitHubEventClient.OwnerCanBeAssignedToIssuesInRepo(
                                                                        issueEventPayload.Repository.Owner.Login,
                                                                        issueEventPayload.Repository.Name,
                                                                        azureSdkOwner))
                                        {
                                            hasValidAssignee = true;
                                            gitHubEventClient.AssignOwnerToIssue(issueEventPayload.Repository.Owner.Login,
                                                                                 issueEventPayload.Repository.Name,
                                                                                 azureSdkOwner);
                                            // As soon as there's a valid assignee, add the comment mentioning everyone
                                            // in the AzureSdkOwners and exit. The @ mention is only necessary if there
                                            // are multiple AzureSdkOwners.
                                            string azureSdkOwnersAtMention = CodeOwnerUtils.CreateAtMentionForOwnerList(codeownersEntry.AzureSdkOwners);
                                            gitHubEventClient.CreateComment(issueEventPayload.Repository.Id,
                                                                            issueEventPayload.Issue.Number,
                                                                            azureSdkOwnersAtMention);
                                            break;
                                        }
                                        else
                                        {
                                            Console.WriteLine($"{azureSdkOwner} is an AzureSdkOwner for service labels {string.Join(",", triageOutput.Labels)} but cannot be assigned as an issue owner in this repository.");
                                        }
                                    }
                                }
                                // If the issue had a valid assignee and only labels provided add the comment
                                // Also safegaurding against empty answer, this comment should be made given an invalid Answer.
                                if (hasValidAssignee && (string.IsNullOrEmpty(triageOutput.AnswerType) || string.IsNullOrEmpty(triageOutput.Answer)))
                                {
                                    string issueComment = "Thank you for your feedback. Tagging and routing to the team member best able to assist.";
                                    gitHubEventClient.CreateComment(issueEventPayload.Repository.Id,
                                                                    issueEventPayload.Issue.Number,
                                                                    issueComment);
                                }
                                else
                                {
                                    // Output a message indicating every owner in the AzureSdkOwners, for the AI label suggestions. The lines immediately
                                    // above this output will contain the messages for each user checked.
                                    Console.WriteLine($"AzureSdkOwners for service labels {string.Join(",", triageOutput.Labels)} has no owners that can be assigned to issues in this repository.");
                                }
                            }

                            // If there's no valid AzureSdkOwner to assign the issue to (this means that there's either
                            // no AzureSdkOwners or none of them have permissions to be assigned to an issue)
                            if (!hasValidAssignee)
                            {
                                // Check to see if there are ServiceOwners and the ServiceAttention rule is turned on. If
                                // both are true then add the ServiceAttention label and run ServiceAttention processing
                                if (codeownersEntry.ServiceOwners.Count > 0
                                    && gitHubEventClient.RulesConfiguration.RuleEnabled(RulesConstants.ServiceAttention,
                                                                                        false /* don't output log messages for this check*/))

                                {
                                    gitHubEventClient.AddLabel(TriageLabelConstants.ServiceAttention);
                                    Common_ProcessServiceAttentionForLabels(gitHubEventClient,
                                                                            issueEventPayload.Issue,
                                                                            issueEventPayload.Repository.Id,
                                                                            triageOutput.Labels);
                                }
                                // At this point, it cannot be determined who this issue belongs to. Add
                                // the needs-team-triage label instead of the needs-team-attention label
                                else
                                {
                                    gitHubEventClient.AddLabel(TriageLabelConstants.NeedsTeamTriage);
                                    addNeedsTeamAttention = false;
                                }
                            }

                            // The needs-team-attention label is only added when it can be determined
                            // who this issue belongs to and it is not customer reported. 
                            if (addNeedsTeamAttention && !isCustomerReported)
                            {
                                gitHubEventClient.AddLabel(TriageLabelConstants.NeedsTeamAttention);
                            }
                            
                            // Making sure the Answer is valid
                            if(!string.IsNullOrEmpty(triageOutput.Answer))
                            {
                                // If answer is a suggestions/solution add the comment.
                                if(triageOutput.AnswerType == "suggestion")
                                {
                                    gitHubEventClient.CreateComment(issueEventPayload.Repository.Id,
                                                                    issueEventPayload.Issue.Number,
                                                                    triageOutput.Answer);
                                }
                            
                                // If answer is a solution add the issue-addressed label
                                // to close out the issue.
                                if(triageOutput.AnswerType == "solution")
                                {
                                    gitHubEventClient.CreateComment(issueEventPayload.Repository.Id,
                                                                    issueEventPayload.Issue.Number,
                                                                    triageOutput.Answer);
                                    gitHubEventClient.AddLabel(TriageLabelConstants.IssueAddressed);
                                }
                            }
                        }
                        // If there are no labels predicted add NeedsTriage to the issue
                        else
                        {
                            gitHubEventClient.AddLabel(TriageLabelConstants.NeedsTriage);
                        }
                    }
                }
            }
        }