All checks were successful
Find and Upload Minecraft Server versions / build (push) Successful in 2m26s
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
286 lines
8.8 KiB
Go
286 lines
8.8 KiB
Go
package tea
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
|
|
"sirherobrine23.com.br/go-bds/go-bds/request/v2"
|
|
)
|
|
|
|
const Repo string = "go-bds/BedrockFetch" // Default repository
|
|
|
|
var (
|
|
Token string = (func() string {
|
|
if ghToken := os.Getenv("GH_TOKEN"); len(ghToken) > 0 {
|
|
return ghToken
|
|
} else if githubToken := os.Getenv("GITHUB_TOKEN"); len(githubToken) > 0 {
|
|
return githubToken
|
|
} else if giteaToken := os.Getenv("GITEA_TOKEN"); len(giteaToken) > 0 {
|
|
return giteaToken
|
|
}
|
|
return ""
|
|
})()
|
|
|
|
RootURL string = func() string {
|
|
if data := os.Getenv("GITHUB_SERVER_URL"); data != "" {
|
|
return data
|
|
}
|
|
return "https://sirherobrine23.com.br"
|
|
}()
|
|
|
|
GiteaReleaseURI = fmt.Sprintf("%s/api/v1/repos/%s/releases", RootURL, Repo) // Gitea api release
|
|
|
|
ErrToken error = errors.New("set Gitea token in Env (GH_TOKEN || GITHUB_TOKEN || GITEA_TOKEN)")
|
|
ErrBackend error = errors.New("catch 500 error in server api")
|
|
ErrNoExist error = errors.New("repository, organization or endpoint dont exists")
|
|
)
|
|
|
|
type GiteaAsset struct {
|
|
Id int64 `json:"id"`
|
|
FileSize int64 `json:"size"`
|
|
Downloads int64 `json:"download_count"`
|
|
Uuid string `json:"uuid"`
|
|
FileUrl string `json:"browser_download_url"`
|
|
FileName string `json:"name"`
|
|
Create time.Time `json:"created_at"`
|
|
}
|
|
|
|
type GiteaRelease struct {
|
|
ReleaseId int64 `json:"id,omitempty"` // Release id
|
|
TagName string `json:"tag_name"` // Release tag name
|
|
Name string `json:"name,omitempty"` // Release name
|
|
Body string `json:"body,omitempty"` // Release body
|
|
IsPrerelease bool `json:"prerelease"` // Set Pre-release
|
|
IsDraft bool `json:"draft"` // Set release to draft
|
|
FileAssets []GiteaAsset `json:"assets,omitempty"` // Files in release
|
|
}
|
|
|
|
type giteaError struct {
|
|
Errors []string `json:"errors"`
|
|
TeaError string `json:"error"`
|
|
Message string `json:"message"`
|
|
Url string `json:"url"`
|
|
}
|
|
|
|
func ErrRes5xx(res *http.Response) (*http.Response, error) {
|
|
if strings.Contains(res.Header.Get("Content-Type"), "application/json") {
|
|
var data giteaError
|
|
defer res.Body.Close()
|
|
bodyBuff, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return nil, errors.Join(ErrBackend, err)
|
|
}
|
|
|
|
if err := json.Unmarshal(bodyBuff, &data); err != nil {
|
|
return nil, errors.Join(ErrBackend, ErrNoExist)
|
|
} else if len(data.Errors) > 0 {
|
|
return nil, errors.Join(ErrBackend, fmt.Errorf("gitea api, errors: %s, %s", data.Message, strings.Join(data.Errors, ", ")))
|
|
} else if data.Message != "" {
|
|
return nil, errors.Join(ErrBackend, fmt.Errorf("backed error: %s", data.Message))
|
|
}
|
|
}
|
|
return nil, ErrBackend
|
|
}
|
|
|
|
// Get release, if not exists create
|
|
func Release(IsPrerelease, Draft bool, TagName, Name, Body string) (*GiteaRelease, error) {
|
|
if TagName = strings.TrimSpace(TagName); len(TagName) == 0 {
|
|
return nil, fmt.Errorf("set valid tag to create release")
|
|
} else if Name = strings.TrimSpace(Name); len(Name) == 0 {
|
|
Name = TagName
|
|
}
|
|
|
|
var giteaRel GiteaRelease
|
|
_, err := request.JSONDo(fmt.Sprintf("%s/tags/%s", GiteaReleaseURI, TagName), &giteaRel, &request.Options{
|
|
Header: map[string]string{
|
|
"Authorization": fmt.Sprintf("token %s", Token),
|
|
"Content-Type": "application/json",
|
|
},
|
|
CodeProcess: map[int]request.CodeCallback{
|
|
500: ErrRes5xx,
|
|
501: ErrRes5xx,
|
|
401: func(res *http.Response) (*http.Response, error) { return nil, ErrToken },
|
|
404: func(res *http.Response) (*http.Response, error) {
|
|
defer res.Body.Close()
|
|
return request.Request(GiteaReleaseURI, &request.Options{
|
|
Method: "POST",
|
|
Header: map[string]string{
|
|
"Authorization": fmt.Sprintf("token %s", Token),
|
|
"Content-Type": "application/json",
|
|
},
|
|
Body: GiteaRelease{
|
|
TagName: TagName,
|
|
Name: Name,
|
|
Body: Body,
|
|
IsPrerelease: IsPrerelease,
|
|
IsDraft: Draft,
|
|
},
|
|
CodeProcess: map[int]request.CodeCallback{
|
|
500: ErrRes5xx,
|
|
501: ErrRes5xx,
|
|
401: func(res *http.Response) (*http.Response, error) { return nil, ErrToken },
|
|
404: func(res *http.Response) (*http.Response, error) {
|
|
if strings.Contains(res.Header.Get("Content-Type"), "application/json") {
|
|
var data giteaError
|
|
defer res.Body.Close()
|
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
|
return nil, ErrNoExist
|
|
} else if len(data.Errors) > 0 {
|
|
return nil, fmt.Errorf("gitea api, errors: %s, %s", data.Message, strings.Join(data.Errors, ", "))
|
|
}
|
|
return nil, errors.New(data.Message)
|
|
}
|
|
return nil, ErrNoExist
|
|
},
|
|
},
|
|
})
|
|
},
|
|
},
|
|
})
|
|
return &giteaRel, err
|
|
}
|
|
|
|
func (rel GiteaRelease) ExistsFile(filename string) bool {
|
|
return rel.GetFile(filename) != nil
|
|
}
|
|
|
|
func (rel GiteaRelease) GetFile(filename string) *GiteaAsset {
|
|
for _, asset := range rel.FileAssets {
|
|
if asset.FileName == filename {
|
|
return &asset
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (asset GiteaAsset) Download() (io.ReadCloser, error) {
|
|
res, err := request.Request(asset.FileUrl, &request.Options{Header: map[string]string{"Authorization": fmt.Sprintf("token %s", Token)}})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return res.Body, err
|
|
}
|
|
|
|
type UploadMap map[string]io.Reader
|
|
|
|
func (rel *GiteaRelease) Upload(filename string, fileBody io.Reader) (*GiteaAsset, error) {
|
|
body := new(bytes.Buffer)
|
|
writer := multipart.NewWriter(body)
|
|
part, err := writer.CreateFormFile("attachment", filename)
|
|
if err != nil {
|
|
return nil, err
|
|
} else if _, err = io.Copy(part, fileBody); err != nil {
|
|
return nil, err
|
|
} else if err = writer.Close(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
asset, _, err := request.JSON[GiteaAsset](fmt.Sprintf("%s/%d/assets", GiteaReleaseURI, rel.ReleaseId), &request.Options{
|
|
Method: "POST",
|
|
Body: body,
|
|
Header: map[string]string{
|
|
"Authorization": fmt.Sprintf("token %s", Token),
|
|
"Content-Type": writer.FormDataContentType(),
|
|
},
|
|
CodeProcess: map[int]request.CodeCallback{
|
|
500: ErrRes5xx,
|
|
501: ErrRes5xx,
|
|
-1: func(res *http.Response) (*http.Response, error) {
|
|
if res.StatusCode != 201 {
|
|
return nil, fmt.Errorf("cannot upload %q to release, code: %d (%s)", filename, res.StatusCode, res.Status)
|
|
}
|
|
return res, nil
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
rel.FileAssets = append(rel.FileAssets, asset)
|
|
return &asset, nil
|
|
}
|
|
|
|
func (rel *GiteaRelease) DeleteRelease() error {
|
|
if rel.ReleaseId > 0 {
|
|
_, err := request.Request(fmt.Sprintf("%s/%d", GiteaReleaseURI, rel.ReleaseId), &request.Options{
|
|
Method: "DELETE",
|
|
Header: map[string]string{
|
|
"Authorization": fmt.Sprintf("token %s", Token),
|
|
"Content-Type": "application/json",
|
|
},
|
|
CodeProcess: map[int]request.CodeCallback{
|
|
500: ErrRes5xx,
|
|
501: ErrRes5xx,
|
|
404: func(res *http.Response) (*http.Response, error) { return nil, ErrNoExist },
|
|
204: func(res *http.Response) (*http.Response, error) { return nil, nil },
|
|
401: func(res *http.Response) (*http.Response, error) { return nil, ErrToken },
|
|
},
|
|
})
|
|
return err
|
|
} else if rel.TagName != "" {
|
|
_, err := request.Request(fmt.Sprintf("%s/tags/%s", GiteaReleaseURI, rel.TagName), &request.Options{
|
|
Method: "DELETE",
|
|
Header: map[string]string{
|
|
"Authorization": fmt.Sprintf("token %s", Token),
|
|
"Content-Type": "application/json",
|
|
},
|
|
CodeProcess: map[int]request.CodeCallback{
|
|
500: ErrRes5xx,
|
|
501: ErrRes5xx,
|
|
404: func(res *http.Response) (*http.Response, error) { return nil, ErrNoExist },
|
|
204: func(res *http.Response) (*http.Response, error) { return nil, nil },
|
|
401: func(res *http.Response) (*http.Response, error) { return nil, ErrToken },
|
|
},
|
|
})
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (rel *GiteaRelease) UpdateRelease() error {
|
|
_, err := request.JSONDo(fmt.Sprintf("%s/%d", GiteaReleaseURI, rel.ReleaseId), rel, &request.Options{
|
|
Method: "PATCH",
|
|
Header: map[string]string{
|
|
"Authorization": fmt.Sprintf("token %s", Token),
|
|
"Content-Type": "application/json",
|
|
},
|
|
Body: rel,
|
|
CodeProcess: map[int]request.CodeCallback{
|
|
505: ErrRes5xx,
|
|
501: ErrRes5xx,
|
|
401: func(res *http.Response) (*http.Response, error) { return nil, ErrToken },
|
|
404: func(res *http.Response) (*http.Response, error) {
|
|
return request.Request(GiteaReleaseURI, &request.Options{
|
|
Method: "POST",
|
|
Header: map[string]string{
|
|
"Authorization": fmt.Sprintf("token %s", Token),
|
|
"Content-Type": "application/json",
|
|
},
|
|
Body: GiteaRelease{
|
|
IsPrerelease: rel.IsPrerelease,
|
|
IsDraft: rel.IsDraft,
|
|
TagName: rel.TagName,
|
|
Name: rel.Name,
|
|
Body: rel.Body,
|
|
},
|
|
CodeProcess: map[int]request.CodeCallback{
|
|
505: ErrRes5xx,
|
|
501: ErrRes5xx,
|
|
401: func(res *http.Response) (*http.Response, error) { return nil, ErrToken },
|
|
},
|
|
})
|
|
},
|
|
},
|
|
})
|
|
return err
|
|
}
|