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"` 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 { 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 { 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) } } 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) } 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) fmt.Printf("Successfully created release at %s", releaseURL) 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 }