.
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
|
var done sync.Mutex
|
||||||
submoduleList := make(map[string]string)
|
submoduleList := make(map[string]string)
|
||||||
|
|
||||||
|
if e.HasError() {
|
||||||
|
return submoduleList
|
||||||
|
}
|
||||||
|
|
||||||
done.Lock()
|
done.Lock()
|
||||||
data_in, data_out := ChanIO{make(chan byte, 256)}, ChanIO{make(chan byte, 70)}
|
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
|
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")
|
u := c.baseUrl.JoinPath("build", project, "_result")
|
||||||
query := u.Query()
|
query := u.Query()
|
||||||
query.Add("view", "status")
|
query.Add("view", "status")
|
||||||
query.Add("view", "binarylist")
|
query.Add("view", "binarylist")
|
||||||
query.Add("multibuild", "1")
|
query.Add("multibuild", "1")
|
||||||
|
for _, pkg := range packages {
|
||||||
|
query.Add("package", pkg)
|
||||||
|
}
|
||||||
u.RawQuery = query.Encode()
|
u.RawQuery = query.Encode()
|
||||||
req, err := http.NewRequest("GET", u.String(), nil)
|
req, err := http.NewRequest("GET", u.String(), nil)
|
||||||
log.Print(u.String())
|
log.Print(u.String())
|
||||||
|
@ -35,6 +35,9 @@ func failOnError(err error, msg string) {
|
|||||||
|
|
||||||
func fetchPrGit(h *common.RequestHandler, pr *models.PullRequest) error {
|
func fetchPrGit(h *common.RequestHandler, pr *models.PullRequest) error {
|
||||||
// clone PR head and base and return path
|
// 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) {
|
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("", "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)
|
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) {
|
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]+)$`)
|
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)
|
match := rx.FindStringSubmatch(notification.URL)
|
||||||
@ -139,15 +163,15 @@ func processPullNotification(h *common.RequestHandler, notification *models.Noti
|
|||||||
|
|
||||||
h.Log("repo content fetching ...")
|
h.Log("repo content fetching ...")
|
||||||
buildPrjBytes := h.GitCatFile(dir, pr.Head.Sha, "project.build")
|
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() {
|
if h.HasError() {
|
||||||
h.LogPlainError(h.Error)
|
h.LogPlainError(h.Error)
|
||||||
/*
|
/*
|
||||||
_, err := h.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project")
|
_, err := h.AddReviewComment(pr, common.ReviewStateRequestChanges, "Cannot find reference project")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.LogPlainError(err)
|
h.LogPlainError(err)
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,11 +216,70 @@ func processPullNotification(h *common.RequestHandler, notification *models.Noti
|
|||||||
// set the review state to pending
|
// set the review state to pending
|
||||||
|
|
||||||
case common.ReviewStatePending:
|
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
|
// waiting for build results
|
||||||
// project := getObsProjectAssociatedWithPr(obsClient.HomeProject, pr)
|
// project := getObsProjectAssociatedWithPr(obsClient.HomeProject, pr)
|
||||||
case common.ReviewStateApproved:
|
case common.ReviewStateApproved:
|
||||||
// done, mark notification as read
|
// done, mark notification as read
|
||||||
h.Log("processing request for success build ...")
|
h.Log("processing request for success build ...")
|
||||||
|
|
||||||
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...")
|
h.Log("processing request for failed request changes...")
|
||||||
@ -229,37 +312,16 @@ func pollWorkNotifications() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var defs common.ListenDefinitions
|
|
||||||
|
|
||||||
defs.Url = ObsBuildBot
|
|
||||||
defs.GitAuthor = GitAuthor
|
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
// go ProcessingObsMessages("rabbit.opensuse.org", "opensuse", "opensuse", "")
|
// go ProcessingObsMessages("rabbit.opensuse.org", "opensuse", "opensuse", "")
|
||||||
|
|
||||||
|
// for {
|
||||||
pollWorkNotifications()
|
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 := make(chan int)
|
||||||
<-stuck
|
<-stuck
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,38 @@
|
|||||||
package main
|
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"
|
"encoding/json"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
rabbitmq "github.com/rabbitmq/amqp091-go"
|
rabbitmq "github.com/rabbitmq/amqp091-go"
|
||||||
|
"src.opensuse.org/autogits/common"
|
||||||
|
"src.opensuse.org/autogits/common/gitea-generated/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BuildNotification struct {
|
type BuildNotification struct {
|
||||||
@ -17,6 +20,50 @@ type BuildNotification struct {
|
|||||||
Starttime, Endtime, Readytime string
|
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) {
|
func processObsMessage(msg *rabbitmq.Delivery) {
|
||||||
key := strings.SplitN(msg.RoutingKey, ".", 4)
|
key := strings.SplitN(msg.RoutingKey, ".", 4)
|
||||||
if len(key) != 4 || len(key[3]) < 7 || key[3][:6] != "build_" {
|
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)
|
log.Printf("%v\n", notification)
|
||||||
|
addObsNotificationToCache(notification)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProcessingObsMessages(host, username, password, queueName string) {
|
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 := ""
|
auth := ""
|
||||||
if len(username) > 0 && len(password) > 0 {
|
if len(username) > 0 && len(password) > 0 {
|
||||||
auth = username + ":" + password + "@"
|
auth = username + ":" + password + "@"
|
||||||
|
Loading…
Reference in New Issue
Block a user