detached 21da1eb

feat(proto): repository topics (#16)

commit
21da1eb04d5860002e691d8dcbe70dce89c5eb37
author
brice · · 2026-10-18 12:08 UTC
committer
bnema · · 2026-10-18 12:08 UTC
parent
72f8f2e
signature
SSH UnverifiedSHA256:VOCA5lYARHcbKDZ7GhTV45VmcjWnJ6ZQIBazj17LivA The key is unknown
refs
tag: v0.5.0
2 files · +55 -11
M gen/ermite/repo.pb.go +44 -10
@@ -163,7 +163,11 @@ type Repo struct {
163163 PushedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=pushed_at,json=pushedAt,proto3" json:"pushed_at,omitempty"`
164164 // Settings are the merge settings of the repository. Always set in a
165165 // response, with the defaults for a repository that never changed them.
166- Settings *RepoSettings `protobuf:"bytes,7,opt,name=settings,proto3" json:"settings,omitempty"`
166+ Settings *RepoSettings `protobuf:"bytes,7,opt,name=settings,proto3" json:"settings,omitempty"`
167+ // Topics classify the repository, as on GitHub: at most 20, each 1-50
168+ // characters from [a-z0-9-], starting with a letter or a digit, sorted
169+ // and without duplicates.
170+ Topics []string `protobuf:"bytes,8,rep,name=topics,proto3" json:"topics,omitempty"`
167171 unknownFields protoimpl.UnknownFields
168172 sizeCache protoimpl.SizeCache
169173 }
@@ -247,6 +251,13 @@ func (x *Repo) GetSettings() *RepoSettings {
247251 return nil
248252 }
249253
254+func (x *Repo) GetTopics() []string {
255+ if x != nil {
256+ return x.Topics
257+ }
258+ return nil
259+}
260+
250261 // ListReposRequest selects a page of repositories.
251262 type ListReposRequest struct {
252263 state protoimpl.MessageState `protogen:"open.v1"`
@@ -461,7 +472,10 @@ type CreateRepoRequest struct {
461472 // Description is an optional one-line description.
462473 Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
463474 // Visibility of the new repository. VISIBILITY_UNSPECIFIED means private.
464- Visibility Visibility `protobuf:"varint,3,opt,name=visibility,proto3,enum=ermite.Visibility" json:"visibility,omitempty"`
475+ Visibility Visibility `protobuf:"varint,3,opt,name=visibility,proto3,enum=ermite.Visibility" json:"visibility,omitempty"`
476+ // Topics are the optional topics of the new repository (see Repo.topics);
477+ // they are lowercased, sorted and deduplicated.
478+ Topics []string `protobuf:"bytes,4,rep,name=topics,proto3" json:"topics,omitempty"`
465479 unknownFields protoimpl.UnknownFields
466480 sizeCache protoimpl.SizeCache
467481 }
@@ -517,6 +531,13 @@ func (x *CreateRepoRequest) GetVisibility() Visibility {
517531 return Visibility_VISIBILITY_UNSPECIFIED
518532 }
519533
534+func (x *CreateRepoRequest) GetTopics() []string {
535+ if x != nil {
536+ return x.Topics
537+ }
538+ return nil
539+}
540+
520541 // CreateRepoResponse holds the new repository.
521542 type CreateRepoResponse struct {
522543 state protoimpl.MessageState `protogen:"open.v1"`
@@ -580,7 +601,7 @@ type UpdateRepoRequest struct {
580601 // the call fails with failed_precondition.
581602 DefaultBranch string `protobuf:"bytes,4,opt,name=default_branch,json=defaultBranch,proto3" json:"default_branch,omitempty"`
582603 // UpdateMask lists the fields to change: "description", "visibility",
583- // "default_branch", "settings.allowed_merge_modes" and/or
604+ // "default_branch", "topics", "settings.allowed_merge_modes" and/or
584605 // "settings.failing_checks_block". "settings" stands for both settings
585606 // paths. It must not be empty. Other paths are invalid_argument.
586607 UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,5,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
@@ -589,7 +610,10 @@ type UpdateRepoRequest struct {
589610 // contain MERGE_MODE_UNSPECIFIED, otherwise the call fails with
590611 // invalid_argument. Changing settings needs the repo:admin scope, like any
591612 // other field.
592- Settings *RepoSettings `protobuf:"bytes,6,opt,name=settings,proto3" json:"settings,omitempty"`
613+ Settings *RepoSettings `protobuf:"bytes,6,opt,name=settings,proto3" json:"settings,omitempty"`
614+ // Topics replace the topics of the repository (see Repo.topics). Used only
615+ // if update_mask contains "topics"; an empty list then clears them.
616+ Topics []string `protobuf:"bytes,7,rep,name=topics,proto3" json:"topics,omitempty"`
593617 unknownFields protoimpl.UnknownFields
594618 sizeCache protoimpl.SizeCache
595619 }
@@ -666,6 +690,13 @@ func (x *UpdateRepoRequest) GetSettings() *RepoSettings {
666690 return nil
667691 }
668692
693+func (x *UpdateRepoRequest) GetTopics() []string {
694+ if x != nil {
695+ return x.Topics
696+ }
697+ return nil
698+}
699+
669700 // UpdateRepoResponse holds the repository after the update.
670701 type UpdateRepoResponse struct {
671702 state protoimpl.MessageState `protogen:"open.v1"`
@@ -802,7 +833,7 @@ const file_ermite_repo_proto_rawDesc = "" +
802833 "\x11ermite/repo.proto\x12\x06ermite\x1a google/protobuf/field_mask.proto\x1a\x12ermite/types.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x83\x01\n" +
803834 "\fRepoSettings\x12A\n" +
804835 "\x13allowed_merge_modes\x18\x01 \x03(\x0e2\x11.ermite.MergeModeR\x11allowedMergeModes\x120\n" +
805- "\x14failing_checks_block\x18\x02 \x01(\bR\x12failingChecksBlock\"\xbd\x02\n" +
836+ "\x14failing_checks_block\x18\x02 \x01(\bR\x12failingChecksBlock\"\xd5\x02\n" +
806837 "\x04Repo\x12\x12\n" +
807838 "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" +
808839 "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" +
@@ -813,7 +844,8 @@ const file_ermite_repo_proto_rawDesc = "" +
813844 "\n" +
814845 "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x127\n" +
815846 "\tpushed_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\bpushedAt\x120\n" +
816- "\bsettings\x18\a \x01(\v2\x14.ermite.RepoSettingsR\bsettings\"N\n" +
847+ "\bsettings\x18\a \x01(\v2\x14.ermite.RepoSettingsR\bsettings\x12\x16\n" +
848+ "\x06topics\x18\b \x03(\tR\x06topics\"N\n" +
817849 "\x10ListReposRequest\x12\x1b\n" +
818850 "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x1d\n" +
819851 "\n" +
@@ -824,15 +856,16 @@ const file_ermite_repo_proto_rawDesc = "" +
824856 "\x0eGetRepoRequest\x12\x12\n" +
825857 "\x04repo\x18\x01 \x01(\tR\x04repo\"3\n" +
826858 "\x0fGetRepoResponse\x12 \n" +
827- "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"}\n" +
859+ "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\x95\x01\n" +
828860 "\x11CreateRepoRequest\x12\x12\n" +
829861 "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" +
830862 "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" +
831863 "\n" +
832864 "visibility\x18\x03 \x01(\x0e2\x12.ermite.VisibilityR\n" +
833- "visibility\"6\n" +
865+ "visibility\x12\x16\n" +
866+ "\x06topics\x18\x04 \x03(\tR\x06topics\"6\n" +
834867 "\x12CreateRepoResponse\x12 \n" +
835- "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\x93\x02\n" +
868+ "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\xab\x02\n" +
836869 "\x11UpdateRepoRequest\x12\x12\n" +
837870 "\x04repo\x18\x01 \x01(\tR\x04repo\x12 \n" +
838871 "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" +
@@ -842,7 +875,8 @@ const file_ermite_repo_proto_rawDesc = "" +
842875 "\x0edefault_branch\x18\x04 \x01(\tR\rdefaultBranch\x12;\n" +
843876 "\vupdate_mask\x18\x05 \x01(\v2\x1a.google.protobuf.FieldMaskR\n" +
844877 "updateMask\x120\n" +
845- "\bsettings\x18\x06 \x01(\v2\x14.ermite.RepoSettingsR\bsettings\"6\n" +
878+ "\bsettings\x18\x06 \x01(\v2\x14.ermite.RepoSettingsR\bsettings\x12\x16\n" +
879+ "\x06topics\x18\a \x03(\tR\x06topics\"6\n" +
846880 "\x12UpdateRepoResponse\x12 \n" +
847881 "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"'\n" +
848882 "\x11DeleteRepoRequest\x12\x12\n" +
@@ -163,7 +163,11 @@ type Repo struct {
163 PushedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=pushed_at,json=pushedAt,proto3" json:"pushed_at,omitempty"`163 PushedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=pushed_at,json=pushedAt,proto3" json:"pushed_at,omitempty"`
164 // Settings are the merge settings of the repository. Always set in a164 // Settings are the merge settings of the repository. Always set in a
165 // response, with the defaults for a repository that never changed them.165 // response, with the defaults for a repository that never changed them.
166- Settings *RepoSettings `protobuf:"bytes,7,opt,name=settings,proto3" json:"settings,omitempty"`166+ Settings *RepoSettings `protobuf:"bytes,7,opt,name=settings,proto3" json:"settings,omitempty"`
167+ // Topics classify the repository, as on GitHub: at most 20, each 1-50
168+ // characters from [a-z0-9-], starting with a letter or a digit, sorted
169+ // and without duplicates.
170+ Topics []string `protobuf:"bytes,8,rep,name=topics,proto3" json:"topics,omitempty"`
167 unknownFields protoimpl.UnknownFields171 unknownFields protoimpl.UnknownFields
168 sizeCache protoimpl.SizeCache172 sizeCache protoimpl.SizeCache
169 }173 }
@@ -247,6 +251,13 @@ func (x *Repo) GetSettings() *RepoSettings {
247 return nil251 return nil
248 }252 }
249 253
254+func (x *Repo) GetTopics() []string {
255+ if x != nil {
256+ return x.Topics
257+ }
258+ return nil
259+}
260+
250 // ListReposRequest selects a page of repositories.261 // ListReposRequest selects a page of repositories.
251 type ListReposRequest struct {262 type ListReposRequest struct {
252 state protoimpl.MessageState `protogen:"open.v1"`263 state protoimpl.MessageState `protogen:"open.v1"`
@@ -461,7 +472,10 @@ type CreateRepoRequest struct {
461 // Description is an optional one-line description.472 // Description is an optional one-line description.
462 Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`473 Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
463 // Visibility of the new repository. VISIBILITY_UNSPECIFIED means private.474 // Visibility of the new repository. VISIBILITY_UNSPECIFIED means private.
464- Visibility Visibility `protobuf:"varint,3,opt,name=visibility,proto3,enum=ermite.Visibility" json:"visibility,omitempty"`475+ Visibility Visibility `protobuf:"varint,3,opt,name=visibility,proto3,enum=ermite.Visibility" json:"visibility,omitempty"`
476+ // Topics are the optional topics of the new repository (see Repo.topics);
477+ // they are lowercased, sorted and deduplicated.
478+ Topics []string `protobuf:"bytes,4,rep,name=topics,proto3" json:"topics,omitempty"`
465 unknownFields protoimpl.UnknownFields479 unknownFields protoimpl.UnknownFields
466 sizeCache protoimpl.SizeCache480 sizeCache protoimpl.SizeCache
467 }481 }
@@ -517,6 +531,13 @@ func (x *CreateRepoRequest) GetVisibility() Visibility {
517 return Visibility_VISIBILITY_UNSPECIFIED531 return Visibility_VISIBILITY_UNSPECIFIED
518 }532 }
519 533
534+func (x *CreateRepoRequest) GetTopics() []string {
535+ if x != nil {
536+ return x.Topics
537+ }
538+ return nil
539+}
540+
520 // CreateRepoResponse holds the new repository.541 // CreateRepoResponse holds the new repository.
521 type CreateRepoResponse struct {542 type CreateRepoResponse struct {
522 state protoimpl.MessageState `protogen:"open.v1"`543 state protoimpl.MessageState `protogen:"open.v1"`
@@ -580,7 +601,7 @@ type UpdateRepoRequest struct {
580 // the call fails with failed_precondition.601 // the call fails with failed_precondition.
581 DefaultBranch string `protobuf:"bytes,4,opt,name=default_branch,json=defaultBranch,proto3" json:"default_branch,omitempty"`602 DefaultBranch string `protobuf:"bytes,4,opt,name=default_branch,json=defaultBranch,proto3" json:"default_branch,omitempty"`
582 // UpdateMask lists the fields to change: "description", "visibility",603 // UpdateMask lists the fields to change: "description", "visibility",
583- // "default_branch", "settings.allowed_merge_modes" and/or604+ // "default_branch", "topics", "settings.allowed_merge_modes" and/or
584 // "settings.failing_checks_block". "settings" stands for both settings605 // "settings.failing_checks_block". "settings" stands for both settings
585 // paths. It must not be empty. Other paths are invalid_argument.606 // paths. It must not be empty. Other paths are invalid_argument.
586 UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,5,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`607 UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,5,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"`
@@ -589,7 +610,10 @@ type UpdateRepoRequest struct {
589 // contain MERGE_MODE_UNSPECIFIED, otherwise the call fails with610 // contain MERGE_MODE_UNSPECIFIED, otherwise the call fails with
590 // invalid_argument. Changing settings needs the repo:admin scope, like any611 // invalid_argument. Changing settings needs the repo:admin scope, like any
591 // other field.612 // other field.
592- Settings *RepoSettings `protobuf:"bytes,6,opt,name=settings,proto3" json:"settings,omitempty"`613+ Settings *RepoSettings `protobuf:"bytes,6,opt,name=settings,proto3" json:"settings,omitempty"`
614+ // Topics replace the topics of the repository (see Repo.topics). Used only
615+ // if update_mask contains "topics"; an empty list then clears them.
616+ Topics []string `protobuf:"bytes,7,rep,name=topics,proto3" json:"topics,omitempty"`
593 unknownFields protoimpl.UnknownFields617 unknownFields protoimpl.UnknownFields
594 sizeCache protoimpl.SizeCache618 sizeCache protoimpl.SizeCache
595 }619 }
@@ -666,6 +690,13 @@ func (x *UpdateRepoRequest) GetSettings() *RepoSettings {
666 return nil690 return nil
667 }691 }
668 692
693+func (x *UpdateRepoRequest) GetTopics() []string {
694+ if x != nil {
695+ return x.Topics
696+ }
697+ return nil
698+}
699+
669 // UpdateRepoResponse holds the repository after the update.700 // UpdateRepoResponse holds the repository after the update.
670 type UpdateRepoResponse struct {701 type UpdateRepoResponse struct {
671 state protoimpl.MessageState `protogen:"open.v1"`702 state protoimpl.MessageState `protogen:"open.v1"`
@@ -802,7 +833,7 @@ const file_ermite_repo_proto_rawDesc = "" +
802 "\x11ermite/repo.proto\x12\x06ermite\x1a google/protobuf/field_mask.proto\x1a\x12ermite/types.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x83\x01\n" +833 "\x11ermite/repo.proto\x12\x06ermite\x1a google/protobuf/field_mask.proto\x1a\x12ermite/types.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x83\x01\n" +
803 "\fRepoSettings\x12A\n" +834 "\fRepoSettings\x12A\n" +
804 "\x13allowed_merge_modes\x18\x01 \x03(\x0e2\x11.ermite.MergeModeR\x11allowedMergeModes\x120\n" +835 "\x13allowed_merge_modes\x18\x01 \x03(\x0e2\x11.ermite.MergeModeR\x11allowedMergeModes\x120\n" +
805- "\x14failing_checks_block\x18\x02 \x01(\bR\x12failingChecksBlock\"\xbd\x02\n" +836+ "\x14failing_checks_block\x18\x02 \x01(\bR\x12failingChecksBlock\"\xd5\x02\n" +
806 "\x04Repo\x12\x12\n" +837 "\x04Repo\x12\x12\n" +
807 "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" +838 "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" +
808 "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" +839 "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" +
@@ -813,7 +844,8 @@ const file_ermite_repo_proto_rawDesc = "" +
813 "\n" +844 "\n" +
814 "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x127\n" +845 "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x127\n" +
815 "\tpushed_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\bpushedAt\x120\n" +846 "\tpushed_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\bpushedAt\x120\n" +
816- "\bsettings\x18\a \x01(\v2\x14.ermite.RepoSettingsR\bsettings\"N\n" +847+ "\bsettings\x18\a \x01(\v2\x14.ermite.RepoSettingsR\bsettings\x12\x16\n" +
848+ "\x06topics\x18\b \x03(\tR\x06topics\"N\n" +
817 "\x10ListReposRequest\x12\x1b\n" +849 "\x10ListReposRequest\x12\x1b\n" +
818 "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x1d\n" +850 "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x1d\n" +
819 "\n" +851 "\n" +
@@ -824,15 +856,16 @@ const file_ermite_repo_proto_rawDesc = "" +
824 "\x0eGetRepoRequest\x12\x12\n" +856 "\x0eGetRepoRequest\x12\x12\n" +
825 "\x04repo\x18\x01 \x01(\tR\x04repo\"3\n" +857 "\x04repo\x18\x01 \x01(\tR\x04repo\"3\n" +
826 "\x0fGetRepoResponse\x12 \n" +858 "\x0fGetRepoResponse\x12 \n" +
827- "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"}\n" +859+ "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\x95\x01\n" +
828 "\x11CreateRepoRequest\x12\x12\n" +860 "\x11CreateRepoRequest\x12\x12\n" +
829 "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" +861 "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" +
830 "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" +862 "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" +
831 "\n" +863 "\n" +
832 "visibility\x18\x03 \x01(\x0e2\x12.ermite.VisibilityR\n" +864 "visibility\x18\x03 \x01(\x0e2\x12.ermite.VisibilityR\n" +
833- "visibility\"6\n" +865+ "visibility\x12\x16\n" +
866+ "\x06topics\x18\x04 \x03(\tR\x06topics\"6\n" +
834 "\x12CreateRepoResponse\x12 \n" +867 "\x12CreateRepoResponse\x12 \n" +
835- "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\x93\x02\n" +868+ "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\xab\x02\n" +
836 "\x11UpdateRepoRequest\x12\x12\n" +869 "\x11UpdateRepoRequest\x12\x12\n" +
837 "\x04repo\x18\x01 \x01(\tR\x04repo\x12 \n" +870 "\x04repo\x18\x01 \x01(\tR\x04repo\x12 \n" +
838 "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" +871 "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" +
@@ -842,7 +875,8 @@ const file_ermite_repo_proto_rawDesc = "" +
842 "\x0edefault_branch\x18\x04 \x01(\tR\rdefaultBranch\x12;\n" +875 "\x0edefault_branch\x18\x04 \x01(\tR\rdefaultBranch\x12;\n" +
843 "\vupdate_mask\x18\x05 \x01(\v2\x1a.google.protobuf.FieldMaskR\n" +876 "\vupdate_mask\x18\x05 \x01(\v2\x1a.google.protobuf.FieldMaskR\n" +
844 "updateMask\x120\n" +877 "updateMask\x120\n" +
845- "\bsettings\x18\x06 \x01(\v2\x14.ermite.RepoSettingsR\bsettings\"6\n" +878+ "\bsettings\x18\x06 \x01(\v2\x14.ermite.RepoSettingsR\bsettings\x12\x16\n" +
879+ "\x06topics\x18\a \x03(\tR\x06topics\"6\n" +
846 "\x12UpdateRepoResponse\x12 \n" +880 "\x12UpdateRepoResponse\x12 \n" +
847 "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"'\n" +881 "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"'\n" +
848 "\x11DeleteRepoRequest\x12\x12\n" +882 "\x11DeleteRepoRequest\x12\x12\n" +
M proto/ermite/repo.proto +11 -1
@@ -56,6 +56,10 @@ message Repo {
5656 // Settings are the merge settings of the repository. Always set in a
5757 // response, with the defaults for a repository that never changed them.
5858 RepoSettings settings = 7;
59+ // Topics classify the repository, as on GitHub: at most 20, each 1-50
60+ // characters from [a-z0-9-], starting with a letter or a digit, sorted
61+ // and without duplicates.
62+ repeated string topics = 8;
5963 }
6064
6165 // RepoService manages repositories and their metadata.
@@ -121,6 +125,9 @@ message CreateRepoRequest {
121125 string description = 2;
122126 // Visibility of the new repository. VISIBILITY_UNSPECIFIED means private.
123127 Visibility visibility = 3;
128+ // Topics are the optional topics of the new repository (see Repo.topics);
129+ // they are lowercased, sorted and deduplicated.
130+ repeated string topics = 4;
124131 }
125132
126133 // CreateRepoResponse holds the new repository.
@@ -145,7 +152,7 @@ message UpdateRepoRequest {
145152 // the call fails with failed_precondition.
146153 string default_branch = 4;
147154 // UpdateMask lists the fields to change: "description", "visibility",
148- // "default_branch", "settings.allowed_merge_modes" and/or
155+ // "default_branch", "topics", "settings.allowed_merge_modes" and/or
149156 // "settings.failing_checks_block". "settings" stands for both settings
150157 // paths. It must not be empty. Other paths are invalid_argument.
151158 google.protobuf.FieldMask update_mask = 5;
@@ -155,6 +162,9 @@ message UpdateRepoRequest {
155162 // invalid_argument. Changing settings needs the repo:admin scope, like any
156163 // other field.
157164 RepoSettings settings = 6;
165+ // Topics replace the topics of the repository (see Repo.topics). Used only
166+ // if update_mask contains "topics"; an empty list then clears them.
167+ repeated string topics = 7;
158168 }
159169
160170 // UpdateRepoResponse holds the repository after the update.
@@ -56,6 +56,10 @@ message Repo {
56 // Settings are the merge settings of the repository. Always set in a56 // Settings are the merge settings of the repository. Always set in a
57 // response, with the defaults for a repository that never changed them.57 // response, with the defaults for a repository that never changed them.
58 RepoSettings settings = 7;58 RepoSettings settings = 7;
59+ // Topics classify the repository, as on GitHub: at most 20, each 1-50
60+ // characters from [a-z0-9-], starting with a letter or a digit, sorted
61+ // and without duplicates.
62+ repeated string topics = 8;
59 }63 }
60 64
61 // RepoService manages repositories and their metadata.65 // RepoService manages repositories and their metadata.
@@ -121,6 +125,9 @@ message CreateRepoRequest {
121 string description = 2;125 string description = 2;
122 // Visibility of the new repository. VISIBILITY_UNSPECIFIED means private.126 // Visibility of the new repository. VISIBILITY_UNSPECIFIED means private.
123 Visibility visibility = 3;127 Visibility visibility = 3;
128+ // Topics are the optional topics of the new repository (see Repo.topics);
129+ // they are lowercased, sorted and deduplicated.
130+ repeated string topics = 4;
124 }131 }
125 132
126 // CreateRepoResponse holds the new repository.133 // CreateRepoResponse holds the new repository.
@@ -145,7 +152,7 @@ message UpdateRepoRequest {
145 // the call fails with failed_precondition.152 // the call fails with failed_precondition.
146 string default_branch = 4;153 string default_branch = 4;
147 // UpdateMask lists the fields to change: "description", "visibility",154 // UpdateMask lists the fields to change: "description", "visibility",
148- // "default_branch", "settings.allowed_merge_modes" and/or155+ // "default_branch", "topics", "settings.allowed_merge_modes" and/or
149 // "settings.failing_checks_block". "settings" stands for both settings156 // "settings.failing_checks_block". "settings" stands for both settings
150 // paths. It must not be empty. Other paths are invalid_argument.157 // paths. It must not be empty. Other paths are invalid_argument.
151 google.protobuf.FieldMask update_mask = 5;158 google.protobuf.FieldMask update_mask = 5;
@@ -155,6 +162,9 @@ message UpdateRepoRequest {
155 // invalid_argument. Changing settings needs the repo:admin scope, like any162 // invalid_argument. Changing settings needs the repo:admin scope, like any
156 // other field.163 // other field.
157 RepoSettings settings = 6;164 RepoSettings settings = 6;
165+ // Topics replace the topics of the repository (see Repo.topics). Used only
166+ // if update_mask contains "topics"; an empty list then clears them.
167+ repeated string topics = 7;
158 }168 }
159 169
160 // UpdateRepoResponse holds the repository after the update.170 // UpdateRepoResponse holds the repository after the update.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 18

↑↓ moveenter openesc close