diff --git a/README.md b/README.md index fb811e4616178c716d8f87fc02d5510716d7eb49..23b07591f0bf18aeb656a3982b2925150a450a94 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,15 @@ If you want to clear some tags when the pull request source branch changes, * kind,sig,openeuler-cla,priority Delete labels beginning with kind,sig,openeuler-cla or priority. * lgtm Delete labels lgtm or beginning with lgtm-. * Except for the above description items, other labels will be judged as equal. +### extraLgtmCountRequired config + If you want to set the number of lgtm tags for a separate repository or organization, + you can configure this configuration item.The configuration item is a list, and the + list element contains the following configuration items: + * lcrType Indicates whether the configuration is for the repository or the organization + * lcrName Configure the spatial address of the repository or organization + * lcrCount Number of lgtm tags +**If your configuration is for a specific repository, you should configure the full path instead of just the repository space address. For example: lcrName:openEuler/ci-bot** ## Getting Started diff --git a/config.yaml b/config.yaml index 39d51eeb3d6aff4f5e3ba125a50dfaac2c9e2fe1..efd5b49f3f4c2c2b85f4b4c8a503e02fe5c25302 100644 --- a/config.yaml +++ b/config.yaml @@ -17,6 +17,16 @@ delLabels: - sig - kind lgtmCountsRequired: 1 +#Add additional lgtm label quantity limit settings to the organization or repositories +#the member variables lcrType indicates whether the setting is for an organization or a repositories, +#optional configuration items: org or repo . +extraLgtmCountRequired: + - lcrType: repo + lcrName: xwzQmxx/test + lcrCount: 2 + - lcrType: org + lcrName: cve-test + lcrCount: 4 requiringLabels: - openeuler-cla/yes missingLabels: @@ -61,4 +71,7 @@ newfilebranch: "master" tmpservicefile: "_service" tmpservicepath: "master/openEuler:Factory/#projectname#/_service" guideurl: "https://gitee.com/openeuler/community/tree/master/zh/contributors" -autoDetectCla: false \ No newline at end of file +autoDetectCla: false +checkPrReviewer: true +#Tips for setting reviewers +setReviewerTip: "Thank you for submitting a PullRequest, but it is detected that you have not set a reviewer, please set a reviewer. " \ No newline at end of file diff --git a/go.mod b/go.mod index 92a62c7113f01cecdf97f6ee15f0cdcc3fc9c53a..d610cebc0061812a5c583ab82d410b5b5c5b205d 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module gitee.com/openeuler/ci-bot go 1.13 require ( - gitee.com/openeuler/go-gitee v0.0.0-20200424023021-ced5a4d67179 + gitee.com/openeuler/go-gitee v0.0.0-20201111035308-c4384bf8d333 github.com/antihax/optional v1.0.0 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/protobuf v1.3.2 // indirect diff --git a/go.sum b/go.sum index 38d5a8c2c4f3eb04ca214b05ede3af5bac3116a2..dd5af7171892b98ed092a7d9c98f29720eb68b12 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,12 @@ cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= gitee.com/openeuler/go-gitee v0.0.0-20200424023021-ced5a4d67179 h1:7bHzennVUJlv27Gljny95CyXknEBrfmHL6KdHCuHumM= gitee.com/openeuler/go-gitee v0.0.0-20200424023021-ced5a4d67179/go.mod h1:TQrS/LP/DFXLqM+lVrZd4nL2pbTrqiXABGT9PJepVTA= +gitee.com/openeuler/go-gitee v0.0.0-20201109090511-81a247e275be h1:eh0eMiF5PNuD196nW8DcVNsGNchbeyKk+nlVgKtnBzg= +gitee.com/openeuler/go-gitee v0.0.0-20201109090511-81a247e275be/go.mod h1:TQrS/LP/DFXLqM+lVrZd4nL2pbTrqiXABGT9PJepVTA= +gitee.com/openeuler/go-gitee v0.0.0-20201110031012-c7f697cc7b12 h1:rgQdF72XcPKOVyM3nmf0Lyp7Mh3mDqxD/uMvY7sixOE= +gitee.com/openeuler/go-gitee v0.0.0-20201110031012-c7f697cc7b12/go.mod h1:TQrS/LP/DFXLqM+lVrZd4nL2pbTrqiXABGT9PJepVTA= +gitee.com/openeuler/go-gitee v0.0.0-20201111035308-c4384bf8d333 h1:Uk05BpyrV24VNVFPd47lEOg0OmUMgnIgd50gnyWqC8s= +gitee.com/openeuler/go-gitee v0.0.0-20201111035308-c4384bf8d333/go.mod h1:TQrS/LP/DFXLqM+lVrZd4nL2pbTrqiXABGT9PJepVTA= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= diff --git a/pkg/cibot/checkpr.go b/pkg/cibot/checkpr.go index 0a0e801bcee2507d60dfd5354f3e4a39b926d115..2866dcd9ca78fb545315d6963a41a714726001f7 100644 --- a/pkg/cibot/checkpr.go +++ b/pkg/cibot/checkpr.go @@ -4,26 +4,33 @@ import ( "gitee.com/openeuler/go-gitee/gitee" "github.com/golang/glog" ) + var checkPrComment = "Cannot use \"/check-pr\", because this command is only used to detect open pull requests" + //CheckPr Check whether the pull request can be merged -func (s *Server)CheckPr(event *gitee.NoteEvent) (err error) { - if *event.NoteableType == "PullRequest" && event.PullRequest.State == "open"{ +func (s *Server) CheckPr(event *gitee.NoteEvent) (err error) { + if *event.NoteableType == "PullRequest" && event.PullRequest.State == "open" { err := s.MergePullRequest(event) if err != nil { - return err - } - }else { - body := gitee.PullRequestCommentPostParam{} - body.AccessToken = s.Config.GiteeToken - body.Body = checkPrComment - owner := event.Repository.Namespace - repo := event.Repository.Name - number := event.PullRequest.Number - _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body) - if err != nil { - glog.Errorf("unable to add comment in pull request: %v", err) - return err + comment := err.Error() + return s.addCommentToPullRequest(event.Repository.Namespace, event.Repository.Name, + comment, event.PullRequest.Number) } + } else { + return s.addCommentToPullRequest(event.Repository.Namespace, event.Repository.Name, + checkPrComment, event.PullRequest.Number) + } + return nil +} + +func (s *Server) addCommentToPullRequest(owner, repo, comment string, number int32) error { + body := gitee.PullRequestCommentPostParam{} + body.AccessToken = s.Config.GiteeToken + body.Body = comment + _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body) + if err != nil { + glog.Errorf("unable to add comment in pull request: %v", err) + return err } return nil } diff --git a/pkg/cibot/clahandler.go b/pkg/cibot/clahandler.go index 9dfaf6e47f61ad09427e9a4cd4592b22c7919497..57fa3b15db7d0c4e45a3e994ddcc1767fef85a86 100644 --- a/pkg/cibot/clahandler.go +++ b/pkg/cibot/clahandler.go @@ -292,7 +292,7 @@ func (s *CLAHandler) HandleRequest(w http.ResponseWriter, request CLARequest, ac } // tostring - data, err := cds.ToString() + _, err = cds.ToString() if err != nil { s.HandleResult(w, CLAResult{ IsSuccess: false, @@ -301,7 +301,7 @@ func (s *CLAHandler) HandleRequest(w http.ResponseWriter, request CLARequest, ac }) return } - glog.Infof("add cla details data: %s", data) + // Check email in database var lenEmail int diff --git a/pkg/cibot/config/config.go b/pkg/cibot/config/config.go index 5c3386780ef6db0aafc58d68dfb62e8ce1e4eb06..c0d43a57e1af2dfde86d6666cb64e513c77a2b8e 100644 --- a/pkg/cibot/config/config.go +++ b/pkg/cibot/config/config.go @@ -1,42 +1,45 @@ package config type Config struct { - GiteeToken string `yaml:"giteeToken" envVariable:"GITEE_TOKEN"` - WebhookSecret string `yaml:"webhookSecret" envVariable:"WEBHOOK_SECRET"` - DataBaseType string `yaml:"databaseType"` - DataBaseHost string `yaml:"databaseHost" envVariable:"DATABASE_HOST"` - DataBasePort int `yaml:"databasePort" envVariable:"DATABASE_PORT"` - DataBaseName string `yaml:"databaseName"` - DataBaseUserName string `yaml:"databaseUserName" envVariable:"DATABASE_USERNAME"` - DataBasePassword string `yaml:"databasePassword" envVariable:"DATABASE_PASSWORD"` - PrUpdateLabelFlag string `yaml:"prUpdateLabelFlag"` - DelLabels []string `yaml:"delLabels"` - WatchProjectFiles []WatchProjectFile `yaml:"watchProjectFiles"` - WatchProjectFileDuration int `yaml:"watchProjectFileDuration"` - WatchSigFiles []WatchSigFile `yaml:"watchSigFiles"` - WatchSigFileDuration int `yaml:"watchSigFileDuration"` - WatchOwnerFiles []WatchOwnerFile `yaml:"watchOwnerFiles"` - WatchOwnerFileDuration int `yaml:"watchOwnerFileDuration"` - WatchFrozenFile []WatchFrozenFile `yaml:"watchFrozenFile"` - WatchFrozenDuration int `yaml:"watchFrozenDuration"` - BotName string `yaml:"botName"` - CommunityName string `yaml:"communityName"` - ClaLink string `yaml:"claLink"` - CommandLink string `yaml:"commandLink"` - ContactEmail string `yaml:"contactEmail"` - LgtmCountsRequired int `yaml:"lgtmCountsRequired"` - AccordingFile string `yaml:"accordingfile"` - NewFileOwner string `yaml:"newfileowner"` - NewFileRepo string `yaml:"newfilerepo"` - NewFileBranch string `yaml:"newfilebranch"` - ServiceFile string `yaml:"tmpservicefile"` - ServicePath string `yaml:"tmpservicepath"` - GuideURL string `yaml:"guideurl"` - CommitsThreshold int `yaml:"commitsThreshold"` - SquashCommitLabel string `yaml:"squashCommitLabel"` - RequiringLabels []string `yaml:"requiringLabels"` - MissingLabels []string `yaml:"missingLabels"` - AutoDetectCla bool `yaml:"autoDetectCla"` + GiteeToken string `yaml:"giteeToken" envVariable:"GITEE_TOKEN"` + WebhookSecret string `yaml:"webhookSecret" envVariable:"WEBHOOK_SECRET"` + DataBaseType string `yaml:"databaseType"` + DataBaseHost string `yaml:"databaseHost" envVariable:"DATABASE_HOST"` + DataBasePort int `yaml:"databasePort" envVariable:"DATABASE_PORT"` + DataBaseName string `yaml:"databaseName"` + DataBaseUserName string `yaml:"databaseUserName" envVariable:"DATABASE_USERNAME"` + DataBasePassword string `yaml:"databasePassword" envVariable:"DATABASE_PASSWORD"` + PrUpdateLabelFlag string `yaml:"prUpdateLabelFlag"` + DelLabels []string `yaml:"delLabels"` + WatchProjectFiles []WatchProjectFile `yaml:"watchProjectFiles"` + WatchProjectFileDuration int `yaml:"watchProjectFileDuration"` + WatchSigFiles []WatchSigFile `yaml:"watchSigFiles"` + WatchSigFileDuration int `yaml:"watchSigFileDuration"` + WatchOwnerFiles []WatchOwnerFile `yaml:"watchOwnerFiles"` + WatchOwnerFileDuration int `yaml:"watchOwnerFileDuration"` + WatchFrozenFile []WatchFrozenFile `yaml:"watchFrozenFile"` + WatchFrozenDuration int `yaml:"watchFrozenDuration"` + BotName string `yaml:"botName"` + CommunityName string `yaml:"communityName"` + ClaLink string `yaml:"claLink"` + CommandLink string `yaml:"commandLink"` + ContactEmail string `yaml:"contactEmail"` + LgtmCountsRequired int `yaml:"lgtmCountsRequired"` + ExtraLgtmCountRequired []ExtraLgtmCountRequire `yaml:"extraLgtmCountRequired"` + AccordingFile string `yaml:"accordingfile"` + NewFileOwner string `yaml:"newfileowner"` + NewFileRepo string `yaml:"newfilerepo"` + NewFileBranch string `yaml:"newfilebranch"` + ServiceFile string `yaml:"tmpservicefile"` + ServicePath string `yaml:"tmpservicepath"` + GuideURL string `yaml:"guideurl"` + CommitsThreshold int `yaml:"commitsThreshold"` + SquashCommitLabel string `yaml:"squashCommitLabel"` + RequiringLabels []string `yaml:"requiringLabels"` + MissingLabels []string `yaml:"missingLabels"` + AutoDetectCla bool `yaml:"autoDetectCla"` + CheckPrReviewer bool `yaml:"checkPrReviewer"` + SetReviewerTip string `yaml:"setReviewerTip"` } type WatchProjectFile struct { @@ -66,3 +69,9 @@ type WatchFrozenFile struct { FrozenFilePath string `yaml:"frozenFilePath"` FrozenFileRef string `yaml:"frozenFileRef"` } + +type ExtraLgtmCountRequire struct { + LcrType string `yaml:"lcrType"` + LcrName string `yaml:"lcrName"` + LcrCount int `yaml:"lcrCount"` +} diff --git a/pkg/cibot/database/database.go b/pkg/cibot/database/database.go index c7b2b04c07d5b4da59772179ba0a1863241beee4..1558854a9a85e2c98951bc232682da9486ec440e 100644 --- a/pkg/cibot/database/database.go +++ b/pkg/cibot/database/database.go @@ -47,8 +47,6 @@ func ConnectDataBase(config config.Config) (*gorm.DB, error) { config.DataBaseHost, config.DataBasePort, config.DataBaseName) - glog.Infof("connecting str: %v", connStr) - return gorm.Open(config.DataBaseType, connStr) } diff --git a/pkg/cibot/inithandler.go b/pkg/cibot/inithandler.go index a1e27fe9aab7b26a17a659fb4f531fb4a933f295..c2d1da7a78f0d79c1fb757929aaafdfa5a12ef73 100644 --- a/pkg/cibot/inithandler.go +++ b/pkg/cibot/inithandler.go @@ -25,6 +25,7 @@ const ( PermissionPull = "pull" BranchProtected = "protected" + BranchNormal = "normal" // not supported yet BranchReadonly = "readonly" ) @@ -60,6 +61,7 @@ type Repository struct { Developers []string `yaml:"developers"` Viewers []string `yaml:"viewers"` Reporters []string `yaml:"reporters"` + Branches []Branch `yaml:"branches"` } // IsCommentable returns if contributors are able to comment @@ -172,7 +174,7 @@ func (handler *InitHandler) watch() { watchPath := wf.WatchprojectFilePath watchRef := wf.WatchProjectFileRef - glog.Infof("begin to serve. watchOwner: %s watchRepo: %s watchPath: %s watchRef: %s watchDuration: %d", + glog.Infof("Init handler begin to serve. watchOwner: %s watchRepo: %s watchPath: %s watchRef: %s watchDuration: %d", watchOwner, watchRepo, watchPath, watchRef, watchDuration) // get project file @@ -858,145 +860,112 @@ func (handler *InitHandler) removeReporters(c Community, r Repository, mapReport func (handler *InitHandler) handleBranches(c Community, r Repository) error { // if the branches are defined in the repositories, it means that // all the branches defined in the community will not inherited by repositories - mapBranches := make(map[string]string) - if len(r.ProtectedBranches) > 0 { + if len(r.Branches) > 0 { // using repository branches - glog.Infof("using repository branches: %s", *r.Name) - for _, b := range r.ProtectedBranches { - mapBranches[b] = b - } - } else { - // using community branches - glog.Infof("using community branches: %s", *r.Name) - for _, b := range c.ProtectedBranches { - mapBranches[b] = b + glog.Infof("Setting repository branches: %s", r.Name) + for _, b := range r.Branches { + //check yaml branches is in db + var bs []database.Branches + err := database.DBConnection.Model(&database.Branches{}). + Where("owner = ? and repo = ? and name = ?", c.Name, r.Name, b.Name).Find(&bs).Error + if err != nil { + glog.Infof("Do not have branches (%s), need to create. %v, ", b.Name, err) + err = handler.addBranchInGiteeAndDb(c, r, b) + if err != nil { + glog.Errorf("Add branch(%s) of repor(%s) failed: %v", b.Name, r.Name, err) + } + continue + } + //branch exist already, need to change some feature only. + err = handler.changeBranchInGiteeAndDb(c, r, b, bs[0]) + if err != nil { + glog.Errorf("Change branch(%s) of repor(%s) failed: %v", b.Name, r.Name, err) + } + continue } } - - // get branches from DB - var bs []database.Branches - err := database.DBConnection.Model(&database.Branches{}). - Where("owner = ? and repo = ?", c.Name, r.Name).Find(&bs).Error - if err != nil { - glog.Errorf("unable to get branches: %v", err) - return err - } - mapBranchesInDB := make(map[string]string) - for _, b := range bs { - mapBranchesInDB[b.Name] = strconv.Itoa(int(b.ID)) - } - - // un-protected branches - err = handler.removeBranchProtections(c, r, mapBranches, mapBranchesInDB) - if err != nil { - glog.Errorf("unable to un-protected branches: %v", err) - } - - // protected branches - err = handler.addBranchProtections(c, r, mapBranches, mapBranchesInDB) - if err != nil { - glog.Errorf("unable to protected branches: %v", err) - } - return nil } // unprotectedBranches unprotect branches -func (handler *InitHandler) removeBranchProtections(c Community, r Repository, mapBranches, mapBranchesInDB map[string]string) error { - // remove branch protections - listOfUnprotectedBranches := make([]string, 0) - - for k := range mapBranchesInDB { - if _, exists := mapBranches[k]; !exists { - listOfUnprotectedBranches = append(listOfUnprotectedBranches, k) - } +func (handler *InitHandler) changeBranchInGiteeAndDb(c Community, r Repository, br Branch, bs database.Branches) error { + // if branch features are same as ones in db, do nothing. + if *r.Name == bs.Repo && *br.Name == bs.Name && *br.Type == bs.Type { + return nil } - glog.Infof("list of un-protected branches: %v", listOfUnprotectedBranches) - if len(listOfUnprotectedBranches) > 0 { + // change branch protected freature in Gitee + var brType string + brType = BranchNormal + if *br.Type == BranchProtected { + protectBody := gitee.BranchProtectionPutParam{} + protectBody.AccessToken = handler.Config.GiteeToken + _, _, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoBranchesBranchProtection( + handler.Context, *c.Name, *r.Name, *br.Name, protectBody) + if err != nil { + glog.Errorf("failed to add branch protection: %v", err) + } + brType = BranchProtected + } else { opts := &gitee.DeleteV5ReposOwnerRepoBranchesBranchProtectionOpts{} opts.AccessToken = optional.NewString(handler.Config.GiteeToken) - - glog.Infof("begin to remove branch protections for %s", *r.Name) - for _, v := range listOfUnprotectedBranches { - // remove branch protection from gitee - _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoBranchesBranchProtection( - handler.Context, *c.Name, *r.Name, v, opts) - if err != nil { - glog.Errorf("failed to remove branch protection: %v", err) - continue - } - // remove branch protection from DB - id, _ := strconv.Atoi(mapBranchesInDB[v]) - bs := database.Branches{} - bs.ID = uint(id) - err = database.DBConnection.Delete(&bs).Error - if err != nil { - glog.Errorf("failed to remove branch protection in database: %v", err) - } + _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoBranchesBranchProtection( + handler.Context, *c.Name, *r.Name, *br.Name, opts) + if err != nil { + glog.Errorf("failed to remove branch protection: %v", err) } - glog.Infof("end to remove branch protections for %s", *r.Name) + } + + // change branch protected freature in DB + updatebranch := &database.Branches{} + updatebranch.ID = bs.ID + err := database.DBConnection.Model(updatebranch).Update("Type", brType).Error + if err != nil { + glog.Errorf("unable to update type: %v", err) } return nil } // addBranchProtections protects branches -func (handler *InitHandler) addBranchProtections(c Community, r Repository, mapBranches, mapBranchesInDB map[string]string) error { - // add branch protections - listOfProtectedBranches := make([]string, 0) - - for k := range mapBranches { - if _, exits := mapBranchesInDB[k]; !exits { - listOfProtectedBranches = append(listOfProtectedBranches, k) - } +func (handler *InitHandler) addBranchInGiteeAndDb(c Community, r Repository, br Branch) error { + // create branch in gitee + repobranchbody := gitee.CreateBranchParam{} + repobranchbody.AccessToken = handler.Config.GiteeToken + repobranchbody.BranchName = *br.Name + repobranchbody.Refs = *br.CreateFrom + _, _, err := handler.GiteeClient.RepositoriesApi.PostV5ReposOwnerRepoBranches(handler.Context, *c.Name, *r.Name, repobranchbody) + if err != nil { + glog.Errorf("fail to add branch (%s) for repository (%s): %v", *br.Name, *r.Name, err) + return nil } - glog.Infof("list of protected branches: %v", listOfProtectedBranches) - - if len(listOfProtectedBranches) > 0 { - getOpts := &gitee.GetV5ReposOwnerRepoBranchesBranchOpts{} - getOpts.AccessToken = optional.NewString(handler.Config.GiteeToken) + glog.Infof("Add branch (%s) for repository (%s) in gitee.", *br.Name, *r.Name) + // add branch protection to gitee + var brType string + brType = BranchNormal + if *br.Type == BranchProtected { protectBody := gitee.BranchProtectionPutParam{} protectBody.AccessToken = handler.Config.GiteeToken - - glog.Errorf("begin to add branch protections for %s", *r.Name) - for _, v := range listOfProtectedBranches { - // check if protected branch exists - branchObj, response, _ := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoBranchesBranch( - handler.Context, *c.Name, *r.Name, v, getOpts) - if response.StatusCode == 404 { - glog.Errorf("branch %s not exists, no need for protection", v) - continue - } - - // If branch has alreay been protected, no need for protection - if branchObj.Protected == true { - glog.Errorf("branch %s has been protected already, no need for protection", v) - continue - } - - // add branch protection to gitee - _, response, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoBranchesBranchProtection( - handler.Context, *c.Name, *r.Name, v, protectBody) - if err != nil { - glog.Errorf("failed to add branch protection: %v", err) - continue - } - // add branch protection to database - bs := database.Branches{ - Owner: *c.Name, - Repo: *r.Name, - Name: v, - Type: BranchProtected, - } - err = database.DBConnection.Create(&bs).Error - if err != nil { - glog.Errorf("failed to add branch protection in database: %v", err) - } + _, _, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoBranchesBranchProtection( + handler.Context, *c.Name, *r.Name, *br.Name, protectBody) + if err != nil { + glog.Errorf("failed to add branch protection: %v", err) } - glog.Infof("end to add branch protections for %s", *r.Name) + brType = BranchProtected + } + // add branch to database + bs := database.Branches{ + Owner: *c.Name, + Repo: *r.Name, + Name: *br.Name, + Type: brType, + AdditionalInfo: *br.CreateFrom, + } + err = database.DBConnection.Create(&bs).Error + if err != nil { + glog.Errorf("failed to add branch protection in database: %v", err) } return nil diff --git a/pkg/cibot/lgtm.go b/pkg/cibot/lgtm.go index 48945a05a71a9a0e253374a85e2640098a41c6b6..9ba36f576c0b7a94f1ad665612397432713bf968 100644 --- a/pkg/cibot/lgtm.go +++ b/pkg/cibot/lgtm.go @@ -11,8 +11,8 @@ import ( ) const ( - lgtmSelfOwnMessage = `***lgtm*** can not be added in your self-own pull request. :astonished: ` - lgtmAddedMessage = `***lgtm*** is added in this pull request by: ***%s***. :wave: + lgtmSelfOwnMessage = `***lgtm*** can not be added in your self-own pull request. :astonished: ` + lgtmAddedMessage = `***lgtm*** is added in this pull request by: ***%s***. :wave: **NOTE:**: If you find this pull request unmerged while all conditions meets, you are encouraged use command: "/check-pr" to try it again. :smile: ` lgtmRemovedMessage = `***lgtm*** is removed in this pull request by: ***%s***. :flushed: ` lgtmAddNoPermissionMessage = `Thanks for your review, ***%s***, your opinion is very important to us.:wave: @@ -20,6 +20,8 @@ The maintainers will consider your advice carefully.` lgtmRemoveNoPermissionMessage = `***%s*** has no permission to remove ***lgtm*** in this pull request. :astonished: please contact to the collaborators in this repository.` lgtmRemovePullRequestChangeMessage = `new changes are detected. ***lgtm*** is removed in this pull request by: ***%s***. :flushed: ` + lgtmRepo = "repo" + lgtmOrg = "org" ) // AddLgtm adds lgtm label @@ -84,7 +86,7 @@ func (s *Server) AddLgtm(event *gitee.NoteEvent) error { addlabel.PullRequest = event.PullRequest addlabel.Repository = event.Repository addlabel.Comment = &gitee.NoteHook{} - err = s.AddSpecifyLabelsInPulRequest(addlabel, []string{s.getLgtmLable(commentAuthor)}, true) + err = s.AddSpecifyLabelsInPulRequest(addlabel, []string{s.getLgtmLable(commentAuthor, owner, repo)}, true) if err != nil { return err } @@ -124,13 +126,44 @@ func (s *Server) AddLgtm(event *gitee.NoteEvent) error { return nil } -func (s *Server) getLgtmLable(commenter string) string { - if s.Config.LgtmCountsRequired > 1 { +func (s *Server) getLgtmLable(commenter, owner, repo string) string { + if s.calculateLgtmLabel(owner, repo) > 1 { return fmt.Sprintf(LabelLgtmWithCommenter, strings.ToLower(commenter)) } return LabelNameLgtm } +func (s *Server) calculateLgtmLabel(owner, repo string) int { + if len(s.Config.ExtraLgtmCountRequired) > 0 { + repoNum := 0 + orgNum := 0 + for _, v := range s.Config.ExtraLgtmCountRequired { + if v.LcrType == lgtmRepo { + if strings.Contains(v.LcrName, "/") { + or := strings.Split(v.LcrName, "/") + if len(or) == 2 && strings.ToLower(or[0]) == owner && strings.ToLower(or[1]) == repo { + repoNum = v.LcrCount + } + } else if strings.ToLower(v.LcrName) == repo { + repoNum = v.LcrCount + } + } + if v.LcrType == lgtmOrg && v.LcrName == owner { + orgNum = v.LcrCount + } + } + if repoNum > 0 { + return repoNum + } + if orgNum > 0 { + return orgNum + } + return s.Config.LgtmCountsRequired + } + return s.Config.LgtmCountsRequired + +} + // RemoveLgtm removes lgtm label func (s *Server) RemoveLgtm(event *gitee.NoteEvent) error { // handle PullRequest @@ -195,7 +228,7 @@ func (s *Server) RemoveLgtm(event *gitee.NoteEvent) error { removelabel.Repository = event.Repository removelabel.Comment = &gitee.NoteHook{} mapOfRemoveLabels := map[string]string{} - lgtmLable := s.getLgtmLable(commentAuthor) + lgtmLable := s.getLgtmLable(commentAuthor, owner, repo) mapOfRemoveLabels[lgtmLable] = lgtmLable err := s.RemoveSpecifyLabelsInPulRequest(removelabel, mapOfRemoveLabels) if err != nil { @@ -219,7 +252,7 @@ func (s *Server) RemoveLgtm(event *gitee.NoteEvent) error { func (s *Server) collectExistingLgtmLabel(owner, repo string, number int32) (map[string]string, error) { labels := make(map[string]string) - if s.Config.LgtmCountsRequired > 1 { + if s.calculateLgtmLabel(owner, repo) > 1 { lvos := &gitee.GetV5ReposOwnerRepoPullsNumberOpts{ AccessToken: optional.NewString(s.Config.GiteeToken), } diff --git a/pkg/cibot/oauth.go b/pkg/cibot/oauth.go index d6e9983de0b7aa816cf43165c28d73ebb8dd11b5..9469da9fbe461855d3917235899812f5e37f0866 100644 --- a/pkg/cibot/oauth.go +++ b/pkg/cibot/oauth.go @@ -3,10 +3,10 @@ package cibot import ( "context" "fmt" + "github.com/golang/glog" "os" "strings" - "github.com/golang/glog" "golang.org/x/oauth2" ) @@ -30,7 +30,7 @@ func GetToken(code string) (*oauth2.Token, error) { ctx := context.Background() config := Setup(client, redirect, secret) - glog.Infof("Token request config : %v, code: %s", config, code) + glog.Infof("Token request config, code: %s", code) return config.Exchange(ctx, code) diff --git a/pkg/cibot/pullrequest.go b/pkg/cibot/pullrequest.go index 61a71958ed9f0a32a8ceec9728a927bd1df3ad0c..ffd49b161073c8a4da31c827d0a1c0ea0fc33eb7 100644 --- a/pkg/cibot/pullrequest.go +++ b/pkg/cibot/pullrequest.go @@ -49,6 +49,16 @@ func (s *Server) HandlePullRequestEvent(actionDesc string, event *gitee.PullRequ glog.Errorf("unable to add comment in pull request: %v", err) } + if s.Config.CheckPrReviewer { + if !s.checkPrHasSetReviewer(event) { + body.Body = fmt.Sprintf(" ***@%s*** %s", event.Sender.Login, s.Config.SetReviewerTip) + _, _, err = s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body) + if err != nil { + glog.Errorf("unable to add comment in pull request: %v", err) + } + } + } + if s.Config.AutoDetectCla { err = s.CheckCLAByPullRequestEvent(event) if err != nil { @@ -403,13 +413,14 @@ func (s *Server) hasLgtmLabel(labels []gitee.Label) bool { return false } -func (s *Server) readyForMerge(labels []gitee.Label) bool { +func (s *Server) readyForMerge(labels []gitee.Label, owner, repo string) error { aproveLabel := 0 lgtmLabel := 0 lgtmPrefix := "" leastLgtm := 0 - if s.Config.LgtmCountsRequired > 1 { - leastLgtm = s.Config.LgtmCountsRequired + count := s.calculateLgtmLabel(owner, repo) + if count > 1 { + leastLgtm = count lgtmPrefix = fmt.Sprintf(LabelLgtmWithCommenter, "") } else { leastLgtm = 1 @@ -423,7 +434,12 @@ func (s *Server) readyForMerge(labels []gitee.Label) bool { } } glog.Infof("Pr labels have approved: %d lgtm: %d, required (%d)", aproveLabel, lgtmLabel, leastLgtm) - return aproveLabel == 1 && lgtmLabel >= leastLgtm + if aproveLabel == 1 && lgtmLabel >= leastLgtm { + return nil + } else { + return fmt.Errorf("This pull request can not be merged, please check that the number of **lgtm** labels >= %d "+ + "and there are an **approve** labels. ", leastLgtm) + } } // check with the labels constraints requiring/missing to determine if mergable @@ -452,83 +468,76 @@ func (s *Server) MergePullRequest(event *gitee.NoteEvent) error { listofPrLabels := pr.Labels glog.Infof("List of pr labels: %v", listofPrLabels) // ready to merge - if s.readyForMerge(listofPrLabels) { - nonRequiringLabels, nonMissingLabels := s.legalLabelsForMerge(listofPrLabels) - if len(nonRequiringLabels) == 0 && len(nonMissingLabels) == 0 { - // current pr can be merged - if c,b :=checkFrozenCanMerge(event.Author.Login, pr.Base.Ref) ;!b{ - //send comment to pr - body := gitee.PullRequestCommentPostParam{} - body.AccessToken = s.Config.GiteeToken - if len(c) >0{ - body.Body = fmt.Sprintf("**Merge failed** The current pull request merge target has been frozen, and only the branch owner( @%s ) can merge.", - strings.Join(c," , @")) - }else { - body.Body = "**Merge failed** The current pull request merge target has been frozen, and only the branch owner can merge." + err = s.readyForMerge(listofPrLabels, owner, repo) + if err != nil { + return err + } + nonRequiringLabels, nonMissingLabels := s.legalLabelsForMerge(listofPrLabels) + if len(nonRequiringLabels) == 0 && len(nonMissingLabels) == 0 { + // current pr can be merged + if c, b := checkFrozenCanMerge(event.Author.Login, pr.Base.Ref); !b { + //send comment to pr + comment := "" + if len(c) > 0 { + comment = fmt.Sprintf("**Merge failed** The current pull request merge target has been frozen, and only the branch owner( @%s ) can merge.", + strings.Join(c, " , @")) + } else { + comment = "**Merge failed** The current pull request merge target has been frozen, and only the branch owner can merge." + } + err = s.addCommentToPullRequest(owner, repo, comment, prNumber) + if err != nil { + glog.Errorf("Cannot add comments to pull request: %v", err) + } + } else { + if event.PullRequest.Mergeable { + // remove assignees + err = s.RemoveAssigneesInPullRequest(event) + if err != nil { + glog.Errorf("unable to remove assignees. err: %v", err) } - - _, _, err = s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, prNumber, body) + // remove testers + err = s.RemoveTestersInPullRequest(event) if err != nil { - glog.Errorf("Cannot add comments to pull request: %v", err) + glog.Errorf("unable to remove testers. err: %v", err) } - } else { - if event.PullRequest.Mergeable { - // remove assignees - err = s.RemoveAssigneesInPullRequest(event) - if err != nil { - glog.Errorf("unable to remove assignees. err: %v", err) - return err - } - // remove testers - err = s.RemoveTestersInPullRequest(event) - if err != nil { - glog.Errorf("unable to remove testers. err: %v", err) - return err - } - // merge pr - body := gitee.PullRequestMergePutParam{} - body.AccessToken = s.Config.GiteeToken - // generate merge body - description, err := s.generateMergeDescription(event) - if err != nil { - glog.Errorf("unable to get merge description.err: %v", err) - return err - } - body.Description = description - - _, err = s.GiteeClient.PullRequestsApi.PutV5ReposOwnerRepoPullsNumberMerge(s.Context, owner, repo, prNumber, body) - if err != nil { - glog.Errorf("unable to merge pull request. err: %v", err) - return err - } + // merge pr + body := gitee.PullRequestMergePutParam{} + body.AccessToken = s.Config.GiteeToken + // generate merge body + description, err := s.generateMergeDescription(event) + if err != nil { + glog.Errorf("unable to get merge description.err: %v", err) + return fmt.Errorf(`The pull request merge failed, please use command "/check-pr" to try again. `) } - } - } else { - // add comment to pr to show the labels reason of not mergable - nonRequiringMsg := "" - if len(nonRequiringLabels) > 0 { - nonRequiringMsg = fmt.Sprintf(nonRequiringLabelsMessage, strings.Join(nonRequiringLabels, ",")) - } - nonMissingMsg := "" - if len(nonMissingLabels) > 0 { - nonMissingMsg = fmt.Sprintf(nonMissingLabelsMessage, strings.Join(nonMissingLabels, ",")) - } + body.Description = description - // add comment back to pr - body := gitee.PullRequestCommentPostParam{} - body.AccessToken = s.Config.GiteeToken - body.Body = fmt.Sprintf(cannotMergeMessage, fmt.Sprintf("%s%s", nonRequiringMsg, nonMissingMsg)) - owner := event.Repository.Namespace - repo := event.Repository.Name - number := event.PullRequest.Number - _, _, err := s.GiteeClient.PullRequestsApi.PostV5ReposOwnerRepoPullsNumberComments(s.Context, owner, repo, number, body) - if err != nil { - glog.Errorf("unable to add comment in pull request: %v", err) - return err + _, err = s.GiteeClient.PullRequestsApi.PutV5ReposOwnerRepoPullsNumberMerge(s.Context, owner, repo, prNumber, body) + if err != nil { + glog.Errorf("unable to merge pull request. err: %v", err) + return fmt.Errorf(`The pull request merge failed, please use command "/check-pr" to try again. `) + } } } + } else { + // add comment to pr to show the labels reason of not mergable + nonRequiringMsg := "" + if len(nonRequiringLabels) > 0 { + nonRequiringMsg = fmt.Sprintf(nonRequiringLabelsMessage, strings.Join(nonRequiringLabels, ",")) + } + nonMissingMsg := "" + if len(nonMissingLabels) > 0 { + nonMissingMsg = fmt.Sprintf(nonMissingLabelsMessage, strings.Join(nonMissingLabels, ",")) + } + // add comment back to pr + comment := fmt.Sprintf(cannotMergeMessage, fmt.Sprintf("%s%s", nonRequiringMsg, nonMissingMsg)) + owner := event.Repository.Namespace + repo := event.Repository.Name + number := event.PullRequest.Number + err = s.addCommentToPullRequest(owner, repo, comment, number) + if err != nil { + glog.Errorf("unable to add comment in pull request: %v", err) + } } - return nil } @@ -603,7 +612,7 @@ func getSignersAndReviewers(user string, comments []gitee.PullRequestComments) ( return signers, reviewers, nil } -func checkFrozenCanMerge(commenter, branch string) ([]string,bool) { +func checkFrozenCanMerge(commenter, branch string) ([]string, bool) { frozen, isFrozen := IsBranchFrozen(branch) if isFrozen { canMerge := false @@ -613,8 +622,30 @@ func checkFrozenCanMerge(commenter, branch string) ([]string,bool) { break } } - return frozen,canMerge + return frozen, canMerge } else { - return frozen,true + return frozen, true } } + +func (s *Server) checkPrHasSetReviewer(pre *gitee.PullRequestEvent) bool { + if pre.PullRequest != nil && len(pre.PullRequest.Assignees) > 0 { + return true + } else { + //get pr info + owner := pre.Repository.Namespace + repo := pre.Repository.Name + number := pre.PullRequest.Number + lvos := &gitee.GetV5ReposOwnerRepoPullsNumberOpts{} + lvos.AccessToken = optional.NewString(s.Config.GiteeToken) + pr, _, err := s.GiteeClient.PullRequestsApi.GetV5ReposOwnerRepoPullsNumber(s.Context, owner, repo, number, lvos) + if err != nil { + glog.Errorf("unable to get pull request. err: %v", err) + return false + } + if len(pr.Assignees) > 0 { + return true + } + } + return false +} diff --git a/pkg/cibot/pullrequest_test.go b/pkg/cibot/pullrequest_test.go index cf3d7e8c5b9d2eb807db500637e987f5826a71f6..9a2a8acf542f91684961f42e0301347787a75d6f 100644 --- a/pkg/cibot/pullrequest_test.go +++ b/pkg/cibot/pullrequest_test.go @@ -2,9 +2,6 @@ package cibot import "testing" -import ( - "testing" -) func Test_formatDescription(t *testing.T) { type args struct { @@ -34,4 +31,4 @@ func Test_formatDescription(t *testing.T) { } }) } -} +} \ No newline at end of file diff --git a/pkg/cibot/repohandler.go b/pkg/cibot/repohandler.go index 22eb8d2f0e7c1dea83dfd05ae78a4da29142b924..1db37fac32fede3c737489efce7e084b25e74904 100644 --- a/pkg/cibot/repohandler.go +++ b/pkg/cibot/repohandler.go @@ -22,10 +22,17 @@ type RepoHandler struct { } type Repos struct { + Version string `yaml:"version"` Community string `yaml:"community"` Repositories []Repository `yaml:"repositories"` } +type Branch struct { + Name *string `yaml:"name"` + Type *string `yaml:"type"` + CreateFrom *string `yaml:"create_from"` +} + // Serve func (handler *RepoHandler) Serve() { // init sha @@ -185,9 +192,9 @@ func (handler *RepoHandler) watch() { result := true for i := 0; i < len(ps.Repositories); i++ { // get repositories length - lenRepositories, err := handler.getRepositoriesLength(ps.Community, *ps.Repositories[i].Name) - if err != nil { - glog.Errorf("failed to get repositories length: %v", err) + lenRepositories, errex := handler.getRepositoriesLength(ps.Community, *ps.Repositories[i].Name) + if errex != nil { + glog.Errorf("failed to get repositories length: %v", errex) result = false continue } @@ -382,6 +389,26 @@ func (handler *RepoHandler) addRepositoriesinGitee(owner string, repo Repository return err } glog.Infof("end to create repository: %s", *repo.Name) + + // create branch + repobranchbody := gitee.CreateBranchParam{} + repobranchbody.AccessToken = handler.Config.GiteeToken + for _, br := range repo.Branches { + if *br.Name == "master" { + continue + } + repobranchbody.BranchName = *br.Name + if *br.CreateFrom == "" { + *br.CreateFrom = "master" + } + repobranchbody.Refs = *br.CreateFrom + _, _, err := handler.GiteeClient.RepositoriesApi.PostV5ReposOwnerRepoBranches(handler.Context, owner, *repo.Name, repobranchbody) + if err != nil { + glog.Errorf("fail to add branch (%s) for repository (%s): %v", *br.Name, *repo.Name, err) + return err + } + glog.Infof("Add branch (%s) for repository (%s)", *br.Name, *repo.Name) + } return nil } @@ -390,139 +417,122 @@ func (handler *RepoHandler) addRepositoriesinGitee(owner string, repo Repository func (handler *RepoHandler) handleBranches(community string, r Repository) error { // if the branches are defined in the repositories, it means that // all the branches defined in the community will not inherited by repositories - mapBranches := make(map[string]string) - if len(r.ProtectedBranches) > 0 { + if len(r.Branches) > 0 { // using repository branches - glog.Infof("using repository branches: %s", *r.Name) - for _, b := range r.ProtectedBranches { - mapBranches[b] = b - } - } - - // get branches from DB - var bs []database.Branches - err := database.DBConnection.Model(&database.Branches{}). - Where("owner = ? and repo = ?", community, r.Name).Find(&bs).Error - if err != nil { - glog.Errorf("unable to get branches: %v", err) - return err - } - mapBranchesInDB := make(map[string]string) - for _, b := range bs { - mapBranchesInDB[b.Name] = strconv.Itoa(int(b.ID)) - } - - // un-protected branches - err = handler.removeBranchProtections(community, r, mapBranches, mapBranchesInDB) - if err != nil { - glog.Errorf("unable to un-protected branches: %v", err) - } + glog.Infof("Setting repository branches: %s", *r.Name) + for _, b := range r.Branches { + //check yaml branches is in db + var bs []database.Branches + err := database.DBConnection.Model(&database.Branches{}). + Where("owner = ? and repo = ? and name = ?", community, r.Name, b.Name).Find(&bs).Error + if err != nil || len(bs) == 0 { + glog.Infof("Do not have branches (%s), need to create. %v, ", *b.Name, err) + err = handler.addBranchGiteeAndDb(community, r, b) + if err != nil { + glog.Errorf("Add branch(%s) of repor(%s) failed: %v", *b.Name, *r.Name, err) + } + continue + } - // protected branches - err = handler.addBranchProtections(community, r, mapBranches, mapBranchesInDB) - if err != nil { - glog.Errorf("unable to protected branches: %v", err) + glog.Infof("Branch exist, branch(%s) of repo(%s).", *b.Name, *r.Name) + err = handler.changeBranchGiteeAndDb(community, r, b, bs[0]) + if err != nil { + glog.Errorf("Change branch(%s) of repor(%s) failed: %v", *b.Name, *r.Name, err) + } + continue + } } - return nil } // unprotectedBranches unprotect branches -func (handler *RepoHandler) removeBranchProtections(community string, r Repository, mapBranches, mapBranchesInDB map[string]string) error { - // remove branch protections - listOfUnprotectedBranches := make([]string, 0) - - for k := range mapBranchesInDB { - if _, exists := mapBranches[k]; !exists { - listOfUnprotectedBranches = append(listOfUnprotectedBranches, k) - } +func (handler *RepoHandler) changeBranchGiteeAndDb(community string, r Repository, br Branch, bs database.Branches) error { + // if branch features are same as ones in db, do nothing. + if *r.Name == bs.Repo && *br.Name == bs.Name && *br.Type == bs.Type { + return nil } - glog.Infof("list of un-protected branches: %v", listOfUnprotectedBranches) - if len(listOfUnprotectedBranches) > 0 { + // change branch protected freature in Gitee + var brType string + brType = BranchNormal + if *br.Type == BranchProtected { + protectBody := gitee.BranchProtectionPutParam{} + protectBody.AccessToken = handler.Config.GiteeToken + _, _, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoBranchesBranchProtection( + handler.Context, community, *r.Name, *br.Name, protectBody) + if err != nil { + glog.Errorf("failed to add branch protection: %v", err) + } + brType = BranchProtected + } else { opts := &gitee.DeleteV5ReposOwnerRepoBranchesBranchProtectionOpts{} opts.AccessToken = optional.NewString(handler.Config.GiteeToken) - - glog.Infof("begin to remove branch protections for %s", *r.Name) - for _, v := range listOfUnprotectedBranches { - // remove branch protection from gitee - _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoBranchesBranchProtection( - handler.Context, community, *r.Name, v, opts) - if err != nil { - glog.Errorf("failed to remove branch protection: %v", err) - continue - } - // remove branch protection from DB - id, _ := strconv.Atoi(mapBranchesInDB[v]) - bs := database.Branches{} - bs.ID = uint(id) - err = database.DBConnection.Delete(&bs).Error - if err != nil { - glog.Errorf("failed to remove branch protection in database: %v", err) - } + _, err := handler.GiteeClient.RepositoriesApi.DeleteV5ReposOwnerRepoBranchesBranchProtection( + handler.Context, community, *r.Name, *br.Name, opts) + if err != nil { + glog.Errorf("failed to remove branch protection: %v", err) } - glog.Infof("end to remove branch protections for %s", *r.Name) + } + + // change branch protected freature in DB + updatebranch := &database.Branches{} + updatebranch.ID = bs.ID + err := database.DBConnection.Model(updatebranch).Update("Type", brType).Error + if err != nil { + glog.Errorf("unable to update type: %v", err) } return nil } // addBranchProtections protects branches -func (handler *RepoHandler) addBranchProtections(community string, r Repository, mapBranches, mapBranchesInDB map[string]string) error { - // add branch protections - listOfProtectedBranches := make([]string, 0) - - for k := range mapBranches { - if _, exits := mapBranchesInDB[k]; !exits { - listOfProtectedBranches = append(listOfProtectedBranches, k) - } +func (handler *RepoHandler) addBranchGiteeAndDb(community string, r Repository, br Branch) error { + // create branch in gitee + repobranchbody := gitee.CreateBranchParam{} + repobranchbody.AccessToken = handler.Config.GiteeToken + if br.Name != nil { + repobranchbody.BranchName = *br.Name + } else { + return nil + } + if br.CreateFrom != nil { + repobranchbody.Refs = *br.CreateFrom + } else { + repobranchbody.Refs = "" } - glog.Infof("list of protected branches: %v", listOfProtectedBranches) - if len(listOfProtectedBranches) > 0 { - getOpts := &gitee.GetV5ReposOwnerRepoBranchesBranchOpts{} - getOpts.AccessToken = optional.NewString(handler.Config.GiteeToken) + _, _, err := handler.GiteeClient.RepositoriesApi.PostV5ReposOwnerRepoBranches(handler.Context, community, *r.Name, repobranchbody) + if err != nil { + glog.Errorf("fail to add branch (%s) for repository (%s): %v", *br.Name, *r.Name, err) + } else { + glog.Infof("Add branch (%s) for repository (%s) in gitee.", *br.Name, *r.Name) + } + // add branch protection to gitee + var brType string + brType = BranchNormal + if *br.Type == BranchProtected { protectBody := gitee.BranchProtectionPutParam{} protectBody.AccessToken = handler.Config.GiteeToken - - glog.Infof("begin to add branch protections for %s", *r.Name) - for _, v := range listOfProtectedBranches { - // check if protected branch exists - branchObj, response, _ := handler.GiteeClient.RepositoriesApi.GetV5ReposOwnerRepoBranchesBranch( - handler.Context, community, *r.Name, v, getOpts) - if response.StatusCode == 404 { - glog.Errorf("branch %s does not exist, no need for protection", v) - continue - } - - // If branch has alreay been protected, no need for protection - if branchObj.Protected == true { - glog.Errorf("branch %s has been protected already, no need for protection", v) - continue - } - - // add branch protection to gitee - _, response, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoBranchesBranchProtection( - handler.Context, community, *r.Name, v, protectBody) - if err != nil { - glog.Errorf("failed to add branch protection: %v", err) - continue - } - // add branch protection to database - bs := database.Branches{ - Owner: community, - Repo: *r.Name, - Name: v, - Type: BranchProtected, - } - err = database.DBConnection.Create(&bs).Error - if err != nil { - glog.Errorf("failed to add branch protection in database: %v", err) - } + _, _, err := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoBranchesBranchProtection( + handler.Context, community, *r.Name, *br.Name, protectBody) + if err != nil { + glog.Errorf("failed to add branch protection: %v", err) } - glog.Infof("end to add branch protections for %s", *r.Name) + brType = BranchProtected + } + // add branch to database + bs := database.Branches{ + Owner: community, + Repo: *r.Name, + Name: *br.Name, + Type: brType, + AdditionalInfo: repobranchbody.Refs, + } + err = database.DBConnection.Create(&bs).Error + if err != nil { + glog.Errorf("failed to add branch protection in database: %v", err) } return nil @@ -531,6 +541,7 @@ func (handler *RepoHandler) addBranchProtections(community string, r Repository, // handleRepositorySetting handles that the repo settings, including: // 1. type is private or public // 2. commentable is true or false +// 3. set none reviewer but not ci-bot(default) func (handler *RepoHandler) handleRepositorySetting(community string, r Repository) error { // get repos from DB var rs database.Repositories @@ -617,5 +628,20 @@ func (handler *RepoHandler) handleRepositorySetting(community string, r Reposito } } + // set none reviewer but not ci-bot(default) + + // reviewerBody := gitee.SetRepoReviewer{} + // reviewerBody.AccessToken = handler.Config.GiteeToken + // reviewerBody.Assignees = " " + // reviewerBody.Testers = " " + // reviewerBody.AssigneesNumber = 0 + // reviewerBody.TestersNumber = 0 + // response, errex := handler.GiteeClient.RepositoriesApi.PutV5ReposOwnerRepoReviewer(handler.Context, community, *r.Name, reviewerBody) + // if errex != nil { + // glog.Errorf("Set repository reviewer info failed: %v, %s", errex, response.Status) + // glog.Errorf("requestURL:%s, %s", response.Request.RequestURI, response.Request.Host) + // return errex + // } + return nil } diff --git a/pkg/cibot/server.go b/pkg/cibot/server.go index 3ec09ff53f6072c8f8ff86ebf479f42f21d2a363..d45e633bad5db60a68ef9604ee506aeb79366dee 100644 --- a/pkg/cibot/server.go +++ b/pkg/cibot/server.go @@ -28,9 +28,6 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, err.Error()) return } - // pstr := string(payload) - // glog.Infof("payload: %v", pstr) - // parse into Event messagetype := gitee.WebHookType(r) glog.Infof("message type: %v", messagetype) diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_pull_requests.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_pull_requests.go index 01845a84328dd3ab5657f7a9e4db3dd78bbd4202..30fedb81129948873ec8a3933fb9ea025f23d611 100644 --- a/vendor/gitee.com/openeuler/go-gitee/gitee/api_pull_requests.go +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_pull_requests.go @@ -1513,17 +1513,10 @@ PullRequestsApiService 编辑评论 * @param repo 仓库路径(path) * @param id 评论的ID * @param body 必填。评论内容 - * @param optional nil or *PatchV5ReposOwnerRepoPullsCommentsIdOpts - Optional Parameters: - * @param "AccessToken" (optional.String) - 用户授权码 @return PullRequestComments */ - -type PatchV5ReposOwnerRepoPullsCommentsIdOpts struct { - AccessToken optional.String -} - -func (a *PullRequestsApiService) PatchV5ReposOwnerRepoPullsCommentsId(ctx context.Context, owner string, repo string, id int32, body string, localVarOptionals *PatchV5ReposOwnerRepoPullsCommentsIdOpts) (PullRequestComments, *http.Response, error) { +func (a *PullRequestsApiService) PatchV5ReposOwnerRepoPullsCommentsId(ctx context.Context, owner string, repo string, id int32, body PullRequestCommentPatchParam) (PullRequestComments, *http.Response, error) { var ( localVarHttpMethod = strings.ToUpper("Patch") localVarPostBody interface{} @@ -1559,10 +1552,8 @@ func (a *PullRequestsApiService) PatchV5ReposOwnerRepoPullsCommentsId(ctx contex if localVarHttpHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHttpHeaderAccept } - if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() { - localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), "")) - } - localVarFormParams.Add("body", parameterToString(body, "")) + // body params + localVarPostBody = &body r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) if err != nil { return localVarReturnValue, nil, err diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/api_repositories.go b/vendor/gitee.com/openeuler/go-gitee/gitee/api_repositories.go index ccdffbb03b7b22dd75aa861fb39966a1835bab95..aaad8fcb26ccb05c3b2021e4614f01f44d59a31f 100644 --- a/vendor/gitee.com/openeuler/go-gitee/gitee/api_repositories.go +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/api_repositories.go @@ -4417,19 +4417,11 @@ RepositoriesApiService 创建分支 * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). * @param owner 仓库所属空间地址(企业、组织或个人的地址path) * @param repo 仓库路径(path) - * @param refs 起点名称, 默认:master - * @param branchName 新创建的分支名称 - * @param optional nil or *PostV5ReposOwnerRepoBranchesOpts - Optional Parameters: - * @param "AccessToken" (optional.String) - 用户授权码 + * @param body 新建分支内容 @return CompleteBranch */ - -type PostV5ReposOwnerRepoBranchesOpts struct { - AccessToken optional.String -} - -func (a *RepositoriesApiService) PostV5ReposOwnerRepoBranches(ctx context.Context, owner string, repo string, refs string, branchName string, localVarOptionals *PostV5ReposOwnerRepoBranchesOpts) (CompleteBranch, *http.Response, error) { +func (a *RepositoriesApiService) PostV5ReposOwnerRepoBranches(ctx context.Context, owner string, repo string, body CreateBranchParam) (CompleteBranch, *http.Response, error) { var ( localVarHttpMethod = strings.ToUpper("Post") localVarPostBody interface{} @@ -4464,11 +4456,8 @@ func (a *RepositoriesApiService) PostV5ReposOwnerRepoBranches(ctx context.Contex if localVarHttpHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHttpHeaderAccept } - if localVarOptionals != nil && localVarOptionals.AccessToken.IsSet() { - localVarFormParams.Add("access_token", parameterToString(localVarOptionals.AccessToken.Value(), "")) - } - localVarFormParams.Add("refs", parameterToString(refs, "")) - localVarFormParams.Add("branch_name", parameterToString(branchName, "")) + // body params + localVarPostBody = &body r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) if err != nil { return localVarReturnValue, nil, err @@ -5766,3 +5755,80 @@ func (a *RepositoriesApiService) PutV5ReposOwnerRepoKeysEnableId(ctx context.Con return localVarHttpResponse, nil } + +/* +RepositoriesApiService 修改代码审查设置 +修改代码审查设置 + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param owner 仓库所属空间地址(企业、组织或个人的地址path) + * @param repo 仓库路径(path) + * @param body 修改代码审查的信息 + + +*/ +func (a *RepositoriesApiService) PutV5ReposOwnerRepoReviewer(ctx context.Context, owner string, repo string, body SetRepoReviewer) (*http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Put") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/v5/repos/{owner}/{repo}/reviewer" + localVarPath = strings.Replace(localVarPath, "{"+"owner"+"}", fmt.Sprintf("%v", owner), -1) + localVarPath = strings.Replace(localVarPath, "{"+"repo"+"}", fmt.Sprintf("%v", repo), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json", "multipart/form-data"} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + // body params + localVarPostBody = &body + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarHttpResponse, err + } + + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + + return localVarHttpResponse, newErr + } + + return localVarHttpResponse, nil +} + diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_models.go b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_models.go index fbdba51e853c1f93cd8ee3ef88bac3c58d192282..137586f6d1c699a71427f366eb1c2161a9bbebea 100644 --- a/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_models.go +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_models.go @@ -158,6 +158,7 @@ type PullRequestHook struct { PatchUrl string `json:"patch_url,omitempty"` Title string `json:"title,omitempty"` Body string `json:"body,omitempty"` + Labels []LabelHook `json:"labels,omitempty"` CreatedAt string `json:"created_at,omitempty"` UpdatedAt string `json:"updated_at,omitempty"` ClosedAt string `json:"closed_at,omitempty"` @@ -170,13 +171,13 @@ type PullRequestHook struct { Tester []UserHook `json:"tester,omitempty"` Testers []UserHook `json:"testers,omitempty"` NeedTest bool `json:"need_test,omitempty"` - need_review bool `json:"need_review,omitempty"` + NeedReview bool `json:"need_review,omitempty"` Milestone *MilestoneHook `json:"milestone,omitempty"` Head *BranchHook `json:"head,omitempty"` Base *BranchHook `json:"base,omitempty"` Merged bool `json:"merged,omitempty"` Mergeable bool `json:"mergeable,omitempty"` - merge_status string `json:"merge_status,omitempty"` + MergeStatus string `json:"merge_status,omitempty"` UpdatedBy *UserHook `json:"updated_by,omitempty"` Comments int32 `json:"comments,omitempty"` Commits int32 `json:"commits,omitempty"` diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_types.go b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_types.go index 2a12e7fbb327278a4559e70a98028a5b91bf5e21..f6820cbb943434c2dc0279ff9c8f5ce55d600951 100644 --- a/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_types.go +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/hook_event_types.go @@ -72,6 +72,7 @@ type RepoInfo struct { type PullRequestEvent struct { Action *string `json:"action,omitempty"` + ActionDesc *string `json:"action_desc,omitempty"` PullRequest *PullRequestHook `json:"pull_request,omitempty"` Number int64 `json:"number,omitempty"` IID int64 `json:"iid,omitempty"` diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_commit_tree.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_commit_tree.go new file mode 100644 index 0000000000000000000000000000000000000000..70c0f3909fcca2e77c3db506197a0dca46c35852 --- /dev/null +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_commit_tree.go @@ -0,0 +1,15 @@ +/* + * 码云 Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 5.3.2 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package gitee + +type CommitTree struct { + Sha string `json:"sha,omitempty"` + Url string `json:"url,omitempty"` +} diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_create_branch_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_create_branch_param.go new file mode 100644 index 0000000000000000000000000000000000000000..988192c8956045a73cf519d588eb1e0f62c2b735 --- /dev/null +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_create_branch_param.go @@ -0,0 +1,19 @@ +/* + * 码云 Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 5.3.2 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package gitee + +type CreateBranchParam struct { + // 用户授权码 + AccessToken string `json:"access_token,omitempty"` + // 分支起点名称,默认master + Refs string `json:"refs,omitempty"` + // 新创建的分支名称 + BranchName string `json:"branch_name,omitempty"` +} diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_comment_patch_param.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_comment_patch_param.go new file mode 100644 index 0000000000000000000000000000000000000000..2695cb30217bdc88022734c9d02488511c6d8780 --- /dev/null +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_pull_request_comment_patch_param.go @@ -0,0 +1,18 @@ +/* + * 码云 Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 5.3.2 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package gitee + +// edit pull request comment +type PullRequestCommentPatchParam struct { + // 用户授权码 + AccessToken string `json:"access_token,omitempty"` + // 必填。评论内容 + Body string `json:"body,omitempty"` +} diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_commit.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_commit.go index c0969ea3ba6b62b49d9ee41dc87cec890fee51ae..3913a6f51d990854975aed1bd764e9d86e72ad14 100644 --- a/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_commit.go +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_repo_commit.go @@ -11,13 +11,13 @@ package gitee // 仓库的某个提交 type RepoCommit struct { - Url string `json:"url,omitempty"` - Sha string `json:"sha,omitempty"` - HtmlUrl string `json:"html_url,omitempty"` - CommentsUrl string `json:"comments_url,omitempty"` - Commit string `json:"commit,omitempty"` - Author string `json:"author,omitempty"` - Committer string `json:"committer,omitempty"` - Parents string `json:"parents,omitempty"` - Stats string `json:"stats,omitempty"` + Url string `json:"url,omitempty"` + Sha string `json:"sha,omitempty"` + HtmlUrl string `json:"html_url,omitempty"` + CommentsUrl string `json:"comments_url,omitempty"` + Commit *SingleCommit `json:"commit,omitempty"` + Author string `json:"author,omitempty"` + Committer string `json:"committer,omitempty"` + Parents string `json:"parents,omitempty"` + Stats string `json:"stats,omitempty"` } diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_set_repo_reviewer.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_set_repo_reviewer.go new file mode 100644 index 0000000000000000000000000000000000000000..a7c052b4f8d61ed226b31981dcc7443d59addacb --- /dev/null +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_set_repo_reviewer.go @@ -0,0 +1,23 @@ +/* + * 码云 Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 5.3.2 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package gitee + +type SetRepoReviewer struct { + // 用户授权码 + AccessToken string `json:"access_token,omitempty"` + // 审查人员 + Assignees string `json:"assignees,omitempty"` + // 测试人员 + Testers string `json:"testers,omitempty"` + // 最少审查人数 + AssigneesNumber int32 `json:"assignees_number,omitempty"` + // 最少测试人员 + TestersNumber int32 `json:"testers_number,omitempty"` +} diff --git a/vendor/gitee.com/openeuler/go-gitee/gitee/model_single_commit.go b/vendor/gitee.com/openeuler/go-gitee/gitee/model_single_commit.go new file mode 100644 index 0000000000000000000000000000000000000000..edc8d6de6dcac4a044c1b995cceed85a5d10e672 --- /dev/null +++ b/vendor/gitee.com/openeuler/go-gitee/gitee/model_single_commit.go @@ -0,0 +1,14 @@ +/* + * 码云 Open API + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 5.3.2 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package gitee + +type SingleCommit struct { + Tree *CommitTree `json:"tree,omitempty"` +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 99412ab49f6dca3e41144c614b33629d14944a19..62bfd298ff2971b7846974684c8a435cae206099 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# gitee.com/openeuler/go-gitee v0.0.0-20200424023021-ced5a4d67179 +# gitee.com/openeuler/go-gitee v0.0.0-20201111035308-c4384bf8d333 gitee.com/openeuler/go-gitee/gitee # github.com/antihax/optional v1.0.0 github.com/antihax/optional