wip
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
all: build
|
all: build
|
||||||
|
|
||||||
api.json:
|
api.json::
|
||||||
curl -o api.json https://src.opensuse.org/swagger.v1.json
|
curl -o api.json https://src.opensuse.org/swagger.v1.json
|
||||||
|
|
||||||
gitea-generated/client/gitea_api_client.go:: api.json
|
gitea-generated/client/gitea_api_client.go:: api.json
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ type AutogitConfig struct {
|
|||||||
Branch string // branch name of PkgGit that aligns with PrjGit submodules
|
Branch string // branch name of PkgGit that aligns with PrjGit submodules
|
||||||
Reviewers []string // only used by `pr` workflow
|
Reviewers []string // only used by `pr` workflow
|
||||||
ReviewGroups []ReviewGroup
|
ReviewGroups []ReviewGroup
|
||||||
|
Committers []string // group in addition to Reviewers and Maintainers that can order the bot around, mostly as helper for factory-maintainers
|
||||||
}
|
}
|
||||||
|
|
||||||
type AutogitConfigs []*AutogitConfig
|
type AutogitConfigs []*AutogitConfig
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ func (data *MaintainershipMap) IsApproved(pkg string, reviews []*models.PullRevi
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogDebug("Looking for review by:", reviewers)
|
||||||
for _, review := range reviews {
|
for _, review := range reviews {
|
||||||
if slices.Contains(reviewers, submitter) {
|
if slices.Contains(reviewers, submitter) {
|
||||||
LogDebug("Submitter is maintainer. Approving.")
|
LogDebug("Submitter is maintainer. Approving.")
|
||||||
|
|||||||
22
common/pr.go
22
common/pr.go
@@ -21,6 +21,8 @@ type PRInfo struct {
|
|||||||
type PRSet struct {
|
type PRSet struct {
|
||||||
PRs []*PRInfo
|
PRs []*PRInfo
|
||||||
Config *AutogitConfig
|
Config *AutogitConfig
|
||||||
|
|
||||||
|
BotUser string
|
||||||
}
|
}
|
||||||
|
|
||||||
func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []*PRInfo, config *AutogitConfig) ([]*PRInfo, error) {
|
func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []*PRInfo, config *AutogitConfig) ([]*PRInfo, error) {
|
||||||
@@ -51,7 +53,7 @@ func readPRData(gitea GiteaPRFetcher, pr *models.PullRequest, currentSet []*PRIn
|
|||||||
return retSet, nil
|
return retSet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchPRSet(gitea GiteaPRFetcher, org, repo string, num int64, config *AutogitConfig) (*PRSet, error) {
|
func FetchPRSet(user string, gitea GiteaPRFetcher, org, repo string, num int64, config *AutogitConfig) (*PRSet, error) {
|
||||||
var pr *models.PullRequest
|
var pr *models.PullRequest
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -77,7 +79,11 @@ func FetchPRSet(gitea GiteaPRFetcher, org, repo string, num int64, config *Autog
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PRSet{PRs: prs, Config: config}, nil
|
return &PRSet{
|
||||||
|
PRs: prs,
|
||||||
|
Config: config,
|
||||||
|
BotUser: user,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rs *PRSet) IsPrjGitPR(pr *models.PullRequest) bool {
|
func (rs *PRSet) IsPrjGitPR(pr *models.PullRequest) bool {
|
||||||
@@ -146,6 +152,9 @@ func (rs *PRSet) AssignReviewers(gitea GiteaReviewFetcherAndRequester, maintaine
|
|||||||
reviewers = slices.Concat(configReviewers.Pkg, maintainers.ListProjectMaintainers(), maintainers.ListPackageMaintainers(pkg))
|
reviewers = slices.Concat(configReviewers.Pkg, maintainers.ListProjectMaintainers(), maintainers.ListPackageMaintainers(pkg))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
slices.Sort(reviewers)
|
||||||
|
reviewers = slices.Compact(reviewers)
|
||||||
|
|
||||||
// submitters do not need to review their own work
|
// submitters do not need to review their own work
|
||||||
if idx := slices.Index(reviewers, pr.PR.User.UserName); idx != -1 {
|
if idx := slices.Index(reviewers, pr.PR.User.UserName); idx != -1 {
|
||||||
reviewers = slices.Delete(reviewers, idx, idx+1)
|
reviewers = slices.Delete(reviewers, idx, idx+1)
|
||||||
@@ -191,6 +200,11 @@ func (rs *PRSet) IsApproved(gitea GiteaPRChecker, maintainers MaintainershipData
|
|||||||
pkg = pr.PR.Base.Repo.Name
|
pkg = pr.PR.Base.Repo.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(pr.PR.Title, "WIP:") {
|
||||||
|
LogInfo("WIP PR. Ignoring")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
r, err := FetchGiteaReviews(gitea, reviewers, pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index)
|
r, err := FetchGiteaReviews(gitea, reviewers, pr.PR.Base.Repo.Owner.UserName, pr.PR.Base.Repo.Name, pr.PR.Index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LogError("Cannot fetch gita reaviews for PR:", err)
|
LogError("Cannot fetch gita reaviews for PR:", err)
|
||||||
@@ -202,10 +216,14 @@ func (rs *PRSet) IsApproved(gitea GiteaPRChecker, maintainers MaintainershipData
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if need_maintainer_review := !rs.IsPrjGitPR(pr.PR) || pr.PR.User.UserName != rs.BotUser; need_maintainer_review {
|
||||||
if is_reviewed = maintainers.IsApproved(pkg, r.reviews, pr.PR.User.UserName); !is_reviewed {
|
if is_reviewed = maintainers.IsApproved(pkg, r.reviews, pr.PR.User.UserName); !is_reviewed {
|
||||||
LogDebug(" not approved?", pkg)
|
LogDebug(" not approved?", pkg)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
LogDebug("PrjGit PR -- bot created, no need for review")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return is_reviewed
|
return is_reviewed
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,4 +50,3 @@ func FetchTimelineSinceReviewRequestOrPush(gitea GiteaTimelineFetcher, groupName
|
|||||||
return timeline, nil
|
return timeline, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
|
|||||||
slices.SortFunc(project.Result, BuildResultSorter)
|
slices.SortFunc(project.Result, BuildResultSorter)
|
||||||
if refProject == nil {
|
if refProject == nil {
|
||||||
// just return if buid finished and have some successes, since new package
|
// just return if buid finished and have some successes, since new package
|
||||||
|
common.LogInfo("New package. Only need some success...")
|
||||||
SomeSuccess := false
|
SomeSuccess := false
|
||||||
for i := 0; i < len(project.Result); i++ {
|
for i := 0; i < len(project.Result); i++ {
|
||||||
repoRes := &project.Result[i]
|
repoRes := &project.Result[i]
|
||||||
@@ -167,6 +168,7 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
|
|||||||
slices.SortFunc(refProject.Result, BuildResultSorter)
|
slices.SortFunc(refProject.Result, BuildResultSorter)
|
||||||
|
|
||||||
common.LogDebug("comparing results", len(project.Result), "vs. ref", len(refProject.Result))
|
common.LogDebug("comparing results", len(project.Result), "vs. ref", len(refProject.Result))
|
||||||
|
SomeSuccess := false
|
||||||
for i := 0; i < len(project.Result); i++ {
|
for i := 0; i < len(project.Result); i++ {
|
||||||
common.LogDebug("searching for", project.Result[i].Repository, "/", project.Result[i].Arch)
|
common.LogDebug("searching for", project.Result[i].Repository, "/", project.Result[i].Arch)
|
||||||
j := 0
|
j := 0
|
||||||
@@ -178,9 +180,10 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
|
|||||||
}
|
}
|
||||||
|
|
||||||
common.LogDebug(" found match for @ idx:", j)
|
common.LogDebug(" found match for @ idx:", j)
|
||||||
res := ProcessRepoBuildStatus(project.Result[i].Status, refProject.Result[j].Status)
|
res, success := ProcessRepoBuildStatus(project.Result[i].Status, refProject.Result[j].Status)
|
||||||
switch res {
|
switch res {
|
||||||
case BuildStatusSummarySuccess:
|
case BuildStatusSummarySuccess:
|
||||||
|
SomeSuccess = SomeSuccess || success
|
||||||
break found
|
break found
|
||||||
default:
|
default:
|
||||||
return res
|
return res
|
||||||
@@ -194,28 +197,42 @@ func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatus
|
|||||||
return BuildStatusSummaryUnknown
|
return BuildStatusSummaryUnknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if SomeSuccess {
|
||||||
return BuildStatusSummarySuccess
|
return BuildStatusSummarySuccess
|
||||||
|
}
|
||||||
|
|
||||||
|
return BuildStatusSummaryFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) BuildStatusSummary {
|
func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) (status BuildStatusSummary, SomeSuccess bool) {
|
||||||
PackageBuildStatusSorter := func(a, b common.PackageBuildStatus) int {
|
PackageBuildStatusSorter := func(a, b common.PackageBuildStatus) int {
|
||||||
return strings.Compare(a.Package, b.Package)
|
return strings.Compare(a.Package, b.Package)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
common.LogDebug("******** REF: ")
|
||||||
|
data, _ := xml.MarshalIndent(ref, "", " ")
|
||||||
|
common.LogDebug(string(data))
|
||||||
|
common.LogDebug("******* RESULTS: ")
|
||||||
|
data, _ = xml.MarshalIndent(results, "", " ")
|
||||||
|
common.LogDebug(string(data))
|
||||||
|
common.LogDebug("*******")
|
||||||
|
|
||||||
// compare build result
|
// compare build result
|
||||||
slices.SortFunc(results, PackageBuildStatusSorter)
|
slices.SortFunc(results, PackageBuildStatusSorter)
|
||||||
slices.SortFunc(ref, PackageBuildStatusSorter)
|
slices.SortFunc(ref, PackageBuildStatusSorter)
|
||||||
|
|
||||||
j := 0
|
j := 0
|
||||||
|
SomeSuccess = false
|
||||||
for i := 0; i < len(results); i++ {
|
for i := 0; i < len(results); i++ {
|
||||||
res, ok := common.ObsBuildStatusDetails[results[i].Code]
|
res, ok := common.ObsBuildStatusDetails[results[i].Code]
|
||||||
if !ok {
|
if !ok {
|
||||||
common.LogInfo("unknown package result code:", results[i].Code, "for package:", results[i].Package)
|
common.LogInfo("unknown package result code:", results[i].Code, "for package:", results[i].Package)
|
||||||
return BuildStatusSummaryUnknown
|
return BuildStatusSummaryUnknown, SomeSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
if !res.Finished {
|
if !res.Finished {
|
||||||
return BuildStatusSummaryBuilding
|
return BuildStatusSummaryBuilding, SomeSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
if !res.Success {
|
if !res.Success {
|
||||||
@@ -227,7 +244,7 @@ func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) BuildStatu
|
|||||||
refRes, ok := common.ObsBuildStatusDetails[ref[j].Code]
|
refRes, ok := common.ObsBuildStatusDetails[ref[j].Code]
|
||||||
if !ok {
|
if !ok {
|
||||||
common.LogInfo("unknown ref package result code:", ref[j].Code, "package:", ref[j].Package)
|
common.LogInfo("unknown ref package result code:", ref[j].Code, "package:", ref[j].Package)
|
||||||
return BuildStatusSummaryUnknown
|
return BuildStatusSummaryUnknown, SomeSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
if !refRes.Finished {
|
if !refRes.Finished {
|
||||||
@@ -235,13 +252,15 @@ func ProcessRepoBuildStatus(results, ref []common.PackageBuildStatus) BuildStatu
|
|||||||
}
|
}
|
||||||
|
|
||||||
if refRes.Success {
|
if refRes.Success {
|
||||||
return BuildStatusSummaryFailed
|
return BuildStatusSummaryFailed, SomeSuccess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
SomeSuccess = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return BuildStatusSummarySuccess
|
return BuildStatusSummarySuccess, SomeSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullRequest, stagingPrj, buildPrj string) (*common.ProjectMeta, error) {
|
func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullRequest, stagingPrj, buildPrj string) (*common.ProjectMeta, error) {
|
||||||
|
|||||||
@@ -111,3 +111,6 @@ func TestPRtoObsProjectMapping(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestStatusCodeResults(t *testing.T) {
|
||||||
|
}
|
||||||
|
|||||||
@@ -130,11 +130,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
common.LogInfo("Running with token from", CurrentUser.UserName)
|
common.LogInfo("Running with token from", CurrentUser.UserName)
|
||||||
|
|
||||||
req.Synced = &PullRequestSynced{}
|
|
||||||
req.Opened = &PullRequestOpened{}
|
|
||||||
req.Closed = &PullRequestClosed{}
|
|
||||||
req.Review = &PullRequestReviewed{}
|
|
||||||
|
|
||||||
if *pr != "" {
|
if *pr != "" {
|
||||||
rx := regexp.MustCompile("^([a-zA-Z0-9_\\.-]+)/([a-zA-Z0-9_\\.-]+)#([0-9]+)$")
|
rx := regexp.MustCompile("^([a-zA-Z0-9_\\.-]+)/([a-zA-Z0-9_\\.-]+)#([0-9]+)$")
|
||||||
if data := rx.FindStringSubmatch(*pr); data == nil {
|
if data := rx.FindStringSubmatch(*pr); data == nil {
|
||||||
@@ -151,32 +146,12 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if pr.State != "open" {
|
|
||||||
common.LogError("Can only deal with open PRs. This one is", pr.State)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c := configs.GetPrjGitConfig(org, repo, pr.Base.Ref)
|
|
||||||
if c == nil {
|
|
||||||
if pr.Base.Repo.DefaultBranch == pr.Base.Ref {
|
|
||||||
c = configs.GetPrjGitConfig(org, repo, "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if c == nil {
|
|
||||||
common.LogError("Cannot find config for PR.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
git, err := GitHandler.CreateGitHandler(org)
|
|
||||||
common.PanicOnError(err)
|
|
||||||
defer git.Close()
|
|
||||||
|
|
||||||
p := common.PullRequestWebhookEvent{
|
p := common.PullRequestWebhookEvent{
|
||||||
Action: "opened",
|
Action: "opened",
|
||||||
Number: num,
|
Number: num,
|
||||||
Pull_Request: common.PullRequestFromModel(pr),
|
Pull_Request: common.PullRequestFromModel(pr),
|
||||||
}
|
}
|
||||||
if err = req.Opened.Process(&p, git, c); err != nil {
|
if err = ProcesPullRequest(&p, configs); err != nil {
|
||||||
common.LogError("processor returned error", err)
|
common.LogError("processor returned error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,36 +4,51 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/opentracing/opentracing-go/log"
|
||||||
"src.opensuse.org/autogits/common"
|
"src.opensuse.org/autogits/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PullRequestProcessor interface {
|
func prGitBranchNameForPR(req *common.PullRequestWebhookEvent) string {
|
||||||
Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error
|
return fmt.Sprintf("PR_%s#%d", req.Pull_Request.Base.Repo.Name, req.Pull_Request.Number)
|
||||||
}
|
}
|
||||||
|
|
||||||
type RequestProcessor struct {
|
func updateSubmoduleInPR(req *common.PullRequestWebhookEvent, git common.Git) {
|
||||||
Opened, Synced, Closed, Review PullRequestProcessor
|
common.LogDebug(req, git)
|
||||||
|
submoduleName := req.Pull_Request.Base.Repo.Name
|
||||||
configuredRepos map[string][]*common.AutogitConfig
|
commitID := req.Pull_Request.Head.Sha
|
||||||
|
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "submodule", "update", "--init", "--checkout", "--depth", "1", submoduleName))
|
||||||
|
common.PanicOnError(git.GitExec(path.Join(common.DefaultGitPrj, submoduleName), "fetch", "--depth", "1", "origin", commitID))
|
||||||
|
common.PanicOnError(git.GitExec(path.Join(common.DefaultGitPrj, submoduleName), "checkout", commitID))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *RequestProcessor) ProcessFunc(request *common.Request) error {
|
type PRProcessor struct {
|
||||||
req, ok := request.Data.(*common.PullRequestWebhookEvent)
|
config *common.AutogitConfig
|
||||||
if !ok {
|
git common.Git
|
||||||
return fmt.Errorf("*** Invalid data format for PR processing.")
|
}
|
||||||
}
|
|
||||||
|
|
||||||
configs := w.configuredRepos[req.Repository.Owner.Username]
|
|
||||||
if len(configs) < 1 {
|
|
||||||
// ignoring pull request against unconfigured project (could be just regular sources?)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
func AllocatePRProcessor(req *common.PullRequestWebhookEvent, configs common.AutogitConfigs) (*PRProcessor, error) {
|
||||||
org := req.Pull_Request.Base.Repo.Owner.Username
|
org := req.Pull_Request.Base.Repo.Owner.Username
|
||||||
pkg := req.Pull_Request.Base.Repo.Name
|
repo := req.Pull_Request.Base.Repo.Name
|
||||||
|
id := req.Pull_Request.Number
|
||||||
|
|
||||||
branch := req.Pull_Request.Base.Ref
|
branch := req.Pull_Request.Base.Ref
|
||||||
assumed_git_project_name := org + "/" + pkg + "#" + branch
|
assumed_git_project_name := org + "/" + repo + "#" + branch
|
||||||
|
|
||||||
|
PRstr := fmt.Sprintf("%s/%s#%d", org, repo, id)
|
||||||
|
common.LogInfo("*** Starting processing PR:", PRstr)
|
||||||
|
|
||||||
|
c := configs.GetPrjGitConfig(org, repo, branch)
|
||||||
|
if c == nil {
|
||||||
|
if req.Pull_Request.Base.Repo.Default_Branch == branch {
|
||||||
|
c = configs.GetPrjGitConfig(org, repo, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c == nil {
|
||||||
|
common.LogError("Cannot find config for PR.")
|
||||||
|
return nil, fmt.Errorf("Cannot find config for PR")
|
||||||
|
}
|
||||||
|
|
||||||
var config *common.AutogitConfig
|
var config *common.AutogitConfig
|
||||||
for _, c := range configs {
|
for _, c := range configs {
|
||||||
@@ -51,30 +66,231 @@ func (w *RequestProcessor) ProcessFunc(request *common.Request) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
common.LogDebug("found config", config)
|
||||||
if config == nil {
|
if config == nil {
|
||||||
return fmt.Errorf("Cannot find config for branch '%s'", req.Pull_Request.Base.Ref)
|
common.LogError("Cannot find config for branch '%s'", req.Pull_Request.Base.Ref)
|
||||||
|
return nil, fmt.Errorf("Cannot find config for branch '%s'", req.Pull_Request.Base.Ref)
|
||||||
}
|
}
|
||||||
|
|
||||||
git, err := GitHandler.CreateGitHandler(config.Organization)
|
git, err := GitHandler.CreateGitHandler(branch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error allocating GitHandler. Err: %w", err)
|
common.LogError("Cannot allocate GitHandler:", err)
|
||||||
|
return nil, fmt.Errorf("Error allocating GitHandler. Err: %w", err)
|
||||||
}
|
}
|
||||||
common.LogDebug("git path:", git.GetPath())
|
common.LogDebug("git path:", git.GetPath())
|
||||||
defer git.Close()
|
|
||||||
|
|
||||||
switch req.Action {
|
return &PRProcessor{
|
||||||
case "opened", "reopened":
|
config: config,
|
||||||
return w.Opened.Process(req, git, config)
|
git: git,
|
||||||
case "synchronized":
|
}, nil
|
||||||
return w.Synced.Process(req, git, config)
|
}
|
||||||
case "edited":
|
|
||||||
// not need to be handled??
|
func (pr *PRProcessor) CreateOrUpdatePrjGitPR(req *common.PullRequestWebhookEvent) error {
|
||||||
|
config := pr.config
|
||||||
|
git := pr.git
|
||||||
|
|
||||||
|
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
|
return nil
|
||||||
case "closed":
|
|
||||||
return w.Closed.Process(req, git, config)
|
|
||||||
case "reviewed":
|
|
||||||
return w.Review.Process(req, git, config)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("Unhandled pull request action: %s", req.Action)
|
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 (pr *PRProcessor) Process(req *common.PullRequestWebhookEvent) error {
|
||||||
|
config := pr.config
|
||||||
|
git := pr.git
|
||||||
|
|
||||||
|
// 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 := pr.CreateOrUpdatePrjGitPR(req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
prset, err := common.FetchPRSet(CurrentUser.UserName, 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
|
||||||
|
}
|
||||||
|
|
||||||
|
type PullRequestProcessor interface {
|
||||||
|
Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type RequestProcessor struct {
|
||||||
|
configuredRepos map[string][]*common.AutogitConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProcesPullRequest(req *common.PullRequestWebhookEvent, configs []*common.AutogitConfig) error {
|
||||||
|
if len(configs) < 1 {
|
||||||
|
// ignoring pull request against unconfigured project (could be just regular sources?)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Pull_Request.State != "open" {
|
||||||
|
common.LogError("Can only deal with open PRs. This one is", req.Pull_Request.State)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pr, err := AllocatePRProcessor(req, configs)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer pr.git.Close()
|
||||||
|
|
||||||
|
switch req.Action {
|
||||||
|
case "opened", "reopened", "synchronized", "edited", "closed", "reviewed":
|
||||||
|
return pr.Process(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
common.LogError("Unhandled pull request action:", req.Action)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *RequestProcessor) ProcessFunc(request *common.Request) error {
|
||||||
|
req, ok := request.Data.(*common.PullRequestWebhookEvent)
|
||||||
|
if !ok {
|
||||||
|
common.LogError("*** Invalid data format for PR processing.")
|
||||||
|
return fmt.Errorf("*** Invalid data format for PR processing.")
|
||||||
|
}
|
||||||
|
|
||||||
|
org := req.Repository.Owner.Username
|
||||||
|
configs := w.configuredRepos[org]
|
||||||
|
return ProcesPullRequest(req, configs)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"src.opensuse.org/autogits/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PullRequestClosed struct{}
|
|
||||||
|
|
||||||
func (*PullRequestClosed) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
|
|
||||||
_, gitPrjRepo, _ := config.GetPrjGit()
|
|
||||||
if req.Pull_Request.Base.Repo.Name != gitPrjRepo {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
common.LogInfo(req.Pull_Request.Url, "is", req.Pull_Request.State)
|
|
||||||
return nil
|
|
||||||
/*
|
|
||||||
req := h.Data.(*common.PullRequestAction)
|
|
||||||
|
|
||||||
if req.Repository.Name != common.DefaultGitPrj {
|
|
||||||
// we only handle project git PR updates here
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := fetchPrGit(h, req.Pull_Request); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
headSubmodules := h.GitSubmoduleList(dir, pr.Head.Sha)
|
|
||||||
baseSubmodules := h.GitSubmoduleList(dir, pr.Base.Sha)
|
|
||||||
return nil
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import "src.opensuse.org/autogits/common"
|
|
||||||
|
|
||||||
type PullRequestReviewed struct{}
|
|
||||||
|
|
||||||
func (o *PullRequestReviewed) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
|
|
||||||
/*
|
|
||||||
prset, err := common.FetchPRSet(Gitea, req.Repository.Owner.Username, req.Repository.Name, req.Number, config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
maintainers, err := common.FetchProjectMaintainershipData(Gitea, prset.Config.Organization, prset.Config.GitProjectName, prset.Config.Branch)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if prset.IsApproved(Gitea, maintainers) {
|
|
||||||
return prset.Merge(git)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"src.opensuse.org/autogits/common"
|
|
||||||
)
|
|
||||||
|
|
||||||
func prGitBranchNameForPR(req *common.PullRequestWebhookEvent) string {
|
|
||||||
return fmt.Sprintf("PR_%s#%d", req.Pull_Request.Base.Repo.Name, req.Pull_Request.Number)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateSubmoduleInPR(req *common.PullRequestWebhookEvent, git common.Git) {
|
|
||||||
common.LogDebug(req, git)
|
|
||||||
submoduleName := req.Pull_Request.Base.Repo.Name
|
|
||||||
commitID := req.Pull_Request.Head.Sha
|
|
||||||
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "submodule", "update", "--init", "--checkout", "--depth", "1", submoduleName))
|
|
||||||
common.PanicOnError(git.GitExec(path.Join(common.DefaultGitPrj, submoduleName), "fetch", "--depth", "1", "origin", commitID))
|
|
||||||
common.PanicOnError(git.GitExec(path.Join(common.DefaultGitPrj, submoduleName), "checkout", commitID))
|
|
||||||
}
|
|
||||||
|
|
||||||
func processPrjGitPullRequestSync(req *common.PullRequestWebhookEvent) error {
|
|
||||||
// req := h.Data.(*common.PullRequestAction)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type PullRequestSynced struct{}
|
|
||||||
|
|
||||||
func (o *PullRequestSynced) Process(req *common.PullRequestWebhookEvent, git common.Git, config *common.AutogitConfig) error {
|
|
||||||
prjGitOrg, prjGitRepo, _ := config.GetPrjGit()
|
|
||||||
if req.Repository.Owner.Username == prjGitOrg && req.Repository.Name == prjGitRepo {
|
|
||||||
return processPrjGitPullRequestSync(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// need to verify that submodule in the PR for prjgit
|
|
||||||
// is still pointing to the HEAD of the PR
|
|
||||||
pr, err := Gitea.GetPullRequest(req.Repository.Owner.Username, req.Repository.Name, req.Number)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Cannot fetch PR data from gitea: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, prs := common.ExtractDescriptionAndPRs(bufio.NewScanner(strings.NewReader(pr.Body)))
|
|
||||||
if len(prs) != 1 {
|
|
||||||
return fmt.Errorf("Package update associated with invalid number of projects. Expected 1. Got %d", len(prs))
|
|
||||||
}
|
|
||||||
|
|
||||||
prjPr, err := Gitea.GetPullRequest(prs[0].Org, prs[0].Repo, prs[0].Num)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Cannot get PrjGit PR in processPullRequestSync. Err: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
branchName := prGitBranchNameForPR(req)
|
|
||||||
remote, err := git.GitClone(common.DefaultGitPrj, branchName, prjPr.Head.Repo.SSHURL)
|
|
||||||
common.PanicOnError(err)
|
|
||||||
commitId, ok := git.GitSubmoduleCommitId(common.DefaultGitPrj, req.Repository.Name, prjPr.Head.Sha)
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("Cannot fetch submodule commit id in prjgit for '%s'", req.Repository.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// nothing changed, still in sync
|
|
||||||
if commitId == req.Pull_Request.Head.Sha {
|
|
||||||
common.LogDebug("commitID already match - nothing to do")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
common.LogDebug("Sync repo update. Old", commitId, " New", req.Pull_Request.Head.Sha)
|
|
||||||
|
|
||||||
commitMsg := fmt.Sprintf(`Sync PR
|
|
||||||
|
|
||||||
Update to %s`, req.Pull_Request.Head.Sha)
|
|
||||||
|
|
||||||
common.LogDebug("Creating new commit msg:", commitMsg)
|
|
||||||
|
|
||||||
// we need to update prjgit PR with the new head hash
|
|
||||||
updateSubmoduleInPR(req, git)
|
|
||||||
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "commit", "-a", "-m", commitMsg))
|
|
||||||
common.PanicOnError(git.GitExec(common.DefaultGitPrj, "push", remote))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -44,26 +44,13 @@ func (s *DefaultStateChecker) ProcessPR(git common.Git, pr *models.PullRequest,
|
|||||||
var event common.PullRequestWebhookEvent
|
var event common.PullRequestWebhookEvent
|
||||||
|
|
||||||
event.Pull_Request = common.PullRequestFromModel(pr)
|
event.Pull_Request = common.PullRequestFromModel(pr)
|
||||||
event.Action = string(pr.State)
|
event.Action = string(pr.State) + "ed"
|
||||||
event.Number = pr.Index
|
event.Number = pr.Index
|
||||||
event.Repository = common.RepositoryFromModel(pr.Base.Repo)
|
event.Repository = common.RepositoryFromModel(pr.Base.Repo)
|
||||||
event.Sender = *common.UserFromModel(pr.User)
|
event.Sender = *common.UserFromModel(pr.User)
|
||||||
event.Requested_reviewer = nil
|
event.Requested_reviewer = nil
|
||||||
|
|
||||||
var err error
|
return ProcesPullRequest(&event, common.AutogitConfigs{config})
|
||||||
switch pr.State {
|
|
||||||
case "open":
|
|
||||||
err = s.processor.Opened.Process(&event, git, config)
|
|
||||||
case "closed":
|
|
||||||
err = s.processor.Closed.Process(&event, git, config)
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("Unhandled pull request state: '%s'. %s/%s/%d", pr.State, config.Organization, "", pr.Index)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
common.LogError(" * processor error returned:", err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *DefaultStateChecker) VerifyProjectState(config *common.AutogitConfig) error {
|
func (s *DefaultStateChecker) VerifyProjectState(config *common.AutogitConfig) error {
|
||||||
@@ -122,6 +109,7 @@ nextSubmodule:
|
|||||||
common.LogError("Cannot fetch repository:", config.Organization, "/", submoduleName, "... submodule skipped.")
|
common.LogError("Cannot fetch repository:", config.Organization, "/", submoduleName, "... submodule skipped.")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
branch = repo.DefaultBranch
|
branch = repo.DefaultBranch
|
||||||
}
|
}
|
||||||
prs, err := Gitea.GetRecentPullRequests(config.Organization, submoduleName, branch)
|
prs, err := Gitea.GetRecentPullRequests(config.Organization, submoduleName, branch)
|
||||||
|
|||||||
Reference in New Issue
Block a user