235 lines
5.7 KiB
Go
235 lines
5.7 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
"github.com/Masterminds/semver/v3"
|
|
"github.com/go-semantic-release/semantic-release/v2/pkg/provider"
|
|
"github.com/go-semantic-release/semantic-release/v2/pkg/semrel"
|
|
)
|
|
|
|
var PVERSION = "dev"
|
|
|
|
var zexlabServerURL = "https://zexlab.dev"
|
|
|
|
type ZexlabRepository struct {
|
|
client *gitea.Client
|
|
repo string
|
|
owner string
|
|
stripVTagPrefix bool
|
|
}
|
|
|
|
// gocyclo:ignore
|
|
func (repo *ZexlabRepository) Init(config map[string]string) error {
|
|
serverURL := config["server_url"]
|
|
if serverURL == "" {
|
|
serverURL = zexlabServerURL
|
|
}
|
|
|
|
slug := config["slug"]
|
|
|
|
if slug == "" {
|
|
slug = os.Getenv("GITHUB_REPOSITORY")
|
|
}
|
|
// Maybe we are running in Gitea Actions
|
|
if slug == "" {
|
|
slug = os.Getenv("GITEA_REPOSITORY")
|
|
}
|
|
// Maybe we are running in WoodpeckerCI
|
|
if slug == "" {
|
|
slug = os.Getenv("CI_REPO_NAME")
|
|
}
|
|
|
|
token := config["token"]
|
|
if token == "" {
|
|
token = os.Getenv("GITEA_TOKEN")
|
|
}
|
|
if token == "" {
|
|
return fmt.Errorf("zexlab token missing")
|
|
}
|
|
|
|
if !strings.Contains(slug, "/") {
|
|
return fmt.Errorf("invalid slug")
|
|
}
|
|
split := strings.Split(slug, "/")
|
|
// This could be due to act locally
|
|
// We'll work backwards to get the values
|
|
repo.owner = split[len(split)-2]
|
|
repo.repo = split[len(split)-1]
|
|
|
|
// Ensure no .git suffix remains
|
|
repo.repo = strings.TrimSuffix(repo.repo, ".git")
|
|
|
|
ctx := context.Background()
|
|
|
|
client, err := gitea.NewClient(serverURL,
|
|
gitea.SetToken(token),
|
|
gitea.SetContext(ctx))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
repo.client = client
|
|
|
|
stripVTagPrefix := config["strip_v_tag_prefix"]
|
|
repo.stripVTagPrefix, err = strconv.ParseBool(stripVTagPrefix)
|
|
|
|
if stripVTagPrefix != "" && err != nil {
|
|
return fmt.Errorf("failed to set property strip_v_tag_prefix: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (repo *ZexlabRepository) GetInfo() (*provider.RepositoryInfo, error) {
|
|
r, _, err := repo.client.GetRepo(repo.owner, repo.repo)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &provider.RepositoryInfo{
|
|
Owner: r.Owner.UserName,
|
|
Repo: r.Name,
|
|
DefaultBranch: r.DefaultBranch,
|
|
Private: r.Private,
|
|
}, nil
|
|
}
|
|
|
|
func (repo *ZexlabRepository) GetCommits(_, toSha string) ([]*semrel.RawCommit, error) {
|
|
allCommits := make([]*semrel.RawCommit, 0)
|
|
opts := &gitea.ListOptions{PageSize: 100}
|
|
for {
|
|
commits, resp, err := repo.client.ListRepoCommits(repo.owner, repo.repo, gitea.ListCommitOptions{
|
|
SHA: toSha,
|
|
ListOptions: *opts,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, commit := range commits {
|
|
sha := commit.SHA
|
|
|
|
// Resolve author info: prefer Gitea user, fallback to git commit data
|
|
authorLogin := ""
|
|
authorName := commit.RepoCommit.Author.Name
|
|
authorEmail := commit.RepoCommit.Author.Email
|
|
if commit.Author != nil {
|
|
authorLogin = commit.Author.UserName
|
|
authorName = commit.Author.FullName
|
|
authorEmail = commit.Author.Email
|
|
}
|
|
|
|
// Resolve committer info: prefer Gitea user, fallback to git commit data
|
|
committerLogin := ""
|
|
committerName := commit.RepoCommit.Committer.Name
|
|
committerEmail := commit.RepoCommit.Committer.Email
|
|
if commit.Committer != nil {
|
|
committerLogin = commit.Committer.UserName
|
|
committerName = commit.Committer.FullName
|
|
committerEmail = commit.Committer.Email
|
|
}
|
|
|
|
allCommits = append(allCommits, &semrel.RawCommit{
|
|
SHA: sha,
|
|
RawMessage: commit.RepoCommit.Message,
|
|
Annotations: map[string]string{
|
|
"author_login": authorLogin,
|
|
"author_name": authorName,
|
|
"author_email": authorEmail,
|
|
"author_date": commit.RepoCommit.Author.Date,
|
|
"committer_login": committerLogin,
|
|
"committer_name": committerName,
|
|
"committer_email": committerEmail,
|
|
"committer_date": commit.RepoCommit.Committer.Date,
|
|
},
|
|
})
|
|
}
|
|
if resp.NextPage == 0 {
|
|
break
|
|
}
|
|
opts.Page = resp.NextPage
|
|
}
|
|
return allCommits, nil
|
|
}
|
|
|
|
//gocyclo:ignore
|
|
func (repo *ZexlabRepository) GetReleases(rawRe string) ([]*semrel.Release, error) {
|
|
re := regexp.MustCompile(rawRe)
|
|
allReleases := make([]*semrel.Release, 0)
|
|
|
|
refs, resp, err := repo.client.GetRepoRefs(repo.owner, repo.repo, "")
|
|
if resp != nil && resp.StatusCode == 404 {
|
|
return allReleases, nil
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, r := range refs {
|
|
tag := strings.TrimPrefix(r.Ref, "refs/tags/")
|
|
if rawRe != "" && !re.MatchString(tag) {
|
|
continue
|
|
}
|
|
objType := r.Object.Type
|
|
if objType != "commit" && objType != "tag" {
|
|
continue
|
|
}
|
|
foundSha := r.Object.SHA
|
|
// resolve annotated tag
|
|
if objType == "tag" {
|
|
resTag, _, err := repo.client.GetRepoRef(repo.owner, repo.repo, foundSha)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if resTag.Object.Type != "commit" {
|
|
continue
|
|
}
|
|
foundSha = resTag.Object.SHA
|
|
}
|
|
version, err := semver.NewVersion(tag)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
allReleases = append(allReleases, &semrel.Release{SHA: foundSha, Version: version.String()})
|
|
}
|
|
|
|
return allReleases, nil
|
|
}
|
|
|
|
func (repo *ZexlabRepository) CreateRelease(release *provider.CreateReleaseConfig) error {
|
|
prefix := "v"
|
|
if repo.stripVTagPrefix {
|
|
prefix = ""
|
|
}
|
|
|
|
tag := prefix + release.NewVersion
|
|
isPrerelease := release.Prerelease || semver.MustParse(release.NewVersion).Prerelease() != ""
|
|
|
|
opt := gitea.CreateReleaseOption{
|
|
TagName: tag,
|
|
Target: release.Branch,
|
|
Title: tag,
|
|
Note: release.Changelog,
|
|
IsPrerelease: isPrerelease,
|
|
}
|
|
|
|
_, _, err := repo.client.CreateRelease(repo.owner, repo.repo, opt)
|
|
if err != nil {
|
|
return fmt.Errorf("error returned %w, tag value [%s]", err, tag)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (repo *ZexlabRepository) Name() string {
|
|
return "Zexlab"
|
|
}
|
|
|
|
func (repo *ZexlabRepository) Version() string {
|
|
return PVERSION
|
|
}
|