зеркало из https://github.com/golang/build.git
internal/task: make Tag idempotent
Proceed if we're trying to write a tag that already exists and matches the desired commit. That way, if we fail just after writing a tag, or need to entirely restart a workflow for whatever reason, we can keep going. For golang/go#51797. Change-Id: Ib2fdb13eea6f8cd6d3dd83cdc6cf7d97f12ca6f5 Reviewed-on: https://go-review.googlesource.com/c/build/+/411195 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Run-TryBot: Heschi Kreinick <heschi@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> Auto-Submit: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Родитель
27978e86d9
Коммит
179cc6f7e0
|
@ -774,15 +774,14 @@ func (c *Client) PublishChangeEdit(ctx context.Context, changeID string) error {
|
|||
return c.do(ctx, nil, "POST", "/changes/"+changeID+"/edit:publish", wantResStatus(http.StatusNoContent))
|
||||
}
|
||||
|
||||
// ErrProjectNotExist is returned when a project doesn't exist.
|
||||
// ErrXNotExist is returned when the requested X doesn't exist.
|
||||
// It is not necessarily returned unless a method is documented as
|
||||
// returning it.
|
||||
var ErrProjectNotExist = errors.New("gerrit: requested project does not exist")
|
||||
|
||||
// ErrChangeNotExist is returned when a change doesn't exist.
|
||||
// It is not necessarily returned unless a method is documented as
|
||||
// returning it.
|
||||
var ErrChangeNotExist = errors.New("gerrit: requested change does not exist")
|
||||
var (
|
||||
ErrProjectNotExist = errors.New("gerrit: requested project does not exist")
|
||||
ErrChangeNotExist = errors.New("gerrit: requested change does not exist")
|
||||
ErrTagNotExist = errors.New("gerrit: requested tag does not exist")
|
||||
)
|
||||
|
||||
// GetProjectInfo returns info about a project.
|
||||
// If the project doesn't exist, the error will be ErrProjectNotExist.
|
||||
|
@ -883,6 +882,19 @@ func (c *Client) GetProjectTags(ctx context.Context, name string) (map[string]Ta
|
|||
return m, nil
|
||||
}
|
||||
|
||||
// GetTag returns a particular tag on project. If the tag doesn't exist, the
|
||||
// error will be ErrTagNotExist.
|
||||
//
|
||||
// See https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#get-tag.
|
||||
func (c *Client) GetTag(ctx context.Context, project, tag string) (TagInfo, error) {
|
||||
var res TagInfo
|
||||
err := c.do(ctx, &res, "GET", fmt.Sprintf("/projects/%s/tags/%s", project, tag))
|
||||
if he, ok := err.(*HTTPError); ok && he.Res.StatusCode == 404 {
|
||||
return TagInfo{}, ErrTagNotExist
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
// TagInput contains information for creating a tag.
|
||||
// See https://gerrit-review.googlesource.com/Documentation/rest-api-projects.html#tag-input
|
||||
type TagInput struct {
|
||||
|
|
|
@ -85,7 +85,20 @@ func (c *RealGerritClient) AwaitSubmit(ctx context.Context, changeID string) (st
|
|||
}
|
||||
|
||||
func (c *RealGerritClient) Tag(ctx context.Context, project, tag, commit string) error {
|
||||
_, err := c.Client.CreateTag(ctx, project, tag, gerrit.TagInput{
|
||||
info, err := c.Client.GetTag(ctx, project, tag)
|
||||
if err != nil && err != gerrit.ErrTagNotExist {
|
||||
return fmt.Errorf("checking if tag already exists: %v", err)
|
||||
}
|
||||
if err == nil {
|
||||
if info.Revision != commit {
|
||||
return fmt.Errorf("tag %q already exists on revision %q rather than our %q", tag, info.Revision, commit)
|
||||
} else {
|
||||
// Nothing to do.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
_, err = c.Client.CreateTag(ctx, project, tag, gerrit.TagInput{
|
||||
Revision: commit,
|
||||
})
|
||||
return err
|
||||
|
|
Загрузка…
Ссылка в новой задаче