github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/pkg/git/v2/publisher.go (about) 1 /* 2 Copyright 2019 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 git 18 19 import ( 20 "fmt" 21 22 "github.com/sirupsen/logrus" 23 ) 24 25 // Publisher knows how to publish local work to a remote 26 type Publisher interface { 27 // Commit stages all changes and commits them with the message 28 Commit(title, body string) error 29 // PushToFork pushes the local state to the fork remote 30 PushToFork(branch string, force bool) error 31 // PushToNamedFork is used for when the fork has a different name than the original repp 32 PushToNamedFork(forkName, branch string, force bool) error 33 // PushToCentral pushes the local state to the central remote 34 PushToCentral(branch string, force bool) error 35 } 36 37 // GitUserGetter fetches a name and email for us in git commits on-demand 38 type GitUserGetter func() (name, email string, err error) 39 40 type remotes struct { 41 publishRemote ForkRemoteResolver 42 centralRemote RemoteResolver 43 } 44 45 type publisher struct { 46 executor executor 47 remotes remotes 48 info GitUserGetter 49 logger *logrus.Entry 50 } 51 52 // Commit adds all of the current content to the index and creates a commit 53 func (p *publisher) Commit(title, body string) error { 54 p.logger.Infof("Committing changes with title %q", title) 55 name, email, err := p.info() 56 if err != nil { 57 return err 58 } 59 commands := [][]string{ 60 {"add", "--all"}, 61 {"commit", "--message", title, "--message", body, "--author", fmt.Sprintf("%s <%s>", name, email)}, 62 } 63 for _, command := range commands { 64 if out, err := p.executor.Run(command...); err != nil { 65 return fmt.Errorf("error committing %q: %w %v", title, err, string(out)) 66 } 67 } 68 return nil 69 } 70 71 func (p *publisher) PushToNamedFork(forkName, branch string, force bool) error { 72 remote, err := p.remotes.publishRemote(forkName) 73 if err != nil { 74 return err 75 } 76 77 args := []string{"push"} 78 if force { 79 args = append(args, "--force") 80 } 81 args = append(args, []string{remote, branch}...) 82 83 p.logger.Infof("Pushing branch %q to %q", branch, remote) 84 if out, err := p.executor.Run(args...); err != nil { 85 return fmt.Errorf("error pushing %q: %w %v", branch, err, string(out)) 86 } 87 return nil 88 } 89 90 // PublishPush pushes the local state to the publish remote 91 func (p *publisher) PushToFork(branch string, force bool) error { 92 return p.PushToNamedFork("", branch, force) 93 } 94 95 // CentralPush pushes the local state to the central remote 96 func (p *publisher) PushToCentral(branch string, force bool) error { 97 remote, err := p.remotes.centralRemote() 98 if err != nil { 99 return err 100 } 101 102 args := []string{"push"} 103 if force { 104 args = append(args, "--force") 105 } 106 args = append(args, []string{remote, branch}...) 107 108 p.logger.Infof("Pushing branch %q to %q", branch, remote) 109 if out, err := p.executor.Run(args...); err != nil { 110 return fmt.Errorf("error pushing %q: %w %v", branch, err, string(out)) 111 } 112 return nil 113 }