github.com/covergates/covergates@v0.2.2-0.20201009050117-42ef8a19fb95/modules/hook/hook.go (about) 1 package hook 2 3 import ( 4 "context" 5 "errors" 6 7 "github.com/covergates/covergates/core" 8 ) 9 10 var errHookEventNotSupport = errors.New("hook event not support") 11 12 // Service of webhook resolve and management 13 type Service struct { 14 SCM core.SCMService 15 RepoStore core.RepoStore 16 ReportStore core.ReportStore 17 ReportService core.ReportService 18 } 19 20 // Create a webhook to repository. If existed webhook found, it will be removed first 21 func (s *Service) Create(ctx context.Context, repo *core.Repo) error { 22 user, err := s.RepoStore.Creator(repo) 23 if err != nil { 24 return err 25 } 26 client, err := s.SCM.Client(repo.SCM) 27 if err != nil { 28 return err 29 } 30 if hook, err := s.RepoStore.FindHook(repo); hook != nil && err == nil { 31 client.Repositories().RemoveHook(ctx, user, repo.FullName(), hook) 32 } 33 hook, err := client.Repositories().CreateHook(ctx, user, repo.FullName()) 34 if err != nil { 35 return err 36 } 37 return s.RepoStore.UpdateHook(repo, hook) 38 } 39 40 // Delete a repository webhook 41 func (s *Service) Delete(ctx context.Context, repo *core.Repo) error { 42 user, err := s.RepoStore.Creator(repo) 43 if err != nil { 44 return err 45 } 46 client, err := s.SCM.Client(repo.SCM) 47 if err != nil { 48 return err 49 } 50 hook, err := s.RepoStore.FindHook(repo) 51 if err != nil { 52 return err 53 } 54 return client.Repositories().RemoveHook(ctx, user, repo.FullName(), hook) 55 } 56 57 // Resolve webhook event from the SCM 58 func (s *Service) Resolve(ctx context.Context, repo *core.Repo, hook core.HookEvent) error { 59 if hook == nil { 60 return errHookEventNotSupport 61 } 62 switch event := hook.(type) { 63 case *core.PullRequestHook: 64 return s.resolvePullRequest(ctx, repo, event) 65 } 66 return nil 67 } 68 69 func (s *Service) resolvePullRequest(ctx context.Context, repo *core.Repo, hook *core.PullRequestHook) error { 70 setting, err := s.RepoStore.Setting(repo) 71 if err != nil { 72 return err 73 } 74 if !setting.MergePullRequest { 75 return nil 76 } 77 78 client, err := s.SCM.Client(repo.SCM) 79 if err != nil { 80 return err 81 } 82 user, err := s.RepoStore.Creator(repo) 83 if err != nil { 84 return err 85 } 86 changes, err := client.PullRequests().ListChanges(ctx, user, repo.FullName(), hook.Number) 87 if err != nil { 88 // TODO: Gitea does not support ListChanges, need to find alternative solution 89 changes = []*core.FileChange{} 90 } 91 92 report, err := s.ReportStore.Find(&core.Report{ 93 ReportID: repo.ReportID, 94 Commit: hook.Commit, 95 }) 96 if err != nil { 97 report, err = s.ReportStore.Find(&core.Report{ 98 ReportID: repo.ReportID, 99 Reference: hook.Source, 100 }) 101 if err != nil { 102 return err 103 } 104 } 105 if previous, err := s.ReportStore.Find(&core.Report{ 106 ReportID: repo.ReportID, 107 Reference: hook.Target, 108 }); err == nil { 109 if report, err = s.ReportService.MergeReport(previous, report, changes); err != nil { 110 return err 111 } 112 } 113 report.Reference = hook.Target 114 report.Commit = hook.Commit 115 // TODO: need to use transation to prevent error occur in the middle 116 if err := s.ReportStore.Upload(report); err != nil { 117 return err 118 } 119 return nil 120 }