зеркало из https://github.com/golang/build.git
cmd/gopherbot: use maintner client to fetch releases
Previously, the https://golang.org/dl/?mode=json endpoint was used to figure out the supported and upcoming Go releases. That endpoint lists versions that have binary release files uploaded. CL 146137 added an RPC endpoint to the maintner server to list supported versions. It uses tags and branches in Gerrit to compute that information, which makes it a better source as it's closer to the canonical source of truth for Go releases. We can use it here, and it allows the parsing code to be simpler. Change-Id: Ida0142f01aa42d5660fd28d4f985ff07914f239d Reviewed-on: https://go-review.googlesource.com/c/147438 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Родитель
ee8efd410a
Коммит
9a109a966d
|
@ -33,7 +33,9 @@ import (
|
|||
"golang.org/x/build/gerrit"
|
||||
"golang.org/x/build/maintner"
|
||||
"golang.org/x/build/maintner/godata"
|
||||
"golang.org/x/build/maintner/maintnerd/apipb"
|
||||
"golang.org/x/oauth2"
|
||||
"grpc.go4.org"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -151,6 +153,14 @@ func getGerritClient() (*gerrit.Client, error) {
|
|||
return c, nil
|
||||
}
|
||||
|
||||
func getMaintnerClient() (apipb.MaintnerServiceClient, error) {
|
||||
cc, err := grpc.NewClient(nil, "https://maintner.golang.org")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return apipb.NewMaintnerServiceClient(cc), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
flag.Usage = func() {
|
||||
os.Stderr.WriteString("gopherbot runs Go's gopherbot role account on GitHub and Gerrit.\n\n")
|
||||
|
@ -179,14 +189,19 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
gerritc, err := getGerritClient()
|
||||
gerrit, err := getGerritClient()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
mc, err := getMaintnerClient()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
bot := &gopherbot{
|
||||
ghc: ghc,
|
||||
gerrit: gerritc,
|
||||
gerrit: gerrit,
|
||||
mc: mc,
|
||||
deletedChanges: map[gerritChange]bool{
|
||||
{"crypto", 35958}: true,
|
||||
},
|
||||
|
@ -235,6 +250,7 @@ func main() {
|
|||
type gopherbot struct {
|
||||
ghc *github.Client
|
||||
gerrit *gerrit.Client
|
||||
mc apipb.MaintnerServiceClient
|
||||
corpus *maintner.Corpus
|
||||
gorepo *maintner.GitHubRepo
|
||||
|
||||
|
@ -1183,63 +1199,35 @@ func (b *gopherbot) onLatestCL(ctx context.Context, cl *maintner.GerritCL, f fun
|
|||
func (b *gopherbot) getMajorReleases(ctx context.Context) ([]string, error) {
|
||||
b.releases.Lock()
|
||||
defer b.releases.Unlock()
|
||||
|
||||
if expiry := b.releases.lastUpdate.Add(time.Hour); time.Now().Before(expiry) {
|
||||
return b.releases.major, nil
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
req, err := http.NewRequest("GET", "https://golang.org/dl/?mode=json", nil)
|
||||
resp, err := b.mc.ListGoReleases(ctx, &apipb.ListGoReleasesRequest{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res, err := http.DefaultClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
var releases []struct {
|
||||
Version string `json:"version"`
|
||||
Stable bool `json:"stable"`
|
||||
}
|
||||
if err := json.NewDecoder(res.Body).Decode(&releases); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
seen := make(map[string]bool)
|
||||
rs := resp.Releases // Supported Go releases, sorted with latest first.
|
||||
|
||||
var majorReleases []string
|
||||
for _, r := range releases {
|
||||
if !r.Stable {
|
||||
continue
|
||||
}
|
||||
parts := strings.Split(r.Version, ".")
|
||||
if len(parts) < 2 {
|
||||
return nil, fmt.Errorf("invalid version: %s", r.Version)
|
||||
}
|
||||
if parts[0] != "go1" {
|
||||
continue
|
||||
}
|
||||
if _, err := strconv.Atoi(parts[1]); err != nil {
|
||||
return nil, fmt.Errorf("invalid version: %s", r.Version)
|
||||
}
|
||||
major := strings.TrimPrefix(parts[0], "go") + "." + parts[1]
|
||||
if seen[major] {
|
||||
continue
|
||||
}
|
||||
seen[major] = true
|
||||
majorReleases = append(majorReleases, major)
|
||||
for i := len(rs) - 1; i >= 0; i-- {
|
||||
x, y := rs[i].Major, rs[i].Minor
|
||||
majorReleases = append(majorReleases, fmt.Sprintf("%d.%d", x, y))
|
||||
}
|
||||
sort.Slice(majorReleases, func(i, j int) bool {
|
||||
ii, _ := strconv.Atoi(majorReleases[i][2:])
|
||||
jj, _ := strconv.Atoi(majorReleases[j][2:])
|
||||
return ii < jj
|
||||
})
|
||||
// Include the next release in the list of major releases.
|
||||
lastRelease := majorReleases[len(majorReleases)-1]
|
||||
lastReleaseVersion, _ := strconv.Atoi(lastRelease[2:])
|
||||
nextRelease := lastRelease[:2] + strconv.Itoa(lastReleaseVersion+1)
|
||||
majorReleases = append(majorReleases, nextRelease)
|
||||
if len(rs) > 0 {
|
||||
// Assume the next release will bump the minor version.
|
||||
nextX, nextY := rs[0].Major, rs[0].Minor+1
|
||||
majorReleases = append(majorReleases, fmt.Sprintf("%d.%d", nextX, nextY))
|
||||
}
|
||||
|
||||
b.releases.major = majorReleases
|
||||
b.releases.lastUpdate = time.Now()
|
||||
b.releases.major = majorReleases[len(majorReleases)-3:]
|
||||
return b.releases.major, nil
|
||||
|
||||
return majorReleases, nil
|
||||
}
|
||||
|
||||
// openCherryPickIssues opens CherryPickCandidate issues for backport when
|
||||
|
|
Загрузка…
Ссылка в новой задаче