Files
autogits/workflow-pr/pr_processor_opened.go
Adam Majer 9c3658b33e pr: remove pending requests
Remove all pending review requests when we merge
2025-05-13 18:34:56 +02:00

168 lines
5.3 KiB
Go

package main
import (
"fmt"
"path"
"src.opensuse.org/autogits/common"
)
type PullRequestOpened struct{}
func (o *PullRequestOpened) CreateOrUpdatePrjGitPR(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
branchName := prGitBranchNameForPR(req)
org, prj, _ := config.GetPrjGit()
prOrg := req.Pull_Request.Base.Repo.Owner.Username
prRepo := req.Pull_Request.Base.Repo.Name
if org == prOrg && prj == prRepo {
common.LogDebug("PrjGit PR. No need to update it...")
return nil
}
prjGit, err := Gitea.CreateRepositoryIfNotExist(git, org, prj)
common.PanicOnErrorWithMsg(err, "Error creating a prjgitrepo:", err)
remoteName, err := git.GitClone(common.DefaultGitPrj, config.Branch, prjGit.SSHURL)
common.PanicOnError(err)
// check if branch already there, and check that out if available
if err := git.GitExec(common.DefaultGitPrj, "fetch", remoteName, branchName); err == nil {
git.GitExecOrPanic(common.DefaultGitPrj, "checkout", "-B", branchName, remoteName+"/"+branchName)
}
commitMsg := fmt.Sprintf(`auto-created for %s
This commit was autocreated by %s
referencing
`+common.PrPattern,
prRepo,
GitAuthor,
prOrg,
prRepo,
req.Pull_Request.Number,
)
subList, err := git.GitSubmoduleList(common.DefaultGitPrj, "HEAD")
common.PanicOnError(err)
if id := subList[prRepo]; id != req.Pull_Request.Head.Sha {
updateSubmoduleInPR(req, git)
status, err := git.GitStatus(common.DefaultGitPrj)
common.LogDebug("status:", status)
common.LogDebug("submodule", prRepo, " hash:", id, " -> ", req.Pull_Request.Head.Sha)
common.PanicOnError(err)
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", commitMsg))
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", remoteName, "+HEAD:"+branchName))
}
_, err = Gitea.CreatePullRequestIfNotExist(prjGit, branchName, prjGit.DefaultBranch,
fmt.Sprintf("Forwarded PR: %s", prRepo),
fmt.Sprintf(`This is a forwarded pull request by %s
referencing the following pull request:
`+common.PrPattern,
GitAuthor, prOrg, prRepo, req.Pull_Request.Number),
)
return err
}
func (o *PullRequestOpened) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
// requests against project are not handled here
common.LogInfo("processing opened PR:", req.Pull_Request.Url)
prOrg := req.Pull_Request.Base.Repo.Owner.Username
prRepo := req.Pull_Request.Base.Repo.Name
common.LogError(req)
prjGitOrg, prjGitRepo, prjGitBranch := config.GetPrjGit()
if prOrg != prjGitOrg || prRepo != prjGitRepo {
if err := o.CreateOrUpdatePrjGitPR(req, git, config); err != nil {
return err
}
}
prset, err := common.FetchPRSet(Gitea, prOrg, prRepo, req.Number, config)
if err != nil {
common.LogError("Cannot fetch PRSet:", err)
return err
}
common.LogInfo("fetched PRSet of size:", len(prset.PRs))
// make sure that prjgit is consistent and only submodules that are to be *updated*
// reset anything that changed that is not part of the prset
// package removals/additions are *not* counted here
if pr, err := prset.GetPrjGitPR(); err == nil {
remote, err := git.GitClone(common.DefaultGitPrj, prjGitBranch, pr.Base.Repo.CloneURL)
common.PanicOnError(err)
git.GitExecOrPanic(common.DefaultGitPrj, "fetch", remote, pr.Base.Ref, pr.Head.Ref)
common.LogDebug("Fetch done")
orig_subs, err := git.GitSubmoduleList(common.DefaultGitPrj, pr.Base.Sha)
common.PanicOnError(err)
new_subs, err := git.GitSubmoduleList(common.DefaultGitPrj, pr.Head.Sha)
common.PanicOnError(err)
common.LogDebug("Submodule parse done")
reset_submodule := func(submodule, sha string) {
spath := path.Join(common.DefaultGitPrj, submodule)
git.GitExecOrPanic(common.DefaultGitPrj, "submodule", "update", "--init", "--depth", "1", submodule)
git.GitExecOrPanic(spath, "fetch", "origin", sha)
git.GitExecOrPanic(spath, "checkout", sha)
}
for path, commit := range new_subs {
if old, ok := orig_subs[path]; ok && old != commit {
found := false
for _, pr := range prset.PRs {
if pr.PR.Base.Repo.Name == path && commit == pr.PR.Head.Sha {
found = true
break
}
}
if !found {
reset_submodule(path, old)
}
}
}
stats, err := git.GitStatus(common.DefaultGitPrj)
common.PanicOnError(err)
if len(stats) > 0 {
git.GitExecOrPanic(common.DefaultGitPrj, "commit", "-a", "-m", "Sync submodule updates with PR-set")
git.GitExecOrPanic(common.DefaultGitPrj, "submodule", "deinit", "--all", "--force")
git.GitExecOrPanic(common.DefaultGitPrj, "push")
}
}
// request build review
PR, err := prset.GetPrjGitPR()
if err != nil {
common.LogError("Error fetching PrjGitPR:", err)
return nil
}
common.LogDebug(" num of reviewers:", len(PR.RequestedReviewers))
org, repo, branch := config.GetPrjGit()
maintainers, err := common.FetchProjectMaintainershipData(Gitea, org, repo, branch)
if err != nil {
return err
}
err = prset.AssignReviewers(Gitea, maintainers)
common.LogInfo("Consistent PRSet:", prset.IsConsistent())
common.LogInfo("Reviewed?", prset.IsApproved(Gitea, maintainers))
if prset.IsConsistent() && prset.IsApproved(Gitea, maintainers) {
common.LogInfo("Merging...")
if err = prset.Merge(Gitea, git); err != nil {
common.LogError("merge error:", err)
}
}
return err
}