From 5027e98c04f84d49b71e989d71e6082c0b02a07e75adfe6197dd90196180bb52 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Mon, 30 Sep 2024 15:09:45 +0200 Subject: [PATCH] pr: processing checks --- bots-common/gitea_utils.go | 35 ++++++++++++++++++++++++++++++++ bots-common/request_pr.go | 39 ++++++++++++++++++++++++++++++++++++ bots-common/request_repo.go | 40 +++++++++++++++++++++++++++++++++++++ workflow-pr/main.go | 39 ++++++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+) diff --git a/bots-common/gitea_utils.go b/bots-common/gitea_utils.go index e4c937f..0005c69 100644 --- a/bots-common/gitea_utils.go +++ b/bots-common/gitea_utils.go @@ -469,6 +469,41 @@ func (gitea *GiteaTransport) GetPullRequestFileContent(pr *models.PullRequest, p return gitea.GetRepositoryFileContent(pr.Head.Repo, pr.Head.Sha, path) } +func (gitea *GiteaTransport) GetRecentPullRequests(org, repo string) ([]*models.PullRequest, error) { + prs := make([]*models.PullRequest, 0, 10) + var page int64 + page = 1 + sort := "recentupdate" + + for { + res, err := gitea.client.Repository.RepoListPullRequests( + repository.NewRepoListPullRequestsParams(). + WithOwner(org). + WithRepo(repo). + WithPage(&page). + WithSort(&sort), + gitea.transport.DefaultAuthentication) + if err != nil { + return nil, err + } + + prs = append(prs, res.Payload...) + n := len(res.Payload) + if n < 10 { + break + } + + // if pr is closed for more than a week, assume that we are done too + if time.Since(time.Time(res.Payload[n-1].Updated)) > 7 * 24 * time.Hour { + break + } + + page++ + } + + return prs, nil +} + func (gitea *GiteaTransport) GetRecentCommits(org, repo, branch string, commitNo int64) ([]*models.Commit, error) { not := false var page int64 diff --git a/bots-common/request_pr.go b/bots-common/request_pr.go index 55b3a6e..884d1f0 100644 --- a/bots-common/request_pr.go +++ b/bots-common/request_pr.go @@ -22,6 +22,8 @@ import ( "encoding/json" "fmt" "io" + + "src.opensuse.org/autogits/common/gitea-generated/models" ) type Head struct { @@ -68,6 +70,43 @@ func (p *PullRequestWebhookEvent) GetAction() string { return p.Action } +func PullRequestLabelFromModel(labels []*models.Label) []IssueLabelDetail { + l := make([]IssueLabelDetail, len(labels)) + for i := range labels { + l[i].Id = int(labels[i].ID) + l[i].Name = labels[i].Name + l[i].Exclusive = labels[i].Exclusive + l[i].Is_archived = labels[i].IsArchived + l[i].Color = labels[i].Color + l[i].Description = labels[i].Description + l[i].Url = labels[i].URL + } + + return l +} + +func PullRequestFromModel(pr *models.PullRequest) *PullRequest { + return &PullRequest{ + Id: int(pr.ID), + Url: pr.URL, + Number: int(pr.Index), + State: string(pr.State), + + Base: Head{ + Ref: pr.Base.Ref, + Sha: pr.Base.Sha, + Repo: RepositoryFromModel(pr.Base.Repo), + }, + Head: Head{ + Ref: pr.Head.Ref, + Sha: pr.Head.Sha, + Repo: RepositoryFromModel(pr.Head.Repo), + }, + Labels: PullRequestLabelFromModel(pr.Labels), + User: *UserFromModel(pr.User), + } +} + func (h *RequestHandler) parsePullRequest(data io.Reader) (action *PullRequestWebhookEvent, err error) { action = new(PullRequestWebhookEvent) err = json.NewDecoder(data).Decode(&action) diff --git a/bots-common/request_repo.go b/bots-common/request_repo.go index b637ed6..f697abc 100644 --- a/bots-common/request_repo.go +++ b/bots-common/request_repo.go @@ -23,6 +23,8 @@ import ( "fmt" "io" "strings" + + "src.opensuse.org/autogits/common/gitea-generated/models" ) type Repository struct { @@ -59,6 +61,44 @@ type RepositoryWebhookEvent struct { PrjGit string } +func UserFromModel(user *models.User) *User { + return &User { + Id: int(user.ID), + Username: user.UserName, + } +} + +func UsersFromModel(users []*models.User) []*User { + u := make([]*User, len(users)) + for i := range users { + u[i] = UserFromModel(users[i]) + } + return u +} + +func RepositoryFromModel(repo *models.Repository) *Repository { + if repo == nil { + return nil + } + + return &Repository{ + Id: uint(repo.ID), + Name: repo.Name, + Full_Name: repo.FullName, + Fork: repo.Fork, + Parent: RepositoryFromModel(repo.Parent), + Owner: &Organization{ + Id: uint(repo.Owner.ID), + Username: repo.Owner.UserName, + }, + Clone_Url: repo.CloneURL, + + Ssh_Url: repo.SSHURL, + Default_Branch: repo.DefaultBranch, + Object_Format_Name: repo.ObjectFormatName, + } +} + func (r *RepositoryWebhookEvent) GetAction() string { return r.Action } diff --git a/workflow-pr/main.go b/workflow-pr/main.go index af71c18..d7c690c 100644 --- a/workflow-pr/main.go +++ b/workflow-pr/main.go @@ -253,6 +253,45 @@ nextSubmodule: if n := strings.LastIndex(sub, "/"); n != -1 { submoduleName = sub[n+1:] } + + // check if open PR have PR against project + prs, err := gitea.GetRecentPullRequests(config.Organization, submoduleName) + if err != nil { + return fmt.Errorf("Error fetching pull requests for %s/%s. Err: %w", config.Organization, submoduleName, err) + } + + if DebugMode { + log.Println(" - # of PRs to check:" , len(prs)) + } + + for _, pr := range prs { + var event common.PullRequestWebhookEvent + + event.Pull_Request = common.PullRequestFromModel(pr) + event.Action = string(pr.State) + event.Number = int(pr.Index) + event.Repository = common.RepositoryFromModel(pr.Base.Repo) + event.Sender = *common.UserFromModel(pr.User) + event.Requested_reviewer = nil + git, err := common.CreateGitHandler(GitAuthor, GitEmail, AppName) + if err != nil { + return fmt.Errorf("Error allocating GitHandler. Err: %w", err) + } + if !DebugMode { + defer git.Close() + } + + switch pr.State { + case "open": + processPullRequestOpened(&event, git, config) + case "closed": + processPullRequestClosed(&event, git, config) + default: + return fmt.Errorf("Unhandled pull request state: '%s'. %s/%s/%d", pr.State, config.Organization, submoduleName, pr.Index) + } + } + + // check if the commited changes are syned with branches commits, err := gitea.GetRecentCommits(config.Organization, submoduleName, config.Branch, 10) if err != nil { return fmt.Errorf("Error fetching recent commits for %s/%s. Err: %w", config.Organization, submoduleName, err)