|
|
|
|
@@ -26,6 +26,7 @@ import (
|
|
|
|
|
"net/url"
|
|
|
|
|
"os"
|
|
|
|
|
"path"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"regexp"
|
|
|
|
|
"runtime/debug"
|
|
|
|
|
"slices"
|
|
|
|
|
@@ -109,161 +110,67 @@ const (
|
|
|
|
|
BuildStatusSummaryUnknown = 4
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func ProcessBuildStatus(project, refProject *common.BuildResultList) BuildStatusSummary {
|
|
|
|
|
if _, finished := refProject.BuildResultSummary(); !finished {
|
|
|
|
|
common.LogDebug("refProject not finished building??")
|
|
|
|
|
return BuildStatusSummaryUnknown
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ProcessBuildStatus(project *common.BuildResultList) BuildStatusSummary {
|
|
|
|
|
if _, finished := project.BuildResultSummary(); !finished {
|
|
|
|
|
common.LogDebug("Still building...")
|
|
|
|
|
return BuildStatusSummaryBuilding
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// the repositories should be setup equally between the projects. We
|
|
|
|
|
// need to verify that packages that are building in `refProject` are not
|
|
|
|
|
// failing in the `project`
|
|
|
|
|
BuildResultSorter := func(a, b *common.BuildResult) int {
|
|
|
|
|
if c := strings.Compare(a.Repository, b.Repository); c != 0 {
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
if c := strings.Compare(a.Arch, b.Arch); c != 0 {
|
|
|
|
|
return c
|
|
|
|
|
}
|
|
|
|
|
//slices.SortFunc(project.Result, BuildResultSorter)
|
|
|
|
|
|
|
|
|
|
panic("Should not happen -- BuiltResultSorter equal repos?")
|
|
|
|
|
}
|
|
|
|
|
slices.SortFunc(project.Result, BuildResultSorter)
|
|
|
|
|
if refProject == nil {
|
|
|
|
|
// just return if buid finished and have some successes, since new package
|
|
|
|
|
common.LogInfo("New package. Only need some success...")
|
|
|
|
|
SomeSuccess := false
|
|
|
|
|
for i := 0; i < len(project.Result); i++ {
|
|
|
|
|
repoRes := project.Result[i]
|
|
|
|
|
repoResStatus, ok := common.ObsRepoStatusDetails[repoRes.Code]
|
|
|
|
|
if !ok {
|
|
|
|
|
common.LogDebug("cannot find code:", repoRes.Code)
|
|
|
|
|
return BuildStatusSummaryUnknown
|
|
|
|
|
}
|
|
|
|
|
if !repoResStatus.Finished {
|
|
|
|
|
return BuildStatusSummaryBuilding
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, pkg := range repoRes.Status {
|
|
|
|
|
pkgStatus, ok := common.ObsBuildStatusDetails[pkg.Code]
|
|
|
|
|
if !ok {
|
|
|
|
|
common.LogInfo("Unknown package build status:", pkg.Code, "for", pkg.Package)
|
|
|
|
|
common.LogDebug("Details:", pkg.Details)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if pkgStatus.Success {
|
|
|
|
|
SomeSuccess = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if SomeSuccess {
|
|
|
|
|
return BuildStatusSummarySuccess
|
|
|
|
|
}
|
|
|
|
|
return BuildStatusSummaryFailed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
slices.SortFunc(refProject.Result, BuildResultSorter)
|
|
|
|
|
|
|
|
|
|
common.LogDebug("comparing results", len(project.Result), "vs. ref", len(refProject.Result))
|
|
|
|
|
SomeSuccess := false
|
|
|
|
|
common.LogDebug("build results", len(project.Result))
|
|
|
|
|
for i := 0; i < len(project.Result); i++ {
|
|
|
|
|
common.LogDebug("searching for", project.Result[i].Repository, "/", project.Result[i].Arch)
|
|
|
|
|
j := 0
|
|
|
|
|
found:
|
|
|
|
|
for ; j < len(refProject.Result); j++ {
|
|
|
|
|
if project.Result[i].Repository != refProject.Result[j].Repository ||
|
|
|
|
|
project.Result[i].Arch != refProject.Result[j].Arch {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for j = 0; j < len(project.Result); j++ {
|
|
|
|
|
common.LogDebug(" found match for @ idx:", j)
|
|
|
|
|
res, success := ProcessRepoBuildStatus(project.Result[i].Status, refProject.Result[j].Status)
|
|
|
|
|
res := ProcessRepoBuildStatus(project.Result[i].Status)
|
|
|
|
|
switch res {
|
|
|
|
|
case BuildStatusSummarySuccess:
|
|
|
|
|
SomeSuccess = SomeSuccess || success
|
|
|
|
|
break found
|
|
|
|
|
case BuildStatusSummaryFailed:
|
|
|
|
|
return BuildStatusSummaryFailed
|
|
|
|
|
default:
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if j >= len(refProject.Result) {
|
|
|
|
|
common.LogDebug("Cannot find results...")
|
|
|
|
|
common.LogDebug(project.Result[i])
|
|
|
|
|
common.LogDebug(refProject.Result)
|
|
|
|
|
return BuildStatusSummaryUnknown
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if SomeSuccess {
|
|
|
|
|
return BuildStatusSummarySuccess
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return BuildStatusSummaryFailed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ProcessRepoBuildStatus(results, ref []*common.PackageBuildStatus) (status BuildStatusSummary, SomeSuccess bool) {
|
|
|
|
|
func ProcessRepoBuildStatus(results []*common.PackageBuildStatus) (status BuildStatusSummary) {
|
|
|
|
|
|
|
|
|
|
PackageBuildStatusSorter := func(a, b *common.PackageBuildStatus) int {
|
|
|
|
|
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, "", " ")
|
|
|
|
|
data, _ := xml.MarshalIndent(results, "", " ")
|
|
|
|
|
common.LogDebug(string(data))
|
|
|
|
|
common.LogDebug("*******")
|
|
|
|
|
|
|
|
|
|
// compare build result
|
|
|
|
|
slices.SortFunc(results, PackageBuildStatusSorter)
|
|
|
|
|
slices.SortFunc(ref, PackageBuildStatusSorter)
|
|
|
|
|
|
|
|
|
|
j := 0
|
|
|
|
|
SomeSuccess = false
|
|
|
|
|
for i := 0; i < len(results); i++ {
|
|
|
|
|
res, ok := common.ObsBuildStatusDetails[results[i].Code]
|
|
|
|
|
if !ok {
|
|
|
|
|
common.LogInfo("unknown package result code:", results[i].Code, "for package:", results[i].Package)
|
|
|
|
|
return BuildStatusSummaryUnknown, SomeSuccess
|
|
|
|
|
return BuildStatusSummaryUnknown
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !res.Finished {
|
|
|
|
|
return BuildStatusSummaryBuilding, SomeSuccess
|
|
|
|
|
return BuildStatusSummaryBuilding
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !res.Success {
|
|
|
|
|
// not failed if reference project also failed for same package here
|
|
|
|
|
for ; j < len(results) && strings.Compare(results[i].Package, ref[j].Package) < 0; j++ {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if j < len(results) && results[i].Package == ref[j].Package {
|
|
|
|
|
refRes, ok := common.ObsBuildStatusDetails[ref[j].Code]
|
|
|
|
|
if !ok {
|
|
|
|
|
common.LogInfo("unknown ref package result code:", ref[j].Code, "package:", ref[j].Package)
|
|
|
|
|
return BuildStatusSummaryUnknown, SomeSuccess
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !refRes.Finished {
|
|
|
|
|
common.LogDebug("Not finished building in reference project?")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if refRes.Success {
|
|
|
|
|
return BuildStatusSummaryFailed, SomeSuccess
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
SomeSuccess = true
|
|
|
|
|
return BuildStatusSummaryFailed
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return BuildStatusSummarySuccess, SomeSuccess
|
|
|
|
|
return BuildStatusSummarySuccess
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullRequest, stagingPrj, buildPrj string, stagingMasterPrj string) (*common.ProjectMeta, error) {
|
|
|
|
|
@@ -322,9 +229,9 @@ func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullReque
|
|
|
|
|
common.LogError("error fetching project meta for", buildPrj, ". Err:", err)
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
common.LogInfo("Meta: ", meta)
|
|
|
|
|
|
|
|
|
|
// generate new project with paths pointinig back to original repos
|
|
|
|
|
// disable publishing
|
|
|
|
|
|
|
|
|
|
meta.Name = stagingPrj
|
|
|
|
|
meta.Description = fmt.Sprintf(`Pull request build job PR#%d to branch %s of %s/%s`,
|
|
|
|
|
@@ -339,7 +246,10 @@ func GenerateObsPrjMeta(git common.Git, gitea common.Gitea, pr *models.PullReque
|
|
|
|
|
|
|
|
|
|
urlPkg := make([]string, 0, len(modifiedOrNew))
|
|
|
|
|
for _, pkg := range modifiedOrNew {
|
|
|
|
|
urlPkg = append(urlPkg, "onlybuild="+url.QueryEscape(pkg))
|
|
|
|
|
// FIXME: skip manifest subdirectories itself
|
|
|
|
|
// strip any leading directory name and just hand over last directory as package name
|
|
|
|
|
onlybuilds := strings.Split(pkg, "/")
|
|
|
|
|
urlPkg = append(urlPkg, "onlybuild="+url.QueryEscape(onlybuilds[len(onlybuilds)-1]))
|
|
|
|
|
}
|
|
|
|
|
meta.ScmSync = pr.Head.Repo.CloneURL + "?" + strings.Join(urlPkg, "&") + "#" + pr.Head.Sha
|
|
|
|
|
if len(meta.ScmSync) >= 65535 {
|
|
|
|
|
@@ -824,10 +734,13 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) (bool, e
|
|
|
|
|
if !stagingConfig.RebuildAll {
|
|
|
|
|
for pkg, headOid := range headSubmodules {
|
|
|
|
|
if baseOid, exists := baseSubmodules[pkg]; !exists || baseOid != headOid {
|
|
|
|
|
if pkg != "rpms" && pkg != "dependencies" {
|
|
|
|
|
_, spkg := filepath.Split(pkg)
|
|
|
|
|
if exists {
|
|
|
|
|
modifiedPackages = append(modifiedPackages, pkg)
|
|
|
|
|
modifiedPackages = append(modifiedPackages, spkg)
|
|
|
|
|
} else {
|
|
|
|
|
newPackages = append(newPackages, pkg)
|
|
|
|
|
newPackages = append(newPackages, spkg)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
common.LogDebug(pkg, ":", baseOid, "->", headOid)
|
|
|
|
|
}
|
|
|
|
|
@@ -931,15 +844,11 @@ func ProcessPullRequest(gitea common.Gitea, org, repo string, id int64) (bool, e
|
|
|
|
|
gitea.AddComment(pr, msg)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
baseResult, err := ObsClient.LastBuildResults(stagingConfig.ObsProject, modifiedPackages...)
|
|
|
|
|
if err != nil {
|
|
|
|
|
common.LogError("failed fetching ref project status for", stagingConfig.ObsProject, ":", err)
|
|
|
|
|
}
|
|
|
|
|
stagingResult, err := ObsClient.BuildStatus(stagingProject)
|
|
|
|
|
if err != nil {
|
|
|
|
|
common.LogError("failed fetching stage project status for", stagingProject, ":", err)
|
|
|
|
|
}
|
|
|
|
|
buildStatus := ProcessBuildStatus(stagingResult, baseResult)
|
|
|
|
|
buildStatus := ProcessBuildStatus(stagingResult)
|
|
|
|
|
|
|
|
|
|
done := false
|
|
|
|
|
switch buildStatus {
|
|
|
|
|
|
the package check should probably stay here?