Chromium Code Reviews| Index: appengine/cmd/milo/buildbucket/common.go |
| diff --git a/appengine/cmd/milo/buildbucket/common.go b/appengine/cmd/milo/buildbucket/common.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..84b739091e397595da6cc5e56eec9d8f174840ae |
| --- /dev/null |
| +++ b/appengine/cmd/milo/buildbucket/common.go |
| @@ -0,0 +1,125 @@ |
| +// Copyright 2016 The LUCI Authors. All rights reserved. |
| +// Use of this source code is governed under the Apache License, Version 2.0 |
| +// that can be found in the LICENSE file. |
| + |
| +package buildbucket |
| + |
| +import ( |
| + "fmt" |
| + "strings" |
| + "time" |
| + |
| + "golang.org/x/net/context" |
| + |
| + "github.com/luci/luci-go/appengine/cmd/milo/resp" |
| + "github.com/luci/luci-go/appengine/gaeauth/client" |
| + "github.com/luci/luci-go/common/api/buildbucket/buildbucket/v1" |
| + "github.com/luci/luci-go/common/transport" |
| +) |
| + |
| +const ( |
| + // StatusScheduled means a build is pending. |
| + StatusScheduled = "SCHEDULED" |
| + // StatusStarted means a build is executing. |
| + StatusStarted = "STARTED" |
| + // StatusCompleted means a build is completed (successfully or not). |
| + StatusCompleted = "COMPLETED" |
| +) |
| + |
| +// ParseTags parses buildbucket build tags to a map. |
| +// Ignores tags that don't have colon (we don't have them in practice because |
|
hinoka
2016/07/08 23:26:05
nit: "doesn't have a colon"
nodir
2016/07/09 00:00:49
Done.
|
| +// buildbucket validates tags). |
| +func ParseTags(tags []string) map[string]string { |
| + result := make(map[string]string, len(tags)) |
| + for _, t := range tags { |
| + parts := strings.SplitN(t, ":", 2) |
| + if len(parts) == 2 { |
| + result[parts[0]] = parts[1] |
| + } |
| + } |
| + return result |
| +} |
| + |
| +func newClient(c context.Context, server string) (*buildbucket.Service, error) { |
| + c, _ = context.WithTimeout(c, 60*time.Second) |
| + c = client.UseServiceAccountTransport(c, nil, nil) |
| + client, err := buildbucket.New(transport.GetClient(c)) |
| + if err != nil { |
| + return nil, err |
| + } |
| + client.BasePath = fmt.Sprintf("https://%s/api/buildbucket/v1/", server) |
| + return client, nil |
| +} |
| + |
| +// parseStatus converts a buildbucket build status to resp.Status. |
| +func parseStatus(build *buildbucket.ApiBuildMessage) (resp.Status, error) { |
| + switch build.Status { |
| + case StatusScheduled: |
| + return resp.NotRun, nil |
| + |
| + case StatusStarted: |
| + return resp.Running, nil |
| + |
| + case StatusCompleted: |
| + switch build.Result { |
| + case "SUCCESS": |
| + return resp.Success, nil |
| + |
| + case "FAILURE": |
| + switch build.FailureReason { |
| + case "BUILD_FAILURE": |
| + return resp.Failure, nil |
| + default: |
| + return resp.InfraFailure, nil |
| + } |
| + |
| + case "CANCELED": |
| + return resp.InfraFailure, nil |
| + |
| + default: |
|
hinoka
2016/07/08 23:26:05
If you remove the defaults and put the error case
nodir
2016/07/09 00:00:49
actually you revealed a bug: the first error shoul
|
| + return 0, fmt.Errorf("unexpected buildbucket build status %q", build.Status) |
| + } |
| + |
| + default: |
| + return 0, fmt.Errorf("unexpected buildbucket build status %q", build.Status) |
| + } |
| +} |
| + |
| +// getChangeList tries to extract CL information from a buildbucket build. |
| +func getChangeList(build *buildbucket.ApiBuildMessage, params *buildParameters, resultDetails *resultDetails) *resp.Commit { |
| + var result *resp.Commit |
| + |
| + prop := ¶ms.Properties |
| + switch prop.PatchStorage { |
| + case "rietveld": |
| + if prop.RietveldURL != "" && prop.Issue != 0 { |
| + result = &resp.Commit{ |
| + Revision: resultDetails.Properties.GotRevision, |
| + RequestRevision: prop.Revision, |
| + Changelist: &resp.Link{ |
| + Label: fmt.Sprintf("Rietveld CL %d", prop.Issue), |
| + URL: fmt.Sprintf("%s/%d/#ps%d", prop.RietveldURL, prop.Issue, prop.PatchSet), |
| + }, |
| + } |
| + } |
| + |
| + case "gerrit": |
| + if prop.GerritURL != "" && prop.GerritChangeNumber != 0 { |
| + result = &resp.Commit{ |
| + Revision: prop.GerritPatchRef, |
| + RequestRevision: prop.GerritPatchRef, |
| + Changelist: &resp.Link{ |
| + Label: fmt.Sprintf("Gerrit CL %d", prop.GerritChangeNumber), |
| + URL: prop.GerritChangeURL, |
| + }, |
| + } |
| + } |
| + } |
| + |
| + if result != nil && len(params.Changes) != 0 { |
| + // tryjobs have one change and it is the CL author |
| + result.AuthorEmail = params.Changes[0].Author.Email |
| + } |
| + |
| + return result |
| +} |