Skip to content

Commit

Permalink
internal/labels: save assigned categories in DB
Browse files Browse the repository at this point in the history
When the labeler assigns labels to an issue, store the category
names in the DB.

We store the categories instead of the labels because we control them,
so we can ensure that they don't change over time or across projects.

For #64.

Change-Id: I857d5ebbc0c761c0c59b4a3ab7ef203278bd8384
Reviewed-on: https://go-review.googlesource.com/c/oscar/+/639015
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
  • Loading branch information
jba committed Dec 29, 2024
1 parent 25a5c47 commit 93d1f17
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 4 deletions.
39 changes: 35 additions & 4 deletions internal/labels/labeler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import (
)

// A Labeler labels GitHub issues.
// It uses the following database keys:
// - ["labels.Labeler"] for the action log.
// - ["labels.Categories", Project, Issue] to record the categories assigned to an issue.
type Labeler struct {
slog *slog.Logger
db storage.DB
Expand Down Expand Up @@ -104,8 +107,9 @@ func (l *Labeler) SkipAuthor(author string) {

// An action has all the information needed to label a GitHub issue.
type action struct {
Issue *github.Issue
NewLabels []string // labels to add
Issue *github.Issue
Categories []string // the names of the categories corresponding to the labels
NewLabels []string // labels to add
}

// result is the result of apply an action.
Expand Down Expand Up @@ -199,8 +203,9 @@ func (l *Labeler) logLabelIssue(ctx context.Context, e *github.Event) (advance b
}

act := &action{
Issue: issue,
NewLabels: []string{cat.Label},
Issue: issue,
Categories: []string{cat.Name},
NewLabels: []string{cat.Label},
}
l.logAction(l.db, logKey(e), storage.JSON(act), l.requireApproval)
return true, nil
Expand Down Expand Up @@ -336,6 +341,7 @@ func (l *Labeler) runAction(ctx context.Context, a *action) (*result, error) {
if err != nil {
return nil, fmt.Errorf("Labeler: edit %s: %w", a.Issue.URL, err)
}
l.setCategories(a.Issue, a.Categories)
return &result{URL: issue.URL}, nil
}

Expand All @@ -344,3 +350,28 @@ func (l *Labeler) runAction(ctx context.Context, a *action) (*result, error) {
func logKey(e *github.Event) []byte {
return ordered.Encode(e.Project, e.Issue)
}

// Latest returns the latest known DBTime marked old by the Poster's Watcher.
func (l *Labeler) Latest() timed.DBTime {
return l.watcher.Latest()
}

func (l *Labeler) setCategories(i *github.Issue, cats []string) {
l.db.Set(categoriesKey(i.Project(), i.Number), []byte(strings.Join(cats, ",")))
}

// Categories returns the list of categories that the Labeler associated with the given issue.
// If there is no association, it returns nil, false.
func (l *Labeler) Categories(project string, issueNumber int64) ([]string, bool) {
catstr, ok := l.db.Get(categoriesKey(project, issueNumber))
if !ok {
return nil, false
}
return strings.Split(string(catstr), ","), true
}

const categoriesPrefix = "labels.Categories"

func categoriesKey(project string, num int64) []byte {
return ordered.Encode(categoriesPrefix, project, num)
}
24 changes: 24 additions & 0 deletions internal/labels/labeler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,27 @@ func TestRun(t *testing.T) {
t.Fatal("not enough edits")
}
}

func TestCategories(t *testing.T) {
const project = "golang/go"
lg := testutil.Slogger(t)
db := storage.MemDB()
gh := github.New(lg, db, nil, nil)
lab := New(lg, db, gh, nil, "test")
issue := &github.Issue{
URL: "https://api.github.com/repos/my/project/whatever",
Number: 123,
}
cats := []string{"bug", "incomplete"}
lab.setCategories(issue, cats)
if _, ok := lab.Categories("my/project", 1); ok {
t.Error("found, but shouldn't have")
}
got, ok := lab.Categories("my/project", 123)
if !ok {
t.Fatal("not found, but should have")
}
if !slices.Equal(got, cats) {
t.Errorf("got %v, want %v", got, cats)
}
}

0 comments on commit 93d1f17

Please sign in to comment.