Add last Github commits

Signed-off-by: Anthony Harivel <aharivel@redhat.com>
This commit is contained in:
Anthony Harivel 2024-05-18 11:51:44 +02:00
parent 7743664527
commit 90d718c186
No known key found for this signature in database
GPG Key ID: 35DE387CF0B01F69
4 changed files with 84 additions and 4 deletions

View File

@ -836,6 +836,7 @@ Example:
repository: glanceapp/glance repository: glanceapp/glance
pull-requests-limit: 5 pull-requests-limit: 5
issues-limit: 3 issues-limit: 3
commits-limit: 3
``` ```
Preview: Preview:
@ -850,6 +851,7 @@ Preview:
| token | string | no | | | token | string | no | |
| pull-requests-limit | integer | no | 3 | | pull-requests-limit | integer | no | 3 |
| issues-limit | integer | no | 3 | | issues-limit | integer | no | 3 |
| commits-limit | integer | no | 3 |
##### `repository` ##### `repository`
The owner and repository name that will have their information displayed. The owner and repository name that will have their information displayed.
@ -863,6 +865,9 @@ The maximum number of latest open pull requests to show. Set to `-1` to not show
##### `issues-limit` ##### `issues-limit`
The maximum number of latest open issues to show. Set to `-1` to not show any. The maximum number of latest open issues to show. Set to `-1` to not show any.
##### `commits-limit`
The maximum number of the lastest commit to show. Set to `-1` to not show any.
### Bookmarks ### Bookmarks
Display a list of links which can be grouped. Display a list of links which can be grouped.

View File

