[status] Add autoroller-status-sk.
-- Add GetAutorollerStatuses RPC.
-- Used the same pattern for a Twirp-version of the autoroller response
(ready to go response object that is occasionally refreshed)
-- Fixed bug in Repos template filling (was not filling the global due
to ':=')
-- autoroller-status-sk queries every minute (the server periodically
updates the response, so configurability of the refresh on the client
side has little value.
-- Refactored colors/classes in commits-table-sk and styles.scss so
they can be reused in autoroller-status-sk.
-- Adjusted reload input label CSS positioning to be more robust.
-- Added the new element to a temporary location in status-sk so it
shows up until it's in the eventual side panel.
Change-Id: I0e82801d5c561031d47380be988dfd55f019fac1
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/326953
Commit-Queue: Weston Tracey <westont@google.com>
Reviewed-by: Eric Boren <borenet@google.com>
diff --git a/status/go/rpc/server_impl.go b/status/go/rpc/server_impl.go
index 6704211..cbbd987 100644
--- a/status/go/rpc/server_impl.go
+++ b/status/go/rpc/server_impl.go
@@ -23,12 +23,13 @@
//go:generate protoc --twirp_typescript_out=../../modules/rpc status.proto
type statusServerImpl struct {
- iCache *incremental.IncrementalCache
- taskDb db.RemoteDB
- getRepo func(string) (string, string, error)
- maxCommitsToLoad int
- defaultCommitsToLoad int
- podID string
+ iCache *incremental.IncrementalCache
+ taskDb db.RemoteDB
+ getAutorollerStatuses func() *GetAutorollerStatusesResponse
+ getRepo func(string) (string, string, error)
+ maxCommitsToLoad int
+ defaultCommitsToLoad int
+ podID string
}
// This is incrementalJsonHandler, adjusted for Twirp, using ConvertUpdate to use generated types.
@@ -193,10 +194,15 @@
return &DeleteCommentResponse{}, nil
}
+func (s *statusServerImpl) GetAutorollerStatuses(ctx context.Context, req *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
+ return s.getAutorollerStatuses(), nil
+}
+
// NewStatusServer creates and returns a Twirp HTTP Server.
func NewStatusServer(
iCache *incremental.IncrementalCache,
taskDb db.RemoteDB,
+ getAutorollStatuses func() *GetAutorollerStatusesResponse,
getRepo func(string) (string, string, error),
maxCommitsToLoad int,
defaultCommitsToLoad int,
@@ -204,6 +210,7 @@
return NewStatusServiceServer(&statusServerImpl{
iCache,
taskDb,
+ getAutorollStatuses,
getRepo,
maxCommitsToLoad,
defaultCommitsToLoad,
diff --git a/status/go/rpc/status.pb.go b/status/go/rpc/status.pb.go
index 761b386..6c9b57c 100644
--- a/status/go/rpc/status.pb.go
+++ b/status/go/rpc/status.pb.go
@@ -961,6 +961,187 @@
return file_status_proto_rawDescGZIP(), []int{11}
}
+// Empty, no parameters needed to ask for latest autoroller status info.
+type GetAutorollerStatusesRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *GetAutorollerStatusesRequest) Reset() {
+ *x = GetAutorollerStatusesRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_status_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GetAutorollerStatusesRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAutorollerStatusesRequest) ProtoMessage() {}
+
+func (x *GetAutorollerStatusesRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_status_proto_msgTypes[12]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAutorollerStatusesRequest.ProtoReflect.Descriptor instead.
+func (*GetAutorollerStatusesRequest) Descriptor() ([]byte, []int) {
+ return file_status_proto_rawDescGZIP(), []int{12}
+}
+
+type GetAutorollerStatusesResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Rollers []*AutorollerStatus `protobuf:"bytes,1,rep,name=rollers,proto3" json:"rollers,omitempty"`
+}
+
+func (x *GetAutorollerStatusesResponse) Reset() {
+ *x = GetAutorollerStatusesResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_status_proto_msgTypes[13]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GetAutorollerStatusesResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAutorollerStatusesResponse) ProtoMessage() {}
+
+func (x *GetAutorollerStatusesResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_status_proto_msgTypes[13]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAutorollerStatusesResponse.ProtoReflect.Descriptor instead.
+func (*GetAutorollerStatusesResponse) Descriptor() ([]byte, []int) {
+ return file_status_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *GetAutorollerStatusesResponse) GetRollers() []*AutorollerStatus {
+ if x != nil {
+ return x.Rollers
+ }
+ return nil
+}
+
+type AutorollerStatus struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ CurrentRollRev string `protobuf:"bytes,2,opt,name=current_roll_rev,json=currentRollRev,proto3" json:"current_roll_rev,omitempty"`
+ LastRollRev string `protobuf:"bytes,3,opt,name=last_roll_rev,json=lastRollRev,proto3" json:"last_roll_rev,omitempty"`
+ Mode string `protobuf:"bytes,4,opt,name=mode,proto3" json:"mode,omitempty"`
+ NumFailed int32 `protobuf:"varint,5,opt,name=num_failed,json=numFailed,proto3" json:"num_failed,omitempty"`
+ NumBehind int32 `protobuf:"varint,6,opt,name=num_behind,json=numBehind,proto3" json:"num_behind,omitempty"`
+ Url string `protobuf:"bytes,7,opt,name=url,proto3" json:"url,omitempty"`
+}
+
+func (x *AutorollerStatus) Reset() {
+ *x = AutorollerStatus{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_status_proto_msgTypes[14]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *AutorollerStatus) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AutorollerStatus) ProtoMessage() {}
+
+func (x *AutorollerStatus) ProtoReflect() protoreflect.Message {
+ mi := &file_status_proto_msgTypes[14]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use AutorollerStatus.ProtoReflect.Descriptor instead.
+func (*AutorollerStatus) Descriptor() ([]byte, []int) {
+ return file_status_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *AutorollerStatus) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *AutorollerStatus) GetCurrentRollRev() string {
+ if x != nil {
+ return x.CurrentRollRev
+ }
+ return ""
+}
+
+func (x *AutorollerStatus) GetLastRollRev() string {
+ if x != nil {
+ return x.LastRollRev
+ }
+ return ""
+}
+
+func (x *AutorollerStatus) GetMode() string {
+ if x != nil {
+ return x.Mode
+ }
+ return ""
+}
+
+func (x *AutorollerStatus) GetNumFailed() int32 {
+ if x != nil {
+ return x.NumFailed
+ }
+ return 0
+}
+
+func (x *AutorollerStatus) GetNumBehind() int32 {
+ if x != nil {
+ return x.NumBehind
+ }
+ return 0
+}
+
+func (x *AutorollerStatus) GetUrl() string {
+ if x != nil {
+ return x.Url
+ }
+ return ""
+}
+
var File_status_proto protoreflect.FileDescriptor
var file_status_proto_rawDesc = []byte{
@@ -1085,7 +1266,28 @@
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22,
0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74,
- 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x88, 0x02, 0x0a, 0x0d, 0x53, 0x74, 0x61,
+ 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41,
+ 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65,
+ 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x53, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41,
+ 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65,
+ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x72, 0x6f, 0x6c,
+ 0x6c, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x2e, 0x41, 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74,
+ 0x61, 0x74, 0x75, 0x73, 0x52, 0x07, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x73, 0x22, 0xd8, 0x01,
+ 0x0a, 0x10, 0x41, 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74,
+ 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
+ 0x74, 0x5f, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x72, 0x65, 0x76, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x0e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x6f, 0x6c, 0x6c, 0x52, 0x65, 0x76,
+ 0x12, 0x22, 0x0a, 0x0d, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x72, 0x6f, 0x6c, 0x6c, 0x5f, 0x72, 0x65,
+ 0x76, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x52, 0x6f, 0x6c,
+ 0x6c, 0x52, 0x65, 0x76, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f,
+ 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x75,
+ 0x6d, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x6e, 0x75, 0x6d, 0x5f, 0x62,
+ 0x65, 0x68, 0x69, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6e, 0x75, 0x6d,
+ 0x42, 0x65, 0x68, 0x69, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x07, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x32, 0xee, 0x02, 0x0a, 0x0d, 0x53, 0x74, 0x61,
0x74, 0x75, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x64, 0x0a, 0x15, 0x47, 0x65,
0x74, 0x49, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x6d, 0x6d,
0x69, 0x74, 0x73, 0x12, 0x24, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x47, 0x65, 0x74,
@@ -1102,9 +1304,16 @@
0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x44, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
- 0x6e, 0x73, 0x65, 0x42, 0x21, 0x5a, 0x1f, 0x67, 0x6f, 0x2e, 0x73, 0x6b, 0x69, 0x61, 0x2e, 0x6f,
- 0x72, 0x67, 0x2f, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f,
- 0x67, 0x6f, 0x2f, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x6e, 0x73, 0x65, 0x12, 0x64, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x72, 0x6f,
+ 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x73,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6c,
+ 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41,
+ 0x75, 0x74, 0x6f, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65,
+ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x21, 0x5a, 0x1f, 0x67, 0x6f, 0x2e,
+ 0x73, 0x6b, 0x69, 0x61, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x69, 0x6e, 0x66, 0x72, 0x61, 0x2f, 0x73,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1119,7 +1328,7 @@
return file_status_proto_rawDescData
}
-var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
+var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
var file_status_proto_goTypes = []interface{}{
(*GetIncrementalCommitsRequest)(nil), // 0: status.GetIncrementalCommitsRequest
(*GetIncrementalCommitsResponse)(nil), // 1: status.GetIncrementalCommitsResponse
@@ -1133,33 +1342,39 @@
(*AddCommentResponse)(nil), // 9: status.AddCommentResponse
(*DeleteCommentRequest)(nil), // 10: status.DeleteCommentRequest
(*DeleteCommentResponse)(nil), // 11: status.DeleteCommentResponse
- (*timestamp.Timestamp)(nil), // 12: google.protobuf.Timestamp
+ (*GetAutorollerStatusesRequest)(nil), // 12: status.GetAutorollerStatusesRequest
+ (*GetAutorollerStatusesResponse)(nil), // 13: status.GetAutorollerStatusesResponse
+ (*AutorollerStatus)(nil), // 14: status.AutorollerStatus
+ (*timestamp.Timestamp)(nil), // 15: google.protobuf.Timestamp
}
var file_status_proto_depIdxs = []int32{
- 12, // 0: status.GetIncrementalCommitsRequest.from:type_name -> google.protobuf.Timestamp
- 12, // 1: status.GetIncrementalCommitsRequest.to:type_name -> google.protobuf.Timestamp
+ 15, // 0: status.GetIncrementalCommitsRequest.from:type_name -> google.protobuf.Timestamp
+ 15, // 1: status.GetIncrementalCommitsRequest.to:type_name -> google.protobuf.Timestamp
7, // 2: status.GetIncrementalCommitsResponse.metadata:type_name -> status.ResponseMetadata
2, // 3: status.GetIncrementalCommitsResponse.update:type_name -> status.IncrementalUpdate
5, // 4: status.IncrementalUpdate.commits:type_name -> status.LongCommit
3, // 5: status.IncrementalUpdate.branch_heads:type_name -> status.Branch
4, // 6: status.IncrementalUpdate.tasks:type_name -> status.Task
6, // 7: status.IncrementalUpdate.comments:type_name -> status.Comment
- 12, // 8: status.LongCommit.timestamp:type_name -> google.protobuf.Timestamp
- 12, // 9: status.Comment.timestamp:type_name -> google.protobuf.Timestamp
- 12, // 10: status.ResponseMetadata.timestamp:type_name -> google.protobuf.Timestamp
- 12, // 11: status.AddCommentResponse.timestamp:type_name -> google.protobuf.Timestamp
- 12, // 12: status.DeleteCommentRequest.timestamp:type_name -> google.protobuf.Timestamp
- 0, // 13: status.StatusService.GetIncrementalCommits:input_type -> status.GetIncrementalCommitsRequest
- 8, // 14: status.StatusService.AddComment:input_type -> status.AddCommentRequest
- 10, // 15: status.StatusService.DeleteComment:input_type -> status.DeleteCommentRequest
- 1, // 16: status.StatusService.GetIncrementalCommits:output_type -> status.GetIncrementalCommitsResponse
- 9, // 17: status.StatusService.AddComment:output_type -> status.AddCommentResponse
- 11, // 18: status.StatusService.DeleteComment:output_type -> status.DeleteCommentResponse
- 16, // [16:19] is the sub-list for method output_type
- 13, // [13:16] is the sub-list for method input_type
- 13, // [13:13] is the sub-list for extension type_name
- 13, // [13:13] is the sub-list for extension extendee
- 0, // [0:13] is the sub-list for field type_name
+ 15, // 8: status.LongCommit.timestamp:type_name -> google.protobuf.Timestamp
+ 15, // 9: status.Comment.timestamp:type_name -> google.protobuf.Timestamp
+ 15, // 10: status.ResponseMetadata.timestamp:type_name -> google.protobuf.Timestamp
+ 15, // 11: status.AddCommentResponse.timestamp:type_name -> google.protobuf.Timestamp
+ 15, // 12: status.DeleteCommentRequest.timestamp:type_name -> google.protobuf.Timestamp
+ 14, // 13: status.GetAutorollerStatusesResponse.rollers:type_name -> status.AutorollerStatus
+ 0, // 14: status.StatusService.GetIncrementalCommits:input_type -> status.GetIncrementalCommitsRequest
+ 8, // 15: status.StatusService.AddComment:input_type -> status.AddCommentRequest
+ 10, // 16: status.StatusService.DeleteComment:input_type -> status.DeleteCommentRequest
+ 12, // 17: status.StatusService.GetAutorollerStatuses:input_type -> status.GetAutorollerStatusesRequest
+ 1, // 18: status.StatusService.GetIncrementalCommits:output_type -> status.GetIncrementalCommitsResponse
+ 9, // 19: status.StatusService.AddComment:output_type -> status.AddCommentResponse
+ 11, // 20: status.StatusService.DeleteComment:output_type -> status.DeleteCommentResponse
+ 13, // 21: status.StatusService.GetAutorollerStatuses:output_type -> status.GetAutorollerStatusesResponse
+ 18, // [18:22] is the sub-list for method output_type
+ 14, // [14:18] is the sub-list for method input_type
+ 14, // [14:14] is the sub-list for extension type_name
+ 14, // [14:14] is the sub-list for extension extendee
+ 0, // [0:14] is the sub-list for field type_name
}
func init() { file_status_proto_init() }
@@ -1312,6 +1527,42 @@
return nil
}
}
+ file_status_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GetAutorollerStatusesRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_status_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GetAutorollerStatusesResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_status_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*AutorollerStatus); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
}
file_status_proto_msgTypes[8].OneofWrappers = []interface{}{
(*AddCommentRequest_Commit)(nil),
@@ -1324,7 +1575,7 @@
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_status_proto_rawDesc,
NumEnums: 0,
- NumMessages: 12,
+ NumMessages: 15,
NumExtensions: 0,
NumServices: 1,
},
diff --git a/status/go/rpc/status.proto b/status/go/rpc/status.proto
index 7c4b780..f0e88d7 100644
--- a/status/go/rpc/status.proto
+++ b/status/go/rpc/status.proto
@@ -12,6 +12,8 @@
rpc AddComment(AddCommentRequest) returns (AddCommentResponse);
// Method to delete a comment to a task, commit, or task spec.
rpc DeleteComment(DeleteCommentRequest) returns (DeleteCommentResponse);
+ // Method to get latest status of various autorollers.
+ rpc GetAutorollerStatuses(GetAutorollerStatusesRequest) returns (GetAutorollerStatusesResponse);
}
// Request for updated commit/task/comment/branch/etc data.
@@ -118,3 +120,20 @@
}
// Empty, valid response to DeleteComment, only success/failure needs to be conveyed.
message DeleteCommentResponse{}
+
+// Empty, no parameters needed to ask for latest autoroller status info.
+message GetAutorollerStatusesRequest{}
+
+message GetAutorollerStatusesResponse {
+ repeated AutorollerStatus rollers = 1;
+}
+
+message AutorollerStatus {
+ string name = 1;
+ string current_roll_rev = 2;
+ string last_roll_rev = 3;
+ string mode = 4;
+ int32 num_failed = 5;
+ int32 num_behind = 6;
+ string url = 7;
+}
diff --git a/status/go/rpc/status.twirp.go b/status/go/rpc/status.twirp.go
index cb289e0..b958e67 100644
--- a/status/go/rpc/status.twirp.go
+++ b/status/go/rpc/status.twirp.go
@@ -55,6 +55,9 @@
// Method to delete a comment to a task, commit, or task spec.
DeleteComment(context.Context, *DeleteCommentRequest) (*DeleteCommentResponse, error)
+
+ // Method to get latest status of various autorollers.
+ GetAutorollerStatuses(context.Context, *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error)
}
// =============================
@@ -63,7 +66,7 @@
type statusServiceProtobufClient struct {
client HTTPClient
- urls [3]string
+ urls [4]string
opts twirp.ClientOptions
}
@@ -80,10 +83,11 @@
}
prefix := urlBase(addr) + StatusServicePathPrefix
- urls := [3]string{
+ urls := [4]string{
prefix + "GetIncrementalCommits",
prefix + "AddComment",
prefix + "DeleteComment",
+ prefix + "GetAutorollerStatuses",
}
return &statusServiceProtobufClient{
@@ -153,13 +157,33 @@
return out, nil
}
+func (c *statusServiceProtobufClient) GetAutorollerStatuses(ctx context.Context, in *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
+ ctx = ctxsetters.WithPackageName(ctx, "status")
+ ctx = ctxsetters.WithServiceName(ctx, "StatusService")
+ ctx = ctxsetters.WithMethodName(ctx, "GetAutorollerStatuses")
+ out := new(GetAutorollerStatusesResponse)
+ ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out)
+ if err != nil {
+ twerr, ok := err.(twirp.Error)
+ if !ok {
+ twerr = twirp.InternalErrorWith(err)
+ }
+ callClientError(ctx, c.opts.Hooks, twerr)
+ return nil, err
+ }
+
+ callClientResponseReceived(ctx, c.opts.Hooks)
+
+ return out, nil
+}
+
// =========================
// StatusService JSON Client
// =========================
type statusServiceJSONClient struct {
client HTTPClient
- urls [3]string
+ urls [4]string
opts twirp.ClientOptions
}
@@ -176,10 +200,11 @@
}
prefix := urlBase(addr) + StatusServicePathPrefix
- urls := [3]string{
+ urls := [4]string{
prefix + "GetIncrementalCommits",
prefix + "AddComment",
prefix + "DeleteComment",
+ prefix + "GetAutorollerStatuses",
}
return &statusServiceJSONClient{
@@ -249,6 +274,26 @@
return out, nil
}
+func (c *statusServiceJSONClient) GetAutorollerStatuses(ctx context.Context, in *GetAutorollerStatusesRequest) (*GetAutorollerStatusesResponse, error) {
+ ctx = ctxsetters.WithPackageName(ctx, "status")
+ ctx = ctxsetters.WithServiceName(ctx, "StatusService")
+ ctx = ctxsetters.WithMethodName(ctx, "GetAutorollerStatuses")
+ out := new(GetAutorollerStatusesResponse)
+ ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out)
+ if err != nil {
+ twerr, ok := err.(twirp.Error)
+ if !ok {
+ twerr = twirp.InternalErrorWith(err)
+ }
+ callClientError(ctx, c.opts.Hooks, twerr)
+ return nil, err
+ }
+
+ callClientResponseReceived(ctx, c.opts.Hooks)
+
+ return out, nil
+}
+
// ============================
// StatusService Server Handler
// ============================
@@ -306,6 +351,9 @@
case "/twirp/status.StatusService/DeleteComment":
s.serveDeleteComment(ctx, resp, req)
return
+ case "/twirp/status.StatusService/GetAutorollerStatuses":
+ s.serveGetAutorollerStatuses(ctx, resp, req)
+ return
default:
msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
err = badRouteError(msg, req.Method, req.URL.Path)
@@ -701,6 +749,135 @@
callResponseSent(ctx, s.hooks)
}
+func (s *statusServiceServer) serveGetAutorollerStatuses(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
+ header := req.Header.Get("Content-Type")
+ i := strings.Index(header, ";")
+ if i == -1 {
+ i = len(header)
+ }
+ switch strings.TrimSpace(strings.ToLower(header[:i])) {
+ case "application/json":
+ s.serveGetAutorollerStatusesJSON(ctx, resp, req)
+ case "application/protobuf":
+ s.serveGetAutorollerStatusesProtobuf(ctx, resp, req)
+ default:
+ msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
+ twerr := badRouteError(msg, req.Method, req.URL.Path)
+ s.writeError(ctx, resp, twerr)
+ }
+}
+
+func (s *statusServiceServer) serveGetAutorollerStatusesJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
+ var err error
+ ctx = ctxsetters.WithMethodName(ctx, "GetAutorollerStatuses")
+ ctx, err = callRequestRouted(ctx, s.hooks)
+ if err != nil {
+ s.writeError(ctx, resp, err)
+ return
+ }
+
+ reqContent := new(GetAutorollerStatusesRequest)
+ unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
+ if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
+ s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
+ return
+ }
+
+ // Call service method
+ var respContent *GetAutorollerStatusesResponse
+ func() {
+ defer ensurePanicResponses(ctx, resp, s.hooks)
+ respContent, err = s.StatusService.GetAutorollerStatuses(ctx, reqContent)
+ }()
+
+ if err != nil {
+ s.writeError(ctx, resp, err)
+ return
+ }
+ if respContent == nil {
+ s.writeError(ctx, resp, twirp.InternalError("received a nil *GetAutorollerStatusesResponse and nil error while calling GetAutorollerStatuses. nil responses are not supported"))
+ return
+ }
+
+ ctx = callResponsePrepared(ctx, s.hooks)
+
+ var buf bytes.Buffer
+ marshaler := &jsonpb.Marshaler{OrigName: true}
+ if err = marshaler.Marshal(&buf, respContent); err != nil {
+ s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
+ return
+ }
+
+ ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
+ respBytes := buf.Bytes()
+ resp.Header().Set("Content-Type", "application/json")
+ resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
+ resp.WriteHeader(http.StatusOK)
+
+ if n, err := resp.Write(respBytes); err != nil {
+ msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
+ twerr := twirp.NewError(twirp.Unknown, msg)
+ callError(ctx, s.hooks, twerr)
+ }
+ callResponseSent(ctx, s.hooks)
+}
+
+func (s *statusServiceServer) serveGetAutorollerStatusesProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
+ var err error
+ ctx = ctxsetters.WithMethodName(ctx, "GetAutorollerStatuses")
+ ctx, err = callRequestRouted(ctx, s.hooks)
+ if err != nil {
+ s.writeError(ctx, resp, err)
+ return
+ }
+
+ buf, err := ioutil.ReadAll(req.Body)
+ if err != nil {
+ s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
+ return
+ }
+ reqContent := new(GetAutorollerStatusesRequest)
+ if err = proto.Unmarshal(buf, reqContent); err != nil {
+ s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
+ return
+ }
+
+ // Call service method
+ var respContent *GetAutorollerStatusesResponse
+ func() {
+ defer ensurePanicResponses(ctx, resp, s.hooks)
+ respContent, err = s.StatusService.GetAutorollerStatuses(ctx, reqContent)
+ }()
+
+ if err != nil {
+ s.writeError(ctx, resp, err)
+ return
+ }
+ if respContent == nil {
+ s.writeError(ctx, resp, twirp.InternalError("received a nil *GetAutorollerStatusesResponse and nil error while calling GetAutorollerStatuses. nil responses are not supported"))
+ return
+ }
+
+ ctx = callResponsePrepared(ctx, s.hooks)
+
+ respBytes, err := proto.Marshal(respContent)
+ if err != nil {
+ s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
+ return
+ }
+
+ ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
+ resp.Header().Set("Content-Type", "application/protobuf")
+ resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
+ resp.WriteHeader(http.StatusOK)
+ if n, err := resp.Write(respBytes); err != nil {
+ msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
+ twerr := twirp.NewError(twirp.Unknown, msg)
+ callError(ctx, s.hooks, twerr)
+ }
+ callResponseSent(ctx, s.hooks)
+}
+
func (s *statusServiceServer) ServiceDescriptor() ([]byte, int) {
return twirpFileDescriptor0, 0
}
@@ -1229,62 +1406,71 @@
}
var twirpFileDescriptor0 = []byte{
- // 898 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0xdd, 0x6e, 0x1b, 0x45,
- 0x14, 0xee, 0xac, 0x1d, 0xc7, 0x7b, 0xe2, 0x98, 0x74, 0xd4, 0x36, 0x53, 0xb7, 0x51, 0xc3, 0xaa,
- 0x95, 0x2c, 0x40, 0x36, 0x0d, 0x5c, 0x70, 0x4b, 0x82, 0x20, 0x95, 0x4a, 0x41, 0x93, 0x72, 0xc3,
- 0x8d, 0x35, 0xf6, 0x8e, 0xd7, 0x4b, 0xbc, 0x3b, 0xcb, 0xcc, 0xd8, 0x28, 0x17, 0xdc, 0xf7, 0x39,
- 0x78, 0x04, 0x6e, 0x90, 0xb8, 0x45, 0xbc, 0x04, 0x4f, 0x83, 0xe6, 0x6f, 0x6d, 0xe7, 0xa7, 0x6d,
- 0x7a, 0x37, 0xe7, 0x9c, 0x6f, 0xcf, 0xcf, 0xf7, 0x9d, 0x99, 0x85, 0x8e, 0xd2, 0x4c, 0x2f, 0xd4,
- 0xa0, 0x92, 0x42, 0x0b, 0xdc, 0x72, 0x56, 0xef, 0x49, 0x26, 0x44, 0x36, 0xe7, 0x43, 0xeb, 0x1d,
- 0x2f, 0xa6, 0x43, 0x9d, 0x17, 0x5c, 0x69, 0x56, 0x54, 0x0e, 0x98, 0xfc, 0x85, 0xe0, 0xf1, 0x77,
- 0x5c, 0xbf, 0x28, 0x27, 0x92, 0x17, 0xbc, 0xd4, 0x6c, 0x7e, 0x22, 0x8a, 0x22, 0xd7, 0x8a, 0xf2,
- 0x5f, 0x17, 0x5c, 0x69, 0x3c, 0x80, 0xe6, 0x54, 0x8a, 0x82, 0xa0, 0x43, 0xd4, 0xdf, 0x39, 0xea,
- 0x0d, 0x5c, 0xc2, 0x41, 0x48, 0x38, 0x78, 0x1d, 0x12, 0x52, 0x8b, 0xc3, 0x9f, 0x40, 0xa4, 0x05,
- 0x89, 0xde, 0x89, 0x8e, 0xb4, 0xc0, 0x1d, 0x40, 0x25, 0x69, 0x1c, 0xa2, 0x7e, 0x83, 0xa2, 0x12,
- 0xef, 0x41, 0xa3, 0x12, 0x29, 0x69, 0x1e, 0xa2, 0x7e, 0x4c, 0xcd, 0x11, 0x3f, 0x82, 0x58, 0xf2,
- 0x4a, 0x8c, 0x2a, 0xa6, 0x67, 0x64, 0xcb, 0xfa, 0xdb, 0xc6, 0xf1, 0x23, 0xd3, 0xb3, 0xe4, 0x0d,
- 0x82, 0x83, 0x1b, 0x3a, 0x57, 0x95, 0x28, 0x15, 0xc7, 0x5f, 0x42, 0xbb, 0xe0, 0x9a, 0xa5, 0x4c,
- 0x33, 0xdf, 0x3e, 0x19, 0x78, 0x96, 0x02, 0xe6, 0x7b, 0x1f, 0xa7, 0x35, 0x12, 0x3f, 0x87, 0xd6,
- 0xa2, 0x4a, 0x99, 0xe6, 0x7e, 0x88, 0x87, 0xe1, 0x9b, 0xb5, 0x4a, 0x3f, 0x59, 0x00, 0xf5, 0xc0,
- 0xe4, 0x5f, 0x04, 0x77, 0xaf, 0x44, 0xf1, 0x67, 0xb0, 0x3d, 0x71, 0x1d, 0x11, 0x74, 0xd8, 0xe8,
- 0xef, 0x1c, 0xe1, 0x90, 0xe9, 0xa5, 0x28, 0x33, 0xd7, 0x2c, 0x0d, 0x10, 0xfc, 0x1c, 0x3a, 0x63,
- 0xc9, 0xca, 0xc9, 0x6c, 0x34, 0xe3, 0x2c, 0x55, 0x24, 0xb2, 0x9f, 0x74, 0xc3, 0x27, 0xc7, 0x36,
- 0x46, 0x77, 0x1c, 0xe6, 0xd4, 0x40, 0x70, 0x02, 0x5b, 0x9a, 0xa9, 0x73, 0x45, 0x1a, 0x16, 0xdb,
- 0x09, 0xd8, 0xd7, 0x4c, 0x9d, 0x53, 0x17, 0xc2, 0x9f, 0x42, 0xdb, 0x54, 0xe0, 0xa5, 0x56, 0xa4,
- 0x69, 0x61, 0x1f, 0x05, 0xd8, 0x89, 0xf3, 0xd3, 0x1a, 0x90, 0x7c, 0x0e, 0x2d, 0x57, 0x07, 0x63,
- 0x68, 0x96, 0xac, 0xe0, 0x96, 0xb6, 0x98, 0xda, 0xb3, 0xf1, 0x99, 0xd6, 0x2c, 0x2d, 0x31, 0xb5,
- 0xe7, 0xe4, 0x0f, 0x04, 0x4d, 0x53, 0x0e, 0x93, 0xcd, 0x61, 0xe3, 0xd5, 0x60, 0x21, 0x55, 0xb4,
- 0x96, 0xaa, 0x0b, 0x51, 0x9e, 0x5a, 0xe5, 0x63, 0x1a, 0xe5, 0x29, 0xee, 0x41, 0x5b, 0xf2, 0x65,
- 0xae, 0x72, 0x51, 0x7a, 0xfd, 0x6b, 0x1b, 0x3f, 0x00, 0xbf, 0xcc, 0x7e, 0x03, 0xbc, 0x85, 0xfb,
- 0xb0, 0xa7, 0x7e, 0x63, 0xb2, 0xc8, 0xcb, 0x6c, 0x64, 0x66, 0x1d, 0xe5, 0x29, 0x69, 0x59, 0x44,
- 0x37, 0xf8, 0x4d, 0x67, 0x2f, 0xd2, 0xe4, 0x6f, 0x04, 0xb0, 0xa2, 0xdc, 0xce, 0xc1, 0xd4, 0x2c,
- 0xcc, 0x66, 0xce, 0xa6, 0x08, 0x5b, 0xe8, 0x99, 0x90, 0xbe, 0x4d, 0x6f, 0x99, 0xb1, 0xd4, 0x62,
- 0xfc, 0x0b, 0x9f, 0x68, 0xdf, 0x6d, 0x30, 0x4d, 0xa4, 0x62, 0xb2, 0xe6, 0x35, 0xa6, 0xc1, 0x34,
- 0xf9, 0xc7, 0x22, 0xbd, 0xf0, 0xed, 0xda, 0x33, 0xfe, 0x0a, 0xe2, 0xfa, 0xe6, 0xd9, 0x2e, 0xdf,
- 0x7e, 0x39, 0x56, 0xe0, 0xe4, 0x9f, 0x08, 0xb6, 0xbd, 0x52, 0x9e, 0x36, 0x54, 0xd3, 0x86, 0xa1,
- 0x69, 0xae, 0x43, 0xa0, 0xd6, 0x9c, 0x37, 0x2b, 0x35, 0x6e, 0x51, 0xc9, 0x64, 0x5b, 0x28, 0x2e,
- 0xbd, 0x00, 0xf6, 0x6c, 0xa6, 0x2c, 0xb8, 0x52, 0x2c, 0xe3, 0x7e, 0x9c, 0x60, 0x9a, 0x48, 0xca,
- 0xe7, 0x5c, 0x73, 0xc7, 0x7a, 0x9b, 0x06, 0x13, 0x3f, 0x83, 0x6e, 0x9e, 0x95, 0x42, 0xf2, 0xd1,
- 0x94, 0xe5, 0xf3, 0x85, 0xe4, 0x64, 0xdb, 0x02, 0x76, 0x9d, 0xf7, 0x5b, 0xe7, 0xc4, 0xf7, 0x60,
- 0x6b, 0x3a, 0x67, 0xe7, 0x17, 0xa4, 0x6d, 0xa3, 0xce, 0xc0, 0x4f, 0xa1, 0x6b, 0xc5, 0x54, 0x15,
- 0x9f, 0x8c, 0xec, 0xde, 0xc4, 0xb6, 0x6e, 0xc7, 0x78, 0xcf, 0x2a, 0x3e, 0x79, 0x65, 0xf6, 0x67,
- 0x1f, 0xb6, 0x83, 0xe4, 0xe0, 0xf4, 0xd2, 0x56, 0x6a, 0xa3, 0xa3, 0xdb, 0x3b, 0xb2, 0xe3, 0xfc,
- 0xce, 0x4a, 0x7e, 0x87, 0xbd, 0xcb, 0x57, 0x1e, 0x1f, 0x00, 0x28, 0xcd, 0xa4, 0x1e, 0x89, 0x25,
- 0x97, 0x96, 0xd5, 0x36, 0x8d, 0xad, 0xe7, 0x87, 0x25, 0x97, 0xe1, 0x39, 0x8a, 0x56, 0xcf, 0xd1,
- 0x07, 0x53, 0x9b, 0xfc, 0x87, 0xe0, 0xee, 0xd7, 0x69, 0x1a, 0x6e, 0x9c, 0x7f, 0x5a, 0x83, 0x7c,
- 0x68, 0x4d, 0x3e, 0x52, 0x0f, 0x60, 0x0b, 0x9f, 0xde, 0x09, 0x23, 0xe0, 0x03, 0x88, 0x6b, 0x66,
- 0xdc, 0x32, 0x9e, 0xde, 0xa1, 0xed, 0x40, 0x0b, 0x7e, 0xb8, 0xa2, 0xa4, 0x19, 0xbe, 0xf4, 0xa4,
- 0xdc, 0x2c, 0x62, 0xad, 0x41, 0x6b, 0x5d, 0x83, 0xf7, 0x13, 0xf0, 0xb8, 0x05, 0x4d, 0x7d, 0x51,
- 0xf1, 0xe4, 0x15, 0xe0, 0xf5, 0xd9, 0xfc, 0xe3, 0xbb, 0x41, 0x16, 0xba, 0x0d, 0x59, 0x7f, 0x22,
- 0xb8, 0xf7, 0x8d, 0xdd, 0xa5, 0xf7, 0xe0, 0xeb, 0xc1, 0x26, 0x5f, 0x35, 0x5b, 0x8f, 0xae, 0xb0,
- 0xb5, 0xc6, 0xd5, 0xfe, 0x25, 0xae, 0x6a, 0xa6, 0x36, 0x9a, 0xde, 0xba, 0x4d, 0xd3, 0xfb, 0x70,
- 0xff, 0x52, 0xcf, 0x8e, 0x87, 0xa3, 0x37, 0x11, 0xec, 0x9e, 0xd9, 0x17, 0xeb, 0x8c, 0xcb, 0x65,
- 0x3e, 0xe1, 0x38, 0x85, 0xfb, 0xd7, 0xfe, 0xb7, 0xf0, 0xd3, 0xf0, 0x32, 0xbf, 0xed, 0x87, 0xdc,
- 0x7b, 0xf6, 0x0e, 0x94, 0xe7, 0xff, 0x04, 0x60, 0xa5, 0x0a, 0xae, 0x7f, 0x62, 0x57, 0xb6, 0xb0,
- 0xd7, 0xbb, 0x2e, 0xe4, 0x93, 0xbc, 0x84, 0xdd, 0x8d, 0xa9, 0xf0, 0xe3, 0x00, 0xbe, 0x4e, 0xa0,
- 0xde, 0xc1, 0x0d, 0x51, 0x97, 0xed, 0xf8, 0xe3, 0x9f, 0x9f, 0x64, 0x62, 0xa0, 0xce, 0x73, 0x36,
- 0x10, 0x32, 0x1b, 0xe6, 0xe5, 0x54, 0xb2, 0xa1, 0xfb, 0x62, 0x98, 0x89, 0xa1, 0xac, 0x26, 0xe3,
- 0x96, 0x65, 0xf9, 0x8b, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x6b, 0x95, 0xd0, 0xb8, 0xce, 0x08,
- 0x00, 0x00,
+ // 1046 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcd, 0x8e, 0x1b, 0x45,
+ 0x10, 0xce, 0x8c, 0xbd, 0x5e, 0x4f, 0xd9, 0x6b, 0x9c, 0x56, 0x92, 0x9d, 0x38, 0x59, 0xb2, 0x8c,
+ 0x12, 0xc9, 0x02, 0x64, 0x93, 0x85, 0x03, 0xd7, 0xec, 0xa2, 0xb0, 0x91, 0x42, 0x40, 0xbd, 0xe1,
+ 0xc2, 0xc5, 0x6a, 0x7b, 0xda, 0xf6, 0xb0, 0x33, 0xd3, 0x43, 0x77, 0x8f, 0xd1, 0x1e, 0xb8, 0xf3,
+ 0x1c, 0x3c, 0x02, 0x17, 0x24, 0xae, 0x88, 0x77, 0x40, 0x3c, 0x04, 0xcf, 0x80, 0xfa, 0x6f, 0xfc,
+ 0xb3, 0x76, 0x92, 0xcd, 0xad, 0xab, 0xea, 0xeb, 0xea, 0xaa, 0xaf, 0x7e, 0x66, 0xa0, 0x2d, 0x24,
+ 0x91, 0xa5, 0x18, 0x14, 0x9c, 0x49, 0x86, 0x1a, 0x46, 0xea, 0x3d, 0x9a, 0x31, 0x36, 0x4b, 0xe9,
+ 0x50, 0x6b, 0xc7, 0xe5, 0x74, 0x28, 0x93, 0x8c, 0x0a, 0x49, 0xb2, 0xc2, 0x00, 0xa3, 0x3f, 0x3c,
+ 0x78, 0xf8, 0x35, 0x95, 0x2f, 0xf2, 0x09, 0xa7, 0x19, 0xcd, 0x25, 0x49, 0xcf, 0x58, 0x96, 0x25,
+ 0x52, 0x60, 0xfa, 0x53, 0x49, 0x85, 0x44, 0x03, 0xa8, 0x4f, 0x39, 0xcb, 0x42, 0xef, 0xd8, 0xeb,
+ 0xb7, 0x4e, 0x7a, 0x03, 0xe3, 0x70, 0xe0, 0x1c, 0x0e, 0x5e, 0x3b, 0x87, 0x58, 0xe3, 0xd0, 0xc7,
+ 0xe0, 0x4b, 0x16, 0xfa, 0x6f, 0x45, 0xfb, 0x92, 0xa1, 0x36, 0x78, 0x79, 0x58, 0x3b, 0xf6, 0xfa,
+ 0x35, 0xec, 0xe5, 0xa8, 0x0b, 0xb5, 0x82, 0xc5, 0x61, 0xfd, 0xd8, 0xeb, 0x07, 0x58, 0x1d, 0xd1,
+ 0x03, 0x08, 0x38, 0x2d, 0xd8, 0xa8, 0x20, 0x72, 0x1e, 0xee, 0x69, 0x7d, 0x53, 0x29, 0xbe, 0x23,
+ 0x72, 0x1e, 0xfd, 0xea, 0xc1, 0xd1, 0x8e, 0xc8, 0x45, 0xc1, 0x72, 0x41, 0xd1, 0x17, 0xd0, 0xcc,
+ 0xa8, 0x24, 0x31, 0x91, 0xc4, 0x86, 0x1f, 0x0e, 0x2c, 0x4b, 0x0e, 0xf3, 0x8d, 0xb5, 0xe3, 0x0a,
+ 0x89, 0x9e, 0x42, 0xa3, 0x2c, 0x62, 0x22, 0xa9, 0x4d, 0xe2, 0xbe, 0xbb, 0xb3, 0xf2, 0xd2, 0xf7,
+ 0x1a, 0x80, 0x2d, 0x30, 0xfa, 0xdb, 0x83, 0xdb, 0xd7, 0xac, 0xe8, 0x53, 0xd8, 0x9f, 0x98, 0x88,
+ 0x42, 0xef, 0xb8, 0xd6, 0x6f, 0x9d, 0x20, 0xe7, 0xe9, 0x25, 0xcb, 0x67, 0x26, 0x58, 0xec, 0x20,
+ 0xe8, 0x29, 0xb4, 0xc7, 0x9c, 0xe4, 0x93, 0xf9, 0x68, 0x4e, 0x49, 0x2c, 0x42, 0x5f, 0x5f, 0xe9,
+ 0xb8, 0x2b, 0xa7, 0xda, 0x86, 0x5b, 0x06, 0x73, 0xae, 0x20, 0x28, 0x82, 0x3d, 0x49, 0xc4, 0xa5,
+ 0x08, 0x6b, 0x1a, 0xdb, 0x76, 0xd8, 0xd7, 0x44, 0x5c, 0x62, 0x63, 0x42, 0x9f, 0x40, 0x53, 0xbd,
+ 0x40, 0x73, 0x29, 0xc2, 0xba, 0x86, 0x7d, 0xe0, 0x60, 0x67, 0x46, 0x8f, 0x2b, 0x40, 0xf4, 0x19,
+ 0x34, 0xcc, 0x3b, 0x08, 0x41, 0x3d, 0x27, 0x19, 0xd5, 0xb4, 0x05, 0x58, 0x9f, 0x95, 0x4e, 0x85,
+ 0xa6, 0x69, 0x09, 0xb0, 0x3e, 0x47, 0xbf, 0x79, 0x50, 0x57, 0xcf, 0xa1, 0x70, 0x3d, 0xd9, 0x60,
+ 0x99, 0x98, 0x73, 0xe5, 0xaf, 0xb8, 0xea, 0x80, 0x9f, 0xc4, 0xba, 0xf2, 0x01, 0xf6, 0x93, 0x18,
+ 0xf5, 0xa0, 0xc9, 0xe9, 0x22, 0x11, 0x09, 0xcb, 0x6d, 0xfd, 0x2b, 0x19, 0xdd, 0x03, 0xdb, 0xcc,
+ 0xb6, 0x03, 0xac, 0x84, 0xfa, 0xd0, 0x15, 0x3f, 0x13, 0x9e, 0x25, 0xf9, 0x6c, 0xa4, 0x72, 0x1d,
+ 0x25, 0x71, 0xd8, 0xd0, 0x88, 0x8e, 0xd3, 0xab, 0xc8, 0x5e, 0xc4, 0xd1, 0x9f, 0x1e, 0xc0, 0x92,
+ 0x72, 0x9d, 0x07, 0x11, 0x73, 0x97, 0x9b, 0x3a, 0xab, 0x47, 0x48, 0x29, 0xe7, 0x8c, 0xdb, 0x30,
+ 0xad, 0xa4, 0xd2, 0x12, 0xe5, 0xf8, 0x47, 0x3a, 0x91, 0x36, 0x5a, 0x27, 0x2a, 0x4b, 0x41, 0x78,
+ 0xc5, 0x6b, 0x80, 0x9d, 0xa8, 0xfc, 0x8f, 0x59, 0x7c, 0x65, 0xc3, 0xd5, 0x67, 0xf4, 0x25, 0x04,
+ 0xd5, 0xe4, 0xe9, 0x28, 0xdf, 0x3c, 0x1c, 0x4b, 0x70, 0xf4, 0x97, 0x0f, 0xfb, 0xb6, 0x52, 0x96,
+ 0x36, 0xaf, 0xa2, 0x0d, 0x41, 0x5d, 0x8d, 0x83, 0xa3, 0x56, 0x9d, 0xd7, 0x5f, 0xaa, 0xdd, 0xe0,
+ 0x25, 0xe5, 0xad, 0x14, 0x94, 0xdb, 0x02, 0xe8, 0xb3, 0xca, 0x32, 0xa3, 0x42, 0x90, 0x19, 0xb5,
+ 0xe9, 0x38, 0x51, 0x59, 0x62, 0x9a, 0x52, 0x49, 0x0d, 0xeb, 0x4d, 0xec, 0x44, 0xf4, 0x04, 0x3a,
+ 0xc9, 0x2c, 0x67, 0x9c, 0x8e, 0xa6, 0x24, 0x49, 0x4b, 0x4e, 0xc3, 0x7d, 0x0d, 0x38, 0x30, 0xda,
+ 0xe7, 0x46, 0x89, 0xee, 0xc0, 0xde, 0x34, 0x25, 0x97, 0x57, 0x61, 0x53, 0x5b, 0x8d, 0x80, 0x1e,
+ 0x43, 0x47, 0x17, 0x53, 0x14, 0x74, 0x32, 0xd2, 0x7d, 0x13, 0xe8, 0x77, 0xdb, 0x4a, 0x7b, 0x51,
+ 0xd0, 0xc9, 0x2b, 0xd5, 0x3f, 0x87, 0xb0, 0xef, 0x4a, 0x0e, 0xa6, 0x5e, 0x52, 0x97, 0x5a, 0xd5,
+ 0xd1, 0xf4, 0x5d, 0xd8, 0x32, 0x7a, 0x23, 0x45, 0xbf, 0x40, 0x77, 0x73, 0xe4, 0xd1, 0x11, 0x80,
+ 0x90, 0x84, 0xcb, 0x11, 0x5b, 0x50, 0xae, 0x59, 0x6d, 0xe2, 0x40, 0x6b, 0xbe, 0x5d, 0x50, 0xee,
+ 0xd6, 0x91, 0xbf, 0x5c, 0x47, 0xef, 0x4d, 0x6d, 0xf4, 0xaf, 0x07, 0xb7, 0x9f, 0xc5, 0xb1, 0x9b,
+ 0x38, 0xbb, 0x5a, 0x5d, 0xf9, 0xbc, 0x95, 0xf2, 0x85, 0x55, 0x02, 0xfa, 0xe1, 0xf3, 0x5b, 0x2e,
+ 0x05, 0x74, 0x04, 0x41, 0xc5, 0x8c, 0x69, 0xc6, 0xf3, 0x5b, 0xb8, 0xe9, 0x68, 0x41, 0xf7, 0x97,
+ 0x94, 0xd4, 0xdd, 0x4d, 0x4b, 0xca, 0xee, 0x22, 0x56, 0x35, 0x68, 0xac, 0xd6, 0xe0, 0xdd, 0x0a,
+ 0x78, 0xda, 0x80, 0xba, 0xbc, 0x2a, 0x68, 0xf4, 0x0a, 0xd0, 0x6a, 0x6e, 0x76, 0xf9, 0xae, 0x91,
+ 0xe5, 0xdd, 0x84, 0xac, 0xdf, 0x3d, 0xb8, 0xf3, 0x95, 0xee, 0xa5, 0x77, 0xe0, 0xeb, 0xde, 0x3a,
+ 0x5f, 0x15, 0x5b, 0x0f, 0xae, 0xb1, 0xb5, 0xc2, 0xd5, 0xe1, 0x06, 0x57, 0x15, 0x53, 0x6b, 0x41,
+ 0xef, 0xdd, 0x24, 0xe8, 0x43, 0xb8, 0xbb, 0x11, 0xb3, 0xe1, 0x21, 0xfa, 0x50, 0x7f, 0x5f, 0x9f,
+ 0x95, 0x92, 0x71, 0x96, 0xa6, 0x94, 0x5f, 0xe8, 0xed, 0x45, 0xdd, 0xf7, 0x35, 0xba, 0xd0, 0x5f,
+ 0xb1, 0x6d, 0x76, 0x4b, 0xe4, 0x09, 0xec, 0x1b, 0x8b, 0xfb, 0x8c, 0x54, 0x1f, 0xb1, 0xcd, 0x4b,
+ 0xd8, 0x01, 0xa3, 0x7f, 0x3c, 0xe8, 0x6e, 0x5a, 0xb7, 0xee, 0xf4, 0x3e, 0x74, 0x27, 0x25, 0x57,
+ 0x7b, 0x6b, 0xa4, 0xb0, 0x23, 0x4e, 0x17, 0x96, 0xc8, 0x8e, 0xd5, 0x63, 0x96, 0xa6, 0x98, 0x2e,
+ 0x50, 0x04, 0x07, 0x29, 0x11, 0x2b, 0x30, 0x43, 0x6a, 0x4b, 0x29, 0x1d, 0x06, 0x41, 0x3d, 0x63,
+ 0x31, 0x75, 0x1b, 0x44, 0x9d, 0xd5, 0x94, 0xe5, 0x65, 0xa6, 0x3b, 0x89, 0xc6, 0x9a, 0xd3, 0x3d,
+ 0x1c, 0xe4, 0x65, 0xf6, 0x5c, 0x2b, 0x9c, 0x79, 0x4c, 0xe7, 0x49, 0x6e, 0x36, 0x89, 0x31, 0x9f,
+ 0x6a, 0x85, 0x1a, 0xc2, 0x92, 0xa7, 0xba, 0xff, 0x02, 0xac, 0x8e, 0x27, 0xff, 0xf9, 0x70, 0x60,
+ 0x12, 0xba, 0xa0, 0x7c, 0x91, 0x4c, 0x28, 0x8a, 0xe1, 0xee, 0xd6, 0xff, 0x00, 0xf4, 0xd8, 0x11,
+ 0xf5, 0xa6, 0x1f, 0x9c, 0xde, 0x93, 0xb7, 0xa0, 0x6c, 0x19, 0xce, 0x00, 0x96, 0x5d, 0x8e, 0xaa,
+ 0x9f, 0x82, 0x6b, 0x53, 0xdd, 0xeb, 0x6d, 0x33, 0x59, 0x27, 0x2f, 0xe1, 0x60, 0xad, 0x4b, 0xd0,
+ 0x43, 0x07, 0xde, 0xd6, 0xf0, 0xbd, 0xa3, 0x1d, 0x56, 0xeb, 0xcd, 0x24, 0x7e, 0xbd, 0x75, 0xd6,
+ 0x12, 0xdf, 0xd9, 0x79, 0x6b, 0x89, 0xef, 0xee, 0xbf, 0xd3, 0x8f, 0x7e, 0x78, 0x34, 0x63, 0x03,
+ 0x71, 0x99, 0x90, 0x01, 0xe3, 0xb3, 0x61, 0x92, 0x4f, 0x39, 0x19, 0x9a, 0x9b, 0xc3, 0x19, 0x1b,
+ 0xf2, 0x62, 0x32, 0x6e, 0xe8, 0xd9, 0xf8, 0xfc, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x68, 0x40,
+ 0x83, 0xac, 0x84, 0x0a, 0x00, 0x00,
}
diff --git a/status/go/status/main.go b/status/go/status/main.go
index 0e9a0dd..140ce0c 100644
--- a/status/go/status/main.go
+++ b/status/go/status/main.go
@@ -14,6 +14,7 @@
"path"
"path/filepath"
"runtime"
+ "sort"
"strconv"
"strings"
"sync"
@@ -72,18 +73,19 @@
var (
autorollMtx sync.RWMutex
- autorollStatus []byte = nil
- capacityClient *capacity.CapacityClient = nil
- capacityTemplate *template.Template = nil
- commitsTemplate *template.Template = nil
- experimentalCommitsTemplate *template.Template = nil
- iCache *incremental.IncrementalCache = nil
- lkgrObj *lkgr.LKGR = nil
- taskDb db.RemoteDB = nil
- taskDriverDb task_driver_db.DB = nil
- taskDriverLogs *logs.LogsManager = nil
- tasksPerCommit *tasksPerCommitCache = nil
- tCache cache.TaskCache = nil
+ autorollStatus []byte = nil
+ autorollStatusTwirp *rpc.GetAutorollerStatusesResponse = nil
+ capacityClient *capacity.CapacityClient = nil
+ capacityTemplate *template.Template = nil
+ commitsTemplate *template.Template = nil
+ experimentalCommitsTemplate *template.Template = nil
+ iCache *incremental.IncrementalCache = nil
+ lkgrObj *lkgr.LKGR = nil
+ taskDb db.RemoteDB = nil
+ taskDriverDb task_driver_db.DB = nil
+ taskDriverLogs *logs.LogsManager = nil
+ tasksPerCommit *tasksPerCommitCache = nil
+ tCache cache.TaskCache = nil
// AUTOROLLERS maps autoroll frontend host to maps of roller IDs to
// their human-friendly display names.
@@ -707,6 +709,12 @@
}
}
+func getAutorollerStatusesTwirp() *rpc.GetAutorollerStatusesResponse {
+ autorollMtx.RLock()
+ defer autorollMtx.RUnlock()
+ return autorollStatusTwirp
+}
+
func runServer(serverURL string, srv http.Handler) {
topLevelRouter := mux.NewRouter()
topLevelRouter.Use(login.RestrictViewer)
@@ -778,7 +786,7 @@
podId = uuid.New().String()
}
- repoURLsByName := make(map[string]string)
+ repoURLsByName = make(map[string]string)
for _, repoURL := range *repoUrls {
repoURLsByName[repoUrlToName(repoURL)] = fmt.Sprintf(gitiles.CommitURL, repoURL, "")
}
@@ -874,25 +882,41 @@
autorollStatusDB := status.NewDatastoreDB()
updateAutorollStatus := func(ctx context.Context) error {
statuses := map[string]autoRollStatus{}
+ statusesTwirp := []*rpc.AutorollerStatus{}
for host, subMap := range AUTOROLLERS {
for roller, friendlyName := range subMap {
s, err := autorollStatusDB.Get(ctx, roller)
if err != nil {
return err
}
+ miniStatus := s.AutoRollMiniStatus
+ url := fmt.Sprintf("https://%s/r/%s", host, roller)
statuses[friendlyName] = autoRollStatus{
- AutoRollMiniStatus: s.AutoRollMiniStatus,
- Url: fmt.Sprintf("https://%s/r/%s", host, roller),
+ AutoRollMiniStatus: miniStatus,
+ Url: url,
}
+ statusesTwirp = append(statusesTwirp,
+ &rpc.AutorollerStatus{
+ Name: friendlyName,
+ CurrentRollRev: miniStatus.CurrentRollRev,
+ LastRollRev: miniStatus.LastRollRev,
+ Mode: miniStatus.Mode,
+ NumBehind: int32(miniStatus.NumNotRolledCommits),
+ NumFailed: int32(miniStatus.NumFailedRolls),
+ Url: url})
}
}
b, err := json.Marshal(statuses)
if err != nil {
return err
}
+ sort.Slice(statusesTwirp, func(i, j int) bool {
+ return statusesTwirp[i].Name < statusesTwirp[j].Name
+ })
autorollMtx.Lock()
defer autorollMtx.Unlock()
autorollStatus = b
+ autorollStatusTwirp = &rpc.GetAutorollerStatusesResponse{Rollers: statusesTwirp}
return nil
}
if err := updateAutorollStatus(ctx); err != nil {
@@ -916,7 +940,7 @@
}
// Create Twirp Server.
- twirpServer := rpc.NewStatusServer(iCache, taskDb, getRepoTwirp, MAX_COMMITS_TO_LOAD, DEFAULT_COMMITS_TO_LOAD, podId)
+ twirpServer := rpc.NewStatusServer(iCache, taskDb, getAutorollerStatusesTwirp, getRepoTwirp, MAX_COMMITS_TO_LOAD, DEFAULT_COMMITS_TO_LOAD, podId)
// Run the server.
runServer(serverURL, twirpServer)
diff --git a/status/modules/autoroller-status-sk/autoroller-status-sk-demo.html b/status/modules/autoroller-status-sk/autoroller-status-sk-demo.html
new file mode 100644
index 0000000..fceb4d7
--- /dev/null
+++ b/status/modules/autoroller-status-sk/autoroller-status-sk-demo.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>autoroller-status-sk</title>
+ <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ </head>
+ <body>
+ <h1>autoroller-status-sk</h1>
+ <theme-chooser-sk></theme-chooser-sk>
+ <div id="container"></div>
+ <h2>Events</h2>
+ <pre id="events"></pre>
+ </body>
+</html>
diff --git a/status/modules/autoroller-status-sk/autoroller-status-sk-demo.ts b/status/modules/autoroller-status-sk/autoroller-status-sk-demo.ts
new file mode 100644
index 0000000..73b86b9
--- /dev/null
+++ b/status/modules/autoroller-status-sk/autoroller-status-sk-demo.ts
@@ -0,0 +1,7 @@
+import './index';
+import '../../../infra-sk/modules/theme-chooser-sk';
+import { getAutorollerStatusesResponse, SetupMocks } from '../rpc-mock';
+
+SetupMocks().expectGetAutorollerStatuses(getAutorollerStatusesResponse);
+const el = document.createElement('autoroller-status-sk');
+document.querySelector('#container')?.appendChild(el);
diff --git a/status/modules/autoroller-status-sk/autoroller-status-sk.scss b/status/modules/autoroller-status-sk/autoroller-status-sk.scss
new file mode 100644
index 0000000..0020ffc
--- /dev/null
+++ b/status/modules/autoroller-status-sk/autoroller-status-sk.scss
@@ -0,0 +1,63 @@
+@import '../styles.scss';
+
+autoroller-status-sk {
+ .table {
+ background-color: var(--surface);
+ color: var(--on-surface);
+ display: table;
+ border-collapse: collapse;
+ }
+
+ .tr {
+ display: table-row;
+ border-bottom: 1px solid var(--grey-200);
+ }
+
+ .tr.roller:hover {
+ background-color: var(--primary);
+ color: var(--on-primary);
+ fill: var(--on-primary);
+ }
+
+ .td,
+ .th {
+ display: table-cell;
+ padding: 10px;
+ }
+
+ .td {
+ font-size: 0.813em;
+ vertical-align: middle;
+ }
+
+ .th {
+ font-size: 0.75em;
+ }
+
+ .number {
+ text-align: right;
+ }
+
+ a {
+ color: inherit;
+ text-decoration: none;
+ }
+
+ a:hover {
+ text-decoration: underline;
+ }
+
+ .td {
+ font-size: 1em;
+ padding: 6px;
+ }
+
+ .th {
+ padding: 8px;
+ }
+
+ // Remove the alpha from the failure color to make it pop.
+ .bg-failure {
+ background-color: var(--failure);
+ }
+}
diff --git a/status/modules/autoroller-status-sk/autoroller-status-sk.ts b/status/modules/autoroller-status-sk/autoroller-status-sk.ts
new file mode 100644
index 0000000..be9dd70
--- /dev/null
+++ b/status/modules/autoroller-status-sk/autoroller-status-sk.ts
@@ -0,0 +1,88 @@
+/**
+ * @module modules/autoroller-status-sk
+ * @description <h2><code>autoroller-status-sk</code></h2>
+ *
+ * Custom element for displaying status of Skia autorollers.
+ */
+import { define } from 'elements-sk/define';
+import { html } from 'lit-html';
+import { ElementSk } from '../../../infra-sk/modules/ElementSk';
+import { StatusService, GetStatusService, AutorollerStatus } from '../rpc';
+
+function colorClass(status: AutorollerStatus) {
+ // Find a color class for the roller.
+ // TODO(borenet): These numbers (especially number of commits behind)
+ // are probably going to differ from roller to roller. How can we give
+ // each roller its own definition of "bad"?
+ var badness = status.numFailed / 2.0;
+ var badnessBehind = status.numBehind / 20.0;
+ if (status.mode !== 'dry run' && badnessBehind > badness) {
+ badness = badnessBehind;
+ }
+ if (status.mode === 'stopped') {
+ return 'bg-unknown';
+ } else if (badness < 0.5) {
+ return 'bg-success';
+ } else if (badness < 1.0) {
+ return 'bg-warning';
+ } else {
+ return 'bg-failure';
+ }
+}
+
+export class AutorollerStatusSk extends ElementSk {
+ private client: StatusService = GetStatusService();
+ private rollers: Array<AutorollerStatus> = [];
+
+ private static template = (el: AutorollerStatusSk) =>
+ html`
+ <div class="table">
+ <div class="tr">
+ <div class="th">Roller</div>
+ <div class="th">Mode</div>
+ <div class="th">Failed</div>
+ <div class="th">Behind</div>
+ </div>
+ ${el.rollers.map(
+ (roller) => html`
+ <a
+ class="tr roller ${colorClass(roller)}"
+ href=${roller.url}
+ target="_blank"
+ rel="noopener noreferrer"
+ >
+ <div class="td">${roller.name}</div>
+ <div class="td">${roller.mode}</div>
+ <div class="td number">${roller.numFailed}</div>
+ <div class="td number">${roller.numBehind}</div>
+ </a>
+ `
+ )}
+ </div>
+ `;
+
+ constructor() {
+ super(AutorollerStatusSk.template);
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ this._render();
+ this.refresh();
+ }
+
+ private refresh() {
+ this.client
+ .getAutorollerStatuses({})
+ .then((resp) => {
+ this.rollers = resp.rollers || [];
+ this._render();
+ })
+ .finally(() => {
+ // Updates happen periodically on the backend, this being configurable provides no benefit.
+ window.setTimeout(() => this.refresh(), 60 * 1000);
+ });
+ }
+}
+
+define('autoroller-status-sk', AutorollerStatusSk);
diff --git a/status/modules/autoroller-status-sk/autoroller-status-sk_puppeteer_test.ts b/status/modules/autoroller-status-sk/autoroller-status-sk_puppeteer_test.ts
new file mode 100644
index 0000000..d0f1b9c
--- /dev/null
+++ b/status/modules/autoroller-status-sk/autoroller-status-sk_puppeteer_test.ts
@@ -0,0 +1,29 @@
+import * as path from 'path';
+import { expect } from 'chai';
+import { setUpPuppeteerAndDemoPageServer, takeScreenshot } from '../../../puppeteer-tests/util';
+
+describe('autoroller-status-sk', () => {
+ const testBed = setUpPuppeteerAndDemoPageServer(
+ path.join(__dirname, '..', '..', 'webpack.config.ts')
+ );
+
+ beforeEach(async () => {
+ await testBed.page.goto(`${testBed.baseUrl}/dist/autoroller-status-sk.html`);
+ await testBed.page.setViewport({ width: 400, height: 550 });
+ });
+
+ it('should render the demo page (smoke test)', async () => {
+ expect(await testBed.page.$$('autoroller-status-sk')).to.have.length(1);
+ });
+
+ describe('screenshots', () => {
+ it('shows the default view', async () => {
+ await takeScreenshot(testBed.page, 'status', 'autoroller-status-sk');
+ });
+
+ it('highlights hovering', async () => {
+ testBed.page.hover('.roller');
+ await takeScreenshot(testBed.page, 'status', 'autoroller-status-sk_hover');
+ });
+ });
+});
diff --git a/status/modules/autoroller-status-sk/autoroller-status-sk_test.ts b/status/modules/autoroller-status-sk/autoroller-status-sk_test.ts
new file mode 100644
index 0000000..3616ba5
--- /dev/null
+++ b/status/modules/autoroller-status-sk/autoroller-status-sk_test.ts
@@ -0,0 +1,27 @@
+import './index';
+import { AutorollerStatusSk } from './autoroller-status-sk';
+
+import { $, $$ } from 'common-sk/modules/dom';
+import { setUpElementUnderTest } from '../../../infra-sk/modules/test_util';
+import { expect } from 'chai';
+import { getAutorollerStatusesResponse, SetupMocks } from '../rpc-mock';
+
+describe('autoroller-status-sk', () => {
+ const newInstance = setUpElementUnderTest<AutorollerStatusSk>('autoroller-status-sk');
+
+ let element: AutorollerStatusSk;
+ beforeEach(async () => {
+ SetupMocks().expectGetAutorollerStatuses(getAutorollerStatusesResponse);
+ element = newInstance();
+ await new Promise((resolve) => setTimeout(resolve, 0));
+ });
+
+ describe('display', () => {
+ it('statuses', () => {
+ expect($('.roller', element)).to.have.length(7);
+ expect($('.bg-failure', element)).to.have.length(1);
+ expect($('.bg-success', element)).to.have.length(4);
+ expect($('.bg-warning', element)).to.have.length(2);
+ });
+ });
+});
diff --git a/status/modules/autoroller-status-sk/index.ts b/status/modules/autoroller-status-sk/index.ts
new file mode 100644
index 0000000..2dda62e
--- /dev/null
+++ b/status/modules/autoroller-status-sk/index.ts
@@ -0,0 +1,2 @@
+import './autoroller-status-sk';
+import './autoroller-status-sk.scss';
diff --git a/status/modules/commits-table-sk/commits-table-sk.scss b/status/modules/commits-table-sk/commits-table-sk.scss
index bd1e375..67b2d5b 100644
--- a/status/modules/commits-table-sk/commits-table-sk.scss
+++ b/status/modules/commits-table-sk/commits-table-sk.scss
@@ -98,9 +98,9 @@
.reloadControls {
#repoLabel {
- position: absolute;
- top: 104px;
- left: 15px;
+ position: relative;
+ top: 30px;
+ left: 3px;
}
select {
@@ -208,39 +208,27 @@
z-index: 2;
}
- .task-success {
- background-color: rgba(102, 166, 30, 0.3);
+ .grow:hover.bg-success,
+ .grow:hover .bg-success {
+ background-color: var(--success);
}
- .task-failure {
- background-color: rgba(217, 95, 2, 0.3);
+ .grow:hover.bg-failure,
+ .grow:hover .bg-failure {
+ background-color: var(--failure);
}
- .task-mishap {
- background-color: rgba(117, 112, 179, 0.3);
- }
-
- .grow:hover.task-success,
- .grow:hover .task-success {
- background-color: rgb(102, 166, 30);
- }
-
- .grow:hover.task-failure,
- .grow:hover .task-failure {
- background-color: rgb(217, 95, 2);
- }
-
- .grow:hover.task-mishap,
- .grow:hover .task-mishap {
- background-color: rgb(117, 112, 179);
+ .grow:hover.bg-mishap,
+ .grow:hover .bg-mishap {
+ background-color: var(--unexpected);
}
.fill-green {
- fill: rgb(102, 166, 30);
+ fill: var(--success);
}
.fill-red {
- fill: #d95f02;
+ fill: var(--failure);
}
}
@@ -255,31 +243,4 @@
background-color: var(--surface-2dp);
}
}
-
- .task-success {
- background-color: rgba(102, 166, 30, 0.9);
- }
-
- .task-failure {
- background-color: rgba(217, 95, 2, 0.9);
- }
-
- .task-mishap {
- background-color: rgba(117, 112, 179, 0.9);
- }
-
- .grow:hover.task-success,
- .grow:hover .task-success {
- background-color: rgb(102, 166, 30);
- }
-
- .grow:hover.task-failure,
- .grow:hover .task-failure {
- background-color: rgb(217, 95, 2);
- }
-
- .grow:hover.task-mishap,
- .grow:hover .task-mishap {
- background-color: rgb(117, 112, 179);
- }
}
diff --git a/status/modules/commits-table-sk/commits-table-sk.ts b/status/modules/commits-table-sk/commits-table-sk.ts
index 409a7f2..a0e63a9 100644
--- a/status/modules/commits-table-sk/commits-table-sk.ts
+++ b/status/modules/commits-table-sk/commits-table-sk.ts
@@ -1047,7 +1047,7 @@
function taskClasses(task: Task, ...classes: Array<string>) {
const map: Record<string, any> = { task: true };
- map[`task-${(task.status || 'PENDING').toLowerCase()}`] = true;
+ map[`bg-${(task.status || 'PENDING').toLowerCase()}`] = true;
classes.forEach((c) => (map[c] = true));
return classMap(map);
}
diff --git a/status/modules/commits-table-sk/commits-table-sk_test.ts b/status/modules/commits-table-sk/commits-table-sk_test.ts
index 08a7620..5be041d 100644
--- a/status/modules/commits-table-sk/commits-table-sk_test.ts
+++ b/status/modules/commits-table-sk/commits-table-sk_test.ts
@@ -36,7 +36,7 @@
it('displays multiple commit tasks', async () => {
const table = await setupWithResponse(responseMultiCommitTask);
expect($('.task', table)).to.have.length(1);
- expect($$('.task', table)!.classList.value).to.include('task-failure');
+ expect($$('.task', table)!.classList.value).to.include('bg-failure');
});
it('displays noncontiguous tasks', async () => {
@@ -144,7 +144,7 @@
expect($('.task[title="Test-Some-Stuff @ parentofabc123"]', table)).to.have.length(1);
expect(
$$('.task[title="Test-Some-Stuff @ parentofabc123"]', table)?.classList.value
- ).to.contain('task-failure');
+ ).to.contain('bg-failure');
// Mock an incremental update, and change the reload interval to trigger it.
mocker.expectGetIncrementalCommits(incrementalResponse1);
const reloadInput = $$('#reloadInput input', table) as HTMLInputElement;
@@ -172,7 +172,7 @@
// Old task is updated.
expect(
$$('.task[title="Test-Some-Stuff @ parentofabc123"]', table)?.classList.value
- ).to.contain('task-success');
+ ).to.contain('bg-success');
});
it('resets with startOver update', async () => {
diff --git a/status/modules/rpc-mock/index.ts b/status/modules/rpc-mock/index.ts
index d1f00b8..807eec4 100644
--- a/status/modules/rpc-mock/index.ts
+++ b/status/modules/rpc-mock/index.ts
@@ -30,6 +30,9 @@
private processDeleteComment:
| ((req: status.DeleteCommentRequest) => status.DeleteCommentResponse)
| null = null;
+ private processGetAutorollerStatuses:
+ | ((req: status.GetAutorollerStatusesRequest) => status.GetAutorollerStatusesResponse)
+ | null = null;
private processGetIncrementalCommits:
| ((req: status.GetIncrementalCommitsRequest) => status.GetIncrementalCommitsResponse)
| null = null;
@@ -80,6 +83,18 @@
return this;
}
+ // Set the GetAutorollerStatuses response.
+ expectGetAutorollerStatuses(
+ resp: status.GetAutorollerStatusesResponse,
+ check: (req: status.GetAutorollerStatusesRequest) => void = (req) => {}
+ ): MockStatusService {
+ this.processGetAutorollerStatuses = (req) => {
+ check(req);
+ return resp;
+ };
+ return this;
+ }
+
getIncrementalCommits(
req: status.GetIncrementalCommitsRequest
): Promise<status.GetIncrementalCommitsResponse> {
@@ -99,4 +114,12 @@
this.processDeleteComment = null;
return process ? Promise.resolve(process(req)) : Promise.reject('No mock response set');
}
+
+ getAutorollerStatuses(
+ req: status.GetAutorollerStatusesRequest
+ ): Promise<status.GetAutorollerStatusesResponse> {
+ const process = this.processGetAutorollerStatuses;
+ this.processGetAutorollerStatuses = null;
+ return process ? Promise.resolve(process(req)) : Promise.reject('No mock response set');
+ }
}
diff --git a/status/modules/rpc-mock/test_data.ts b/status/modules/rpc-mock/test_data.ts
index 0973c45..fe2c55f 100644
--- a/status/modules/rpc-mock/test_data.ts
+++ b/status/modules/rpc-mock/test_data.ts
@@ -2,7 +2,14 @@
* Deterministic data for tests, crafted to cover various use cases, whereas mock_data is for
* visualizing a complete status table via nondeterministically generated tasks/commits.
*/
-import { Branch, GetIncrementalCommitsResponse, Comment, Task, LongCommit } from '../rpc/status';
+import {
+ Branch,
+ GetIncrementalCommitsResponse,
+ Comment,
+ Task,
+ LongCommit,
+ GetAutorollerStatusesResponse,
+} from '../rpc/status';
function copy<T>(obj: T): T {
return JSON.parse(JSON.stringify(obj));
@@ -241,3 +248,71 @@
r.metadata!.startOver = true;
return r;
})();
+
+export const getAutorollerStatusesResponse: GetAutorollerStatusesResponse = {
+ rollers: [
+ {
+ name: 'ANGLE',
+ mode: 'running',
+ numBehind: 0,
+ numFailed: 0,
+ currentRollRev: 'abc123',
+ lastRollRev: 'def456',
+ url: 'https://autoroll.skia.org/r/angle-skia-autoroll',
+ },
+ {
+ name: 'Android',
+ mode: 'running',
+ numBehind: 0,
+ numFailed: 1,
+ currentRollRev: 'abc123',
+ lastRollRev: 'def456',
+ url: 'https://autoroll.skia.org/r/android-skia-autoroll',
+ },
+ {
+ name: 'Chrome',
+ mode: 'running',
+ numBehind: 0,
+ numFailed: 1,
+ currentRollRev: 'abc123',
+ lastRollRev: 'def456',
+ url: 'https://autoroll.skia.org/r/chrome-skia-autoroll',
+ },
+ {
+ name: 'Flutter',
+ mode: 'running',
+ numBehind: 3,
+ numFailed: 6,
+ currentRollRev: 'abc123',
+ lastRollRev: 'def456',
+ url: 'https://autoroll.skia.org/r/flutter-skia-autoroll',
+ },
+ {
+ name: 'Google3',
+ mode: 'running',
+ numBehind: 0,
+ numFailed: 0,
+ currentRollRev: 'abc123',
+ lastRollRev: 'def456',
+ url: 'https://autoroll.skia.org/r/g3-skia-autoroll',
+ },
+ {
+ name: 'SwiftSh',
+ mode: 'running',
+ numBehind: 0,
+ numFailed: 0,
+ currentRollRev: 'abc123',
+ lastRollRev: 'def456',
+ url: 'https://autoroll.skia.org/r/swiftsh-skia-autoroll',
+ },
+ {
+ name: 'skcms',
+ mode: 'running',
+ numBehind: 0,
+ numFailed: 0,
+ currentRollRev: 'abc123',
+ lastRollRev: 'def456',
+ url: 'https://autoroll.skia.org/r/skcms-skia-autoroll',
+ },
+ ],
+};
diff --git a/status/modules/rpc/status.ts b/status/modules/rpc/status.ts
index bfa49e6..6c3b267 100644
--- a/status/modules/rpc/status.ts
+++ b/status/modules/rpc/status.ts
@@ -288,10 +288,68 @@
};
};
+export interface GetAutorollerStatusesRequest {
+}
+
+interface GetAutorollerStatusesRequestJSON {
+}
+
+const GetAutorollerStatusesRequestToJSON = (m: GetAutorollerStatusesRequest): GetAutorollerStatusesRequestJSON => {
+ return {
+ };
+};
+
+export interface GetAutorollerStatusesResponse {
+ rollers?: AutorollerStatus[];
+}
+
+interface GetAutorollerStatusesResponseJSON {
+ rollers?: AutorollerStatusJSON[];
+}
+
+const JSONToGetAutorollerStatusesResponse = (m: GetAutorollerStatusesResponseJSON): GetAutorollerStatusesResponse => {
+ return {
+ rollers: m.rollers && m.rollers.map(JSONToAutorollerStatus),
+ };
+};
+
+export interface AutorollerStatus {
+ name: string;
+ currentRollRev: string;
+ lastRollRev: string;
+ mode: string;
+ numFailed: number;
+ numBehind: number;
+ url: string;
+}
+
+interface AutorollerStatusJSON {
+ name?: string;
+ current_roll_rev?: string;
+ last_roll_rev?: string;
+ mode?: string;
+ num_failed?: number;
+ num_behind?: number;
+ url?: string;
+}
+
+const JSONToAutorollerStatus = (m: AutorollerStatusJSON): AutorollerStatus => {
+ return {
+ name: m.name || "",
+ currentRollRev: m.current_roll_rev || "",
+ lastRollRev: m.last_roll_rev || "",
+ mode: m.mode || "",
+ numFailed: m.num_failed || 0,
+ numBehind: m.num_behind || 0,
+ url: m.url || "",
+ };
+};
+
export interface StatusService {
getIncrementalCommits: (getIncrementalCommitsRequest: GetIncrementalCommitsRequest) => Promise<GetIncrementalCommitsResponse>;
addComment: (addCommentRequest: AddCommentRequest) => Promise<AddCommentResponse>;
deleteComment: (deleteCommentRequest: DeleteCommentRequest) => Promise<DeleteCommentResponse>;
+ getAutorollerStatuses: (getAutorollerStatusesRequest: GetAutorollerStatusesRequest) => Promise<GetAutorollerStatusesResponse>;
}
export class StatusServiceClient implements StatusService {
@@ -352,4 +410,19 @@
return resp.json().then(JSONToDeleteCommentResponse);
});
}
+
+ getAutorollerStatuses(getAutorollerStatusesRequest: GetAutorollerStatusesRequest): Promise<GetAutorollerStatusesResponse> {
+ const url = this.hostname + this.pathPrefix + "GetAutorollerStatuses";
+ let body: GetAutorollerStatusesRequest | GetAutorollerStatusesRequestJSON = getAutorollerStatusesRequest;
+ if (!this.writeCamelCase) {
+ body = GetAutorollerStatusesRequestToJSON(getAutorollerStatusesRequest);
+ }
+ return this.fetch(createTwirpRequest(url, body, this.optionsOverride)).then((resp) => {
+ if (!resp.ok) {
+ return throwTwirpError(resp);
+ }
+
+ return resp.json().then(JSONToGetAutorollerStatusesResponse);
+ });
+ }
}
diff --git a/status/modules/status-sk/status-sk-demo.ts b/status/modules/status-sk/status-sk-demo.ts
index c605e5a..6566a71 100644
--- a/status/modules/status-sk/status-sk-demo.ts
+++ b/status/modules/status-sk/status-sk-demo.ts
@@ -1,9 +1,11 @@
import './index';
-import { incrementalResponse0, SetupMocks } from '../rpc-mock';
+import { getAutorollerStatusesResponse, incrementalResponse0, SetupMocks } from '../rpc-mock';
import { $$ } from 'common-sk/modules/dom';
import { SetTestSettings } from '../settings';
-SetupMocks().expectGetIncrementalCommits(incrementalResponse0);
+SetupMocks()
+ .expectGetIncrementalCommits(incrementalResponse0)
+ .expectGetAutorollerStatuses(getAutorollerStatusesResponse);
SetTestSettings({
swarmingUrl: 'example.com/swarming',
taskSchedulerUrl: 'example.com/ts',
diff --git a/status/modules/status-sk/status-sk.scss b/status/modules/status-sk/status-sk.scss
index b90a41c..c8fdbc2 100644
--- a/status/modules/status-sk/status-sk.scss
+++ b/status/modules/status-sk/status-sk.scss
@@ -1 +1,9 @@
@import '../styles.scss';
+
+status-sk {
+ autoroller-status-sk {
+ // TODO(westont): Temporary, this will be going into a fixed panel.
+ float: left;
+ margin: 10px;
+ }
+}
diff --git a/status/modules/status-sk/status-sk.ts b/status/modules/status-sk/status-sk.ts
index 7dc5e50..2c388d0 100644
--- a/status/modules/status-sk/status-sk.ts
+++ b/status/modules/status-sk/status-sk.ts
@@ -10,6 +10,7 @@
import '../../../infra-sk/modules/theme-chooser-sk';
import '../commits-table-sk';
+import '../autoroller-status-sk';
import 'elements-sk/error-toast-sk';
export class StatusSk extends ElementSk {
@@ -17,6 +18,7 @@
html`
<h2>lit-html/TS/Twirp Status Page Under Development</h2>
<theme-chooser-sk></theme-chooser-sk>
+ <autoroller-status-sk></autoroller-status-sk>
<commits-table-sk></commits-table-sk>
<error-toast-sk></error-toast-sk>
`;
diff --git a/status/modules/styles.scss b/status/modules/styles.scss
index c6088fd..03cf78c 100644
--- a/status/modules/styles.scss
+++ b/status/modules/styles.scss
@@ -9,8 +9,47 @@
min-height: fit-content;
}
+.bg-success {
+ background-color: var(--success-alpha);
+}
+
+.bg-warning {
+ background-color: var(--warning-alpha);
+ color: var(--black);
+}
+
+.bg-failure {
+ background-color: var(--failure-alpha);
+}
+
+.bg-mishap {
+ background-color: var(--unexpected-alpha);
+}
+
+.bg-unknown {
+ background-color: var(--unexpected-alpha);
+}
+
:root {
--primary: var(--light-green-700);
// TODO(westont): Move to named colors, unify theme.
--secondary: #e6ab02;
+
+ --success: rgb(102, 166, 30);
+ --success-alpha: rgba(102, 166, 30, 0.3);
+ --warning: var(--orange-400);
+ --warning-alpha: var(--orange-a200);
+ --failure: rgb(217, 95, 2);
+ --failure-alpha: rgba(217, 95, 2, 0.3);
+ --unexpected: rgb(117, 112, 179);
+ --unexpected-alpha: rgba(117, 112, 179, 0.3);
+ --disabled: var(--grey-500);
+ --disabled-alpha: rgba(117, 117, 117, 0.3);
+
+ .darkmode {
+ --success-alpha: rgba(102, 166, 30, 0.9);
+ --failure-alpha: rgba(217, 95, 2, 0.9);
+ --unexpected-alpha: rgba(117, 112, 179, 0.9);
+ --disabled-alpha: rgba(117, 117, 117, 0.9);
+ }
}