144 lines
3.0 KiB
Go
144 lines
3.0 KiB
Go
|
package gitproviders
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"sync"
|
||
|
|
||
|
"code.gitea.io/sdk/gitea"
|
||
|
"go.uber.org/zap"
|
||
|
)
|
||
|
|
||
|
type Gitea struct {
|
||
|
logger *zap.Logger
|
||
|
giteamu sync.Mutex
|
||
|
giteaClients map[string]*gitea.Client
|
||
|
}
|
||
|
|
||
|
func NewGitea(logger *zap.Logger) *Gitea {
|
||
|
return &Gitea{
|
||
|
logger: logger,
|
||
|
giteamu: sync.Mutex{},
|
||
|
giteaClients: make(map[string]*gitea.Client, 0),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (g *Gitea) ListRepositoriesForOrganization(
|
||
|
ctx context.Context,
|
||
|
server string,
|
||
|
organization string,
|
||
|
) ([]string, error) {
|
||
|
client, err := g.getOrCreateClient(ctx, server)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
g.logger.Debug("Listing repos for gitea", zap.String("server", server))
|
||
|
repos, resp, err := client.ListOrgRepos(organization, gitea.ListOrgReposOptions{
|
||
|
ListOptions: gitea.ListOptions{
|
||
|
Page: 0,
|
||
|
PageSize: 20,
|
||
|
},
|
||
|
})
|
||
|
if err != nil {
|
||
|
return nil, fmt.Errorf("could not list repos: %w", err)
|
||
|
}
|
||
|
|
||
|
if resp.StatusCode >= 300 {
|
||
|
return nil, fmt.Errorf("gitea responded with a non 200 status code (gitea response: %s)", resp.Status)
|
||
|
}
|
||
|
|
||
|
repoUrls := make([]string, len(repos))
|
||
|
for i, repo := range repos {
|
||
|
repoUrls[i] = repo.SSHURL
|
||
|
}
|
||
|
|
||
|
return repoUrls, err
|
||
|
}
|
||
|
|
||
|
func (g *Gitea) CreatePr(
|
||
|
ctx context.Context,
|
||
|
server string,
|
||
|
organization string,
|
||
|
repository string,
|
||
|
head string,
|
||
|
base string,
|
||
|
actionName string,
|
||
|
) error {
|
||
|
client, err := g.getOrCreateClient(ctx, server)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
prs, _, err := client.ListRepoPullRequests(organization, repository, gitea.ListPullRequestsOptions{
|
||
|
ListOptions: gitea.ListOptions{
|
||
|
Page: 0,
|
||
|
PageSize: 30,
|
||
|
},
|
||
|
State: gitea.StateOpen,
|
||
|
Sort: "recentupdate",
|
||
|
Milestone: 0,
|
||
|
})
|
||
|
if err != nil {
|
||
|
return fmt.Errorf(
|
||
|
"could not list repos, needed because we need to check for conflicts. Original error: %w",
|
||
|
err,
|
||
|
)
|
||
|
}
|
||
|
for _, pr := range prs {
|
||
|
if pr.Head.Name == head {
|
||
|
g.logger.Info(
|
||
|
"returning early from creating pull-request, as it already exists.",
|
||
|
zap.String("repository", repository),
|
||
|
zap.String("pull-request", pr.URL),
|
||
|
)
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pr, _, err := client.CreatePullRequest(organization, repository, gitea.CreatePullRequestOption{
|
||
|
Head: head,
|
||
|
Base: base,
|
||
|
Title: actionName,
|
||
|
})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
g.logger.Debug(
|
||
|
"Created pr",
|
||
|
zap.String("repository", repository),
|
||
|
zap.String("branch", head),
|
||
|
zap.String("pull-request", pr.URL),
|
||
|
)
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (g *Gitea) getOrCreateClient(ctx context.Context, server string) (*gitea.Client, error) {
|
||
|
g.giteamu.Lock()
|
||
|
defer g.giteamu.Unlock()
|
||
|
client, ok := g.giteaClients[server]
|
||
|
if !ok || client == nil {
|
||
|
c, err := gitea.NewClient(server)
|
||
|
username, ok := os.LookupEnv("GITEA_USERNAME")
|
||
|
if !ok {
|
||
|
return nil, errors.New("missing environment variable GITEA_USERNAME")
|
||
|
}
|
||
|
apitoken, ok := os.LookupEnv("GITEA_API_TOKEN")
|
||
|
if !ok {
|
||
|
return nil, errors.New("missing environment variable GITEA_API_TOKEN")
|
||
|
}
|
||
|
c.SetBasicAuth(username, apitoken)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
g.giteaClients[server] = c
|
||
|
return c, nil
|
||
|
}
|
||
|
|
||
|
return client, nil
|
||
|
}
|