mirror of
https://github.com/glanceapp/glance.git
synced 2025-06-22 02:41:23 +02:00
releases: Add support for gitlab
This commit is contained in:
parent
39f40670d0
commit
7d1ede8c91
@ -1008,6 +1008,7 @@ Preview:
|
|||||||
| token | string | no | |
|
| token | string | no | |
|
||||||
| limit | integer | no | 10 |
|
| limit | integer | no | 10 |
|
||||||
| collapse-after | integer | no | 5 |
|
| collapse-after | integer | no | 5 |
|
||||||
|
| source | string | no | github |
|
||||||
|
|
||||||
##### `repositories`
|
##### `repositories`
|
||||||
A list of repositores for which to fetch the latest release for. Only the name/repo is required, not the full URL.
|
A list of repositores for which to fetch the latest release for. Only the name/repo is required, not the full URL.
|
||||||
@ -1039,7 +1040,10 @@ This way you can safely check your `glance.yml` in version control without expos
|
|||||||
The maximum number of releases to show.
|
The maximum number of releases to show.
|
||||||
|
|
||||||
#### `collapse-after`
|
#### `collapse-after`
|
||||||
How many releases are visible before the "SHOW MORE" button appears. Set to `-1` to never collapse.
|
how many releases are visible before the "show more" button appears. set to `-1` to never collapse.
|
||||||
|
|
||||||
|
#### `source`
|
||||||
|
Either `github` or `gitlab`. Wether to retrieve the releases from github repositories or gitlab repositories.
|
||||||
|
|
||||||
### Repository
|
### Repository
|
||||||
Display general information about a repository as well as a list of the latest open pull requests and issues.
|
Display general information about a repository as well as a list of the latest open pull requests and issues.
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package feed
|
package feed
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -17,6 +19,19 @@ type githubReleaseLatestResponseJson struct {
|
|||||||
} `json:"reactions"`
|
} `json:"reactions"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type gitlabReleaseResponseJson struct {
|
||||||
|
TagName string `json:"tag_name"`
|
||||||
|
PublishedAt string `json:"created_at"`
|
||||||
|
Links struct {
|
||||||
|
Self string `json:"self"`
|
||||||
|
} `json:"_links"`
|
||||||
|
Draft bool `json:"draft"`
|
||||||
|
PreRelease bool `json:"prerelease"`
|
||||||
|
Reactions struct {
|
||||||
|
Downvotes int `json:"-1"`
|
||||||
|
} `json:"reactions"`
|
||||||
|
}
|
||||||
|
|
||||||
func parseGithubTime(t string) time.Time {
|
func parseGithubTime(t string) time.Time {
|
||||||
parsedTime, err := time.Parse("2006-01-02T15:04:05Z", t)
|
parsedTime, err := time.Parse("2006-01-02T15:04:05Z", t)
|
||||||
|
|
||||||
@ -27,7 +42,107 @@ func parseGithubTime(t string) time.Time {
|
|||||||
return parsedTime
|
return parsedTime
|
||||||
}
|
}
|
||||||
|
|
||||||
func FetchLatestReleasesFromGithub(repositories []string, token string) (AppReleases, error) {
|
func FetchLatestReleasesFromGitForge(repositories []string, token string, source string) (AppReleases, error) {
|
||||||
|
switch source {
|
||||||
|
case "github":
|
||||||
|
return fetchLatestReleasesFromGithub(repositories, token)
|
||||||
|
case "gitlab":
|
||||||
|
return fetchLatestReleasesFromGitlab(repositories, token)
|
||||||
|
default:
|
||||||
|
return nil, errors.New(fmt.Sprintf("Release source %s is invalid", source))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchLatestReleasesFromGitlab(repositories []string, token string) (AppReleases, error) {
|
||||||
|
appReleases := make(AppReleases, 0, len(repositories))
|
||||||
|
|
||||||
|
if len(repositories) == 0 {
|
||||||
|
return appReleases, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
requests := make([]*http.Request, len(repositories))
|
||||||
|
|
||||||
|
for i, repository := range repositories {
|
||||||
|
request, _ := http.NewRequest("GET", fmt.Sprintf("https://gitlab.com/api/v4/projects/%s/releases/", url.QueryEscape(repository)), nil)
|
||||||
|
|
||||||
|
if token != "" {
|
||||||
|
request.Header.Add("PRIVATE-TOKEN", token)
|
||||||
|
}
|
||||||
|
|
||||||
|
requests[i] = request
|
||||||
|
}
|
||||||
|
|
||||||
|
task := decodeJsonFromRequestTask[[]gitlabReleaseResponseJson](defaultClient)
|
||||||
|
job := newJob(task, requests).withWorkers(15)
|
||||||
|
responses, errs, err := workerPoolDo(job)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var failed int
|
||||||
|
|
||||||
|
for i := range responses {
|
||||||
|
if errs[i] != nil {
|
||||||
|
failed++
|
||||||
|
slog.Error("Failed to fetch or parse gitlab release", "error", errs[i], "url", requests[i].URL)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
releases := responses[i]
|
||||||
|
|
||||||
|
if len(releases) < 1 {
|
||||||
|
failed++
|
||||||
|
slog.Error("No releases found", "repository", repositories[i], "url", requests[i].URL)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var liveRelease *gitlabReleaseResponseJson
|
||||||
|
|
||||||
|
for i := range releases {
|
||||||
|
release := &releases[i]
|
||||||
|
|
||||||
|
if !release.Draft && !release.PreRelease {
|
||||||
|
liveRelease = release
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if liveRelease == nil {
|
||||||
|
slog.Error("No live release found", "repository", repositories[i], "url", requests[i].URL)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
version := liveRelease.TagName
|
||||||
|
|
||||||
|
if version[0] != 'v' {
|
||||||
|
version = "v" + version
|
||||||
|
}
|
||||||
|
|
||||||
|
appReleases = append(appReleases, AppRelease{
|
||||||
|
Name: repositories[i],
|
||||||
|
Version: version,
|
||||||
|
NotesUrl: liveRelease.Links.Self,
|
||||||
|
TimeReleased: parseGithubTime(liveRelease.PublishedAt),
|
||||||
|
Downvotes: liveRelease.Reactions.Downvotes,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(appReleases) == 0 {
|
||||||
|
return nil, ErrNoContent
|
||||||
|
}
|
||||||
|
|
||||||
|
appReleases.SortByNewest()
|
||||||
|
|
||||||
|
if failed > 0 {
|
||||||
|
return appReleases, fmt.Errorf("%w: could not get %d releases", ErrPartialContent, failed)
|
||||||
|
}
|
||||||
|
|
||||||
|
return appReleases, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func fetchLatestReleasesFromGithub(repositories []string, token string) (AppReleases, error) {
|
||||||
appReleases := make(AppReleases, 0, len(repositories))
|
appReleases := make(AppReleases, 0, len(repositories))
|
||||||
|
|
||||||
if len(repositories) == 0 {
|
if len(repositories) == 0 {
|
@ -16,6 +16,7 @@ type Releases struct {
|
|||||||
Token OptionalEnvString `yaml:"token"`
|
Token OptionalEnvString `yaml:"token"`
|
||||||
Limit int `yaml:"limit"`
|
Limit int `yaml:"limit"`
|
||||||
CollapseAfter int `yaml:"collapse-after"`
|
CollapseAfter int `yaml:"collapse-after"`
|
||||||
|
Source string `yaml:"source"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (widget *Releases) Initialize() error {
|
func (widget *Releases) Initialize() error {
|
||||||
@ -29,11 +30,15 @@ func (widget *Releases) Initialize() error {
|
|||||||
widget.CollapseAfter = 5
|
widget.CollapseAfter = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if widget.Source == "" {
|
||||||
|
widget.Source = "github"
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (widget *Releases) Update(ctx context.Context) {
|
func (widget *Releases) Update(ctx context.Context) {
|
||||||
releases, err := feed.FetchLatestReleasesFromGithub(widget.Repositories, string(widget.Token))
|
releases, err := feed.FetchLatestReleasesFromGitForge(widget.Repositories, string(widget.Token), widget.Source)
|
||||||
|
|
||||||
if !widget.canContinueUpdateAfterHandlingErr(err) {
|
if !widget.canContinueUpdateAfterHandlingErr(err) {
|
||||||
return
|
return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user