mirror of
https://github.com/go-i2p/go-github-dashboard.git
synced 2025-06-07 18:24:21 -04:00
Add support for repository actions
This commit is contained in:
@ -32,6 +32,7 @@ func NewCache(config *types.Config) *Cache {
|
||||
gob.Register([]types.PullRequest{})
|
||||
gob.Register([]types.Issue{})
|
||||
gob.Register([]types.Discussion{})
|
||||
gob.Register([]types.WorkflowRun{})
|
||||
|
||||
cache := &Cache{
|
||||
items: make(map[string]CacheItem),
|
||||
|
@ -221,6 +221,42 @@ func (g *GitHubClient) GetDiscussions(ctx context.Context, owner, repo string) (
|
||||
return []types.Discussion{}, nil
|
||||
}
|
||||
|
||||
// GetWorkflowRuns fetches recent workflow runs for a repository
|
||||
func (g *GitHubClient) GetWorkflowRuns(ctx context.Context, owner, repo string) ([]types.WorkflowRun, error) {
|
||||
var allRuns []types.WorkflowRun
|
||||
cacheKey := fmt.Sprintf("workflow_runs_%s_%s", owner, repo)
|
||||
|
||||
// Try to get from cache first
|
||||
if cachedRuns, found := g.cache.Get(cacheKey); found {
|
||||
if g.config.Verbose {
|
||||
log.Printf("Using cached workflow runs for %s/%s", owner, repo)
|
||||
}
|
||||
return cachedRuns.([]types.WorkflowRun), nil
|
||||
}
|
||||
|
||||
if g.config.Verbose {
|
||||
log.Printf("Fetching workflow runs for %s/%s", owner, repo)
|
||||
}
|
||||
|
||||
opts := &github.ListWorkflowRunsOptions{
|
||||
ListOptions: github.ListOptions{PerPage: 10}, // Limit to 10 most recent runs
|
||||
}
|
||||
|
||||
runs, _, err := g.client.Actions.ListRepositoryWorkflowRuns(ctx, owner, repo, opts)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching workflow runs: %w", err)
|
||||
}
|
||||
|
||||
for _, run := range runs.WorkflowRuns {
|
||||
allRuns = append(allRuns, convertWorkflowRun(run))
|
||||
}
|
||||
|
||||
// Cache the results
|
||||
g.cache.Set(cacheKey, allRuns)
|
||||
|
||||
return allRuns, nil
|
||||
}
|
||||
|
||||
// Helper functions to convert GitHub API types to our domain types
|
||||
func convertRepository(repo *github.Repository) types.Repository {
|
||||
r := types.Repository{
|
||||
@ -294,3 +330,26 @@ func convertIssue(issue *github.Issue) types.Issue {
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
// Helper function to convert GitHub API types to our domain types
|
||||
func convertWorkflowRun(run *github.WorkflowRun) types.WorkflowRun {
|
||||
workflowRun := types.WorkflowRun{
|
||||
ID: run.GetID(),
|
||||
Name: run.GetName(),
|
||||
URL: run.GetHTMLURL(),
|
||||
Status: run.GetStatus(),
|
||||
Conclusion: run.GetConclusion(),
|
||||
RunNumber: run.GetRunNumber(),
|
||||
Branch: run.GetHeadBranch(),
|
||||
}
|
||||
|
||||
if run.CreatedAt != nil {
|
||||
workflowRun.CreatedAt = run.CreatedAt.Time
|
||||
}
|
||||
|
||||
if run.UpdatedAt != nil {
|
||||
workflowRun.UpdatedAt = run.UpdatedAt.Time
|
||||
}
|
||||
|
||||
return workflowRun
|
||||
}
|
||||
|
@ -136,10 +136,17 @@ func runGenerate() error {
|
||||
log.Printf("Error fetching discussions for %s/%s: %v", owner, repoName, err)
|
||||
}
|
||||
|
||||
// Fetch workflow runs
|
||||
workflowRuns, err := githubClient.GetWorkflowRuns(ctx, owner, repoName)
|
||||
if err != nil {
|
||||
log.Printf("Error fetching workflow runs for %s/%s: %v", owner, repoName, err)
|
||||
}
|
||||
|
||||
// Update the repository with the fetched data
|
||||
repo.PullRequests = pullRequests
|
||||
repo.Issues = issues
|
||||
repo.Discussions = discussions
|
||||
repo.WorkflowRuns = workflowRuns
|
||||
|
||||
// Send the updated repository to the channel
|
||||
reposChan <- repo
|
||||
|
@ -39,6 +39,7 @@ func NewHTMLGenerator(config *types.Config) (*HTMLGenerator, error) {
|
||||
<span>{{.TotalPRs}} open pull requests</span>
|
||||
<span>{{.TotalIssues}} open issues</span>
|
||||
<span>{{.TotalDiscussions}} recent discussions</span>
|
||||
<span>{{.TotalWorkflowRuns}} recent workflow runs</span>
|
||||
</div>
|
||||
<p class="generated-at">Generated on {{.GeneratedAt.Format "January 2, 2006 at 15:04"}}</p>
|
||||
</header>
|
||||
@ -57,6 +58,7 @@ func NewHTMLGenerator(config *types.Config) (*HTMLGenerator, error) {
|
||||
<span class="stat">{{len .PullRequests}} PRs</span>
|
||||
<span class="stat">{{len .Issues}} issues</span>
|
||||
<span class="stat">{{len .Discussions}} discussions</span>
|
||||
<span class="stat">{{len .WorkflowRuns}} workflows</span>
|
||||
</div>
|
||||
</label>
|
||||
<div class="collapsible-content">
|
||||
@ -162,6 +164,51 @@ func NewHTMLGenerator(config *types.Config) (*HTMLGenerator, error) {
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .WorkflowRuns}}
|
||||
<div class="collapsible">
|
||||
<input type="checkbox" id="workflows-{{.Name}}" class="toggle">
|
||||
<label for="workflows-{{.Name}}" class="toggle-label section-label workflow-label">
|
||||
Recent Workflow Runs ({{len .WorkflowRuns}})
|
||||
</label>
|
||||
<div class="collapsible-content">
|
||||
<table class="data-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Workflow</th>
|
||||
<th>Branch</th>
|
||||
<th>Status</th>
|
||||
<th>Run #</th>
|
||||
<th>Created</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .WorkflowRuns}}
|
||||
<tr>
|
||||
<td><a href="{{.URL}}" target="_blank">{{.Name}}</a></td>
|
||||
<td>{{.Branch}}</td>
|
||||
<td class="workflow-status workflow-status-{{.Status}} workflow-conclusion-{{.Conclusion}}">
|
||||
{{if eq .Status "completed"}}
|
||||
{{if eq .Conclusion "success"}}✅ Success{{end}}
|
||||
{{if eq .Conclusion "failure"}}❌ Failure{{end}}
|
||||
{{if eq .Conclusion "cancelled"}}⚪ Cancelled{{end}}
|
||||
{{if eq .Conclusion "skipped"}}⏭️ Skipped{{end}}
|
||||
{{if eq .Conclusion "timed_out"}}⏱️ Timed Out{{end}}
|
||||
{{if eq .Conclusion ""}}⚪ {{.Status}}{{end}}
|
||||
{{else}}
|
||||
{{if eq .Status "in_progress"}}🔄 In Progress{{end}}
|
||||
{{if eq .Status "queued"}}⏳ Queued{{end}}
|
||||
{{if eq .Status ""}}⚪ Unknown{{end}}
|
||||
{{end}}
|
||||
</td>
|
||||
<td>{{.RunNumber}}</td>
|
||||
<td>{{.CreatedAt.Format "2006-01-02 15:04"}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="repo-links">
|
||||
<a href="repositories/{{.Name}}.md">View as Markdown</a>
|
||||
@ -433,6 +480,30 @@ footer {
|
||||
align-items: flex-start;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.workflow-label {
|
||||
color: #2088ff;
|
||||
}
|
||||
|
||||
.workflow-status {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.workflow-status-completed.workflow-conclusion-success {
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
.workflow-status-completed.workflow-conclusion-failure {
|
||||
color: #cb2431;
|
||||
}
|
||||
|
||||
.workflow-status-in_progress {
|
||||
color: #dbab09;
|
||||
}
|
||||
|
||||
.workflow-status-queued {
|
||||
color: #6f42c1;
|
||||
}
|
||||
}`
|
||||
|
||||
err := os.WriteFile(filepath.Join(g.outputDir, "style.css"), []byte(css), 0644)
|
||||
|
@ -59,6 +59,17 @@ func NewMarkdownGenerator(config *types.Config) (*MarkdownGenerator, error) {
|
||||
*No recent discussions*
|
||||
{{end}}
|
||||
|
||||
## Recent Workflow Runs
|
||||
|
||||
{{if .WorkflowRuns}}
|
||||
| Workflow | Branch | Status | Run # | Created |
|
||||
|----------|--------|--------|-------|---------|
|
||||
{{range .WorkflowRuns}}| [{{.Name}}]({{.URL}}) | {{.Branch}} | {{if eq .Status "completed"}}{{if eq .Conclusion "success"}}✅ Success{{end}}{{if eq .Conclusion "failure"}}❌ Failure{{end}}{{if eq .Conclusion "cancelled"}}⚪ Cancelled{{end}}{{if eq .Conclusion "skipped"}}⏭️ Skipped{{end}}{{if eq .Conclusion "timed_out"}}⏱️ Timed Out{{end}}{{if eq .Conclusion ""}}⚪ {{.Status}}{{end}}{{else}}{{if eq .Status "in_progress"}}🔄 In Progress{{end}}{{if eq .Status "queued"}}⏳ Queued{{end}}{{if eq .Status ""}}⚪ Unknown{{end}}{{end}} | {{.RunNumber}} | {{.CreatedAt.Format "2006-01-02 15:04"}} |
|
||||
{{end}}
|
||||
{{else}}
|
||||
*No recent workflow runs*
|
||||
{{end}}
|
||||
|
||||
---
|
||||
*Generated at {{.GeneratedAt.Format "2006-01-02 15:04:05"}}*
|
||||
`)
|
||||
|
@ -13,9 +13,11 @@ type Repository struct {
|
||||
Forks int
|
||||
LastUpdated time.Time
|
||||
|
||||
PullRequests []PullRequest
|
||||
Issues []Issue
|
||||
Discussions []Discussion
|
||||
PullRequests []PullRequest
|
||||
Issues []Issue
|
||||
Discussions []Discussion
|
||||
WorkflowRuns []WorkflowRun
|
||||
TotalWorkflowRuns int
|
||||
}
|
||||
|
||||
// PullRequest represents a GitHub pull request
|
||||
@ -62,13 +64,14 @@ type Label struct {
|
||||
|
||||
// Dashboard represents the entire dashboard data
|
||||
type Dashboard struct {
|
||||
Username string
|
||||
Organization string
|
||||
GeneratedAt time.Time
|
||||
Repositories []Repository
|
||||
TotalPRs int
|
||||
TotalIssues int
|
||||
TotalDiscussions int
|
||||
Username string
|
||||
Organization string
|
||||
GeneratedAt time.Time
|
||||
Repositories []Repository
|
||||
TotalPRs int
|
||||
TotalIssues int
|
||||
TotalDiscussions int
|
||||
TotalWorkflowRuns int
|
||||
}
|
||||
|
||||
// Config holds the application configuration
|
||||
@ -81,3 +84,16 @@ type Config struct {
|
||||
CacheTTL time.Duration
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
// WorkflowRun represents a GitHub Actions workflow run
|
||||
type WorkflowRun struct {
|
||||
ID int64
|
||||
Name string
|
||||
URL string
|
||||
Status string // "completed", "in_progress", "queued"
|
||||
Conclusion string // "success", "failure", "cancelled", "skipped", etc.
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
RunNumber int
|
||||
Branch string
|
||||
}
|
||||
|
Reference in New Issue
Block a user