init project
This commit is contained in:
commit
8042fec969
7 changed files with 275 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
release-action
|
19
LICENSE
Normal file
19
LICENSE
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2023 The Actions Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Release Action
|
||||
|
||||
This action will help Gitea users to publish release and attachments.
|
27
action.yml
Normal file
27
action.yml
Normal file
|
@ -0,0 +1,27 @@
|
|||
name: 'Gitea Release Action'
|
||||
description: 'A Gitea Action to manage Gitea release'
|
||||
inputs:
|
||||
files:
|
||||
description: 'The files needs to be uploaded'
|
||||
required: true
|
||||
title:
|
||||
description: 'The release title'
|
||||
required: false
|
||||
pre_release:
|
||||
description: "Whether it's a pre release"
|
||||
required: false
|
||||
draft:
|
||||
description: "Whether it's a draft"
|
||||
required: false
|
||||
api_key:
|
||||
description: 'The access token to interact with Gitea'
|
||||
required: false
|
||||
insecure:
|
||||
description: 'Whether allow insecure Gitea instance'
|
||||
required: false
|
||||
outputs:
|
||||
status:
|
||||
description: 'The upload status'
|
||||
runs:
|
||||
using: 'go'
|
||||
main: 'main.go'
|
13
go.mod
Normal file
13
go.mod
Normal file
|
@ -0,0 +1,13 @@
|
|||
module gitea.com/actions/release-action
|
||||
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
code.gitea.io/sdk/gitea v0.15.1
|
||||
github.com/sethvargo/go-githubactions v1.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/hashicorp/go-version v1.2.1 // indirect
|
||||
github.com/sethvargo/go-envconfig v0.8.0 // indirect
|
||||
)
|
37
go.sum
Normal file
37
go.sum
Normal file
|
@ -0,0 +1,37 @@
|
|||
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=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sethvargo/go-envconfig v0.8.0 h1:AcmdAewSFAc7pQ1Ghz+vhZkilUtxX559QlDuLLiSkdI=
|
||||
github.com/sethvargo/go-envconfig v0.8.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0=
|
||||
github.com/sethvargo/go-githubactions v1.1.0 h1:mg03w+b+/s5SMS298/2G6tHv8P0w0VhUFaqL1THIqzY=
|
||||
github.com/sethvargo/go-githubactions v1.1.0/go.mod h1:qIboSF7yq2Qnaw2WXDsqCReM0Lo1gU4QXUWmhBC3pxE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
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/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
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=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
175
main.go
Normal file
175
main.go
Normal file
|
@ -0,0 +1,175 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
gha "github.com/sethvargo/go-githubactions"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx, err := gha.Context()
|
||||
if err != nil {
|
||||
gha.Fatalf("failed to get context: %w", err)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(ctx.Ref, "refs/tags/") {
|
||||
gha.Fatalf("ref %s is not a tag", ctx.Ref)
|
||||
}
|
||||
|
||||
files := gha.GetInput("files")
|
||||
title := gha.GetInput("title")
|
||||
apiKey := gha.GetInput("api_key")
|
||||
preRelease, _ := strconv.ParseBool(gha.GetInput("pre_release"))
|
||||
draft, _ := strconv.ParseBool(gha.GetInput("draft"))
|
||||
if title == "" {
|
||||
title = ctx.RefName
|
||||
}
|
||||
if apiKey == "" {
|
||||
apiKey = os.Getenv("GITHUB_TOKEN")
|
||||
}
|
||||
insecure, _ := strconv.ParseBool(gha.GetInput("insecure"))
|
||||
|
||||
client := http.DefaultClient
|
||||
if insecure {
|
||||
tr := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
client = &http.Client{Transport: tr}
|
||||
}
|
||||
|
||||
c, err := gitea.NewClient(ctx.ServerURL, gitea.SetToken(apiKey), gitea.SetHTTPClient(client))
|
||||
if err != nil {
|
||||
gha.Fatalf("failed to create gitea client: %v", err)
|
||||
}
|
||||
|
||||
owner := ctx.RepositoryOwner
|
||||
repo := strings.Split(ctx.Repository, "/")[1]
|
||||
|
||||
rel, err := createRelease(ctx, c, owner, repo, gitea.CreateReleaseOption{
|
||||
TagName: ctx.RefName,
|
||||
IsDraft: draft,
|
||||
IsPrerelease: preRelease,
|
||||
Title: title,
|
||||
// Note: rc.Note,
|
||||
})
|
||||
if err != nil {
|
||||
gha.Fatalf("failed to create release: %w", err)
|
||||
}
|
||||
|
||||
matchedFiles, err := getFiles(ctx.Workspace, files)
|
||||
if err != nil {
|
||||
gha.Fatalf("failed to get files: %v", err)
|
||||
}
|
||||
|
||||
if err := uploadFiles(ctx, c, owner, repo, rel.ID, matchedFiles); err != nil {
|
||||
gha.Fatalf("Failed to upload files: %w", err)
|
||||
}
|
||||
|
||||
gha.SetOutput("status", "success")
|
||||
}
|
||||
|
||||
func getDirFiles(dir string) ([]string, error) {
|
||||
d, err := os.Open(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer d.Close()
|
||||
info, err := d.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return []string{dir}, nil
|
||||
}
|
||||
list, err := d.Readdirnames(0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := make([]string, 0, len(list))
|
||||
for _, f := range list {
|
||||
subs, err := getDirFiles(filepath.Join(dir, f))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, subs...)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func getFiles(parentDir, files string) ([]string, error) {
|
||||
var fileList []string
|
||||
lines := strings.Split(files, "\n")
|
||||
for _, line := range lines {
|
||||
line = strings.Trim(line, "'")
|
||||
line = strings.Trim(line, `"`)
|
||||
if filepath.IsAbs(line) {
|
||||
return nil, fmt.Errorf("file path %s is absolute", line)
|
||||
}
|
||||
line = filepath.Join(parentDir, line)
|
||||
matches, err := filepath.Glob(line)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, match := range matches {
|
||||
files, err := getDirFiles(match)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fileList = append(fileList, files...)
|
||||
}
|
||||
}
|
||||
return fileList, nil
|
||||
}
|
||||
|
||||
func createRelease(ctx *gha.GitHubContext, c *gitea.Client, owner, repo string, opts gitea.CreateReleaseOption) (*gitea.Release, error) {
|
||||
// Create the release
|
||||
release, _, err := c.CreateRelease(owner, repo, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create release: %w", err)
|
||||
}
|
||||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
func uploadFiles(ctx *gha.GitHubContext, c *gitea.Client, owner, repo string, releaseID int64, files []string) error {
|
||||
attachments, _, err := c.ListReleaseAttachments(owner, repo, releaseID, gitea.ListReleaseAttachmentsOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to fetch existing release attachments: %w", err)
|
||||
}
|
||||
|
||||
for _, file := range files {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open release attachment %s: %w", file, err)
|
||||
}
|
||||
|
||||
for _, attachment := range attachments {
|
||||
if attachment.Name == path.Base(file) {
|
||||
if _, err := c.DeleteReleaseAttachment(owner, repo, releaseID, attachment.ID); err != nil {
|
||||
f.Close()
|
||||
return fmt.Errorf("failed to delete release attachment %s: %w", file, err)
|
||||
}
|
||||
|
||||
fmt.Printf("Successfully deleted old release attachment %s\n", attachment.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if _, _, err = c.CreateReleaseAttachment(owner, repo, releaseID, f, path.Base(file)); err != nil {
|
||||
f.Close()
|
||||
return fmt.Errorf("failed to upload release attachment %s: %w", file, err)
|
||||
}
|
||||
f.Close()
|
||||
|
||||
fmt.Printf("Successfully uploaded release attachment %s\n", file)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in a new issue