@@ -6,9 +6,74 @@ package github
66
77import (
88 "context"
9+ "errors"
910 "fmt"
11+ "regexp"
12+ "strconv"
13+
14+ "github.com/google/go-github/v32/github"
1015)
1116
17+ type Strategy interface {
18+ FindPullRequestID (pr * github.PullRequest ) (int , error )
19+ }
20+
21+ var ErrStrategyFailed = errors .New ("strategy failed" )
22+
23+ type BackportPRNumber struct {
24+ Strategy
25+ }
26+
27+ func (s * BackportPRNumber ) FindPullRequestID (pr * github.PullRequest ) (int , error ) {
28+ patterns := []string {`backport #(\d+)` , `cherry-pick of #(\d+)` , `cherry-pick of PR #(\d+)` }
29+ rDigit , _ := regexp .Compile (`(\d+)` )
30+
31+ for _ , label := range pr .Labels {
32+ if label .GetName () == "backport" {
33+ for _ , p := range patterns {
34+ regexPattern , _ := regexp .Compile (p )
35+ backport := regexPattern .FindString (pr .GetTitle ())
36+ if backport == "" {
37+ backport = regexPattern .FindString (* pr .Body )
38+ }
39+
40+ PRNumber , err := strconv .Atoi (rDigit .FindString (backport ))
41+ if err == nil {
42+ return PRNumber , err
43+ }
44+ }
45+ }
46+ }
47+ return - 1 , ErrStrategyFailed
48+ }
49+
50+ type PRNumber struct {
51+ Strategy
52+ }
53+
54+ func (s * PRNumber ) FindPullRequestID (pr * github.PullRequest ) (int , error ) {
55+ if pr .Number != nil {
56+ return pr .GetNumber (), nil
57+ }
58+ return - 1 , ErrStrategyFailed
59+ }
60+
61+ func TestStrategies (pr * github.PullRequest , strategies ... Strategy ) (int , error ) {
62+ var (
63+ prID int
64+ err error
65+ )
66+
67+ for _ , s := range strategies {
68+ prID , err = s .FindPullRequestID (pr )
69+ if err == nil {
70+ break
71+ }
72+ }
73+
74+ return prID , err
75+ }
76+
1277type PRForCommit struct {
1378 CommitHash string `json:"commit"`
1479 PullRequestID int `json:"pull-request"`
@@ -29,10 +94,18 @@ func FindPR(ctx context.Context, c *Client, owner, repo, commit string) (FoundPR
2994 Items : make ([]PRForCommit , len (prs )),
3095 }
3196
97+ backportStrategy := & BackportPRNumber {}
98+ prNumberStrategy := & PRNumber {}
99+
32100 for i , pr := range prs {
101+ prID , err := TestStrategies (pr , backportStrategy , prNumberStrategy )
102+ if err != nil {
103+ return FoundPRs {}, fmt .Errorf ("failed testing strategies: %w" , err )
104+ }
105+
33106 respData .Items [i ] = PRForCommit {
34107 CommitHash : commit ,
35- PullRequestID : pr . GetNumber () ,
108+ PullRequestID : prID ,
36109 }
37110 }
38111
0 commit comments