package plugin import ( "bytes" "context" "fmt" "os" "regexp" "text/template" "code.gitea.io/sdk/gitea" ) var ( defaultTitleFormat = "Release {{.Tag}}" defaultTagRegex = regexp.MustCompile(`((?P[\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"` 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"` } 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 { fmt.Println("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 { tag, err = getLatestGitTag() if err != nil { return fmt.Errorf("error getting git tag %w", err) } } else if args.TagFile != "" { 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] } } } 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() client, err := gitea.NewClient(args.GiteaUrl, gitea.SetBasicAuth(args.GiteaUsername, args.GiteaPassword)) if err != nil { return fmt.Errorf("error creating Gitea client %w", err) } _, _, 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) } return err }