Skip to content

Commit

Permalink
Support last-modified
Browse files Browse the repository at this point in the history
Signed-off-by: Galo Navarro <anglorvaroa@gmail.com>
  • Loading branch information
srvaroa committed Sep 2, 2024
1 parent b42a2b2 commit cd24841
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 25 deletions.
12 changes: 12 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
version: 1

labels:
# Type: Recent changes
- label: "@type/new"
last-modified: 1d

# Type: Old changes
- label: "@type/old"
last-modified: 30d

# Type: Build-related changes
- label: "@type/recently-changed"
last-modified: 1d

# Type: Build-related changes
- label: "@type/build"
title: '^build(?:\(.+\))?\!?:'
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ alphabetical order. Some important considerations:
This condition is satisfied when the age of the PR or Issue are larger than
the given one. The age is calculated from the creation date.

If you're looking to evaluate on the modification date of the issue or PR,
check on <a href="#last-modified" ></a>

This condition is best used when with a <a href="#schedule">schedule trigger</a>.

Example:
Expand Down Expand Up @@ -407,6 +410,35 @@ regular expressions (Regex). Special characters need to be escaped with double
backslashes. This is because the backslash in Go strings is an escape character
and therefore must be escaped itself to appear as a literal in the regex.

### Last Modified (PRs and Issues) <a name="last-modified" />

This condition is satisfied when the modification date of the PR or Issue is
larger than the given one.

If you're looking to evaluate on the creation date of the issue or PR,
check on <a href="#age" ></a>

This condition is best used when with a <a href="#schedule">schedule trigger</a>.

Example:

```yaml
last-modified: 1d
```

Will label PRs that were last modified one or more days ago.

The syntax for values is based on a number, followed by a suffix:

* s: seconds
* m: minutes
* h: hours
* d: days
* w: weeks
* y: years

For example, `2d` means 2 days, `4w` means 4 weeks, and so on.

### Mergeable status (PRs only) <a name="mergeable" />

This condition is satisfied when the [mergeable
Expand Down
25 changes: 0 additions & 25 deletions pkg/condition_age.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package labeler

import (
"fmt"
"strconv"
"strings"
"time"
)

Expand Down Expand Up @@ -36,26 +34,3 @@ func AgeCondition(l *Labeler) Condition {
},
}
}

func parseExtendedDuration(s string) (time.Duration, error) {
multiplier := time.Hour * 24 // default to days

if strings.HasSuffix(s, "w") {
multiplier = time.Hour * 24 * 7 // weeks
s = strings.TrimSuffix(s, "w")
} else if strings.HasSuffix(s, "y") {
multiplier = time.Hour * 24 * 365 // years
s = strings.TrimSuffix(s, "y")
} else if strings.HasSuffix(s, "d") {
s = strings.TrimSuffix(s, "d") // days
} else {
return time.ParseDuration(s) // default to time.ParseDuration for hours, minutes, seconds
}

value, err := strconv.Atoi(s)
if err != nil {
return 0, err
}

return time.Duration(value) * multiplier, nil
}
34 changes: 34 additions & 0 deletions pkg/condition_last_modified.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package labeler

import (
"fmt"
"time"
)

func LastModifiedCondition(l *Labeler) Condition {
return Condition{
GetName: func() string {
return "Last modification of issue/PR"
},
CanEvaluate: func(target *Target) bool {
return target.ghIssue != nil || target.ghPR != nil
},
Evaluate: func(target *Target, matcher LabelMatcher) (bool, error) {
// Parse the age from the configuration
threshold, err := parseExtendedDuration(matcher.LastModified)
if err != nil {
return false, fmt.Errorf("failed to parse last-modified parameter in configuration: %v", err)
}

// Determine the last modification time of the issue or PR
var lastModified time.Time
if target.ghIssue != nil {
lastModified = target.ghIssue.UpdatedAt.Time
} else if target.ghPR != nil {
lastModified = target.ghPR.UpdatedAt.Time
}

return time.Since(lastModified) > threshold, nil
},
}
}
2 changes: 2 additions & 0 deletions pkg/labeler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type LabelMatcher struct {
Draft string
Files []string
Label string
LastModified string `yaml:"last-modified"`
Mergeable string
Negate bool
Size *SizeConfig
Expand Down Expand Up @@ -223,6 +224,7 @@ func (l *Labeler) findMatches(target *Target, config *LabelerConfigV1) (LabelUpd
BodyCondition(),
BranchCondition(),
FilesCondition(l),
LastModifiedCondition(l),
IsDraftCondition(),
IsMergeableCondition(),
SizeCondition(l),
Expand Down
30 changes: 30 additions & 0 deletions pkg/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package labeler

import (
"strconv"
"strings"
"time"
)

func parseExtendedDuration(s string) (time.Duration, error) {
multiplier := time.Hour * 24 // default to days

if strings.HasSuffix(s, "w") {
multiplier = time.Hour * 24 * 7 // weeks
s = strings.TrimSuffix(s, "w")
} else if strings.HasSuffix(s, "y") {
multiplier = time.Hour * 24 * 365 // years
s = strings.TrimSuffix(s, "y")
} else if strings.HasSuffix(s, "d") {
s = strings.TrimSuffix(s, "d") // days
} else {
return time.ParseDuration(s) // default to time.ParseDuration for hours, minutes, seconds
}

value, err := strconv.Atoi(s)
if err != nil {
return 0, err
}

return time.Duration(value) * multiplier, nil
}
File renamed without changes.

0 comments on commit cd24841

Please sign in to comment.