Add support for repository actions

This commit is contained in:
eyedeekay
2025-05-05 18:22:30 -04:00
parent 01225ae735
commit 5dec0bce18
6 changed files with 175 additions and 10 deletions

View File

@ -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),

View File

@ -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
}

View File

@ -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

View File

@ -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)

View File

@ -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"}}*
`)

View File

@ -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
}