@ -7,6 +7,23 @@
<li>{{ .RepositoryDetails.Forks | formatNumber }} forks</li> <li>{{ .RepositoryDetails.Forks | formatNumber }} forks</li>
</ul> </ul>
{{ if gt (len .RepositoryDetails.Commits) 0 }}
<hr class="margin-block-10">
<a class="text-compact" href="https://github.com/{{ $.RepositoryDetails.Name }}/commits" target="_blank" rel="noreferrer">Last {{ .RepositoryDetails.LastCommits | formatNumber }} commits</a>
<div class="flex gap-7 size-h5 margin-top-3">
<ul class="list list-gap-2">
{{ range .RepositoryDetails.Commits }}
<li title="{{ .Date | formatTime }}" {{ dynamicRelativeTimeAttrs .Date }}>{{ .Date | relativeTime }}</li>
{{ end }}
</ul>
<ul class="list list-gap-2 min-width-0">
{{ range .RepositoryDetails.Commits }}
<li><a class="color-primary-if-not-visited text-truncate block" title="{{ .Author }}" target="_blank" rel="noreferrer" href="https://github.com/{{ $.RepositoryDetails.Name }}/commits/{{ .Sha }}">{{ .Message }}</a></li>
{{ end }}
</ul>
</div>
{{ end }}
{{ if gt (len .RepositoryDetails.PullRequests) 0 }} {{ if gt (len .RepositoryDetails.PullRequests) 0 }}
<hr class="margin-block-10"> <hr class="margin-block-10">
<a class="text-compact" href="https://github.com/{{ $.RepositoryDetails.Name }}/pulls" target="_blank" rel="noreferrer">Open pull requests ({{ .RepositoryDetails.OpenPullRequests | formatNumber }} total)</a> <a class="text-compact" href="https://github.com/{{ $.RepositoryDetails.Name }}/pulls" target="_blank" rel="noreferrer">Open pull requests ({{ .RepositoryDetails.OpenPullRequests | formatNumber }} total)</a>

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"log/slog" "log/slog"
"net/http" "net/http"
"strings"
"sync" "sync"
"time" "time"
) )
@ -21,7 +22,6 @@ type githubReleaseResponseJson struct {
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)
if err != nil { if err != nil {
return time.Now() return time.Now()
} }
@ -51,7 +51,6 @@ func FetchLatestReleasesFromGithub(repositories []string, token string) (AppRele
task := decodeJsonFromRequestTask[[]githubReleaseResponseJson](defaultClient) task := decodeJsonFromRequestTask[[]githubReleaseResponseJson](defaultClient)
job := newJob(task, requests).withWorkers(15) job := newJob(task, requests).withWorkers(15)
responses, errs, err := workerPoolDo(job) responses, errs, err := workerPoolDo(job)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -131,6 +130,8 @@ type RepositoryDetails struct {
PullRequests []GithubTicket PullRequests []GithubTicket
OpenIssues int OpenIssues int
Issues []GithubTicket Issues []GithubTicket
LastCommits int
Commits []CommitsDetails
} }
type githubRepositoryDetailsResponseJson struct { type githubRepositoryDetailsResponseJson struct {
@ -148,21 +149,46 @@ type githubTicketResponseJson struct {
} `json:"items"` } `json:"items"`
} }
func FetchRepositoryDetailsFromGithub(repository string, token string, maxPRs int, maxIssues int) (RepositoryDetails, error) { type CommitsDetails struct {
repositoryRequest, err := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/repos/%s", repository), nil) Sha string
Author string
Email string
Date time.Time
Message string
}
type Author struct {
Name string `json:"name"`
Email string `json:"email"`
Date string `json:"date"`
}
type Commit struct {
Sha string `json:"sha"`
Commit struct {
Author Author `json:"author"`
Message string `json:"message"`
} `json:"commit"`
}
type githubCommitsResponseJson []Commit
func FetchRepositoryDetailsFromGithub(repository string, token string, maxPRs int, maxIssues int, maxCommits int) (RepositoryDetails, error) {
repositoryRequest, err := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/repos/%s", repository), nil)
if err != nil { if err != nil {
return RepositoryDetails{}, fmt.Errorf("%w: could not create request with repository: %v", ErrNoContent, err) return RepositoryDetails{}, fmt.Errorf("%w: could not create request with repository: %v", ErrNoContent, err)
} }
PRsRequest, _ := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/search/issues?q=is:pr+is:open+repo:%s&per_page=%d", repository, maxPRs), nil) PRsRequest, _ := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/search/issues?q=is:pr+is:open+repo:%s&per_page=%d", repository, maxPRs), nil)
issuesRequest, _ := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/search/issues?q=is:issue+is:open+repo:%s&per_page=%d", repository, maxIssues), nil) issuesRequest, _ := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/search/issues?q=is:issue+is:open+repo:%s&per_page=%d", repository, maxIssues), nil)
CommitsRequest, _ := http.NewRequest("GET", fmt.Sprintf("https://api.github.com/repos/%s/commits?per_page=%d", repository, maxCommits), nil)
if token != "" { if token != "" {
token = fmt.Sprintf("Bearer %s", token) token = fmt.Sprintf("Bearer %s", token)
repositoryRequest.Header.Add("Authorization", token) repositoryRequest.Header.Add("Authorization", token)
PRsRequest.Header.Add("Authorization", token) PRsRequest.Header.Add("Authorization", token)
issuesRequest.Header.Add("Authorization", token) issuesRequest.Header.Add("Authorization", token)
CommitsRequest.Header.Add("Authorization", token)
} }
var detailsResponse githubRepositoryDetailsResponseJson var detailsResponse githubRepositoryDetailsResponseJson
@ -171,6 +197,8 @@ func FetchRepositoryDetailsFromGithub(repository string, token string, maxPRs in
var PRsErr error var PRsErr error
var issuesResponse githubTicketResponseJson var issuesResponse githubTicketResponseJson
var issuesErr error var issuesErr error
var CommitsResponse githubCommitsResponseJson
var CommitsErr error
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(1) wg.Add(1)
@ -195,6 +223,13 @@ func FetchRepositoryDetailsFromGithub(repository string, token string, maxPRs in
})() })()
} }
if maxCommits > 0 {
wg.Add(1)
go (func() {
defer wg.Done()
CommitsResponse, CommitsErr = decodeJsonFromRequest[githubCommitsResponseJson](defaultClient, CommitsRequest)
})()
}
wg.Wait() wg.Wait()
if detailsErr != nil { if detailsErr != nil {
@ -207,6 +242,7 @@ func FetchRepositoryDetailsFromGithub(repository string, token string, maxPRs in
Forks: detailsResponse.Forks, Forks: detailsResponse.Forks,
PullRequests: make([]GithubTicket, 0, len(PRsResponse.Tickets)), PullRequests: make([]GithubTicket, 0, len(PRsResponse.Tickets)),
Issues: make([]GithubTicket, 0, len(issuesResponse.Tickets)), Issues: make([]GithubTicket, 0, len(issuesResponse.Tickets)),
Commits: make([]CommitsDetails, 0, len(CommitsResponse)),
} }
err = nil err = nil
@ -244,5 +280,21 @@ func FetchRepositoryDetailsFromGithub(repository string, token string, maxPRs in
} }
} }
if maxCommits > 0 {
if CommitsErr != nil {
err = fmt.Errorf("%w: could not get issues: %s", ErrPartialContent, CommitsErr)
} else {
for _, commit := range CommitsResponse {
details.LastCommits++
details.Commits = append(details.Commits, CommitsDetails{
Sha: commit.Sha,
Author: commit.Commit.Author.Name,
Email: commit.Commit.Author.Email,
Date: parseGithubTime(commit.Commit.Author.Date),
Message: strings.SplitN(commit.Commit.Message, "\n\n", 2)[0],
})
}
}
}
return details, err return details, err
} }

View File

@ -15,6 +15,7 @@ type Repository struct {
Token OptionalEnvString `yaml:"token"` Token OptionalEnvString `yaml:"token"`
PullRequestsLimit int `yaml:"pull-requests-limit"` PullRequestsLimit int `yaml:"pull-requests-limit"`
IssuesLimit int `yaml:"issues-limit"` IssuesLimit int `yaml:"issues-limit"`
CommitsLimits int `yaml:"commits-limit"`
RepositoryDetails feed.RepositoryDetails RepositoryDetails feed.RepositoryDetails
} }
@ -29,6 +30,10 @@ func (widget *Repository) Initialize() error {
widget.IssuesLimit = 3 widget.IssuesLimit = 3
} }
if widget.CommitsLimits == 0 || widget.CommitsLimits < -1 {
widget.CommitsLimits = 3
}
return nil return nil
} }
@ -38,6 +43,7 @@ func (widget *Repository) Update(ctx context.Context) {
string(widget.Token), string(widget.Token),
widget.PullRequestsLimit, widget.PullRequestsLimit,
widget.IssuesLimit, widget.IssuesLimit,
widget.CommitsLimits,
) )
if !widget.canContinueUpdateAfterHandlingErr(err) { if !widget.canContinueUpdateAfterHandlingErr(err) {