package triageparent import ( "fmt" "reflect" "sort" "github.com/google/go-github/v47/github" "edge-infra.dev/pkg/f8n/devinfra/jack/constants" guestservices "edge-infra.dev/pkg/f8n/devinfra/jack/guest_services" "edge-infra.dev/pkg/f8n/devinfra/jack/plugin" "edge-infra.dev/pkg/lib/logging" ) func init() { plugin.RegisterIssueHandler(constants.PluginParent, handleIssue) plugin.RegisterIssueCommentHandler(constants.PluginParent, handleIssueComment) } func handleIssueComment(hp plugin.HandlerParams, ce github.IssueCommentEvent) { hp.Log.WithName(constants.PluginParent) // if the new events action isn't created leave if ce.GetAction() != "created" { return } if ce.GetIssue().IsPullRequest() { return } labels := ce.Issue.Labels isEpic := guestservices.HasEpicLabel(labels) // if an epic label exists leave since epics cant have parents if isEpic { return } hp.Log.Info("Running triage_parent plugin") body := ce.Issue.GetBody() commentBody := ce.Comment.GetBody() repoID := ce.GetRepo().GetID() sender := guestservices.ParentChild{} sender.New(body, labels, constants.Preamble, constants.Postamble, repoID) parentCommands := guestservices.GetCommands(commentBody) // if theres a parent in the list // and theres no commands to remove parents // attempt to remove the triage label and leave if len(sender.List.Parent) > 0 && len(parentCommands.Parents.Removed) < len(sender.List.Parent) { hp.Log.Info(fmt.Sprintf("parents exist and no parents being removed. \nattempting to remove %s", constants.TriageParentLabel)) _, err := hp.Client.Issues().RemoveLabelForIssue(hp.Ctx, hp.Org, hp.Repo, ce.Issue.GetNumber(), constants.TriageParentLabel) if err != nil { hp.Log.Error(err, fmt.Sprintf("Failed to remove %s", constants.TriageParentLabel)) } return } tmpList := []string{} for _, rent := range sender.List.Parent { tmpList = append(tmpList, fmt.Sprint(rent.Number)) } // sort the list of epics being removed since reflect will fail if they dont sort.Strings(parentCommands.Parents.Removed) // if the parent list matches what is being removed (all parents being removed) // add the triage parent labels if len(parentCommands.Parents.Removed) > 0 && reflect.DeepEqual(tmpList, parentCommands.Parents.Removed) { hp.Log.Info(fmt.Sprintf("all parents are being removed. \nattempting to add %s", constants.TriageParentLabel)) newLabels := []string{constants.TriageParentLabel} _, _, err := hp.Client.Issues().AddLabelsToIssue(hp.Ctx, hp.Org, hp.Repo, ce.Issue.GetNumber(), newLabels) if err != nil { hp.Log.Error(err, fmt.Sprintf("Failed to add %s", constants.TriageParentLabel)) } return } // no parent command and no parents being added add the triage label if len(parentCommands.Parents.Added) == 0 && len(sender.List.Parent) == 0 { hp.Log.Info(fmt.Sprintf("no parents being added \nattempting to add %s", constants.TriageParentLabel)) newLabels := []string{constants.TriageParentLabel} _, _, err := hp.Client.Issues().AddLabelsToIssue(hp.Ctx, hp.Org, hp.Repo, ce.Issue.GetNumber(), newLabels) if err != nil { hp.Log.Error(err, fmt.Sprintf("Failed to add %s", constants.TriageParentLabel)) } return } // if theres a parent command and the triage label exists remove it if len(parentCommands.Parents.Added) > 0 { hp.Log.Info(fmt.Sprintf("parents exist \nattempting to remove %s", constants.TriageParentLabel)) _, err := hp.Client.Issues().RemoveLabelForIssue(hp.Ctx, hp.Org, hp.Repo, ce.Issue.GetNumber(), constants.TriageParentLabel) if err != nil { hp.Log.Error(err, fmt.Sprintf("Failed to remove %s", constants.TriageParentLabel)) } return } } func handleIssue(hp plugin.HandlerParams, ie github.IssuesEvent) { hp.Log.WithName(constants.PluginParent) log := *logging.NewLogger() ctx := hp.Ctx client := hp.Client switch action := ie.GetAction(); action { case "opened": if err := checkForParentInNewIssue(ctx, log, client, ie, hp.Org, hp.Repo); err != nil { log.Error(err, "Parent: Failed to check for parent in new issue") } case "labeled": if err := checkLabelsAndCall(hp, ie, true); err != nil { log.Error(err, "Parent: Failed to remove label from issue") } case "unlabeled": if err := checkLabelsAndCall(hp, ie, false); err != nil { log.Error(err, "Parent: Failed to add label to issue") } } } // checkLabelsAndCall is a middleman function just to check that the label being changed is something we care about func checkLabelsAndCall(hp plugin.HandlerParams, ie github.IssuesEvent, add bool) error { label := ie.GetLabel().GetName() // exit if it's not a label we care about if label != string(constants.Epic) && label != constants.TriageParentLabel { return nil } hp.Log.Info(fmt.Sprintf("its a label we care about: %s", label)) if add { return labelAdded(hp, ie) } return labelRemoved(hp, ie) }