package size import ( "context" "fmt" "strings" "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 addSizeToNewIssue(ctx context.Context, log logging.EdgeLogger, client plugin.GithubClientInterface, event github.IssuesEvent) error { // check if its an epic if so bounce // may need to check the body for an epic command since jack may not have created the struct yet hasParentLabel, _ := guestservices.CheckForParentLabel("", event.GetIssue().Labels) if hasParentLabel { log.Info("cant add size to epic exiting addSizeToNewIssue") return nil } hasSizeLabel := false labels := event.GetIssue().Labels for _, label := range labels { _, isSize := validateSizeCommand(label.GetName()) if isSize { hasSizeLabel = true } } // check if a size label already exists if so bounce if hasSizeLabel { log.Info("a size label already exists exiting") return nil } // check for a size command in the issue body // if none add the triage label commands := guestservices.GetSpecificCommandFromBody(event.Issue.GetBody(), "size", false, false) if len(commands) <= 0 { commands = append(commands, constants.TriageSizeLabel) } // grab the first command if the first word is extra // assume it needs to be appended to the second word (extra large) tempCommand := commands[0] if len(commands) > 1 && commands[0] == "extra" { tempCommand = fmt.Sprintf("%s-%s", commands[0], commands[1]) } // Validate the size and if its not a valid size bounce size, validSize := validateSizeCommand(tempCommand) if !validSize { log.Info("command is not a valid size") size = constants.TriageSizeLabel } // if there is a size command validate it // if the command is not valid add the triage label issueNumber := event.GetIssue().GetNumber() repo := event.GetRepo() repoName := repo.GetName() repoOwner := repo.GetOwner().GetLogin() // if the command is valid add the appropriate label to the issue labelBody := []string{} // takes in the first size that the user wants to add in even if they want to add in multiple // updates the labels labelBody = append(labelBody, size) _, _, err := client.Issues().AddLabelsToIssue(ctx, repoOwner, repoName, issueNumber, labelBody) if err != nil { log.Error(err, "Failed to update issue desc") return err } return nil } func addLabel(ctx context.Context, log logging.EdgeLogger, client plugin.GithubClientInterface, event github.IssuesEvent) error { epicLabelAdded := false issueNumber := event.GetIssue().GetNumber() repo := event.GetRepo() repoName := repo.GetName() repoOwner := repo.GetOwner().GetLogin() labelName := event.Label.GetName() isParentLabel := guestservices.IsParentLabel(labelName) hasParent, _ := guestservices.CheckForParentLabel(labelName, event.GetIssue().Labels) // if its a parent label and a parent already exists just bounce if isParentLabel && hasParent { return nil } else if isParentLabel && !hasParent { // if its a parent label and no parent label exists clear the size labelBody := createNewLabelBodyNoSize(event.GetIssue().Labels) return updateIssueLabels(ctx, client, labelBody, repoOwner, repoName, issueNumber) } // check if the new label is a size / triage size label if not bounce labelName, valid := validateSizeCommand(event.Label.GetName()) if !valid { log.Info("not a valid size label exiting removelabel") return nil } // if its a size label and there's an existing parent label remove the new label if valid && hasParent { labelBody := createNewLabelBodyNoSize(event.GetIssue().Labels) return updateIssueLabels(ctx, client, labelBody, repoOwner, repoName, issueNumber) } log.Info(fmt.Sprintf("%s is a valid size command", labelName)) // check if the issue is an epic // if it is remove the new size label and comment that you cannot add sizes to an epic hasParentLabel, _ := guestservices.CheckForParentLabel("", event.GetIssue().Labels) // remove old size / triage size labels labelNames := []string{} for _, label := range event.GetIssue().Labels { name := label.GetName() if !strings.Contains(name, "size/") && name != constants.TriageSizeLabel { //name == labelName || log.Info(fmt.Sprintf("adding %s", name)) labelNames = append(labelNames, name) } } // if its not an epic add the new label back to the list if !hasParentLabel && !epicLabelAdded { labelNames = append(labelNames, labelName) } // update labels with old sizes removed githubIssueBody := &github.IssueRequest{Labels: &labelNames} _, _, err := client.Issues().Edit(ctx, repoOwner, repoName, issueNumber, githubIssueBody) if err != nil { log.Error(err, "Failed to update issue desc") return err } return nil } func removeLabel(ctx context.Context, log logging.EdgeLogger, client plugin.GithubClientInterface, event github.IssuesEvent) error { // check that the label was a size label log.Info(event.Label.GetName()) labelName := event.Label.GetName() issueNumber := event.GetIssue().GetNumber() repo := event.GetRepo() repoName := repo.GetName() repoOwner := repo.GetOwner().GetLogin() hasParent, _ := guestservices.CheckForParentLabel(labelName, event.GetIssue().Labels) // if a parent label still exists bounce if hasParent { return nil } // check if the label being removed is the epic label if guestservices.IsParentLabel(labelName) { labelBody := createNewLabelBodyWithSize(event.GetIssue().Labels) return updateIssueLabels(ctx, client, labelBody, repoOwner, repoName, issueNumber) } // bounce if the label isnt a valid size and isnt the kind/epic label _, valid := validateSizeCommand(event.Label.GetName()) if !valid { log.Info("not a valid size label exiting removelabel") return nil } log.Info("Removed size label") labelBody := createNewLabelBodyWithSize(event.GetIssue().Labels) err := updateIssueLabels(ctx, client, labelBody, repoOwner, repoName, issueNumber) if err != nil { log.Error(err, "Failed to update issue desc") return err } return nil } // update an issues labels (sets all labels) func updateIssueLabels(ctx context.Context, client plugin.GithubClientInterface, labels []string, repoOwner, repoName string, issueNumber int) error { githubIssueBody := &github.IssueRequest{Labels: &labels} _, _, err := client.Issues().Edit(ctx, repoOwner, repoName, issueNumber, githubIssueBody) if err != nil { return err } return nil } func createNewLabelBodyNoSize(labels []*github.Label) []string { label := []string{} // Add all existing labels to new label slice and toggle sizeLabel for _, v := range labels { name := v.GetName() if !strings.Contains(name, "size/") && name != constants.TriageSizeLabel { label = append(label, name) } } return label } func createNewLabelBodyWithSize(labels []*github.Label) []string { label := []string{} sizeLabelString := constants.TriageSizeLabel isEpic := false // Add all existing labels to new label slice and toggle sizeLabel hasSizeLabel := false for _, v := range labels { name := v.GetName() label = append(label, name) if strings.Contains(name, "size/") { hasSizeLabel = true } if strings.Contains(name, "epic") { isEpic = true } } // Add size label if non detected if !hasSizeLabel && !isEpic { label = append(label, sizeLabelString) } return label }