diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2906418 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,27 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +tab_width = 4 +indent_style = space +insert_final_newline = false +max_line_length = 120 +trim_trailing_whitespace = true + +[*.go] +indent_style = tab +ij_smart_tabs = true +ij_go_GROUP_CURRENT_PROJECT_IMPORTS = true +ij_go_group_stdlib_imports = true +ij_go_import_sorting = goimports +ij_go_local_group_mode = project +ij_go_move_all_imports_in_one_declaration = true +ij_go_move_all_stdlib_imports_in_one_group = true +ij_go_remove_redundant_import_aliases = true + +[*.{yml,yaml}] +indent_size = 2 +tab_width = 2 +insert_final_newline = true \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2dfe0fe --- /dev/null +++ b/go.mod @@ -0,0 +1,19 @@ +module code.icb4dc0.de/buildr/gitea-plugin + +go 1.21.0 + +require ( + code.gitea.io/sdk/gitea v0.15.1 // indirect + code.icb4dc0.de/buildr/api v0.0.0-20230823165833-52d0bd9e9741 // indirect + code.icb4dc0.de/buildr/common v0.0.0-20230823164419-5a757074eaa3 // indirect + code.icb4dc0.de/buildr/wasi-module-sdk-go v0.0.0-20230823191215-19c20245ba6e // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/hashicorp/go-version v1.2.1 // indirect + github.com/tetratelabs/tinymem v0.1.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/grpc v1.57.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..1550049 --- /dev/null +++ b/go.sum @@ -0,0 +1,54 @@ +code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= +code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M= +code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA= +code.icb4dc0.de/buildr/api v0.0.0-20230823165833-52d0bd9e9741 h1:uG2ECI+OT5oA5x2+G7upBhwKsYBS49xBIX+qlZrs9gw= +code.icb4dc0.de/buildr/api v0.0.0-20230823165833-52d0bd9e9741/go.mod h1:eCeIvmMgYp/04nar7GnBDORMdO4jHYQl/RMiNJhyGf8= +code.icb4dc0.de/buildr/common v0.0.0-20230823164419-5a757074eaa3 h1:jWQCCE56vhfNoOuJj4JlCEcfXUB/40iR8L59j5xeh+s= +code.icb4dc0.de/buildr/common v0.0.0-20230823164419-5a757074eaa3/go.mod h1:u0PEZjq0l3ICCUgARZObM6Hc0ZlqkcjK0PBEozhAdNQ= +code.icb4dc0.de/buildr/wasi-module-sdk-go v0.0.0-20230823191215-19c20245ba6e h1:gdiU4PYpWByUKJneEj73XvW8EuUdqxZkoh7z+khVfbE= +code.icb4dc0.de/buildr/wasi-module-sdk-go v0.0.0-20230823191215-19c20245ba6e/go.mod h1:UBNjqJZCJrthVAell2vdK1tqIlHo2lpdu5bOaWOUnpE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tetratelabs/tinymem v0.1.0 h1:Qza1JAg9lquPPJ/CIei5qQYx7t18KLie83O2WR6CM58= +github.com/tetratelabs/tinymem v0.1.0/go.mod h1:WFFTZFhLod6lTL+UetFAopVbGaB+KFsVcIY+RUv7NeY= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +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.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/main.go b/main.go new file mode 100644 index 0000000..12b5f23 --- /dev/null +++ b/main.go @@ -0,0 +1,15 @@ +//go:generate tinygo build -o gitea.wasm -gc=leaking --no-debug -target=wasi main.go + +package main + +import sdk "code.icb4dc0.de/buildr/wasi-module-sdk-go" + +func init() { + sdk.Register(sdk.CategoryRelease, "gitea", sdk.ModuleFactoryFunc(func() sdk.Module { + return nil + })) +} + +func main() { + +} diff --git a/release/api.go b/release/api.go new file mode 100644 index 0000000..500867b --- /dev/null +++ b/release/api.go @@ -0,0 +1,22 @@ +package release + +import ( + "context" + "io" + + "code.gitea.io/sdk/gitea" +) + +type contextSetter interface { + SetContext(ctx context.Context) +} + +type releaseCreator interface { + contextSetter + CreateRelease(owner, repo string, opt gitea.CreateReleaseOption) (*gitea.Release, *gitea.Response, error) +} + +type releaseAttachmentCreator interface { + contextSetter + CreateReleaseAttachment(user, repo string, release int64, file io.Reader, filename string) (*gitea.Attachment, *gitea.Response, error) +} diff --git a/release/gitea.go b/release/gitea.go new file mode 100644 index 0000000..71b7c3e --- /dev/null +++ b/release/gitea.go @@ -0,0 +1,106 @@ +package release + +import ( + "errors" + "io" + "os" + "path/filepath" + + "code.gitea.io/sdk/gitea" + "golang.org/x/sync/errgroup" + + sdk "code.icb4dc0.de/buildr/wasi-module-sdk-go" +) + +var ( + _ sdk.Module = (*GiteaRelease)(nil) +) + +type GiteaRelease struct { + API struct { + URL string + Token string + } + + Repo struct { + Owner string + Name string + } + Tag string + Target string + Title string + Note string + PreRelease bool + Draft bool + Attachments []string +} + +func (GiteaRelease) Category() sdk.Category { + return sdk.CategoryRelease +} + +func (GiteaRelease) Type() string { + return "gitea" +} + +func (g GiteaRelease) Execute(ctx sdk.ExecutionContext) error { + giteaClient, err := gitea.NewClient(g.API.URL, gitea.SetToken(g.API.Token)) + if err != nil { + return err + } + + giteaClient.SetContext(ctx) + + release, err := g.createRelease(giteaClient) + if err != nil { + return err + } + + return g.createReleaseAttachments(ctx, giteaClient, release) +} + +func (g GiteaRelease) createRelease(cli releaseCreator) (*gitea.Release, error) { + releaseOpts := gitea.CreateReleaseOption{ + TagName: g.Tag, + Target: g.Target, + Title: g.Title, + Note: g.Note, + IsDraft: g.Draft, + IsPrerelease: g.PreRelease, + } + + release, _, err := cli.CreateRelease(g.Repo.Owner, g.Repo.Name, releaseOpts) + + return release, err +} + +func (g GiteaRelease) createReleaseAttachments(ctx sdk.ExecutionContext, cli releaseAttachmentCreator, release *gitea.Release) error { + grp, grpCtx := errgroup.WithContext(ctx) + + for _, attachment := range g.Attachments { + attachment := attachment + grp.Go(func() (err error) { + var attachmentReader io.ReadCloser + if filepath.IsAbs(attachment) { + attachmentReader, err = os.Open(attachment) + } else { + attachmentReader, err = os.Open(filepath.Join(ctx.WorkingDir(), attachment)) + } + if err != nil { + return err + } + + defer func() { + err = errors.Join(err, attachmentReader.Close()) + }() + + _, fileName := filepath.Split(attachment) + + cli.SetContext(grpCtx) + _, _, err = cli.CreateReleaseAttachment(g.Repo.Owner, g.Repo.Name, release.ID, attachmentReader, fileName) + return err + }) + } + + return grp.Wait() +} diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..89cc11e --- /dev/null +++ b/renovate.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + ":dependencyDashboard", + ":ignoreModulesAndTests", + ":semanticPrefixFixDepsChoreOthers", + ":autodetectPinVersions", + ":prHourlyLimit2", + ":prConcurrentLimit10", + "group:monorepos", + "group:recommended", + "workarounds:all" + ], + "postUpdateOptions": [ + "gomodTidy1.17", + "gomodUpdateImportPaths" + ] +}