This commit is contained in:
Adam Majer 2024-10-29 15:36:20 +01:00
parent 6ecc4ecb3a
commit a672bb85fb

View File

@ -21,6 +21,7 @@ package main
import ( import (
"bytes" "bytes"
"errors" "errors"
"flag"
"fmt" "fmt"
"log" "log"
"net/url" "net/url"
@ -56,17 +57,14 @@ func failOnError(err error, msg string) {
func fetchPrGit(git *common.GitHandler, pr *models.PullRequest) error { func fetchPrGit(git *common.GitHandler, pr *models.PullRequest) error {
// clone PR head and base and return path // clone PR head and base and return path
if h.HasError() { if _, err := os.Stat(path.Join(git.GitPath, pr.Head.Sha)); os.IsNotExist(err) {
return h.Error
}
if _, err := os.Stat(path.Join(h.GitPath, pr.Head.Sha)); os.IsNotExist(err) {
git.GitExec("", "clone", "--depth", "1", pr.Head.Repo.CloneURL, pr.Head.Sha) git.GitExec("", "clone", "--depth", "1", pr.Head.Repo.CloneURL, pr.Head.Sha)
git.GitExec(pr.Head.Sha, "fetch", "--depth", "1", "origin", pr.Head.Sha, pr.Base.Sha) git.GitExec(pr.Head.Sha, "fetch", "--depth", "1", "origin", pr.Head.Sha, pr.Base.Sha)
} else if err != nil { } else if err != nil {
h.Error = err return err
} }
return h.Error return nil
} }
func getObsProjectAssociatedWithPr(baseProject string, pr *models.PullRequest) string { func getObsProjectAssociatedWithPr(baseProject string, pr *models.PullRequest) string {
@ -100,13 +98,13 @@ const (
BuildStatusSummaryUnknown = 4 BuildStatusSummaryUnknown = 4
) )
func processBuildStatus(h *common.RequestHandler, project, refProject *common.BuildResultList) BuildStatusSummary { func processBuildStatus(project, refProject *common.BuildResultList) BuildStatusSummary {
if _, finished := project.BuildResultSummary(); !finished { if _, finished := project.BuildResultSummary(); !finished {
return BuildStatusSummaryBuilding return BuildStatusSummaryBuilding
} }
if _, finished := refProject.BuildResultSummary(); !finished { if _, finished := refProject.BuildResultSummary(); !finished {
h.LogError("refProject not finished building??") log.Println("refProject not finished building??")
return BuildStatusSummaryUnknown return BuildStatusSummaryUnknown
} }
@ -141,7 +139,7 @@ func processBuildStatus(h *common.RequestHandler, project, refProject *common.Bu
for _, pkg := range repoRes.Status { for _, pkg := range repoRes.Status {
pkgStatus, ok := common.ObsBuildStatusDetails[pkg.Code] pkgStatus, ok := common.ObsBuildStatusDetails[pkg.Code]
if !ok { if !ok {
log.Println("Unknown package build status: %s", pkg.Code, "for", pkg.Package) log.Println("Unknown package build status:", pkg.Code, "for", pkg.Package)
log.Println("Details:", pkg.Details) log.Println("Details:", pkg.Details)
} }
@ -171,7 +169,7 @@ func processBuildStatus(h *common.RequestHandler, project, refProject *common.Bu
} }
log.Printf("found match for %s/%s @ %d\n", project.Result[i].Repository, project.Result[i].Arch, j) log.Printf("found match for %s/%s @ %d\n", project.Result[i].Repository, project.Result[i].Arch, j)
res := processRepoBuildStatus(h, project.Result[i].Status, refProject.Result[j].Status) res := processRepoBuildStatus(project.Result[i].Status, refProject.Result[j].Status)
switch res { switch res {
case BuildStatusSummarySuccess: case BuildStatusSummarySuccess:
break found break found
@ -189,7 +187,7 @@ func processBuildStatus(h *common.RequestHandler, project, refProject *common.Bu
return BuildStatusSummarySuccess return BuildStatusSummarySuccess
} }
func processRepoBuildStatus(h *common.RequestHandler, results, ref []common.PackageBuildStatus) BuildStatusSummary { func processRepoBuildStatus(results, ref []common.PackageBuildStatus) BuildStatusSummary {
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)
} }
@ -437,7 +435,7 @@ func processPullNotification(gitea *common.GiteaTransport, thread *models.Notifi
// create build project, if doesn't exist, and add it to pending requests // create build project, if doesn't exist, and add it to pending requests
case common.ReviewStateUnknown, common.ReviewStateRequestReview: case common.ReviewStateUnknown, common.ReviewStateRequestReview:
if err := startOrUpdateBuild(git, pr, obsClient); err != nil { if err := startOrUpdateBuild(git, gitea, pr, obsClient); err != nil {
return return
} }
@ -454,8 +452,14 @@ func processPullNotification(gitea *common.GiteaTransport, thread *models.Notifi
// find modified submodules and new submodules -- build them // find modified submodules and new submodules -- build them
dir := pr.Head.Sha dir := pr.Head.Sha
headSubmodules := git.GitSubmoduleList(dir, pr.Head.Sha) headSubmodules, err := git.GitSubmoduleList(dir, pr.Head.Sha)
baseSubmodules := git.GitSubmoduleList(dir, pr.Base.Sha) if err != nil {
log.Panicln(err)
}
baseSubmodules, err := git.GitSubmoduleList(dir, pr.Base.Sha)
if err != nil {
log.Panicln(err)
}
modifiedOrNew := make([]string, 0, 16) modifiedOrNew := make([]string, 0, 16)
for pkg, headOid := range headSubmodules { for pkg, headOid := range headSubmodules {
@ -465,7 +469,11 @@ func processPullNotification(gitea *common.GiteaTransport, thread *models.Notifi
} }
log.Println("repo content fetching ...") log.Println("repo content fetching ...")
refPrj := string(bytes.TrimSpace(h.GitCatFile(dir, pr.Head.Sha, "project.build"))) refPrjData, err := git.GitCatFile(dir, pr.Head.Sha, "project.build")
if err != nil {
log.Panicln(err)
}
refPrj := string(bytes.TrimSpace(refPrjData))
if len(refPrj) < 1 { if len(refPrj) < 1 {
_, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project") _, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project")
@ -473,11 +481,7 @@ func processPullNotification(gitea *common.GiteaTransport, thread *models.Notifi
log.Println(err) log.Println(err)
return return
} }
h.LogError("Cannot find reference project for %s PR#%d", pr.Base.Name, pr.Index) log.Printf("Cannot find reference project for %s PR#%d\n", pr.Base.Name, pr.Index)
return
}
if h.HasError() {
h.LogPlainError(h.Error)
return return
} }
@ -486,57 +490,56 @@ func processPullNotification(gitea *common.GiteaTransport, thread *models.Notifi
if err != nil { if err != nil {
if errors.Is(err, common.ObsProjectNotFound{Project: obsProject}) { if errors.Is(err, common.ObsProjectNotFound{Project: obsProject}) {
// recreate missing project // recreate missing project
h.LogError("missing OBS project ... recreating '%s': %v", obsProject, err) log.Printf("missing OBS project ... recreating '%s': %v\n", obsProject, err)
startOrUpdateBuild(h, pr, obsClient) startOrUpdateBuild(git, gitea, pr, obsClient)
return return
} }
h.LogError("failed fetching build status for '%s': %v", obsProject, err) log.Printf("failed fetching build status for '%s': %v\n", obsProject, err)
return return
} }
refProjectResult, err := obsClient.BuildStatus(refPrj, prjResult.GetPackageList()...) refProjectResult, err := obsClient.BuildStatus(refPrj, prjResult.GetPackageList()...)
if err != nil { if err != nil {
h.LogError("failed fetching ref project status for '%s': %v", refPrj, err) log.Printf("failed fetching ref project status for '%s': %v\n", refPrj, err)
} }
buildStatus := processBuildStatus(h, prjResult, refProjectResult) buildStatus := processBuildStatus(prjResult, refProjectResult)
switch buildStatus { switch buildStatus {
case BuildStatusSummarySuccess: case BuildStatusSummarySuccess:
_, err := h.AddReviewComment(pr, common.ReviewStateApproved, "Build successful") _, err := gitea.AddReviewComment(pr, common.ReviewStateApproved, "Build successful")
if err != nil { if err != nil {
h.LogPlainError(err) log.Println(err)
} }
case BuildStatusSummaryFailed: case BuildStatusSummaryFailed:
_, err := h.AddReviewComment(pr, common.ReviewStateRequestChanges, "Build failed") _, err := gitea.AddReviewComment(pr, common.ReviewStateRequestChanges, "Build failed")
if err != nil { if err != nil {
h.LogPlainError(err) log.Println(err)
} }
} }
h.Log("Build status waiting: %d", buildStatus) log.Println("Build status waiting:", buildStatus)
// waiting for build results -- nothing to do // waiting for build results -- nothing to do
case common.ReviewStateApproved: case common.ReviewStateApproved:
// done, mark notification as read // done, mark notification as read
h.Log("processing request for success build ...") log.Println("processing request for success build ...")
h.SetNotificationRead(thread.ID) gitea.SetNotificationRead(thread.ID)
case common.ReviewStateRequestChanges: case common.ReviewStateRequestChanges:
// build failures, nothing to do here, mark notification as read // build failures, nothing to do here, mark notification as read
h.Log("processing request for failed request changes...") log.Println("processing request for failed request changes...")
h.SetNotificationRead(thread.ID) gitea.SetNotificationRead(thread.ID)
} }
break break
} }
} }
func pollWorkNotifications() { func pollWorkNotifications(giteaHost string) {
h := common.CreateRequestHandler(GitAuthor, BotName) gitea := common.AllocateGiteaTransport(giteaHost)
data, err := h.GetPullNotifications(nil) data, err := gitea.GetPullNotifications(nil)
if err != nil { if err != nil {
h.LogPlainError(err) log.Println(err)
return return
} }
@ -544,9 +547,9 @@ func pollWorkNotifications() {
for _, notification := range data { for _, notification := range data {
switch notification.Subject.Type { switch notification.Subject.Type {
case "Pull": case "Pull":
processPullNotification(h, notification) processPullNotification(gitea, notification)
default: default:
h.SetNotificationRead(notification.ID) gitea.SetNotificationRead(notification.ID)
} }
} }
} }
@ -556,13 +559,13 @@ func main() {
failOnError(common.RequireGiteaSecretToken(), "Cannot find GITEA_TOKEN") failOnError(common.RequireGiteaSecretToken(), "Cannot find GITEA_TOKEN")
failOnError(common.RequireObsSecretToken(), "Cannot find OBS_USER and OBS_PASSWORD") failOnError(common.RequireObsSecretToken(), "Cannot find OBS_USER and OBS_PASSWORD")
giteaHost := flag.String("giteaHost", "src.opensuse.org", "Gitea hostname")
// go ProcessingObsMessages("rabbit.opensuse.org", "opensuse", "opensuse", "") // go ProcessingObsMessages("rabbit.opensuse.org", "opensuse", "opensuse", "")
for { for {
pollWorkNotifications() pollWorkNotifications(*giteaHost)
time.Sleep(10 * time.Minute) time.Sleep(10 * time.Minute)
} }
stuck := make(chan int)
<-stuck
} }