github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/mungegithub/mungers/sig-mention-handler.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package mungers
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  
    23  	"github.com/golang/glog"
    24  	"k8s.io/kubernetes/pkg/util/sets"
    25  	"k8s.io/test-infra/mungegithub/features"
    26  	"k8s.io/test-infra/mungegithub/github"
    27  	"k8s.io/test-infra/mungegithub/options"
    28  )
    29  
    30  var labelPrefixes = []string{"sig/", "committee/", "wg/"}
    31  
    32  type SigMentionHandler struct{}
    33  
    34  func init() {
    35  	h := &SigMentionHandler{}
    36  	RegisterMungerOrDie(h)
    37  }
    38  
    39  // Name is the name usable in --pr-mungers
    40  func (*SigMentionHandler) Name() string { return "sig-mention-handler" }
    41  
    42  // RequiredFeatures is a slice of 'features' that must be provided
    43  func (*SigMentionHandler) RequiredFeatures() []string {
    44  	return []string{}
    45  }
    46  
    47  // Initialize will initialize the munger
    48  func (s *SigMentionHandler) Initialize(config *github.Config, features *features.Features) error {
    49  	return nil
    50  }
    51  
    52  // EachLoop is called at the start of every munge loop
    53  func (*SigMentionHandler) EachLoop() error { return nil }
    54  
    55  // RegisterOptions registers options for this munger; returns any that require a restart when changed.
    56  func (*SigMentionHandler) RegisterOptions(opts *options.Options) sets.String { return nil }
    57  
    58  func (*SigMentionHandler) HasSigLabel(obj *github.MungeObject) bool {
    59  	labels := obj.Issue.Labels
    60  
    61  	for i := range labels {
    62  		if labels[i].Name == nil {
    63  			continue
    64  		}
    65  		for j := range labelPrefixes {
    66  			if strings.HasPrefix(*labels[i].Name, labelPrefixes[j]) {
    67  				return true
    68  			}
    69  		}
    70  	}
    71  
    72  	return false
    73  }
    74  
    75  func (*SigMentionHandler) HasNeedsSigLabel(obj *github.MungeObject) bool {
    76  	labels := obj.Issue.Labels
    77  
    78  	for i := range labels {
    79  		if labels[i].Name != nil && strings.Compare(*labels[i].Name, "needs-sig") == 0 {
    80  			return true
    81  		}
    82  	}
    83  
    84  	return false
    85  }
    86  
    87  // Munge is the workhorse notifying issue owner to add a @kubernetes/sig mention if there is none
    88  // The algorithm:
    89  // (1) return if it is a PR and/or the issue is closed
    90  // (2) find if the issue has a sig label
    91  // (3) find if the issue has a needs-sig label
    92  // (4) if the issue has both the sig and needs-sig labels, remove the needs-sig label
    93  // (5) if the issue has none of the labels, add the needs-sig label and comment
    94  // (6) if the issue has only the sig label, do nothing
    95  // (7) if the issue has only the needs-sig label, do nothing
    96  func (s *SigMentionHandler) Munge(obj *github.MungeObject) {
    97  	if obj.Issue == nil || obj.IsPR() || obj.Issue.State == nil || *obj.Issue.State == "closed" {
    98  		return
    99  	}
   100  
   101  	hasSigLabel := s.HasSigLabel(obj)
   102  	hasNeedsSigLabel := s.HasNeedsSigLabel(obj)
   103  
   104  	if hasSigLabel && hasNeedsSigLabel {
   105  		if err := obj.RemoveLabel("needs-sig"); err != nil {
   106  			glog.Errorf("failed to remove needs-sig label for issue #%v", *obj.Issue.Number)
   107  		}
   108  	} else if !hasSigLabel && !hasNeedsSigLabel {
   109  		if err := obj.AddLabel("needs-sig"); err != nil {
   110  			glog.Errorf("failed to add needs-sig label for issue #%v", *obj.Issue.Number)
   111  			return
   112  		}
   113  
   114  		msg := fmt.Sprintf(`@%s
   115  There are no sig labels on this issue. Please [add a sig label](https://github.com/kubernetes/test-infra/blob/master/commands.md) by:
   116  
   117  1. mentioning a sig: `+"`@kubernetes/sig-<group-name>-<group-suffix>`"+`
   118      e.g., `+"`@kubernetes/sig-contributor-experience-<group-suffix>`"+` to notify the contributor experience sig, OR
   119  
   120  2. specifying the label manually: `+"`/sig <label>`"+`
   121      e.g., `+"`/sig scalability`"+` to apply the `+"`sig/scalability`"+` label
   122  
   123  Note: Method 1 will trigger an email to the group. You can find the group list [here](https://github.com/kubernetes/community/blob/master/sig-list.md) and label list [here](https://github.com/kubernetes/kubernetes/labels).
   124  The `+"`<group-suffix>`"+` in the method 1 has to be replaced with one of these: _**bugs, feature-requests, pr-reviews, test-failures, proposals**_`, *obj.Issue.User.Login)
   125  
   126  		if err := obj.WriteComment(msg); err != nil {
   127  			glog.Errorf("failed to leave comment for %s that issue #%v needs sig label", *obj.Issue.User.Login, *obj.Issue.Number)
   128  		}
   129  	}
   130  }