Compare commits

..

1 Commits

Author SHA256 Message Date
Frank Schreiner
9f67f43ac9 t: add Dockerfiles for building in OBS 2026-03-10 17:27:05 +01:00
5 changed files with 36 additions and 54 deletions

View File

@@ -1,8 +1,4 @@
MODULES := devel-importer utils/hujson utils/maintainer-update gitea-events-rabbitmq-publisher gitea_status_proxy group-review obs-forward-bot obs-staging-bot obs-status-service workflow-direct workflow-pr
.PHONY: build $(MODULES)
build: $(MODULES)
$(MODULES):
go build -C $@ -buildmode=pie
build:
for m in $(MODULES); do go build -C $$m -buildmode=pie || exit 1 ; done

View File

@@ -0,0 +1,7 @@
#!BuildTag: openbuildservice/gwf-test-basecontainer
#!UseOBSRepositories
FROM registry.suse.com/bci/bci-base:15.7
RUN zypper -n install binutils gawk git git-core git-lfs jq make openssh openssh-clients sqlite3 vim which
RUN zypper -n install autogits-gitea-events-rabbitmq-publisher autogits-obs-staging-bot autogits-workflow-pr gitea

View File

@@ -0,0 +1,5 @@
#!BuildTag: openbuildservice/gwf-client
#!UseOBSRepositories
FROM opensuse/tumbleweed
RUN zypper -n install podman podman-compose vim make python3-pytest python3-requests python3-pytest-dependency python3-pytest-httpserver

View File

@@ -8,7 +8,6 @@ import (
"runtime/debug"
"slices"
"strings"
"sync"
"time"
"github.com/opentracing/opentracing-go/log"
@@ -629,29 +628,9 @@ func (pr *PRProcessor) Process(req *models.PullRequest) error {
return err
}
// prLocks serialises concurrent processing of the same PR.
// Both the RabbitMQ event loop and the consistency-checker goroutine call
// ProcesPullRequest; without this lock they can race on reviewer add/remove.
// Key format: "org/repo#num"
var prLocks sync.Map // map[string]chan struct{}
func prLockKey(pr *models.PullRequest) string {
return fmt.Sprintf("%s/%s#%d", pr.Base.Repo.Owner.UserName, pr.Base.Repo.Name, pr.Index)
}
func acquirePRLock(key string) chan struct{} {
v, _ := prLocks.LoadOrStore(key, make(chan struct{}, 1))
ch := v.(chan struct{})
ch <- struct{}{}
return ch
}
func releasePRLock(ch chan struct{}) {
<-ch
}
type RequestProcessor struct {
configuredRepos map[string][]*common.AutogitConfig
recursive int
}
func (w *RequestProcessor) Process(pr *models.PullRequest) error {
@@ -668,9 +647,6 @@ func ProcesPullRequest(pr *models.PullRequest, configs []*common.AutogitConfig)
return nil
}
lock := acquirePRLock(prLockKey(pr))
defer releasePRLock(lock)
PRProcessor, err := AllocatePRProcessor(pr, configs)
if err != nil {
log.Error(err)
@@ -687,23 +663,17 @@ func (w *RequestProcessor) ProcessFunc(request *common.Request) (err error) {
common.LogInfo("panic cought --- recovered")
common.LogError(string(debug.Stack()))
}
w.recursive--
}()
w.recursive++
if w.recursive > 3 {
common.LogError("Recursion limit reached... something is wrong with this PR?")
return nil
}
var pr *models.PullRequest
if req, ok := request.Data.(*common.PullRequestWebhookEvent); ok {
// Skip pull_request_sync events triggered by the bot's own pushes to
// prjgit branches. Those would re-run AssignReviewers immediately
// after the bot itself just set them, producing spurious add/remove
// cycles. Human-triggered syncs have a different sender and are still
// processed normally.
if request.Type == common.RequestType_PRSync && CurrentUser != nil &&
req.Sender.Username == CurrentUser.UserName {
common.LogDebug("Skipping self-triggered pull_request_sync from", req.Sender.Username,
"on", req.Pull_Request.Base.Repo.Owner.Username+"/"+req.Pull_Request.Base.Repo.Name,
"#", req.Pull_Request.Number)
return nil
}
pr, err = Gitea.GetPullRequest(req.Pull_Request.Base.Repo.Owner.Username, req.Pull_Request.Base.Repo.Name, req.Pull_Request.Number)
if err != nil {
common.LogError("Cannot find PR for issue:", req.Pull_Request.Base.Repo.Owner.Username, req.Pull_Request.Base.Repo.Name, req.Pull_Request.Number)
@@ -740,16 +710,8 @@ func (w *RequestProcessor) ProcessFunc(request *common.Request) (err error) {
common.LogError("*** Cannot find config for org:", pr.Base.Repo.Owner.UserName)
}
if err = ProcesPullRequest(pr, configs); err == updatePrjGitError_requeue {
// Retry after a delay in a background goroutine so the event loop is
// not blocked while we wait. The per-PR lock inside ProcesPullRequest
// ensures no other processing races with the retry.
go func() {
time.Sleep(time.Second * 5)
if err := ProcesPullRequest(pr, configs); err != nil {
common.LogError("requeue retry failed:", err)
}
}()
return nil
time.Sleep(time.Second * 5)
return w.ProcessFunc(request)
}
return err
}

View File

@@ -989,6 +989,18 @@ func TestProcessFunc(t *testing.T) {
}
})
t.Run("Recursion limit", func(t *testing.T) {
reqProc.recursive = 3
err := reqProc.ProcessFunc(&common.Request{})
if err != nil {
t.Errorf("Expected nil error on recursion limit, got %v", err)
}
if reqProc.recursive != 3 {
t.Errorf("Expected recursive to be 3, got %d", reqProc.recursive)
}
reqProc.recursive = 0 // Reset
})
t.Run("Invalid data format", func(t *testing.T) {
err := reqProc.ProcessFunc(&common.Request{Data: nil})
if err == nil || !strings.Contains(err.Error(), "Invalid data format") {