drone-gitea-release/plugin/plugin.go

189 lines
4.9 KiB
Go
Raw Permalink Normal View History

package plugin
import (
"bytes"
"context"
"fmt"
"os"
"regexp"
"text/template"
"code.gitea.io/sdk/gitea"
2024-07-11 15:09:36 +00:00
log "github.com/sirupsen/logrus"
)
var (
defaultTitleFormat = "Release {{.Tag}}"
defaultTagRegex = regexp.MustCompile(`((?P<version>[\d]+\.[\d]+\.[\w-]+))`)
)
// Args provides plugin execution arguments.
type Args struct {
Pipeline
// Level defines the plugin log level.
Level string `envconfig:"PLUGIN_LOG_LEVEL"`
GiteaUrl string `envconfig:"PLUGIN_GITEA_URL"`
GiteaUsername string `envconfig:"PLUGIN_GITEA_USERNAME"`
GiteaPassword string `envconfig:"PLUGIN_GITEA_PASSWORD"`
GitUsername string `envconfig:"PLUGIN_GIT_USERNAME"`
GitPassword string `envconfig:"PLUGIN_GIT_PASSWORD"`
Owner string `envconfig:"PLUGIN_OWNER"`
Repo string `envconfig:"PLUGIN_REPO"`
TitleFormat string `envconfig:"PLUGIN_TITLE_FORMAT"`
UseLatestGitTag bool `envconfig:"PLUGIN_USE_LATEST_GIT_TAG" default:"true"`
TagFile string `envconfig:"PLUGIN_TAG_FILE"`
TagRegex string `envconfig:"PLUGIN_TAG_REGEX"`
NotesFile string `envconfig:"PLUGIN_NOTES_FILE"`
Notes string `envconfig:"PLUGIN_NOTES"`
IsPrerelease bool `envconfig:"PLUGIN_IS_PRERELEASE"`
SkipIfNoNotesFile bool `envconfig:"PLUGIN_SKIP_IF_NO_NOTES_FILE"`
FetchGitTags bool `envconfig:"PLUGIN_FETCH_GIT_TAGS" default:"true"`
}
type ReleaseCard struct {
Title string
Tag string
Url string
}
type TitleTemplateCtx struct {
Tag string
GiteaUrl string
Owner string
Repo string
IsPrerelease bool
}
// Exec executes the plugin.
func Exec(ctx context.Context, args Args) error {
var (
note string
tag string
title string
err error
)
if args.Notes != "" {
note = args.Notes
} else if args.NotesFile != "" {
content, err := os.ReadFile(args.NotesFile)
if err != nil {
if os.IsNotExist(err) && args.SkipIfNoNotesFile {
2024-07-11 15:09:36 +00:00
log.Info("No notes file found, skipping release")
return nil
}
return fmt.Errorf("error reading notes file %w", err)
}
note = string(content)
} else {
return fmt.Errorf("notes or notes file must be specified")
}
if args.UseLatestGitTag {
var options = make([]GetLatestGitTagOption, 0)
if args.GitUsername != "" && args.GitPassword != "" {
options = append(options, SetBasicAuth(args.GitUsername, args.GitPassword))
}
if args.FetchGitTags {
options = append(options, FetchTags())
}
tag, err = getLatestGitTag(options...)
if err != nil {
return fmt.Errorf("error getting git tag %w", err)
}
log.WithField("tag", tag).Info("Fetched latest git tag")
} else if args.TagFile != "" {
2024-07-11 15:09:36 +00:00
log.WithField("file", args.TagFile).Info("Reading tag from file")
var pattern = defaultTagRegex
if args.TagRegex != "" {
pattern = regexp.MustCompile(args.TagRegex)
}
content, err := os.ReadFile(args.TagFile)
if err != nil {
return fmt.Errorf("error reading tag file %w", err)
}
matches := pattern.FindStringSubmatch(string(content))
if len(matches) == 0 {
return fmt.Errorf("no matches found in tag file")
}
for i, name := range pattern.SubexpNames() {
if name == "version" {
tag = matches[i]
}
}
2024-07-11 15:09:36 +00:00
log.WithField("tag", tag).Info("Found tag")
} else {
return fmt.Errorf("latest git tag or tag file must be given")
}
var titleTmpl *template.Template
if args.TitleFormat != "" {
titleTmpl, err = template.New("title").Parse(args.TitleFormat)
} else {
titleTmpl, err = template.New("title").Parse(defaultTitleFormat)
}
if err != nil {
return fmt.Errorf("error reading template %w", err)
}
var titleBytes []byte
var titleBuffer = bytes.NewBuffer(titleBytes)
if err = titleTmpl.Execute(titleBuffer, TitleTemplateCtx{Tag: tag, GiteaUrl: args.GiteaUrl, Owner: args.Owner, Repo: args.Repo}); err != nil {
return fmt.Errorf("error reading template %w", err)
}
title = titleBuffer.String()
2024-07-11 15:09:36 +00:00
log.WithFields(log.Fields{
"template": titleTmpl.DefinedTemplates(),
"title": title,
}).Info("Generated title with template")
client, err := gitea.NewClient(args.GiteaUrl, gitea.SetBasicAuth(args.GiteaUsername, args.GiteaPassword))
if err != nil {
return fmt.Errorf("error creating Gitea client %w", err)
}
release, _, err := client.CreateRelease(args.Owner, args.Repo, gitea.CreateReleaseOption{
TagName: tag,
Title: title,
Note: note,
IsPrerelease: args.IsPrerelease,
})
if err != nil {
return fmt.Errorf("error creating Gitea release %w", err)
}
releaseURL := fmt.Sprintf("%s/%s/%s/releases/tag/%s", args.GiteaUrl, args.Owner, args.Repo, release.TagName)
log.WithField("url", releaseURL).Info("Successfully created release")
writeCard(
args.Pipeline.Card.Path,
"https://gitea.dikurium.ch/InnoPeak/drone-gitea-release/raw/branch/main/card.json",
ReleaseCard{
Title: title,
Tag: tag,
Url: releaseURL,
},
)
return err
}