220 lines
5.6 KiB
Go
220 lines
5.6 KiB
Go
package common
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
transport "github.com/go-openapi/runtime/client"
|
|
apiclient "src.opensuse.org/autogits/common/gitea-generated/client"
|
|
"src.opensuse.org/autogits/common/gitea-generated/client/organization"
|
|
"src.opensuse.org/autogits/common/gitea-generated/client/repository"
|
|
"src.opensuse.org/autogits/common/gitea-generated/models"
|
|
)
|
|
|
|
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)
|
|
}
|
|
|
|
func (h *RequestHandler) CreateRepositoryIfNotExist(org Organization, repoName string) *models.Repository {
|
|
if h.HasError() {
|
|
return nil
|
|
}
|
|
|
|
transport, client := h.allocateGiteaTransport()
|
|
repo, err := client.Repository.RepoGet(
|
|
repository.NewRepoGetParams().WithDefaults().WithOwner(org.Username).WithRepo(repoName),
|
|
transport.DefaultAuthentication)
|
|
|
|
if err != nil {
|
|
switch err.(type) {
|
|
case *repository.RepoGetNotFound:
|
|
h.Log("repo '%s' does not exist. Trying to create it ....", repoName)
|
|
|
|
repo, err := client.Organization.CreateOrgRepo(
|
|
organization.NewCreateOrgRepoParams().WithDefaults().WithBody(
|
|
&models.CreateRepoOption{
|
|
AutoInit: false,
|
|
Name: &repoName,
|
|
ObjectFormatName: models.CreateRepoOptionObjectFormatNameSha256,
|
|
},
|
|
).WithOrg(org.Username),
|
|
nil,
|
|
)
|
|
|
|
if err != nil {
|
|
switch err.(type) {
|
|
case *organization.CreateOrgRepoCreated:
|
|
h.Log("repo '%s' created, with notification error?", repoName)
|
|
default:
|
|
h.Error = err
|
|
h.LogError("error creating repo '%s' under '%s': %s", repoName, org.Username, err.Error())
|
|
return nil
|
|
}
|
|
} else {
|
|
h.Log("repo '%s' created", repoName)
|
|
}
|
|
|
|
// initialize repository
|
|
h.Error = os.Mkdir(filepath.Join(h.GitPath, DefaultGitPrj), 0700)
|
|
if h.HasError() {
|
|
return nil
|
|
}
|
|
h.GitExec(DefaultGitPrj, "init", "--object-format="+repo.Payload.ObjectFormatName)
|
|
h.GitExec(DefaultGitPrj, "checkout", "-b", repo.Payload.DefaultBranch)
|
|
if h.HasError() {
|
|
return nil
|
|
}
|
|
readmeFilename := filepath.Join(h.GitPath, DefaultGitPrj, "README.md")
|
|
{
|
|
file, _ := os.Create(readmeFilename)
|
|
defer file.Close()
|
|
|
|
io.WriteString(file, ReadmeBoilerplate)
|
|
}
|
|
h.GitExec(DefaultGitPrj, "add", "README.md")
|
|
h.GitExec(DefaultGitPrj, "commit", "-m", "Automatic devel project creation")
|
|
h.GitExec(DefaultGitPrj, "remote", "add", "origin", repo.Payload.SSHURL)
|
|
|
|
return repo.Payload
|
|
default:
|
|
h.Error = err
|
|
h.LogError("cannot fetch repo data for '%s' / '%s' : %w", org.Username, repoName, err)
|
|
}
|
|
}
|
|
|
|
return repo.Payload
|
|
}
|
|
|
|
func (h *RequestHandler) CreatePullRequest(repo *models.Repository, srcId, targetId, title, body string) *models.PullRequest {
|
|
if h.HasError() {
|
|
return nil
|
|
}
|
|
|
|
transport, client := h.allocateGiteaTransport()
|
|
|
|
prOptions := models.CreatePullRequestOption{
|
|
Base: repo.DefaultBranch,
|
|
Head: srcId,
|
|
Title: title,
|
|
Body: body,
|
|
}
|
|
|
|
pr, err := client.Repository.RepoCreatePullRequest(
|
|
repository.
|
|
NewRepoCreatePullRequestParams().
|
|
WithDefaults().
|
|
WithOwner(repo.Owner.UserName).
|
|
WithRepo(repo.Name).
|
|
WithBody(&prOptions),
|
|
transport.DefaultAuthentication,
|
|
)
|
|
|
|
if err != nil {
|
|
h.LogError("Cannot create pull request: %v", err)
|
|
h.Error = err
|
|
return nil
|
|
}
|
|
|
|
if !pr.IsSuccess() {
|
|
h.LogError("PR creation failed: %s", pr.Error())
|
|
h.Error = errors.New(pr.Error())
|
|
return nil
|
|
}
|
|
|
|
return pr.GetPayload()
|
|
}
|
|
|
|
func (h *RequestHandler) RequestReviews(pr *models.PullRequest, reviewer string) []*models.PullReview {
|
|
if h.HasError() {
|
|
return nil
|
|
}
|
|
|
|
transport, client := h.allocateGiteaTransport()
|
|
|
|
reviewOptions := models.PullReviewRequestOptions{
|
|
Reviewers: []string{reviewer},
|
|
}
|
|
|
|
review, err := client.Repository.RepoCreatePullReviewRequests(
|
|
repository.
|
|
NewRepoCreatePullReviewRequestsParams().
|
|
WithOwner(pr.Base.Repo.Owner.UserName).
|
|
WithRepo(pr.Base.Repo.Name).
|
|
WithIndex(pr.Index).
|
|
WithBody(&reviewOptions),
|
|
transport.DefaultAuthentication,
|
|
)
|
|
|
|
if err != nil {
|
|
h.LogError("Cannot create pull request: %v", err)
|
|
h.Error = err
|
|
return nil
|
|
}
|
|
|
|
if !review.IsSuccess() {
|
|
h.LogError("PR creation failed: %s", review.Error())
|
|
h.Error = errors.New(review.Error())
|
|
return nil
|
|
}
|
|
|
|
return review.GetPayload()
|
|
}
|
|
|
|
func (h *RequestHandler) GetAssociatedPrjGitPR(pr *PullRequestAction) *models.PullRequest {
|
|
if h.HasError() {
|
|
return nil
|
|
}
|
|
|
|
transport, client := h.allocateGiteaTransport()
|
|
|
|
var page, maxSize int64;
|
|
page = 1
|
|
maxSize = 10000
|
|
state := "open"
|
|
prs, err := client.Repository.RepoListPullRequests(
|
|
repository.
|
|
NewRepoListPullRequestsParams().
|
|
WithDefaults().
|
|
WithOwner(pr.Repository.Owner.Username).
|
|
WithRepo(DefaultGitPrj).
|
|
WithState(&state).
|
|
WithLimit(&maxSize).
|
|
WithPage(&page),
|
|
transport.DefaultAuthentication)
|
|
|
|
if err != nil {
|
|
h.Error = fmt.Errorf("cannot fetch PR list for %s / %s : %v", pr.Repository.Owner.Username, pr.Repository.Name, err)
|
|
return nil
|
|
}
|
|
|
|
if !prs.IsSuccess() {
|
|
h.Error = fmt.Errorf("cannot fetch PR list for %s / %s : %s", pr.Repository.Owner.Username, pr.Repository.Name, prs.Error())
|
|
}
|
|
|
|
prLine := fmt.Sprintf(PrPattern, pr.Repository.Owner.Username, pr.Repository.Name, pr.Number)
|
|
h.Log("attemping to match line: '%s'", prLine)
|
|
|
|
// payload_processing:
|
|
for _, pr := range prs.Payload {
|
|
lines := strings.Split(pr.Body, "\n")
|
|
|
|
for _, line := range lines {
|
|
if strings.TrimSpace(line) == prLine {
|
|
return pr
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|