зеркало из https://github.com/golang/build.git
cmd/gerritbot: don’t create more than one Gerrit change for a PR
Due to maintner’s async nature, there is a period of time where a Gerrit change may exist for a Pull Request but it is not reflected in the corpus. Account for this by keeping an in-memory map of PRs with stale data, and query Gerrit (should that map be incorrect due to a restart) before creating a new change. Update: golang/go#18517 Change-Id: Ife142697b15269caca088c3616c4acd4b227bfeb Reviewed-on: https://go-review.googlesource.com/80840 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Родитель
3182fd29ca
Коммит
16c2cdbbb6
|
@ -99,10 +99,17 @@ type bot struct {
|
|||
sync.RWMutex
|
||||
corpus *maintner.Corpus
|
||||
importedPRs map[string]*maintner.GerritCL // GitHub owner/repo#n -> Gerrit CL
|
||||
|
||||
// CLs that have been created on Gerrit for GitHub PRs but are not yet
|
||||
// reflected in the maintner corpus yet.
|
||||
pendingCLs map[string]bool // GitHub owner/repo#n -> true
|
||||
}
|
||||
|
||||
func newBot() *bot {
|
||||
return &bot{importedPRs: map[string]*maintner.GerritCL{}}
|
||||
return &bot{
|
||||
importedPRs: map[string]*maintner.GerritCL{},
|
||||
pendingCLs: map[string]bool{},
|
||||
}
|
||||
}
|
||||
|
||||
// initCorpus fetches a full maintner corpus, overwriting any existing data.
|
||||
|
@ -199,11 +206,28 @@ func prShortLink(pr *github.PullRequest) string {
|
|||
// b's RWMutex read-write lock must be held.
|
||||
func (b *bot) processPullRequest(ctx context.Context, pr *github.PullRequest) error {
|
||||
log.Printf("Processing PR %s ...", pr.GetHTMLURL())
|
||||
cl := b.importedPRs[prShortLink(pr)]
|
||||
shortLink := prShortLink(pr)
|
||||
cl := b.importedPRs[shortLink]
|
||||
if cl != nil && b.pendingCLs[shortLink] {
|
||||
delete(b.pendingCLs, shortLink)
|
||||
}
|
||||
if b.pendingCLs[shortLink] {
|
||||
return nil
|
||||
}
|
||||
|
||||
if cl == nil {
|
||||
if err := createGerritChangeFromPR(pr); err != nil {
|
||||
return fmt.Errorf("createGerritChangeFromPR(%v): %v", prShortLink(pr), err)
|
||||
gcl, err := gerritChangeForPR(pr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("gerritChangeForPR(%+v): %v", pr, err)
|
||||
}
|
||||
if gcl != nil {
|
||||
b.pendingCLs[shortLink] = true
|
||||
return nil
|
||||
}
|
||||
if err := createGerritChangeFromPR(pr); err != nil {
|
||||
return fmt.Errorf("createGerritChangeFromPR(%v): %v", shortLink, err)
|
||||
}
|
||||
b.pendingCLs[shortLink] = true
|
||||
return nil
|
||||
}
|
||||
if pr.GetCommits() != 1 {
|
||||
|
@ -219,13 +243,31 @@ func (b *bot) processPullRequest(ctx context.Context, pr *github.PullRequest) er
|
|||
if pr.Head.GetSHA() == lastRev {
|
||||
log.Printf("Change https://go-review.googlesource.com/q/%s is up to date; nothing to do.",
|
||||
cl.ChangeID())
|
||||
// Nothing to do. Change is up to date.
|
||||
return nil
|
||||
}
|
||||
// Import PR to existing Gerrit Change.
|
||||
return nil
|
||||
}
|
||||
|
||||
// gerritChangeForPR returns the Gerrit Change info associated with the given PR.
|
||||
// If no change exists for pr, it returns nil (with a nil error).
|
||||
func gerritChangeForPR(pr *github.PullRequest) (*gerrit.ChangeInfo, error) {
|
||||
c, err := gerritClient()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("gerritClient(): %v", err)
|
||||
}
|
||||
q := fmt.Sprintf(`is:open "%s %s"`, prefixGitFooterPR, prShortLink(pr))
|
||||
cs, err := c.QueryChanges(context.Background(), q)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("c.QueryChanges(ctx, %q): %v", q, err)
|
||||
}
|
||||
if len(cs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
// Return the first result no matter what.
|
||||
return cs[0], nil
|
||||
}
|
||||
|
||||
const gerritHostBase = "https://go.googlesource.com/"
|
||||
|
||||
func createGerritChangeFromPR(pr *github.PullRequest) error {
|
||||
|
|
Загрузка…
Ссылка в новой задаче