.
This commit is contained in:
parent
249fbab882
commit
00ecf8ee85
@ -561,6 +561,10 @@ func (e *RequestHandler) GitSubmoduleList(cwd, commitId string) map[string]strin
|
||||
var done sync.Mutex
|
||||
submoduleList := make(map[string]string)
|
||||
|
||||
if e.HasError() {
|
||||
return submoduleList
|
||||
}
|
||||
|
||||
done.Lock()
|
||||
data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
|
||||
|
||||
|
@ -219,12 +219,15 @@ func parseBuildResults(data []byte) (*BuildResultList, error) {
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *ObsClient) BuildStatus(project string) (*BuildResultList, error) {
|
||||
func (c *ObsClient) BuildStatus(project string, packages ...string) (*BuildResultList, error) {
|
||||
u := c.baseUrl.JoinPath("build", project, "_result")
|
||||
query := u.Query()
|
||||
query.Add("view", "status")
|
||||
query.Add("view", "binarylist")
|
||||
query.Add("multibuild", "1")
|
||||
for _, pkg := range packages {
|
||||
query.Add("package", pkg)
|
||||
}
|
||||
u.RawQuery = query.Encode()
|
||||
req, err := http.NewRequest("GET", u.String(), nil)
|
||||
log.Print(u.String())
|
||||
|
@ -35,6 +35,9 @@ func failOnError(err error, msg string) {
|
||||
|
||||
func fetchPrGit(h *common.RequestHandler, pr *models.PullRequest) error {
|
||||
// clone PR head and base and return path
|
||||
if h.HasError() {
|
||||
return h.Error
|
||||
}
|
||||
if _, err := os.Stat(path.Join(h.GitPath, pr.Head.Sha)); os.IsNotExist(err) {
|
||||
h.GitExec("", "clone", "--depth", "1", pr.Head.Repo.CloneURL, pr.Head.Sha)
|
||||
h.GitExec(pr.Head.Sha, "fetch", "--depth", "1", "origin", pr.Head.Sha, pr.Base.Sha)
|
||||
@ -55,6 +58,27 @@ func getObsProjectAssociatedWithPr(baseProject string, pr *models.PullRequest) s
|
||||
)
|
||||
}
|
||||
|
||||
type BuildStatusSummary string
|
||||
|
||||
const BuildUnresolveable = BuildStatusSummary("unresolveable")
|
||||
const BuildBuilding = BuildStatusSummary("building")
|
||||
const BuildFailed = BuildStatusSummary("failed")
|
||||
const BuildSuccess = BuildStatusSummary("success")
|
||||
|
||||
type BuildStatus struct {
|
||||
Status BuildStatusSummary
|
||||
Detail string
|
||||
}
|
||||
|
||||
var buildStatus map[string]BuildStatus
|
||||
|
||||
func processBuildStatusUpdate() {
|
||||
}
|
||||
|
||||
func processBuildStatus(project, refProject *common.BuildResultList) BuildStatusSummary {
|
||||
return BuildBuilding
|
||||
}
|
||||
|
||||
func processPullNotification(h *common.RequestHandler, notification *models.NotificationSubject) {
|
||||
rx := regexp.MustCompile(`^https://src\.(?:open)?suse\.(?:org|de)/api/v\d+/repos/(?<org>[a-zA-Z0-9]+)/(?<project>[_a-zA-Z0-9]+)/issues/(?<num>[0-9]+)$`)
|
||||
match := rx.FindStringSubmatch(notification.URL)
|
||||
@ -139,7 +163,7 @@ func processPullNotification(h *common.RequestHandler, notification *models.Noti
|
||||
|
||||
h.Log("repo content fetching ...")
|
||||
buildPrjBytes := h.GitCatFile(dir, pr.Head.Sha, "project.build")
|
||||
// buildPrjBytes, err := h.GetPullRequestFileContent(pr, "project.build")
|
||||
// buildPrjBytes, err := h.GetPullRequestFileContent(pr, "project.build")
|
||||
if h.HasError() {
|
||||
h.LogPlainError(h.Error)
|
||||
/*
|
||||
@ -147,7 +171,7 @@ func processPullNotification(h *common.RequestHandler, notification *models.Noti
|
||||
if err != nil {
|
||||
h.LogPlainError(err)
|
||||
}
|
||||
*/
|
||||
*/
|
||||
return
|
||||
}
|
||||
|
||||
@ -192,11 +216,70 @@ func processPullNotification(h *common.RequestHandler, notification *models.Noti
|
||||
// set the review state to pending
|
||||
|
||||
case common.ReviewStatePending:
|
||||
err := fetchPrGit(h, pr)
|
||||
if err != nil {
|
||||
h.LogError("Cannot fetch PR git: %s", pr.URL)
|
||||
return
|
||||
}
|
||||
|
||||
// find modified submodules and new submodules -- build them
|
||||
dir := pr.Head.Sha
|
||||
headSubmodules := h.GitSubmoduleList(dir, pr.Head.Sha)
|
||||
baseSubmodules := h.GitSubmoduleList(dir, pr.Base.Sha)
|
||||
|
||||
modifiedOrNew := make([]string, 0, 16)
|
||||
for pkg, headOid := range headSubmodules {
|
||||
if baseOid, exists := baseSubmodules[pkg]; !exists || baseOid != headOid {
|
||||
modifiedOrNew = append(modifiedOrNew, pkg)
|
||||
}
|
||||
}
|
||||
|
||||
h.Log("repo content fetching ...")
|
||||
refProject := string(h.GitCatFile(dir, pr.Head.Sha, "project.build"))
|
||||
// buildPrjBytes, err := h.GetPullRequestFileContent(pr, "project.build")
|
||||
if h.HasError() {
|
||||
h.LogPlainError(h.Error)
|
||||
/*
|
||||
_, err := h.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project")
|
||||
if err != nil {
|
||||
h.LogPlainError(err)
|
||||
}
|
||||
*/
|
||||
return
|
||||
}
|
||||
|
||||
obsProject := getObsProjectAssociatedWithPr(obsClient.HomeProject, pr)
|
||||
prjResult, err := obsClient.BuildStatus(obsProject)
|
||||
if err != nil {
|
||||
h.LogError("failed fetching build status for '%s': %v", obsProject, err)
|
||||
return
|
||||
}
|
||||
refProjectResult, err := obsClient.BuildStatus(refProject)
|
||||
if err != nil {
|
||||
h.LogError("failed fetching ref project status for '%s': %v", refProject, err)
|
||||
}
|
||||
buildStatus := processBuildStatus(prjResult, refProjectResult)
|
||||
|
||||
switch buildStatus {
|
||||
case BuildSuccess:
|
||||
_, err := h.AddReviewComment(pr, common.ReviewStateApproved, "Build successful")
|
||||
if err != nil {
|
||||
h.LogPlainError(err)
|
||||
}
|
||||
case BuildFailed:
|
||||
_, err := h.AddReviewComment(pr, common.ReviewStateRequestChanges, "Build failed")
|
||||
if err != nil {
|
||||
h.LogPlainError(err)
|
||||
}
|
||||
case BuildBuilding:
|
||||
}
|
||||
|
||||
// waiting for build results
|
||||
// project := getObsProjectAssociatedWithPr(obsClient.HomeProject, pr)
|
||||
// project := getObsProjectAssociatedWithPr(obsClient.HomeProject, pr)
|
||||
case common.ReviewStateApproved:
|
||||
// done, mark notification as read
|
||||
h.Log("processing request for success build ...")
|
||||
|
||||
case common.ReviewStateRequestChanges:
|
||||
// build failures, nothing to do here, mark notification as read
|
||||
h.Log("processing request for failed request changes...")
|
||||
@ -229,37 +312,16 @@ func pollWorkNotifications() {
|
||||
}
|
||||
|
||||
func main() {
|
||||
var defs common.ListenDefinitions
|
||||
|
||||
defs.Url = ObsBuildBot
|
||||
defs.GitAuthor = GitAuthor
|
||||
|
||||
failOnError(common.RequireGiteaSecretToken(), "Cannot find GITEA_TOKEN")
|
||||
failOnError(common.RequireObsSecretToken(), "Cannot find OBS_USER and OBS_PASSWORD")
|
||||
|
||||
// go ProcessingObsMessages("rabbit.opensuse.org", "opensuse", "opensuse", "")
|
||||
|
||||
// for {
|
||||
pollWorkNotifications()
|
||||
// time.Sleep(1000)
|
||||
// }
|
||||
|
||||
/*
|
||||
h := allocateRequestHandler()
|
||||
//" autogits/_ObsPrj/raw/project.build?ref=9680b770855e4fc2e9d9cebbd87e6a0d119693c3e03db187494e3aeff727312f"
|
||||
// https://src.opensuse.org/adamm/autogits/commit/8db4d8c3021fc21baa606b87eaad0e476bb7f624f76cb37b6a1819bdb5f04b43#diff-6e698c75c21cd4458440e8a71408c6301ba3a562
|
||||
f, err := h.GetRepositoryFileContent(
|
||||
&models.Repository{
|
||||
Owner: &models.User{
|
||||
UserName: "adamm",
|
||||
},
|
||||
Name: "autogits",
|
||||
},
|
||||
"54e418acaf960c5ed8be7f4a29616ae7b5eb75f797f7ed4d487f79485d056108",
|
||||
"bots-common/obs/client.go")
|
||||
|
||||
if err != nil {
|
||||
h.LogPlainError(err)
|
||||
}
|
||||
h.Log("len: %d", len(f))
|
||||
*/
|
||||
stuck := make(chan int)
|
||||
<-stuck
|
||||
}
|
||||
|
@ -1,2 +1,38 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"src.opensuse.org/autogits/common/gitea-generated/models"
|
||||
)
|
||||
|
||||
func TestPRtoObsProjectMapping(t *testing.T) {
|
||||
pr := models.PullRequest{
|
||||
Base: &models.PRBranchInfo {
|
||||
Repo: &models.Repository {
|
||||
Name: "Repo",
|
||||
Owner: &models.User {
|
||||
UserName: "foobar",
|
||||
},
|
||||
},
|
||||
},
|
||||
Index: 10,
|
||||
}
|
||||
p := getObsProjectAssociatedWithPr("home:foo", &pr)
|
||||
if p != "home:foo:foobar:Repo:PR:10" {
|
||||
t.Errorf("invalid project: %s", p)
|
||||
}
|
||||
|
||||
pr.Base.Repo.Name = "_FooBar"
|
||||
p = getObsProjectAssociatedWithPr("home:foo", &pr)
|
||||
if p != "home:foo:foobar:XFooBar:PR:10" {
|
||||
t.Errorf("invalid project: %s", p)
|
||||
}
|
||||
|
||||
pr.Base.Repo.Owner.UserName = "_some_thing"
|
||||
p = getObsProjectAssociatedWithPr("home:foo", &pr)
|
||||
if p != "home:foo:Xsome_thing:XFooBar:PR:10" {
|
||||
t.Errorf("invalid project: %s", p)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,10 +5,13 @@ import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
rabbitmq "github.com/rabbitmq/amqp091-go"
|
||||
"src.opensuse.org/autogits/common"
|
||||
"src.opensuse.org/autogits/common/gitea-generated/models"
|
||||
)
|
||||
|
||||
type BuildNotification struct {
|
||||
@ -17,6 +20,50 @@ type BuildNotification struct {
|
||||
Starttime, Endtime, Readytime string
|
||||
}
|
||||
|
||||
var obsNotifications map[string]*BuildNotification // Project/Package/Repositry/Arch as key
|
||||
var notificationMutex sync.RWMutex
|
||||
var notificationChannels map[string][]chan *BuildNotification
|
||||
|
||||
func getProjectBuildStatus(project string) []*BuildNotification {
|
||||
notificationMutex.RLock()
|
||||
defer notificationMutex.RUnlock()
|
||||
|
||||
data := make([]*BuildNotification, 0, 4)
|
||||
for _, val := range obsNotifications {
|
||||
if val.Package == project {
|
||||
data = append(data, val)
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func addProjectWatcher(meta *common.ProjectMeta, pr *models.PullReview) {
|
||||
}
|
||||
|
||||
func addObsNotificationToCache(notification *BuildNotification) {
|
||||
key := strings.Join(
|
||||
[]string{
|
||||
notification.Project,
|
||||
notification.Package,
|
||||
notification.Repository,
|
||||
notification.Arch,
|
||||
},
|
||||
"/",
|
||||
)
|
||||
|
||||
notificationMutex.Lock()
|
||||
obsNotifications[key] = notification
|
||||
|
||||
chns, ok := notificationChannels[notification.Project]
|
||||
notificationMutex.Unlock()
|
||||
if ok {
|
||||
for _, ch := range chns {
|
||||
ch <- notification
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func processObsMessage(msg *rabbitmq.Delivery) {
|
||||
key := strings.SplitN(msg.RoutingKey, ".", 4)
|
||||
if len(key) != 4 || len(key[3]) < 7 || key[3][:6] != "build_" {
|
||||
@ -44,7 +91,7 @@ func processObsMessage(msg *rabbitmq.Delivery) {
|
||||
}
|
||||
|
||||
log.Printf("%v\n", notification)
|
||||
|
||||
addObsNotificationToCache(notification)
|
||||
}
|
||||
|
||||
func ProcessingObsMessages(host, username, password, queueName string) {
|
||||
@ -56,6 +103,11 @@ func ProcessingObsMessages(host, username, password, queueName string) {
|
||||
}
|
||||
}()
|
||||
|
||||
if obsNotifications == nil {
|
||||
obsNotifications = make(map[string]*BuildNotification)
|
||||
// notificationChannels = make(map[string]chan *BuildNotification)
|
||||
}
|
||||
|
||||
auth := ""
|
||||
if len(username) > 0 && len(password) > 0 {
|
||||
auth = username + ":" + password + "@"
|
||||
|
Loading…
Reference in New Issue
Block a user