Add top issues ranking as a scheduled GitHub Action. (#1497)

Signed-off-by: Jakub Martin <kubam@spacelift.io>
This commit is contained in:
Kuba Martin 2024-04-16 13:53:21 +02:00 committed by GitHub
parent 63c88507a8
commit 2835650ef8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 166 additions and 0 deletions

View File

@ -0,0 +1,9 @@
module github.com/opentofu/opentofu/.github/scripts/update_top_issues_ranking
go 1.22.1
require (
github.com/google/go-github/v61 v61.0.0
)
require github.com/google/go-querystring v1.1.0 // indirect

View File

@ -0,0 +1,117 @@
package main
import (
"bytes"
"context"
_ "embed"
"log"
"os"
"slices"
"strconv"
"text/template"
"github.com/google/go-github/v61/github"
)
//go:embed ranking.tmpl
var rankingTemplateContent []byte
func main() {
owner := os.Args[1]
repo := os.Args[2]
issueNumberToUpdate, err := strconv.Atoi(os.Args[3])
if err != nil {
log.Fatal(err)
}
ctx := context.Background()
// Initialize client.
client := github.NewClient(nil).WithAuthToken(os.Getenv("GITHUB_TOKEN"))
// List all open issues.
listOpts := &github.IssueListByRepoOptions{
State: "open",
ListOptions: github.ListOptions{
PerPage: 100,
},
}
var issues []*github.Issue
for {
curIssues, resp, err := client.Issues.ListByRepo(ctx, owner, repo, listOpts)
if err != nil {
log.Fatal(err)
}
issues = append(issues, curIssues...)
if resp.NextPage == 0 {
break
}
listOpts.Page = resp.NextPage
}
// Filter to those that have at least 2 thumbs-up.
allIssues := issues
issues = nil
for _, issue := range allIssues {
if issue.GetReactions().GetPlusOne() < 2 {
continue
}
issues = append(issues, issue)
}
// Sort by thumbs-up descending.
slices.SortFunc(issues, func(a, b *github.Issue) int {
return b.GetReactions().GetPlusOne() - a.GetReactions().GetPlusOne()
})
templateParams := struct {
EnhancementIssues []*github.Issue
BugIssues []*github.Issue
RFCIssues []*github.Issue
}{
getTopIssuesByLabel("enhancement", issues),
getTopIssuesByLabel("bug", issues),
getTopIssuesByLabel("rfc", issues),
}
// Render template for issue body.
var rankingBodyBuffer bytes.Buffer
rankingTemplate := template.Must(template.New("ranking").Parse(string(rankingTemplateContent)))
if err := rankingTemplate.Execute(&rankingBodyBuffer, templateParams); err != nil {
log.Fatal(err)
}
rankingBodyString := rankingBodyBuffer.String()
// Update the issue.
_, _, err = client.Issues.Edit(ctx, owner, repo, issueNumberToUpdate, &github.IssueRequest{
Body: &rankingBodyString,
})
if err != nil {
log.Fatal(err)
}
}
func getTopIssuesByLabel(label string, issues []*github.Issue) []*github.Issue {
var labelledIssues []*github.Issue
for _, issue := range issues {
if hasLabel(label, issue) {
labelledIssues = append(labelledIssues, issue)
}
}
// Just the top 20.
if len(labelledIssues) > 20 {
labelledIssues = labelledIssues[:20]
}
return labelledIssues
}
func hasLabel(label string, issue *github.Issue) bool {
for _, issueLabel := range issue.Labels {
if issueLabel.GetName() == label {
return true
}
}
return false
}

View File

@ -0,0 +1,13 @@
## Top Enhancements
{{range .EnhancementIssues}}1. {{.HTMLURL}} - {{.Reactions.PlusOne}} :+1:
{{end}}
## Top Bugs
{{range .BugIssues}}1. {{.HTMLURL}} - {{.Reactions.PlusOne}} :+1:
{{end}}
## Top RFCs
{{range .RFCIssues}}1. {{.HTMLURL}} - {{.Reactions.PlusOne}} :+1:
{{end}}

View File

@ -0,0 +1,27 @@
name: update-top-issues-ranking
on:
workflow_dispatch:
schedule:
- cron: '0 10 * * *'
jobs:
update:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.22
- name: Update top issues ranking
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
cd .github/scripts/update_top_issues_ranking
go mod download
go run main.go opentofu opentofu 1496