...

Source file src/edge-infra.dev/pkg/f8n/devinfra/jack/plugin/size/issues.go

Documentation: edge-infra.dev/pkg/f8n/devinfra/jack/plugin/size

     1  package size
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/google/go-github/v47/github"
     9  
    10  	"edge-infra.dev/pkg/f8n/devinfra/jack/constants"
    11  	guestservices "edge-infra.dev/pkg/f8n/devinfra/jack/guest_services"
    12  	"edge-infra.dev/pkg/f8n/devinfra/jack/plugin"
    13  	"edge-infra.dev/pkg/lib/logging"
    14  )
    15  
    16  func addSizeToNewIssue(ctx context.Context, log logging.EdgeLogger, client plugin.GithubClientInterface, event github.IssuesEvent) error {
    17  	// check if its an epic if so bounce
    18  	// may need to check the body for an epic command since jack may not have created the struct yet
    19  	hasParentLabel, _ := guestservices.CheckForParentLabel("", event.GetIssue().Labels)
    20  	if hasParentLabel {
    21  		log.Info("cant add size to epic exiting addSizeToNewIssue")
    22  		return nil
    23  	}
    24  
    25  	hasSizeLabel := false
    26  	labels := event.GetIssue().Labels
    27  	for _, label := range labels {
    28  		_, isSize := validateSizeCommand(label.GetName())
    29  		if isSize {
    30  			hasSizeLabel = true
    31  		}
    32  	}
    33  
    34  	// check if a size label already exists if so bounce
    35  	if hasSizeLabel {
    36  		log.Info("a size label already exists exiting")
    37  		return nil
    38  	}
    39  
    40  	// check for a size command in the issue body
    41  	// if none add the triage label
    42  	commands := guestservices.GetSpecificCommandFromBody(event.Issue.GetBody(), "size", false, false)
    43  	if len(commands) <= 0 {
    44  		commands = append(commands, constants.TriageSizeLabel)
    45  	}
    46  
    47  	// grab the first command if the first word is extra
    48  	// assume it needs to be appended to the second word (extra large)
    49  	tempCommand := commands[0]
    50  	if len(commands) > 1 && commands[0] == "extra" {
    51  		tempCommand = fmt.Sprintf("%s-%s", commands[0], commands[1])
    52  	}
    53  
    54  	// Validate the size and if its not a valid size bounce
    55  	size, validSize := validateSizeCommand(tempCommand)
    56  	if !validSize {
    57  		log.Info("command is not a valid size")
    58  		size = constants.TriageSizeLabel
    59  	}
    60  
    61  	// if there is a size command validate it
    62  	// if the command is not valid add the triage label
    63  
    64  	issueNumber := event.GetIssue().GetNumber()
    65  	repo := event.GetRepo()
    66  	repoName := repo.GetName()
    67  	repoOwner := repo.GetOwner().GetLogin()
    68  
    69  	// if the command is valid add the appropriate label to the issue
    70  	labelBody := []string{}
    71  	// takes in the first size that the user wants to add in even if they want to add in multiple
    72  	// updates the labels
    73  	labelBody = append(labelBody, size)
    74  	_, _, err := client.Issues().AddLabelsToIssue(ctx, repoOwner, repoName, issueNumber, labelBody)
    75  	if err != nil {
    76  		log.Error(err, "Failed to update issue desc")
    77  		return err
    78  	}
    79  
    80  	return nil
    81  }
    82  
    83  func addLabel(ctx context.Context, log logging.EdgeLogger, client plugin.GithubClientInterface, event github.IssuesEvent) error {
    84  	epicLabelAdded := false
    85  	issueNumber := event.GetIssue().GetNumber()
    86  	repo := event.GetRepo()
    87  	repoName := repo.GetName()
    88  	repoOwner := repo.GetOwner().GetLogin()
    89  
    90  	labelName := event.Label.GetName()
    91  	isParentLabel := guestservices.IsParentLabel(labelName)
    92  	hasParent, _ := guestservices.CheckForParentLabel(labelName, event.GetIssue().Labels)
    93  
    94  	// if its a parent label and a parent already exists just bounce
    95  	if isParentLabel && hasParent {
    96  		return nil
    97  	} else if isParentLabel && !hasParent { // if its a parent label and no parent label exists clear the size
    98  		labelBody := createNewLabelBodyNoSize(event.GetIssue().Labels)
    99  		return updateIssueLabels(ctx, client, labelBody, repoOwner, repoName, issueNumber)
   100  	}
   101  
   102  	// check if the new label is a size / triage size label if not bounce
   103  	labelName, valid := validateSizeCommand(event.Label.GetName())
   104  	if !valid {
   105  		log.Info("not a valid size label exiting removelabel")
   106  		return nil
   107  	}
   108  
   109  	// if its a size label and there's an existing parent label remove the new label
   110  	if valid && hasParent {
   111  		labelBody := createNewLabelBodyNoSize(event.GetIssue().Labels)
   112  		return updateIssueLabels(ctx, client, labelBody, repoOwner, repoName, issueNumber)
   113  	}
   114  
   115  	log.Info(fmt.Sprintf("%s is a valid size command", labelName))
   116  
   117  	// check if the issue is an epic
   118  	// if it is remove the new size label and comment that you cannot add sizes to an epic
   119  	hasParentLabel, _ := guestservices.CheckForParentLabel("", event.GetIssue().Labels)
   120  	// remove old size / triage size labels
   121  	labelNames := []string{}
   122  	for _, label := range event.GetIssue().Labels {
   123  		name := label.GetName()
   124  		if !strings.Contains(name, "size/") && name != constants.TriageSizeLabel { //name == labelName ||
   125  			log.Info(fmt.Sprintf("adding %s", name))
   126  			labelNames = append(labelNames, name)
   127  		}
   128  	}
   129  
   130  	// if its not an epic add the new label back to the list
   131  	if !hasParentLabel && !epicLabelAdded {
   132  		labelNames = append(labelNames, labelName)
   133  	}
   134  
   135  	// update labels with old sizes removed
   136  	githubIssueBody := &github.IssueRequest{Labels: &labelNames}
   137  	_, _, err := client.Issues().Edit(ctx, repoOwner, repoName, issueNumber, githubIssueBody)
   138  	if err != nil {
   139  		log.Error(err, "Failed to update issue desc")
   140  		return err
   141  	}
   142  
   143  	return nil
   144  }
   145  
   146  func removeLabel(ctx context.Context, log logging.EdgeLogger, client plugin.GithubClientInterface, event github.IssuesEvent) error {
   147  	// check that the label was a size label
   148  	log.Info(event.Label.GetName())
   149  	labelName := event.Label.GetName()
   150  
   151  	issueNumber := event.GetIssue().GetNumber()
   152  	repo := event.GetRepo()
   153  	repoName := repo.GetName()
   154  	repoOwner := repo.GetOwner().GetLogin()
   155  
   156  	hasParent, _ := guestservices.CheckForParentLabel(labelName, event.GetIssue().Labels)
   157  	// if a parent label still exists bounce
   158  	if hasParent {
   159  		return nil
   160  	}
   161  
   162  	// check if the label being removed is the epic label
   163  	if guestservices.IsParentLabel(labelName) {
   164  		labelBody := createNewLabelBodyWithSize(event.GetIssue().Labels)
   165  		return updateIssueLabels(ctx, client, labelBody, repoOwner, repoName, issueNumber)
   166  	}
   167  
   168  	// bounce if the label isnt a valid size and isnt the kind/epic label
   169  	_, valid := validateSizeCommand(event.Label.GetName())
   170  	if !valid {
   171  		log.Info("not a valid size label exiting removelabel")
   172  		return nil
   173  	}
   174  
   175  	log.Info("Removed size label")
   176  	labelBody := createNewLabelBodyWithSize(event.GetIssue().Labels)
   177  
   178  	err := updateIssueLabels(ctx, client, labelBody, repoOwner, repoName, issueNumber)
   179  	if err != nil {
   180  		log.Error(err, "Failed to update issue desc")
   181  		return err
   182  	}
   183  
   184  	return nil
   185  }
   186  
   187  // update an issues labels (sets all labels)
   188  func updateIssueLabels(ctx context.Context, client plugin.GithubClientInterface, labels []string, repoOwner, repoName string, issueNumber int) error {
   189  	githubIssueBody := &github.IssueRequest{Labels: &labels}
   190  	_, _, err := client.Issues().Edit(ctx, repoOwner, repoName, issueNumber, githubIssueBody)
   191  	if err != nil {
   192  		return err
   193  	}
   194  	return nil
   195  }
   196  
   197  func createNewLabelBodyNoSize(labels []*github.Label) []string {
   198  	label := []string{}
   199  
   200  	// Add all existing labels to new label slice and toggle sizeLabel
   201  	for _, v := range labels {
   202  		name := v.GetName()
   203  		if !strings.Contains(name, "size/") && name != constants.TriageSizeLabel {
   204  			label = append(label, name)
   205  		}
   206  	}
   207  
   208  	return label
   209  }
   210  
   211  func createNewLabelBodyWithSize(labels []*github.Label) []string {
   212  	label := []string{}
   213  	sizeLabelString := constants.TriageSizeLabel
   214  	isEpic := false
   215  
   216  	// Add all existing labels to new label slice and toggle sizeLabel
   217  	hasSizeLabel := false
   218  	for _, v := range labels {
   219  		name := v.GetName()
   220  		label = append(label, name)
   221  		if strings.Contains(name, "size/") {
   222  			hasSizeLabel = true
   223  		}
   224  		if strings.Contains(name, "epic") {
   225  			isEpic = true
   226  		}
   227  	}
   228  
   229  	// Add size label if non detected
   230  	if !hasSizeLabel && !isEpic {
   231  		label = append(label, sizeLabelString)
   232  	}
   233  
   234  	return label
   235  }
   236  

View as plain text