From 629b10fbac4b5a7f38b06e90a35402407fc9c0d4ce62d2375b63e2d89e9a3898 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Fri, 30 Aug 2024 17:05:57 +0200 Subject: [PATCH] . --- bots-common/gitea_utils.go | 153 ++++++++++++++++--------------------- prjgit-updater/main.go | 8 +- 2 files changed, 70 insertions(+), 91 deletions(-) diff --git a/bots-common/gitea_utils.go b/bots-common/gitea_utils.go index 3c82415..8e89b77 100644 --- a/bots-common/gitea_utils.go +++ b/bots-common/gitea_utils.go @@ -3,7 +3,6 @@ package common import ( "fmt" "io" - "log" "os" "path/filepath" "slices" @@ -21,14 +20,6 @@ import ( const PrPattern = "PR: %s/%s#%d" -func (h *RequestHandler) allocateGiteaTransport() (*transport.Runtime, *apiclient.GiteaAPI) { - r := transport.New("src.opensuse.org", apiclient.DefaultBasePath, [](string){"https"}) - r.DefaultAuthentication = transport.BearerToken(giteaToken) - // r.SetDebug(true) - - return r, apiclient.New(r, nil) -} - const ( // from Gitea // ReviewStateApproved pr is approved @@ -45,44 +36,56 @@ const ( ReviewStateUnknown models.ReviewStateType = "" ) -func (h *RequestHandler) GetPullRequestAndReviews(org, project string, num int64) (*models.PullRequest, []*models.PullReview, error) { - transport, client := h.allocateGiteaTransport() - pr, err := client.Repository.RepoGetPullRequest( +type GiteaTransport struct { + transport *transport.Runtime + client *apiclient.GiteaAPI +} + +func AllocateGiteaTransport(host string) *GiteaTransport { + var r GiteaTransport + + r.transport = transport.New(host, apiclient.DefaultBasePath, [](string){"https"}) + r.transport.DefaultAuthentication = transport.BearerToken(giteaToken) + + r.client = apiclient.New(r.transport, nil) + + return &r +} + +func (gitea *GiteaTransport) GetPullRequestAndReviews(org, project string, num int64) (*models.PullRequest, []*models.PullReview, error) { + pr, err := gitea.client.Repository.RepoGetPullRequest( repository.NewRepoGetPullRequestParams(). WithDefaults(). WithOwner(org). WithRepo(project). WithIndex(num), - transport.DefaultAuthentication, + gitea.transport.DefaultAuthentication, ) if err != nil { - log.Println(err.Error()) return nil, nil, err } limit := int64(1000) - reviews, err := client.Repository.RepoListPullReviews( + reviews, err := gitea.client.Repository.RepoListPullReviews( repository.NewRepoListPullReviewsParams(). WithDefaults(). WithOwner(org). WithRepo(project). WithIndex(num). WithLimit(&limit), - transport.DefaultAuthentication, + gitea.transport.DefaultAuthentication, ) if err != nil { - log.Println(err.Error()) return nil, nil, err } return pr.Payload, reviews.Payload, nil } -func (h *RequestHandler) GetPullNotifications(since *time.Time) ([]*models.NotificationThread, error) { +func (gitea *GiteaTransport) GetPullNotifications(since *time.Time) ([]*models.NotificationThread, error) { bigLimit := int64(100000) - transport, client := h.allocateGiteaTransport() params := notification.NewNotifyGetListParams(). WithDefaults(). @@ -95,51 +98,38 @@ func (h *RequestHandler) GetPullNotifications(since *time.Time) ([]*models.Notif params.SetSince(&s) } - list, err := client.Notification.NotifyGetList(params, transport.DefaultAuthentication) + list, err := gitea.client.Notification.NotifyGetList(params, gitea.transport.DefaultAuthentication) if err != nil { return nil, err } - if !list.IsSuccess() { - return nil, fmt.Errorf("Cannot fetch notifications: %s", list.Error()) - } - return list.Payload, nil } -func (h *RequestHandler) SetNotificationRead(notificationId int64) error { - transport, client := h.allocateGiteaTransport() - list, err := client.Notification.NotifyReadThread( +func (gitea *GiteaTransport) SetNotificationRead(notificationId int64) error { + _, err := gitea.client.Notification.NotifyReadThread( notification.NewNotifyReadThreadParams(). WithDefaults(). WithID(fmt.Sprint(notificationId)), - transport.DefaultAuthentication, + gitea.transport.DefaultAuthentication, ) if err != nil { - log.Printf("Error setting notification: %d: %v\n", notificationId, err) - return err - } - - if !list.IsSuccess() { - return fmt.Errorf("Cannot update notifications: %d", notificationId) + return fmt.Errorf("Error setting notification: %d. Err: %w", notificationId, err) } return nil } -func (h *RequestHandler) CreateRepositoryIfNotExist(org Organization, repoName string) (*models.Repository, error) { - transport, client := h.allocateGiteaTransport() - repo, err := client.Repository.RepoGet( +func (gitea *GiteaTransport) CreateRepositoryIfNotExist(git GitHandler, org Organization, repoName string) (*models.Repository, error) { + repo, err := gitea.client.Repository.RepoGet( repository.NewRepoGetParams().WithDefaults().WithOwner(org.Username).WithRepo(repoName), - transport.DefaultAuthentication) + gitea.transport.DefaultAuthentication) if err != nil { switch err.(type) { case *repository.RepoGetNotFound: - h.StdLogger.Printf("repo '%s' does not exist. Trying to create it ....\n", repoName) - - repo, err := client.Organization.CreateOrgRepo( + repo, err := gitea.client.Organization.CreateOrgRepo( organization.NewCreateOrgRepoParams().WithDefaults().WithBody( &models.CreateRepoOption{ AutoInit: false, @@ -153,44 +143,39 @@ func (h *RequestHandler) CreateRepositoryIfNotExist(org Organization, repoName s if err != nil { switch err.(type) { case *organization.CreateOrgRepoCreated: - h.StdLogger.Printf("repo '%s' created, with notification error?\n", repoName) + // weird, but ok, repo created default: - log.Printf("error creating repo '%s' under '%s': %s\n", repoName, org.Username, err.Error()) - return nil, err + return nil, fmt.Errorf("error creating repo '%s' under '%s'. Err: %w", repoName, org.Username, err) } - } else { - h.StdLogger.Printf("repo '%s' created\n", repoName) } // initialize repository - if err = os.Mkdir(filepath.Join(h.Git.GitPath, DefaultGitPrj), 0700); err != nil { + if err = os.Mkdir(filepath.Join(git.GitPath, DefaultGitPrj), 0700); err != nil { return nil, err } - h.Git.GitExec(DefaultGitPrj, "init", "--object-format="+repo.Payload.ObjectFormatName) - h.Git.GitExec(DefaultGitPrj, "checkout", "-b", repo.Payload.DefaultBranch) - readmeFilename := filepath.Join(h.Git.GitPath, DefaultGitPrj, "README.md") + git.GitExec(DefaultGitPrj, "init", "--object-format="+repo.Payload.ObjectFormatName) + git.GitExec(DefaultGitPrj, "checkout", "-b", repo.Payload.DefaultBranch) + readmeFilename := filepath.Join(git.GitPath, DefaultGitPrj, "README.md") { file, _ := os.Create(readmeFilename) defer file.Close() io.WriteString(file, ReadmeBoilerplate) } - h.Git.GitExec(DefaultGitPrj, "add", "README.md") - h.Git.GitExec(DefaultGitPrj, "commit", "-m", "Automatic devel project creation") - h.Git.GitExec(DefaultGitPrj, "remote", "add", "origin", repo.Payload.SSHURL) + git.GitExec(DefaultGitPrj, "add", "README.md") + git.GitExec(DefaultGitPrj, "commit", "-m", "Automatic devel project creation") + git.GitExec(DefaultGitPrj, "remote", "add", "origin", repo.Payload.SSHURL) return repo.Payload, nil default: - return nil, fmt.Errorf("cannot fetch repo data for '%s' / '%s' : %w", org.Username, repoName, err) + return nil, fmt.Errorf("cannot fetch repo data for '%s' / '%s' : %w", org.Username, repoName, err) } } return repo.Payload, nil } -func (h *RequestHandler) CreatePullRequest(repo *models.Repository, srcId, targetId, title, body string) (*models.PullRequest, error) { - transport, client := h.allocateGiteaTransport() - +func (gitea *GiteaTransport) CreatePullRequest(repo *models.Repository, srcId, targetId, title, body string) (*models.PullRequest, error) { prOptions := models.CreatePullRequestOption{ Base: repo.DefaultBranch, Head: srcId, @@ -198,14 +183,14 @@ func (h *RequestHandler) CreatePullRequest(repo *models.Repository, srcId, targe Body: body, } - pr, err := client.Repository.RepoCreatePullRequest( + pr, err := gitea.client.Repository.RepoCreatePullRequest( repository. NewRepoCreatePullRequestParams(). WithDefaults(). WithOwner(repo.Owner.UserName). WithRepo(repo.Name). WithBody(&prOptions), - transport.DefaultAuthentication, + gitea.transport.DefaultAuthentication, ) if err != nil { @@ -215,21 +200,19 @@ func (h *RequestHandler) CreatePullRequest(repo *models.Repository, srcId, targe return pr.GetPayload(), nil } -func (h *RequestHandler) RequestReviews(pr *models.PullRequest, reviewer string) ([]*models.PullReview, error) { - transport, client := h.allocateGiteaTransport() - +func (gitea *GiteaTransport) RequestReviews(pr *models.PullRequest, reviewer string) ([]*models.PullReview, error) { reviewOptions := models.PullReviewRequestOptions{ Reviewers: []string{reviewer}, } - review, err := client.Repository.RepoCreatePullReviewRequests( + review, err := gitea.client.Repository.RepoCreatePullReviewRequests( repository. NewRepoCreatePullReviewRequestsParams(). WithOwner(pr.Base.Repo.Owner.UserName). WithRepo(pr.Base.Repo.Name). WithIndex(pr.Index). WithBody(&reviewOptions), - transport.DefaultAuthentication, + gitea.transport.DefaultAuthentication, ) if err != nil { @@ -239,8 +222,7 @@ func (h *RequestHandler) RequestReviews(pr *models.PullRequest, reviewer string) return review.GetPayload(), nil } -func (h *RequestHandler) IsReviewed(pr *models.PullRequest) (bool, error) { - transport, client := h.allocateGiteaTransport() +func (gitea *GiteaTransport) IsReviewed(pr *models.PullRequest) (bool, error) { // TODO: get review from project git reviewers := pr.RequestedReviewers var page, limit int64 @@ -248,13 +230,13 @@ func (h *RequestHandler) IsReviewed(pr *models.PullRequest) (bool, error) { page = 0 limit = 20 for { - res, err := client.Repository.RepoListPullReviews( + res, err := gitea.client.Repository.RepoListPullReviews( repository.NewRepoListPullReviewsParams(). WithOwner(pr.Base.Repo.Owner.UserName). WithRepo(pr.Base.Repo.Name). WithPage(&page). WithLimit(&limit), - transport.DefaultAuthentication) + gitea.transport.DefaultAuthentication) if err != nil { return false, err @@ -282,10 +264,10 @@ func (h *RequestHandler) IsReviewed(pr *models.PullRequest) (bool, error) { continue } - next_review: + next_review: for i, reviewer := range reviewers { if review.User.UserName == reviewer.UserName { - switch (review.State) { + switch review.State { case ReviewStateApproved: reviewers = slices.Delete(reviewers, i, i) break next_review @@ -299,12 +281,8 @@ func (h *RequestHandler) IsReviewed(pr *models.PullRequest) (bool, error) { return len(reviewers) == 0, nil } -func (h *RequestHandler) AddReviewComment(pr *models.PullRequest, state models.ReviewStateType, comment string) (*models.PullReview, error) { - transport, client := h.allocateGiteaTransport() - - h.StdLogger.Printf("%#v", *pr) - - c, err := client.Repository.RepoCreatePullReview( +func (gitea *GiteaTransport) AddReviewComment(pr *models.PullRequest, state models.ReviewStateType, comment string) (*models.PullReview, error) { + c, err := gitea.client.Repository.RepoCreatePullReview( repository.NewRepoCreatePullReviewParams(). WithDefaults(). WithOwner(pr.Base.Repo.Owner.UserName). @@ -314,7 +292,7 @@ func (h *RequestHandler) AddReviewComment(pr *models.PullRequest, state models.R Event: state, Body: comment, }), - transport.DefaultAuthentication, + gitea.transport.DefaultAuthentication, ) /* c, err := client.Repository.RepoSubmitPullReview( @@ -350,14 +328,12 @@ func (h *RequestHandler) AddReviewComment(pr *models.PullRequest, state models.R return c.Payload, nil } -func (h *RequestHandler) GetAssociatedPrjGitPR(pr *PullRequestWebhookEvent) (*models.PullRequest, error) { - transport, client := h.allocateGiteaTransport() - +func (gitea *GiteaTransport) GetAssociatedPrjGitPR(pr *PullRequestWebhookEvent) (*models.PullRequest, error) { var page, maxSize int64 page = 1 maxSize = 10000 state := "open" - prs, err := client.Repository.RepoListPullRequests( + prs, err := gitea.client.Repository.RepoListPullRequests( repository. NewRepoListPullRequestsParams(). WithDefaults(). @@ -366,14 +342,14 @@ func (h *RequestHandler) GetAssociatedPrjGitPR(pr *PullRequestWebhookEvent) (*mo WithState(&state). WithLimit(&maxSize). WithPage(&page), - transport.DefaultAuthentication) + gitea.transport.DefaultAuthentication) if err != nil { return nil, fmt.Errorf("cannot fetch PR list for %s / %s : %w", pr.Repository.Owner.Username, pr.Repository.Name, err) } prLine := fmt.Sprintf(PrPattern, pr.Repository.Owner.Username, pr.Repository.Name, pr.Number) - h.StdLogger.Printf("attemping to match line: '%s'\n", prLine) +// h.StdLogger.Printf("attemping to match line: '%s'\n", prLine) // payload_processing: for _, pr := range prs.Payload { @@ -389,8 +365,7 @@ func (h *RequestHandler) GetAssociatedPrjGitPR(pr *PullRequestWebhookEvent) (*mo return nil, nil } -func (h *RequestHandler) GetRepositoryFileContent(repo *models.Repository, hash, path string) ([]byte, error) { - transport, client := h.allocateGiteaTransport() +func (gitea *GiteaTransport) GetRepositoryFileContent(repo *models.Repository, hash, path string) ([]byte, error) { var retData []byte dataOut := writeFunc(func(data []byte) (int, error) { @@ -400,13 +375,13 @@ func (h *RequestHandler) GetRepositoryFileContent(repo *models.Repository, hash, retData = data return len(data), nil }) - _, err := client.Repository.RepoGetRawFile( + _, err := gitea.client.Repository.RepoGetRawFile( repository.NewRepoGetRawFileParams(). WithOwner(repo.Owner.UserName). WithRepo(repo.Name). WithFilepath(path). WithRef(&hash), - transport.DefaultAuthentication, + gitea.transport.DefaultAuthentication, dataOut, repository.WithContentTypeApplicationOctetStream, ) @@ -418,6 +393,6 @@ func (h *RequestHandler) GetRepositoryFileContent(repo *models.Repository, hash, return retData, nil } -func (h *RequestHandler) GetPullRequestFileContent(pr *models.PullRequest, path string) ([]byte, error) { - return h.GetRepositoryFileContent(pr.Head.Repo, pr.Head.Sha, path) +func (gitea *GiteaTransport) GetPullRequestFileContent(pr *models.PullRequest, path string) ([]byte, error) { + return gitea.GetRepositoryFileContent(pr.Head.Repo, pr.Head.Sha, path) } diff --git a/prjgit-updater/main.go b/prjgit-updater/main.go index f278552..5bed583 100644 --- a/prjgit-updater/main.go +++ b/prjgit-updater/main.go @@ -20,6 +20,7 @@ type ConfigRepos struct { } var configuredRepos map[string]ConfigRepos +var gitea *common.GiteaTransport func isConfiguredOrg(org *common.Organization) bool { _, found := configuredRepos[org.Username] @@ -45,7 +46,7 @@ func processRepositoryAction(h *common.RequestHandler) error { return nil } - prjGitRepo, err := h.CreateRepositoryIfNotExist(*action.Organization, prjgit) + prjGitRepo, err := gitea.CreateRepositoryIfNotExist(h.Git, *action.Organization, prjgit) if err != nil { return fmt.Errorf("Error accessing/creating prjgit: %s err: %w", prjgit, err) } @@ -94,7 +95,7 @@ func processPushAction(h *common.RequestHandler) error { return nil } - prjGitRepo, err := h.CreateRepositoryIfNotExist(*action.Repository.Owner, prjgit) + prjGitRepo, err := gitea.CreateRepositoryIfNotExist(h.Git, *action.Repository.Owner, prjgit) if err != nil { return fmt.Errorf("Error accessing/creating prjgit: %s err: %w", prjgit, err) } @@ -159,6 +160,7 @@ var debugMode bool func main() { workflowConfig := flag.String("config", "", "Repository and workflow definition file") + giteaHost := flag.String("gitea", "src.opensuse.org", "Gitea instance") rabbitUrl := flag.String("url", "amqps://rabbit.opensuse.org", "URL for RabbitMQ instance") flag.BoolVar(&debugMode, "debug", false, "Extra debugging information") flag.BoolVar(&checkOnStart, "check-on-start", false, "Check all repositories for consistency on start, without delays") @@ -191,6 +193,8 @@ func main() { } } + gitea = common.AllocateGiteaTransport(*giteaHost) + var defs common.ListenDefinitions defs.GitAuthor = "GiteaBot - AutoDevel"