sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/plugins/testfreeze/testfreeze.go (about) 1 /* 2 Copyright 2022 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 testfreeze 18 19 import ( 20 "fmt" 21 "html/template" 22 "strings" 23 "time" 24 25 "github.com/sirupsen/logrus" 26 27 "sigs.k8s.io/prow/pkg/config" 28 "sigs.k8s.io/prow/pkg/github" 29 "sigs.k8s.io/prow/pkg/pluginhelp" 30 "sigs.k8s.io/prow/pkg/plugins" 31 "sigs.k8s.io/prow/pkg/plugins/testfreeze/checker" 32 ) 33 34 const ( 35 PluginName = "testfreeze" 36 defaultKubernetesBranch = "master" 37 defaultKubernetesRepoAndOrg = "kubernetes" 38 templateString = `Please note that we're already in [Test Freeze](https://github.com/kubernetes/sig-release/blob/master/releases/release_phases.md#test-freeze) for the ` + "`{{ .Branch }}`" + ` branch. This means every merged PR will be automatically fast-forwarded via the periodic [ci-fast-forward](https://testgrid.k8s.io/sig-release-releng-blocking#git-repo-kubernetes-fast-forward) job to the release branch of the upcoming {{ .Tag }} release. 39 40 Fast forwards are scheduled to happen every 6 hours, whereas the most recent run was: {{ .LastFastForward }}. 41 ` 42 ) 43 44 func init() { 45 plugins.RegisterPullRequestHandler(PluginName, handlePullRequestEvent, helpProvider) 46 } 47 48 func helpProvider(*plugins.Configuration, []config.OrgRepo) (*pluginhelp.PluginHelp, error) { 49 return &pluginhelp.PluginHelp{ 50 Description: fmt.Sprintf( 51 "The %s plugin adds additional documentation about cherry-picks during the Test Freeze period.", 52 PluginName, 53 ), 54 }, nil 55 } 56 57 func handlePullRequestEvent(p plugins.Agent, e github.PullRequestEvent) error { 58 h := newHandler() 59 log := p.Logger 60 if err := h.handle( 61 log, 62 p.GitHubClient, 63 e.Action, 64 e.Number, 65 e.Repo.Owner.Login, 66 e.Repo.Name, 67 e.PullRequest.Base.Ref, 68 ); err != nil { 69 log.WithError(err).Error("skipping") 70 } 71 return nil 72 } 73 74 type handler struct { 75 verifier verifier 76 } 77 78 func newHandler() *handler { 79 return &handler{ 80 verifier: &defaultVerifier{}, 81 } 82 } 83 84 //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 85 //counterfeiter:generate . verifier 86 type verifier interface { 87 CheckInTestFreeze(*logrus.Entry) (*checker.Result, error) 88 CreateComment(plugins.PluginGitHubClient, string, string, int, string) error 89 } 90 91 type defaultVerifier struct{} 92 93 func (*defaultVerifier) CheckInTestFreeze(log *logrus.Entry) (*checker.Result, error) { 94 return checker.New(log).InTestFreeze() 95 } 96 97 func (*defaultVerifier) CreateComment( 98 client plugins.PluginGitHubClient, 99 org, repo string, 100 number int, 101 comment string, 102 ) error { 103 return client.CreateComment(org, repo, number, comment) 104 } 105 106 func (h *handler) handle( 107 log *logrus.Entry, 108 client plugins.PluginGitHubClient, 109 action github.PullRequestEventAction, 110 number int, 111 org, repo, branch string, 112 ) error { 113 funcStart := time.Now() 114 defer func() { 115 log.WithField("duration", time.Since(funcStart).String()). 116 Debug("Completed handlePullRequest") 117 }() 118 119 if action != github.PullRequestActionOpened && 120 action != github.PullRequestActionReopened { 121 log.Debugf("Skipping pull request action %s", action) 122 return nil 123 } 124 125 if org != defaultKubernetesRepoAndOrg || 126 repo != defaultKubernetesRepoAndOrg || 127 branch != defaultKubernetesBranch { 128 log.Debug("Skipping non k/k master branch PR") 129 return nil 130 } 131 132 result, err := h.verifier.CheckInTestFreeze(log) 133 if err != nil { 134 return fmt.Errorf("get test freeze result: %w", err) 135 } 136 137 if !result.InTestFreeze { 138 log.Debugf("Not in test freeze, skipping") 139 return nil 140 } 141 142 comment := &strings.Builder{} 143 tpl, err := template.New(PluginName).Parse(templateString) 144 if err != nil { 145 return fmt.Errorf("parse template: %w", err) 146 } 147 if err := tpl.Execute(comment, result); err != nil { 148 return fmt.Errorf("execute template: %w", err) 149 } 150 151 if err := h.verifier.CreateComment( 152 client, org, repo, number, comment.String(), 153 ); err != nil { 154 return fmt.Errorf("create comment on %s/%s#%d: %q: %w", org, repo, number, comment, err) 155 } 156 157 return nil 158 }