feat: ✨ implement drone-gitea-release plugin with support for tag from latest git tag or version file and notes from settings or file
This commit is contained in:
commit
96a95e2dc7
18
go.mod
Normal file
18
go.mod
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module gitea.dikurium.ch/InnoPeak/drone-gitea-release
|
||||||
|
|
||||||
|
go 1.22.3
|
||||||
|
|
||||||
|
require (
|
||||||
|
code.gitea.io/sdk/gitea v0.18.0
|
||||||
|
github.com/kelseyhightower/envconfig v1.4.0
|
||||||
|
github.com/sirupsen/logrus v1.9.3
|
||||||
|
github.com/spf13/pflag v1.0.5
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davidmz/go-pageant v1.0.2 // indirect
|
||||||
|
github.com/go-fed/httpsig v1.1.0 // indirect
|
||||||
|
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||||
|
golang.org/x/crypto v0.22.0 // indirect
|
||||||
|
golang.org/x/sys v0.19.0 // indirect
|
||||||
|
)
|
44
go.sum
Normal file
44
go.sum
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
code.gitea.io/sdk/gitea v0.18.0 h1:+zZrwVmujIrgobt6wVBWCqITz6bn1aBjnCUHmpZrerI=
|
||||||
|
code.gitea.io/sdk/gitea v0.18.0/go.mod h1:IG9xZJoltDNeDSW0qiF2Vqx5orMWa7OhVWrjvrd5NpI=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
|
||||||
|
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
|
||||||
|
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
|
||||||
|
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
|
||||||
|
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||||
|
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
|
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
|
||||||
|
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||||
|
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||||
|
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||||
|
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||||
|
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||||
|
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
56
main.go
Normal file
56
main.go
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"gitea.dikurium.ch/InnoPeak/drone-gitea-release/plugin"
|
||||||
|
|
||||||
|
"github.com/kelseyhightower/envconfig"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
logrus.SetFormatter(new(formatter))
|
||||||
|
|
||||||
|
var args plugin.Args
|
||||||
|
|
||||||
|
if err := envconfig.Process("", &args); err != nil {
|
||||||
|
logrus.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
flag.StringVar(&args.TitleFormat, "title-format", "", "Format to use for the release title")
|
||||||
|
flag.StringVar(&args.TagFile, "tag-file", "", "File to check for tag to release")
|
||||||
|
flag.StringVar(&args.TagRegex, "tag-regex", "", "Regex pattern to look for tag in tag-file")
|
||||||
|
flag.StringVar(&args.Notes, "notes", "", "Notes to use in release")
|
||||||
|
flag.StringVar(&args.NotesFile, "notes-file", "", "File to use for release notes")
|
||||||
|
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
switch args.Level {
|
||||||
|
case "debug":
|
||||||
|
logrus.SetFormatter(textFormatter)
|
||||||
|
logrus.SetLevel(logrus.DebugLevel)
|
||||||
|
case "trace":
|
||||||
|
logrus.SetFormatter(textFormatter)
|
||||||
|
logrus.SetLevel(logrus.TraceLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := plugin.Exec(context.Background(), args); err != nil {
|
||||||
|
logrus.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,
|
||||||
|
}
|
149
plugin/pipeline.go
Normal file
149
plugin/pipeline.go
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Copyright 2020 the Drone Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Blue Oak Model License
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package plugin
|
||||||
|
|
||||||
|
// Pipeline provides Pipeline metadata from the environment.
|
||||||
|
type Pipeline struct {
|
||||||
|
// Build provides build metadata.
|
||||||
|
Build struct {
|
||||||
|
Branch string `envconfig:"DRONE_BUILD_BRANCH"`
|
||||||
|
Number int `envconfig:"DRONE_BUILD_NUMBER"`
|
||||||
|
Parent int `envconfig:"DRONE_BUILD_PARENT"`
|
||||||
|
Event string `envconfig:"DRONE_BUILD_EVENT"`
|
||||||
|
Action string `envconfig:"DRONE_BUILD_ACTION"`
|
||||||
|
Status string `envconfig:"DRONE_BUILD_STATUS"`
|
||||||
|
Created int64 `envconfig:"DRONE_BUILD_CREATED"`
|
||||||
|
Started int64 `envconfig:"DRONE_BUILD_STARTED"`
|
||||||
|
Finished int64 `envconfig:"DRONE_BUILD_FINISHED"`
|
||||||
|
Link string `envconfig:"DRONE_BUILD_LINK"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calver provides the calver details parsed from the
|
||||||
|
// git tag. If the git tag is empty or is not a valid
|
||||||
|
// calver, the values will be empty.
|
||||||
|
Calver struct {
|
||||||
|
Version string `envconfig:"DRONE_CALVER"`
|
||||||
|
Short string `envconfig:"DRONE_CALVER_SHORT"`
|
||||||
|
MajorMinor string `envconfig:"DRONE_CALVER_MAJOR_MINOR"`
|
||||||
|
Major string `envconfig:"DRONE_CALVER_MAJOR"`
|
||||||
|
Minor string `envconfig:"DRONE_CALVER_MINOR"`
|
||||||
|
Micro string `envconfig:"DRONE_CALVER_MICRO"`
|
||||||
|
Modifier string `envconfig:"DRONE_CALVER_MODIFIER"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Card provides adaptive card configuration options.
|
||||||
|
Card struct {
|
||||||
|
Path string `envconfig:"DRONE_CARD_PATH"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit provides the commit metadata.
|
||||||
|
Commit struct {
|
||||||
|
Rev string `envconfig:"DRONE_COMMIT_SHA"`
|
||||||
|
Before string `envconfig:"DRONE_COMMIT_BEFORE"`
|
||||||
|
After string `envconfig:"DRONE_COMMIT_AFTER"`
|
||||||
|
Ref string `envconfig:"DRONE_COMMIT_REF"`
|
||||||
|
Branch string `envconfig:"DRONE_COMMIT_BRANCH"`
|
||||||
|
Source string `envconfig:"DRONE_COMMIT_SOURCE"`
|
||||||
|
Target string `envconfig:"DRONE_COMMIT_TARGET"`
|
||||||
|
Link string `envconfig:"DRONE_COMMIT_LINK"`
|
||||||
|
Message string `envconfig:"DRONE_COMMIT_MESSAGE"`
|
||||||
|
|
||||||
|
Author struct {
|
||||||
|
Username string `envconfig:"DRONE_COMMIT_AUTHOR"`
|
||||||
|
Name string `envconfig:"DRONE_COMMIT_AUTHOR_NAME"`
|
||||||
|
Email string `envconfig:"DRONE_COMMIT_AUTHOR_EMAIL"`
|
||||||
|
Avatar string `envconfig:"DRONE_COMMIT_AUTHOR_AVATAR"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deploy provides the deployment metadata.
|
||||||
|
Deploy struct {
|
||||||
|
ID string `envconfig:"DRONE_DEPLOY_TO"`
|
||||||
|
Target string `envconfig:"DRONE_DEPLOY_ID"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed provides a list of failed steps and failed stages
|
||||||
|
// for the current pipeline.
|
||||||
|
Failed struct {
|
||||||
|
Steps []string `envconfig:"DRONE_FAILED_STEPS"`
|
||||||
|
Stages []string `envconfig:"DRONE_FAILED_STAGES"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Git provides the git repository metadata.
|
||||||
|
Git struct {
|
||||||
|
HTTPURL string `envconfig:"DRONE_GIT_HTTP_URL"`
|
||||||
|
SSHURL string `envconfig:"DRONE_GIT_SSH_URL"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullRequest provides the pull request metadata.
|
||||||
|
PullRequest struct {
|
||||||
|
Number int `envconfig:"DRONE_PULL_REQUEST"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Repo provides the repository metadata.
|
||||||
|
Repo struct {
|
||||||
|
Branch string `envconfig:"DRONE_REPO_BRANCH"`
|
||||||
|
Link string `envconfig:"DRONE_REPO_LINK"`
|
||||||
|
Namespace string `envconfig:"DRONE_REPO_NAMESPACE"`
|
||||||
|
Name string `envconfig:"DRONE_REPO_NAME"`
|
||||||
|
Private bool `envconfig:"DRONE_REPO_PRIVATE"`
|
||||||
|
Remote string `envconfig:"DRONE_GIT_HTTP_URL"`
|
||||||
|
SCM string `envconfig:"DRONE_REPO_SCM"`
|
||||||
|
Slug string `envconfig:"DRONE_REPO"`
|
||||||
|
Visibility string `envconfig:"DRONE_REPO_VISIBILITY"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stage provides the stage metadata.
|
||||||
|
Stage struct {
|
||||||
|
Kind string `envconfig:"DRONE_STAGE_KIND"`
|
||||||
|
Type string `envconfig:"DRONE_STAGE_TYPE"`
|
||||||
|
Name string `envconfig:"DRONE_STAGE_NAME"`
|
||||||
|
Number int `envconfig:"DRONE_STAGE_NUMBER"`
|
||||||
|
Machine string `envconfig:"DRONE_STAGE_MACHINE"`
|
||||||
|
OS string `envconfig:"DRONE_STAGE_OS"`
|
||||||
|
Arch string `envconfig:"DRONE_STAGE_ARCH"`
|
||||||
|
Variant string `envconfig:"DRONE_STAGE_VARIANT"`
|
||||||
|
Status string `envconfig:"DRONE_STAGE_STATUS"`
|
||||||
|
Started int64 `envconfig:"DRONE_STAGE_STARTED"`
|
||||||
|
Finished int64 `envconfig:"DRONE_STAGE_FINISHED"`
|
||||||
|
DependsOn []string `envconfig:"DRONE_STAGE_DEPENDS_ON"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step provides the step metadata.
|
||||||
|
Step struct {
|
||||||
|
Number int `envconfig:"DRONE_STEP_NUMBER"`
|
||||||
|
Name string `envconfig:"DRONE_STEP_NAME"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Semver provides the semver details parsed from the
|
||||||
|
// git tag. If the git tag is empty or is not a valid
|
||||||
|
// semver, the values will be empty and the error field
|
||||||
|
// will be populated with the parsing error.
|
||||||
|
Semver struct {
|
||||||
|
Version string `envconfig:"DRONE_SEMVER"`
|
||||||
|
Short string `envconfig:"DRONE_SEMVER_SHORT"`
|
||||||
|
Major string `envconfig:"DRONE_SEMVER_MAJOR"`
|
||||||
|
Minor string `envconfig:"DRONE_SEMVER_MINOR"`
|
||||||
|
Patch string `envconfig:"DRONE_SEMVER_PATCH"`
|
||||||
|
Build string `envconfig:"DRONE_SEMVER_BUILD"`
|
||||||
|
PreRelease string `envconfig:"DRONE_SEMVER_PRERELEASE"`
|
||||||
|
Error string `envconfig:"DRONE_SEMVER_ERROR"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// System provides the Drone system metadata, including
|
||||||
|
// the system version of details required to create the
|
||||||
|
// drone website address.
|
||||||
|
System struct {
|
||||||
|
Proto string `envconfig:"DRONE_SYSTEM_PROTO"`
|
||||||
|
Host string `envconfig:"DRONE_SYSTEM_HOST"`
|
||||||
|
Hostname string `envconfig:"DRONE_SYSTEM_HOSTNAME"`
|
||||||
|
Version string `envconfig:"DRONE_SYSTEM_VERSION"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tag provides the git tag details.
|
||||||
|
Tag struct {
|
||||||
|
Name string `envconfig:"DRONE_TAG"`
|
||||||
|
}
|
||||||
|
}
|
142
plugin/plugin.go
Normal file
142
plugin/plugin.go
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
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"`
|
||||||
|
Owner string `envconfig:"PLUGIN_OWNER"`
|
||||||
|
Repo string `envconfig:"PLUGIN_REPO"`
|
||||||
|
TitleFormat string `envconfig:"PLUGIN_TITLE_FORMAT"`
|
||||||
|
UseLatestGitTag bool `envconfig:"PLUGIN_USE_LATEST_GIT_TAG"`
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
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
|
||||||
|
}
|
11
plugin/plugin_test.go
Normal file
11
plugin/plugin_test.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2020 the Drone Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Blue Oak Model License
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package plugin
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestPlugin(t *testing.T) {
|
||||||
|
t.Skip()
|
||||||
|
}
|
47
plugin/util.go
Normal file
47
plugin/util.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2020 the Drone Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Blue Oak Model License
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getLatestGitTag() (string, error) {
|
||||||
|
tag, err := exec.Command("git", "describe", "--tags", "--abbrev=0").Output()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error getting git tag %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(tag), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeCard(path, schema string, card interface{}) {
|
||||||
|
data, _ := json.Marshal(map[string]interface{}{
|
||||||
|
"schema": schema,
|
||||||
|
"data": card,
|
||||||
|
})
|
||||||
|
switch {
|
||||||
|
case path == "/dev/stdout":
|
||||||
|
writeCardTo(os.Stdout, data)
|
||||||
|
case path == "/dev/stderr":
|
||||||
|
writeCardTo(os.Stderr, data)
|
||||||
|
case path != "":
|
||||||
|
os.WriteFile(path, data, 0644)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeCardTo(out io.Writer, data []byte) {
|
||||||
|
encoded := base64.StdEncoding.EncodeToString(data)
|
||||||
|
io.WriteString(out, "\u001B]1338;")
|
||||||
|
io.WriteString(out, encoded)
|
||||||
|
io.WriteString(out, "\u001B]0m")
|
||||||
|
io.WriteString(out, "\n")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user