189 lines
4.9 KiB
Go
189 lines
4.9 KiB
Go
package plugin
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"regexp"
|
|
"text/template"
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
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 {
|
|
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 != "" {
|
|
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]
|
|
}
|
|
}
|
|
|
|
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()
|
|
|
|
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
|
|
}
|