Compare commits

...

24 Commits
0.7.0 ... main

Author SHA1 Message Date
964ea60e55 chore: bump 0.12.0 → 0.13.0 [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
2024-10-25 16:16:43 +00:00
2386e278c7 Merge branch 'main' of https://gitea.dikurium.ch/InnoPeak/drone-gitea-release into main
Some checks failed
continuous-integration/drone/push Build is failing
2024-10-25 18:16:24 +02:00
66de41874d feat: use time.Time.Before() instead of Sub() 2024-10-25 18:16:24 +02:00
9aace7aa2b chore: bump 0.11.1 → 0.12.0 [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
2024-10-25 16:14:51 +00:00
6c787535a8 feat: use tagger.when to find latest tag
Some checks failed
continuous-integration/drone/push Build is failing
2024-10-25 18:14:25 +02:00
e65c52c67c chore: bump 0.11.0 → 0.11.1 [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
2024-07-11 17:54:57 +02:00
d19022dad8 fix: 🐛 append newline after success message, use logger [CI SKIP] 2024-07-11 17:54:33 +02:00
2daf8b0d53 chore: bump 0.10.1 → 0.11.0 [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
2024-07-11 15:34:11 +00:00
d9f25a2613 Merge branch 'main' of https://gitea.dikurium.ch/InnoPeak/drone-gitea-release into main
Some checks failed
continuous-integration/drone/push Build is failing
2024-07-11 17:33:48 +02:00
b2c43a5f3d feat: use log.textformatter 2024-07-11 17:33:47 +02:00
1c9f839870 chore: bump 0.10.0 → 0.10.1 [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
2024-07-11 15:26:02 +00:00
76e800c9d4 Merge branch 'main' of https://gitea.dikurium.ch/InnoPeak/drone-gitea-release into main
Some checks failed
continuous-integration/drone/push Build is failing
2024-07-11 17:25:35 +02:00
fe6812860e fix: revert: fix: 🐛 use latest instead of last (oldest) tag
- Add logs
2024-07-11 17:25:35 +02:00
8ff9355fcf chore: bump 0.9.0 → 0.10.0 [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
2024-07-11 15:09:55 +00:00
913e80c62b Merge branch 'main' of https://gitea.dikurium.ch/InnoPeak/drone-gitea-release into main
Some checks failed
continuous-integration/drone/push Build is failing
2024-07-11 17:09:36 +02:00
cecbbddd07 feat: 🔊 add logs 2024-07-11 17:09:36 +02:00
30fafd87cd chore: bump 0.8.1 → 0.9.0 [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
2024-07-11 14:57:20 +00:00
3f0e9dd908 Merge branch 'main' of https://gitea.dikurium.ch/InnoPeak/drone-gitea-release into main
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-11 16:57:03 +02:00
f954801b4e feat: add support for adaptive cards 2024-07-11 16:57:02 +02:00
65beb47d43 chore: bump 0.8.0 → 0.8.1 [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
2024-07-11 14:55:38 +00:00
a7f7cfbc65 fix: 🐛 use latest instead of last (oldest) tag
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-11 16:55:20 +02:00
aca8272527 chore: bump 0.7.0 → 0.8.0 [CI SKIP]
All checks were successful
continuous-integration/drone/tag Build is passing
2024-07-03 12:16:58 +00:00
bc99681992 Merge branch 'main' of https://gitea.dikurium.ch/InnoPeak/drone-gitea-release into main
All checks were successful
continuous-integration/drone/push Build is passing
2024-07-03 14:16:41 +02:00
e11f467042 feat: add git username and password options for http 2024-07-03 14:16:40 +02:00
8 changed files with 218 additions and 44 deletions

View File

@ -30,7 +30,7 @@ steps:
from_secret: docker_username from_secret: docker_username
password: password:
from_secret: docker_password from_secret: docker_password
- image: gitea.dikurium.ch/innopeak/drone-gitea-release:0.6 - image: gitea.dikurium.ch/innopeak/drone-gitea-release:0.7
name: create release name: create release
settings: settings:
gitea_password: gitea_password:

View File

@ -1,3 +1,57 @@
## 0.13.0 (2024-10-25)
### Feat
- :sparkles: use time.Time.Before() instead of Sub()
## 0.12.0 (2024-10-25)
### Feat
- :sparkles: use tagger.when to find latest tag
## 0.11.1 (2024-07-11)
### Fix
- :bug: append newline after success message, use logger [CI SKIP]
## 0.11.0 (2024-07-11)
### Feat
- :sparkles: use log.textformatter
## 0.10.1 (2024-07-11)
### Fix
- revert: :rewind: fix: 🐛 use latest instead of last (oldest) tag - Add logs
## 0.10.0 (2024-07-11)
### Feat
- :loud_sound: add logs
## 0.9.0 (2024-07-11)
### Feat
- :sparkles: add support for adaptive cards
## 0.8.1 (2024-07-11)
### Fix
- :bug: use latest instead of last (oldest) tag
## 0.8.0 (2024-07-03)
### Feat
- :sparkles: add git username and password options for http
## 0.7.0 (2024-07-03) ## 0.7.0 (2024-07-03)
### Feat ### Feat

25
card.json Normal file
View File

@ -0,0 +1,25 @@
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5",
"body": [
{
"type": "TextBlock",
"text": "${title}",
"wrap": true,
"style": "heading"
},
{
"type": "TextBlock",
"text": "Tag: ${tag}",
"wrap": true
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "View release",
"url": "${url}"
}
]
}

25
cards/release.json Normal file
View File

@ -0,0 +1,25 @@
{
"type": "AdaptiveCard",
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.6",
"body": [
{
"type": "TextBlock",
"text": "Publish Adaptive Card Schema",
"wrap": true,
"style": "heading"
},
{
"type": "TextBlock",
"text": "Tag: 1.0.0",
"wrap": true
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "View release",
"url": "https://google.com"
}
]
}

View File

@ -5,5 +5,5 @@ commitizen:
name: cz_conventional_commits name: cz_conventional_commits
tag_format: $version tag_format: $version
update_changelog_on_bump: true update_changelog_on_bump: true
version: 0.7.0 version: 0.13.0
version_scheme: semver version_scheme: semver

34
main.go
View File

@ -6,7 +6,7 @@ import (
"gitea.dikurium.ch/InnoPeak/drone-gitea-release/plugin" "gitea.dikurium.ch/InnoPeak/drone-gitea-release/plugin"
"github.com/kelseyhightower/envconfig" "github.com/kelseyhightower/envconfig"
"github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
flag "github.com/spf13/pflag" flag "github.com/spf13/pflag"
) )
@ -15,7 +15,7 @@ var args plugin.Args
func init() { func init() {
if err := envconfig.Process("", &args); err != nil { if err := envconfig.Process("", &args); err != nil {
logrus.Fatalln(err) log.Fatalln(err)
} }
var ( var (
@ -24,6 +24,7 @@ func init() {
tagRegex *string = flag.String("tag-regex", "", "Regex pattern to look for tag in tag-file") tagRegex *string = flag.String("tag-regex", "", "Regex pattern to look for tag in tag-file")
notes *string = flag.String("notes", "", "Notes to use in release") notes *string = flag.String("notes", "", "Notes to use in release")
notesFile *string = flag.String("notes-file", "", "File to use for release notes") notesFile *string = flag.String("notes-file", "", "File to use for release notes")
logLevel *string = flag.String("log-level", "", "Level for logging")
) )
flag.Parse() flag.Parse()
@ -47,34 +48,25 @@ func init() {
if notesFile != nil && *notesFile != "" { if notesFile != nil && *notesFile != "" {
args.NotesFile = *notesFile args.NotesFile = *notesFile
} }
if logLevel != nil && *logLevel != "" {
args.Level = *logLevel
}
} }
func main() { func main() {
logrus.SetFormatter(new(formatter)) log.SetFormatter(&log.TextFormatter{
DisableTimestamp: true,
})
switch args.Level { switch args.Level {
case "debug": case "debug":
logrus.SetFormatter(textFormatter) log.SetLevel(log.DebugLevel)
logrus.SetLevel(logrus.DebugLevel)
case "trace": case "trace":
logrus.SetFormatter(textFormatter) log.SetLevel(log.TraceLevel)
logrus.SetLevel(logrus.TraceLevel)
} }
if err := plugin.Exec(context.Background(), args); err != nil { if err := plugin.Exec(context.Background(), args); err != nil {
logrus.Fatalln(err) log.Fatalln(err)
} }
} }
// default formatter that writes logs without including timestamp
// or level information.
type formatter struct{}
func (*formatter) Format(entry *logrus.Entry) ([]byte, error) {
return []byte(entry.Message), nil
}
// text formatter that writes logs with level information
var textFormatter = &logrus.TextFormatter{
DisableTimestamp: true,
}

View File

@ -9,6 +9,7 @@ import (
"text/template" "text/template"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
log "github.com/sirupsen/logrus"
) )
var ( var (
@ -26,6 +27,8 @@ type Args struct {
GiteaUrl string `envconfig:"PLUGIN_GITEA_URL"` GiteaUrl string `envconfig:"PLUGIN_GITEA_URL"`
GiteaUsername string `envconfig:"PLUGIN_GITEA_USERNAME"` GiteaUsername string `envconfig:"PLUGIN_GITEA_USERNAME"`
GiteaPassword string `envconfig:"PLUGIN_GITEA_PASSWORD"` GiteaPassword string `envconfig:"PLUGIN_GITEA_PASSWORD"`
GitUsername string `envconfig:"PLUGIN_GIT_USERNAME"`
GitPassword string `envconfig:"PLUGIN_GIT_PASSWORD"`
Owner string `envconfig:"PLUGIN_OWNER"` Owner string `envconfig:"PLUGIN_OWNER"`
Repo string `envconfig:"PLUGIN_REPO"` Repo string `envconfig:"PLUGIN_REPO"`
TitleFormat string `envconfig:"PLUGIN_TITLE_FORMAT"` TitleFormat string `envconfig:"PLUGIN_TITLE_FORMAT"`
@ -39,6 +42,12 @@ type Args struct {
FetchGitTags bool `envconfig:"PLUGIN_FETCH_GIT_TAGS" default:"true"` FetchGitTags bool `envconfig:"PLUGIN_FETCH_GIT_TAGS" default:"true"`
} }
type ReleaseCard struct {
Title string
Tag string
Url string
}
type TitleTemplateCtx struct { type TitleTemplateCtx struct {
Tag string Tag string
GiteaUrl string GiteaUrl string
@ -63,7 +72,7 @@ func Exec(ctx context.Context, args Args) error {
if err != nil { if err != nil {
if os.IsNotExist(err) && args.SkipIfNoNotesFile { if os.IsNotExist(err) && args.SkipIfNoNotesFile {
fmt.Println("No notes file found, skipping release") log.Info("No notes file found, skipping release")
return nil return nil
} }
return fmt.Errorf("error reading notes file %w", err) return fmt.Errorf("error reading notes file %w", err)
@ -76,15 +85,22 @@ func Exec(ctx context.Context, args Args) error {
if args.UseLatestGitTag { if args.UseLatestGitTag {
var options = make([]GetLatestGitTagOption, 0) var options = make([]GetLatestGitTagOption, 0)
if args.GitUsername != "" && args.GitPassword != "" {
options = append(options, SetBasicAuth(args.GitUsername, args.GitPassword))
}
if args.FetchGitTags { if args.FetchGitTags {
options = append(options, FetchTags) options = append(options, FetchTags())
} }
tag, err = getLatestGitTag(options...) tag, err = getLatestGitTag(options...)
if err != nil { if err != nil {
return fmt.Errorf("error getting git tag %w", err) return fmt.Errorf("error getting git tag %w", err)
} }
log.WithField("tag", tag).Info("Fetched latest git tag")
} else if args.TagFile != "" { } else if args.TagFile != "" {
log.WithField("file", args.TagFile).Info("Reading tag from file")
var pattern = defaultTagRegex var pattern = defaultTagRegex
if args.TagRegex != "" { if args.TagRegex != "" {
pattern = regexp.MustCompile(args.TagRegex) pattern = regexp.MustCompile(args.TagRegex)
@ -107,6 +123,8 @@ func Exec(ctx context.Context, args Args) error {
tag = matches[i] tag = matches[i]
} }
} }
log.WithField("tag", tag).Info("Found tag")
} else { } else {
return fmt.Errorf("latest git tag or tag file must be given") return fmt.Errorf("latest git tag or tag file must be given")
} }
@ -131,6 +149,11 @@ func Exec(ctx context.Context, args Args) error {
title = titleBuffer.String() 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)) client, err := gitea.NewClient(args.GiteaUrl, gitea.SetBasicAuth(args.GiteaUsername, args.GiteaPassword))
if err != nil { if err != nil {
@ -149,7 +172,17 @@ func Exec(ctx context.Context, args Args) error {
} }
releaseURL := fmt.Sprintf("%s/%s/%s/releases/tag/%s", args.GiteaUrl, args.Owner, args.Repo, release.TagName) 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) 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 return err
} }

View File

@ -9,46 +9,87 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"net/http"
"os" "os"
"strings" "time"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/transport/client"
githttp "github.com/go-git/go-git/v5/plumbing/transport/http"
log "github.com/sirupsen/logrus"
) )
type GetLatestGitTagOption func(repo *git.Repository) error type GetLatestGitTagOption func(repo *git.Repository) error
var FetchTags = func(repo *git.Repository) error { type BasicAuthTransport struct {
err := repo.Fetch(&git.FetchOptions{Tags: git.AllTags}) Username string
Password string
if err == git.NoErrAlreadyUpToDate { RoundTriper http.RoundTripper
return nil
}
return err
} }
func getLatestGitTag(options ...GetLatestGitTagOption) (tag string, err error) { func (bat BasicAuthTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
r, err := git.PlainOpen(".") creds := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", bat.Username, bat.Password)))
req.Header.Set("Authorization", fmt.Sprintf("Basic %s", creds))
return bat.RoundTriper.RoundTrip(req)
}
func SetBasicAuth(username, password string) func(repo *git.Repository) error {
return func(repo *git.Repository) error {
log.Println("Configuring basic auth for https")
customClient := &http.Client{
Transport: BasicAuthTransport{username, password, http.DefaultTransport},
}
// Override http(s) default protocol to use our custom client
client.InstallProtocol("https", githttp.NewClient(customClient))
return nil
}
}
func FetchTags() func(repo *git.Repository) error {
return func(repo *git.Repository) error {
log.Info("Fetching git tags")
err := repo.Fetch(&git.FetchOptions{Tags: git.AllTags})
if err == git.NoErrAlreadyUpToDate {
return nil
}
return err
}
}
func getLatestGitTag(options ...GetLatestGitTagOption) (string, error) {
var (
tag string
tagDate *time.Time
err error
)
repo, err := git.PlainOpen(".")
if err != nil { if err != nil {
return "", fmt.Errorf("error opening git repo at %s: %w", ".", err) return "", fmt.Errorf("error opening git repo at %s: %w", ".", err)
} }
for _, opt := range options { for _, opt := range options {
err := opt(r) err := opt(repo)
if err != nil { if err != nil {
return "", err return "", err
} }
} }
tagRefs, err := r.Tags() tags, err := repo.TagObjects()
if err != nil { if err != nil {
return "", fmt.Errorf("error getting git tag refs %w", err) return "", fmt.Errorf("error getting git tags %w", err)
} }
for { for {
r, err := tagRefs.Next() t, err := tags.Next()
if err == io.EOF { if err == io.EOF {
break break
@ -58,15 +99,19 @@ func getLatestGitTag(options ...GetLatestGitTagOption) (tag string, err error) {
return "", fmt.Errorf("error iterating tags %w", err) return "", fmt.Errorf("error iterating tags %w", err)
} }
parts := strings.Split(string(r.Name()), "/") if tagDate != nil && t.Tagger.When.Before(*tagDate) {
tag = strings.Join(parts[2:], "/") continue
}
tagDate = &t.Tagger.When
tag = t.Name
} }
if tag == "" { if tag == "" {
return tag, fmt.Errorf("couldn't find any git tags") return tag, fmt.Errorf("couldn't find any git tags")
} }
return return tag, err
} }
func writeCard(path, schema string, card interface{}) { func writeCard(path, schema string, card interface{}) {