This commit is contained in:
Izrafil Archimedes
2026-02-23 09:20:56 +01:00
commit fccdc61545
18 changed files with 1595 additions and 0 deletions

234
pkg/provider/zexlab.go Normal file
View File

@@ -0,0 +1,234 @@
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
}