1// SPDX-License-Identifier: MIT
2
3syntax = "proto3";
4
5package ermite;
6
7import "google/protobuf/field_mask.proto";
8import "ermite/types.proto";
9import "google/protobuf/timestamp.proto";
10
11// Visibility says who may read a repository.
12enum Visibility {
13 // Not set. In requests, the server applies its default (private on create,
14 // unchanged on update). Never returned by the server.
15 VISIBILITY_UNSPECIFIED = 0;
16 // Anyone, including anonymous callers, may read the repository.
17 VISIBILITY_PUBLIC = 1;
18 // Only callers holding the repo:read scope on the repository may read it.
19 // Everyone else gets not_found, never permission_denied.
20 VISIBILITY_PRIVATE = 2;
21}
22
23// RepoSettings are the settings of a repository that govern its merge
24// requests.
25message RepoSettings {
26 // AllowedMergeModes are the modes with which a merge request of the
27 // repository may be merged. It is never empty in a response and has no
28 // duplicate. Both MERGE_MODE_FAST_FORWARD and MERGE_MODE_SQUASH are allowed
29 // by default. MERGE_MODE_UNSPECIFIED is rejected.
30 repeated MergeMode allowed_merge_modes = 1;
31 // FailingChecksBlock says whether a merge request whose checks fail cannot be
32 // merged. It is true at creation of the repository and always stored
33 // explicitly, so a later change of the server default never alters an
34 // existing repository.
35 bool failing_checks_block = 2;
36}
37
38// Repo is the metadata of a repository. Git-owned state (refs, trees, history)
39// is read through GitService.
40message Repo {
41 // Name is the unique, lowercase repository name: 1-100 characters from
42 // [a-z0-9._-], without a ".git" suffix. It is also the URL path: /<name>.
43 string name = 1;
44 // Description is a free one-line description. It may be empty.
45 string description = 2;
46 // Visibility is who may read the repository.
47 Visibility visibility = 3;
48 // DefaultBranch is the short name of the branch HEAD points to, for example
49 // "main". It is set even when the branch does not exist yet (empty
50 // repository).
51 string default_branch = 4;
52 // CreatedAt is when the repository was created.
53 google.protobuf.Timestamp created_at = 5;
54 // PushedAt is the time of the last push. It is unset until the first push.
55 google.protobuf.Timestamp pushed_at = 6;
56 // Settings are the merge settings of the repository. Always set in a
57 // response, with the defaults for a repository that never changed them.
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;
63}
64
65// RepoService manages repositories and their metadata.
66//
67// Anonymous callers see public repositories only. A private repository that the
68// caller cannot read is reported as not_found.
69service RepoService {
70 // ListRepos lists the repositories the caller may see, ordered by name.
71 rpc ListRepos(ListReposRequest) returns (ListReposResponse);
72 // GetRepo returns one repository. Fails with not_found if it does not exist
73 // or is private and not readable by the caller.
74 rpc GetRepo(GetRepoRequest) returns (GetRepoResponse);
75 // CreateRepo creates an empty repository with the default settings. Needs
76 // the repo:write scope. Fails
77 // with already_exists if the name is taken and invalid_argument if the name
78 // is not valid.
79 rpc CreateRepo(CreateRepoRequest) returns (CreateRepoResponse);
80 // UpdateRepo changes the fields named in update_mask, including the merge
81 // settings. Needs the repo:admin scope.
82 rpc UpdateRepo(UpdateRepoRequest) returns (UpdateRepoResponse);
83 // DeleteRepo deletes a repository. Needs the repo:admin scope. The server
84 // moves the data aside rather than destroying it; there is no undelete RPC.
85 rpc DeleteRepo(DeleteRepoRequest) returns (DeleteRepoResponse);
86}
87
88// ListReposRequest selects a page of repositories.
89message ListReposRequest {
90 // PageSize is the maximum number of repositories to return. 0 means the
91 // server default; values above the server maximum are lowered to it.
92 int32 page_size = 1;
93 // PageToken is the next_page_token of a previous response, to get the page
94 // after it. Empty for the first page.
95 string page_token = 2;
96}
97
98// ListReposResponse is one page of repositories.
99message ListReposResponse {
100 // Repos are the repositories of this page, ordered by name.
101 repeated Repo repos = 1;
102 // NextPageToken is passed as page_token to get the next page. Empty when
103 // there is no next page.
104 string next_page_token = 2;
105}
106
107// GetRepoRequest names the repository to read.
108message GetRepoRequest {
109 // Repo is the repository name.
110 string repo = 1;
111}
112
113// GetRepoResponse holds the repository.
114message GetRepoResponse {
115 // Repo is the repository metadata.
116 Repo repo = 1;
117}
118
119// CreateRepoRequest describes the repository to create.
120message CreateRepoRequest {
121 // Name is the name of the new repository. Names are lowercase; an uppercase
122 // name is rejected with invalid_argument.
123 string name = 1;
124 // Description is an optional one-line description.
125 string description = 2;
126 // Visibility of the new repository. VISIBILITY_UNSPECIFIED means private.
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;
131}
132
133// CreateRepoResponse holds the new repository.
134message CreateRepoResponse {
135 // Repo is the created repository.
136 Repo repo = 1;
137}
138
139// UpdateRepoRequest changes some fields of a repository.
140message UpdateRepoRequest {
141 // Repo is the name of the repository to change. Repositories cannot be
142 // renamed.
143 string repo = 1;
144 // Description is the new description. Used only if update_mask contains
145 // "description"; an empty value then clears it.
146 string description = 2;
147 // Visibility is the new visibility. Used only if update_mask contains
148 // "visibility"; it must not be VISIBILITY_UNSPECIFIED then.
149 Visibility visibility = 3;
150 // DefaultBranch is the short name of the new default branch. Used only if
151 // update_mask contains "default_branch". The branch must exist, otherwise
152 // the call fails with failed_precondition.
153 string default_branch = 4;
154 // UpdateMask lists the fields to change: "description", "visibility",
155 // "default_branch", "topics", "settings.allowed_merge_modes" and/or
156 // "settings.failing_checks_block". "settings" stands for both settings
157 // paths. It must not be empty. Other paths are invalid_argument.
158 google.protobuf.FieldMask update_mask = 5;
159 // Settings holds the new merge settings. Only the fields named in
160 // update_mask are used. allowed_merge_modes must then not be empty nor
161 // contain MERGE_MODE_UNSPECIFIED, otherwise the call fails with
162 // invalid_argument. Changing settings needs the repo:admin scope, like any
163 // other field.
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;
168}
169
170// UpdateRepoResponse holds the repository after the update.
171message UpdateRepoResponse {
172 // Repo is the updated repository.
173 Repo repo = 1;
174}
175
176// DeleteRepoRequest names the repository to delete.
177message DeleteRepoRequest {
178 // Repo is the repository name.
179 string repo = 1;
180}
181
182// DeleteRepoResponse is empty.
183message DeleteRepoResponse {}