Triage GitHub issues by adding labels based on keywords

To use this script - Set the secret variable g/all/pretty_secret to a GitHub access token with the issues scope on the target repository(s) - Set webhooks in the target GitHub repository(s), pointing to the flow URL, and set them to send issues events

Script github

by barquenuagique ยท 11/18/2022

  • Submitted by barquenuagique Go
    Created 1267 days ago
    1
    package inner
    2
    
    
    3
    import (
    4
    	"encoding/json"
    5
    	"errors"
    6
    	"fmt"
    7
    	"net/http"
    8
    	"strconv"
    9
      "strings"
    10
    
    
    11
    	wmill "github.com/windmill-labs/windmill-go-client"
    12
    )
    13
    
    
    14
    type payload struct {
    15
    	Repo        string // a repo full name: owner/repo
    16
    	LabelWith   []string
    17
    	IssueNumber int
    18
    }
    19
    
    
    20
    // Issues will be mapped to team(s) or label(s) based on keywords
    21
    var keyWordToLabel = map[string]string{
    22
    	"backend":     "team/backend",
    23
    	"worker":      "team/backend",
    24
      "logs":      "team/backend",
    25
    	"frontend":    "team/frontend",
    26
    	"client":      "team/frontend",
    27
      "editor":      "team/frontend",
    28
    	"UI":          "team/frontend",
    29
    	"doc":         "team/product",
    30
    	"improvement": "feature-request",
    31
    	"request":     "feature-request",
    32
    	"add support": "feature-request",
    33
    	"bug":         "bug",
    34
    }
    35
    
    
    36
    func getRequest(gh_token string, url string, target interface{}) error {
    37
    	bearer := "token " + gh_token
    38
    	req, _ := http.NewRequest("GET", url, nil)
    39
    	req.Header.Add("Accept", "application/vnd.github+json")
    40
    	req.Header.Add("Authorization", bearer)
    41
    	res, err := http.DefaultClient.Do(req)
    42
    
    
    43
    	if err != nil {
    44
    		return errors.New(fmt.Sprintf("request failed %s", err))
    45
    	}
    46
    	if !(res.StatusCode >= 200 && res.StatusCode < 300) {
    47
    		return errors.New(fmt.Sprintf("request failed %s at %s", res.Status, url))
    48
    	}
    49
    	defer res.Body.Close()
    50
    
    
    51
      json.NewDecoder(res.Body).Decode(&target)
    52
      return nil
    53
    }
    54
    
    
    55
    func getIssue(repo_fullname string, issue_number int) (description string, title string, e error) {
    56
    	gh_token, err := wmill.GetVariable("u/mm/gh_token")
    57
    	URL := "https://api.github.com/repos/" + repo_fullname + "/issues/" + strconv.Itoa(issue_number)
    58
    	fmt.Println(URL)
    59
    	if err != nil {
    60
    		return "", "", err
    61
    	}
    62
    	issue := new(struct{
    63
        Body string `json:"body"`
    64
        Title string `json:"title"`
    65
      })
    66
      err = getRequest(gh_token, URL, issue)
    67
      if err != nil{
    68
        return "", "", errors.New(fmt.Sprintf("request failed %s at %s", err))
    69
      }
    70
      return issue.Body, issue.Title, nil
    71
    }
    72
    
    
    73
    func contains(s []string, str string) bool {
    74
    	for _, v := range s {
    75
    		if v == str {
    76
    			return true
    77
    		}
    78
    	}
    79
    	return false
    80
    }
    81
    
    
    82
    func main(
    83
    	issue struct {
    84
    		Number int `json:"number"`
    85
    	},
    86
    	action string,
    87
    	sender interface{},
    88
    	repository struct {
    89
    		Full_name string `json:"full_name"`
    90
    	}) (interface{}, error) {
    91
    
    
    92
    	labels := []string{}
    93
    
    
    94
    	if action == "opened" {
    95
    		description, title, err := getIssue(repository.Full_name, issue.Number)
    96
        if err!= nil{
    97
          return nil, err
    98
        }
    99
         for keyword, label := range keyWordToLabel{
    100
            if (strings.Contains(title, keyword) || strings.Contains(description, keyword)) && !(contains(labels, label)) {
    101
              labels = append(labels, label)
    102
            }
    103
         } 
    104
    		return payload{Repo: repository.Full_name, LabelWith: labels, IssueNumber: issue.Number}, nil
    105
    	} else {
    106
    		return "", nil
    107
    	}
    108
    }