Files
request/github/releases.go
Matheus Sampaio Queiroga 520d37c408
All checks were successful
Golang test / go-test (push) Successful in 26s
Add Gitea and Github basic clients
2025-04-02 22:31:24 -03:00

195 lines
6.8 KiB
Go

package github
import (
"fmt"
"io"
"iter"
"net/http"
"net/url"
"path"
"strconv"
"time"
"sirherobrine23.com.br/go-bds/request/v2"
)
// File assert
type ReleaseAsset struct {
URL string `json:"url"`
ID int `json:"id"`
NodeID string `json:"node_id"`
Name string `json:"name"`
Label string `json:"label"`
Uploader *User `json:"uploader"`
ContentType string `json:"content_type"`
State string `json:"state"`
Size int `json:"size"`
DownloadCount int `json:"download_count"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
BrowserDownloadURL string `json:"browser_download_url"`
}
// Release
type Release struct {
ID int `json:"id"`
TagName string `json:"tag_name"`
Name string `json:"name"`
URL string `json:"url"`
AssetsURL string `json:"assets_url"`
UploadURL string `json:"upload_url"`
HTMLURL string `json:"html_url"`
NodeID string `json:"node_id"`
TargetCommitish string `json:"target_commitish"`
Body string `json:"body"`
Draft bool `json:"draft"`
Prerelease bool `json:"prerelease"`
CreatedAt time.Time `json:"created_at"`
PublishedAt time.Time `json:"published_at"`
TarballURL string `json:"tarball_url"`
ZipballURL string `json:"zipball_url"`
MentionsCount int `json:"mentions_count,omitempty"`
Author *User `json:"author"`
Assets []*ReleaseAsset `json:"assets"`
Reactions struct {
URL string `json:"url"`
TotalCount int `json:"total_count"`
PlusOne int `json:"+1"`
LessOne int `json:"-1"`
Laugh int `json:"laugh"`
Hooray int `json:"hooray"`
Confused int `json:"confused"`
Heart int `json:"heart"`
Rocket int `json:"rocket"`
Eyes int `json:"eyes"`
} `json:"reactions"`
}
// Get release by tag name
func (client Github) ReleaseTag(tagName string) (*Release, error) {
reqOptions := &request.Options{Method: "GET", Header: request.Header{}, CodeProcess: processCodes}
client.authHeader(&reqOptions.Header)
res, _, err := request.JSON[*Release](client.Host.ResolveReference(&url.URL{Path: path.Join(client.Host.Path, "repos", client.repoPath(), "releases/tags", url.PathEscape(tagName))}).String(), reqOptions)
return res, err
}
// Get release by ID
func (client Github) Release(id int) (*Release, error) {
reqOptions := &request.Options{Method: "GET", Header: request.Header{}, CodeProcess: processCodes}
client.authHeader(&reqOptions.Header)
res, _, err := request.JSON[*Release](client.Host.ResolveReference(&url.URL{Path: path.Join(client.Host.Path, "repos", client.repoPath(), "releases", strconv.Itoa(id))}).String(), reqOptions)
return res, err
}
// Return all release from API
func (client Github) ReleaseSeq() iter.Seq2[*Release, error] {
releases, res, err := []*Release{}, (*http.Response)(nil), error(nil)
reqOptions := &request.Options{Method: "GET", Header: request.Header{}, CodeProcess: processCodes}
client.authHeader(&reqOptions.Header)
return func(yield func(*Release, error) bool) {
requestUrl := client.Host.ResolveReference(&url.URL{RawQuery: "per_page=100", Path: path.Join(client.Host.Path, "repos", client.repoPath(), "releases")}).String()
for requestUrl != "" {
if len(releases) == 0 {
if releases, res, err = request.JSON[[]*Release](requestUrl, reqOptions); res != nil {
requestUrl = parsePaginator(res.Header).NextPageToken
} else {
requestUrl = ""
}
}
if err != nil {
yield(nil, err)
return
}
for len(releases) > 0 {
if !yield(releases[0], nil) {
return
}
releases = releases[1:]
}
}
}
}
// List all release Assets in [iter.Seq2]
func (client Github) AssetsSeq(releaseID int) iter.Seq2[*ReleaseAsset, error] {
asserts, res, err := []*ReleaseAsset{}, (*http.Response)(nil), error(nil)
reqOptions := &request.Options{Method: "GET", Header: request.Header{}, CodeProcess: processCodes}
client.authHeader(&reqOptions.Header)
return func(yield func(*ReleaseAsset, error) bool) {
requestUrl := client.Host.ResolveReference(&url.URL{Path: path.Join(client.Host.Path, "repos", client.repoPath(), "releases", strconv.Itoa(releaseID), "assets")}).String()
for requestUrl != "" {
if len(asserts) == 0 {
if asserts, res, err = request.JSON[[]*ReleaseAsset](requestUrl, reqOptions); res != nil {
requestUrl = parsePaginator(res.Header).NextPageToken
} else {
requestUrl = ""
}
}
if err != nil {
yield(nil, err)
return
}
for len(asserts) > 0 {
if !yield(asserts[0], nil) {
return
}
asserts = asserts[1:]
}
}
}
}
// Return all release in to slice
func (client Github) AllReleases() ([]*Release, error) {
allRels := []*Release{}
for release, err := range client.ReleaseSeq() {
if err != nil {
return nil, err
}
allRels = append(allRels, release)
}
return allRels, nil
}
// List all release Assets in to slice
func (client Github) AllAssets(releaseID int) ([]*ReleaseAsset, error) {
asserts := []*ReleaseAsset{}
for assert, err := range client.AssetsSeq(releaseID) {
if err != nil {
return nil, err
}
asserts = append(asserts, assert)
}
return asserts, nil
}
// Delete assert file from Release
func (client Github) DeleteAsset(assetID int) error {
reqOptions := &request.Options{Method: "DELETE", Header: request.Header{}, CodeProcess: processCodes}
client.authHeader(&reqOptions.Header)
res, err := request.MakeRequestWithStatus(client.Host.ResolveReference(&url.URL{Path: path.Join(client.Host.Path, "repos", client.repoPath(), "releases/assets", strconv.Itoa(assetID))}), reqOptions)
res.Body.Close()
return err
}
// Upload file to Release
func (client Github) UploadAsset(releaseID int, name string, file io.Reader) (*ReleaseAsset, error) {
reqOptions := &request.Options{
Method: "POST",
Body: file,
Header: request.Header{"Content-Type": "application/octet-stream"},
CodeProcess: processCodes.Extends(request.MapCode{
201: func(res *http.Response) (*http.Response, error) { return res, nil },
422: func(res *http.Response) (*http.Response, error) {
return nil, fmt.Errorf("same filename exists in release: %s", name)
},
}),
}
client.authHeader(&reqOptions.Header)
requestUrl := client.Host.ResolveReference(&url.URL{Path: path.Join(client.Host.Path, "repos", client.repoPath(), "releases", strconv.Itoa(releaseID), "assets")})
requestUrl.RawQuery = fmt.Sprintf("name=%s", url.QueryEscape(name))
fileInfo, _, err := request.JSON[*ReleaseAsset](requestUrl.String(), reqOptions)
return fileInfo, err
}