1// SPDX-License-Identifier: MIT
2
3syntax = "proto3";
4
5package ermite;
6
7import "ermite/issue.proto";
8import "ermite/merge_request.proto";
9import "ermite/mirror.proto";
10import "ermite/repo.proto";
11import "ermite/run.proto";
12import "google/protobuf/timestamp.proto";
13
14// EventService streams what happens on the forge.
15service EventService {
16 // Watch streams events until the client cancels the call or the server shuts
17 // down. Events are filtered by the caller's access: events of a private
18 // repository are only sent to callers that may read it.
19 //
20 // The events are repo_created, repo_updated, repo_deleted, pushed, gap and,
21 // for merge requests, merge_request_opened, merge_request_merged,
22 // merge_request_closed, comment_added, comment_edited, comment_deleted and
23 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,
24 // issue_closed, issue_reopened and issue_commented, and issue_submitted. Each
25 // one is delivered on the "repo:<name>" topic of its repository and on
26 // "home", subject to the visibility of the repository, except
27 // issue_submitted: it is delivered only on the "owner" topic, never on
28 // "home" or "repo:<name>", and carries no content (see IssueSubmitted).
29 //
30 // Servers with the feature "ci.runs" also publish run_updated and
31 // job_updated, only on the "repo:<name>" topic of their repository (never on
32 // "home"), subject to the same visibility. They carry the state after the
33 // change and are published when a run or a job is created, changes status
34 // or conclusion, or when one of its steps starts or ends (never per log
35 // line: follow a log with RunService.GetJobLog). The order of these events
36 // is not guaranteed, between jobs and runs or between two updates of the same
37 // one: a client keeps the copy with the higher Run.version or
38 // RunJob.version and drops the other. There is no event for a change of title or
39 // description: after a gap, or to see such changes, clients read the merge
40 // request again. A merge publishes
41 // merge_request_merged, then pushed for the target branch.
42 //
43 // The server keeps a bounded buffer of recent events. With resume_after set,
44 // buffered events after that id are replayed first, then live events follow.
45 // When resume_after is no longer buffered (or unknown), the stream begins
46 // with a Gap event, then continues with the oldest buffered event: the client
47 // must reload its state. Without resume_after, only new events are sent.
48 //
49 // The access of the caller is checked again for every event: the stream ends
50 // with unauthenticated when the token was revoked or has expired (the server
51 // may take a few seconds to notice). A repository that becomes private
52 // sends one last repo_updated to the callers who could read it before, with
53 // the new visibility and nothing else about it; no later event of it
54 // reaches them. The server limits the watchers: more than 64 topics is
55 // invalid_argument, and too many concurrent streams, in total or from one
56 // client, is resource_exhausted.
57 rpc Watch(WatchRequest) returns (stream WatchResponse);
58}
59
60// WatchRequest selects the events to receive.
61message WatchRequest {
62 // Topics are the subjects to follow: "home" for every repository visible to
63 // the caller, "repo:<name>" for one repository, or "owner". Empty means
64 // "home". Unknown topics are invalid_argument. A "repo:<name>" topic for a
65 // repository that does not exist or is not visible is not_found.
66 //
67 // The "owner" topic needs owner rights: root, an owner session, or a token
68 // that holds every scope with no repository or branch limit. Anyone else
69 // gets the same invalid_argument as for an unknown topic, so the topic is
70 // not revealed. It carries the merge request and issue events of every
71 // repository (merge_request_opened, merge_request_merged,
72 // merge_request_closed, comment_added, and the issue events), repo_updated
73 // and repo_deleted, plus issue_submitted, which is delivered nowhere else.
74 repeated string topics = 1;
75 // ResumeAfter is the Event.id of the last event the client has seen. Empty
76 // to receive only new events.
77 string resume_after = 2;
78}
79
80// WatchResponse carries one event of the stream.
81message WatchResponse {
82 // Event is the event.
83 Event event = 1;
84}
85
86// Event is something that happened on the forge.
87message Event {
88 // Id identifies the event and is passed as resume_after to resume a stream.
89 // It is opaque and only comparable for equality; clients must not parse it.
90 // Empty on a Gap event.
91 string id = 1;
92 // Time is when the event happened.
93 google.protobuf.Timestamp time = 2;
94 // Kind is the type and payload of the event. New kinds may be added; clients
95 // must ignore kinds they do not know.
96 oneof kind {
97 // RepoCreated: a repository was created.
98 RepoCreated repo_created = 3;
99 // RepoUpdated: repository metadata changed.
100 RepoUpdated repo_updated = 4;
101 // RepoDeleted: a repository was deleted.
102 RepoDeleted repo_deleted = 5;
103 // Pushed: refs of a repository were updated by a push.
104 Pushed pushed = 6;
105 // Gap: events were lost, reload state.
106 Gap gap = 7;
107 // MergeRequestOpened: a merge request was opened.
108 MergeRequestOpened merge_request_opened = 8;
109 // MergeRequestMerged: a merge request was merged.
110 MergeRequestMerged merge_request_merged = 9;
111 // MergeRequestClosed: a merge request was closed without merging.
112 MergeRequestClosed merge_request_closed = 10;
113 // CommentAdded: a comment was added to a merge request.
114 CommentAdded comment_added = 11;
115 // RunUpdated: a CI run was created or changed.
116 RunUpdated run_updated = 12;
117 // JobUpdated: a CI job was created or changed.
118 JobUpdated job_updated = 13;
119 // CommentEdited: the text of a merge request comment was changed.
120 CommentEdited comment_edited = 14;
121 // CommentDeleted: a merge request comment was deleted.
122 CommentDeleted comment_deleted = 15;
123 // CommentResolved: a merge request comment was resolved or unresolved.
124 CommentResolved comment_resolved = 16;
125 // IssueOpened: an issue was opened.
126 IssueOpened issue_opened = 17;
127 // IssueClosed: an issue was closed.
128 IssueClosed issue_closed = 18;
129 // IssueReopened: an issue was reopened.
130 IssueReopened issue_reopened = 19;
131 // IssueCommented: a comment was added to an issue.
132 IssueCommented issue_commented = 20;
133 // IssueSubmitted: an issue is awaiting moderation. Delivered only on the
134 // "owner" topic, never on "home" or "repo:<name>", and carries no content.
135 IssueSubmitted issue_submitted = 21;
136 // MergeRequestMergeability: the mergeability of an open merge request
137 // changed.
138 MergeRequestMergeability merge_request_mergeability = 22;
139 // MirrorFailed: a mirror entered failing or paused.
140 MirrorFailed mirror_failed = 23;
141 // MirrorRecovered: a failing or paused mirror succeeded again.
142 MirrorRecovered mirror_recovered = 24;
143 // MergeRequestAutoMergeEnabled: auto-merge was enabled on a merge request.
144 MergeRequestAutoMergeEnabled merge_request_auto_merge_enabled = 25;
145 // MergeRequestAutoMergeCancelled: the auto-merge of a merge request was
146 // cancelled.
147 MergeRequestAutoMergeCancelled merge_request_auto_merge_cancelled = 26;
148 }
149}
150
151// RepoCreated reports a new repository.
152message RepoCreated {
153 // Repo is the new repository.
154 Repo repo = 1;
155}
156
157// RepoUpdated reports a metadata change.
158message RepoUpdated {
159 // Repo is the repository after the change.
160 Repo repo = 1;
161}
162
163// RepoDeleted reports a deleted repository.
164message RepoDeleted {
165 // Repo is the name of the deleted repository.
166 string repo = 1;
167}
168
169// Pushed reports the ref updates of one push.
170message Pushed {
171 // Repo is the name of the repository.
172 string repo = 1;
173 // RefUpdates are the refs changed by the push.
174 repeated RefUpdate ref_updates = 2;
175}
176
177// RefUpdate is the change of one ref.
178message RefUpdate {
179 // Ref is the full ref name, for example "refs/heads/main".
180 string ref = 1;
181 // OldId is the object id before the update. Empty when the ref was created.
182 string old_id = 2;
183 // NewId is the object id after the update. Empty when the ref was deleted.
184 string new_id = 3;
185}
186
187// MergeRequestOpened reports a new merge request.
188message MergeRequestOpened {
189 // MergeRequest is the new merge request.
190 MergeRequest merge_request = 1;
191}
192
193// MergeRequestMerged reports a merged merge request. It is published before
194// the Pushed event of the target branch.
195message MergeRequestMerged {
196 // MergeRequest is the merge request after the merge.
197 MergeRequest merge_request = 1;
198 // Auto is true when the server merged it by auto-merge.
199 bool auto = 2;
200}
201
202// MergeRequestAutoMergeEnabled reports auto-merge enabled on an open merge
203// request. It is published again when auto-merge is enabled again.
204message MergeRequestAutoMergeEnabled {
205 // MergeRequest is the merge request, with auto_merge set.
206 MergeRequest merge_request = 1;
207}
208
209// MergeRequestAutoMergeCancelled reports the auto-merge of a merge request
210// cancelled, by a caller or by the server.
211message MergeRequestAutoMergeCancelled {
212 // MergeRequest is the merge request, with auto_merge unset.
213 MergeRequest merge_request = 1;
214 // Reason says in one line why it was cancelled. For display only.
215 string reason = 2;
216}
217
218// MergeRequestMergeability reports the mergeability of an open merge request.
219// It is published each time the server settles a result for new tips of the
220// source or target branch, so the state may be the same as the previous
221// event's. A push that moves neither branch publishes nothing.
222message MergeRequestMergeability {
223 // Repo is the name of the repository.
224 string repo = 1;
225 // Number is the number of the merge request.
226 int64 number = 2;
227 // Mergeability is the new result.
228 Mergeability mergeability = 3;
229}
230
231// MergeRequestClosed reports a merge request closed without merging.
232message MergeRequestClosed {
233 // MergeRequest is the merge request after closing.
234 MergeRequest merge_request = 1;
235}
236
237// CommentAdded reports a new comment on a merge request.
238message CommentAdded {
239 // Repo is the name of the repository.
240 string repo = 1;
241 // Number is the number of the merge request.
242 int64 number = 2;
243 // Comment is the new comment.
244 Comment comment = 3;
245}
246
247// CommentEdited reports a comment of a merge request whose text was changed.
248message CommentEdited {
249 // Repo is the name of the repository.
250 string repo = 1;
251 // Number is the number of the merge request.
252 int64 number = 2;
253 // Comment is the comment after the edit.
254 Comment comment = 3;
255}
256
257// CommentDeleted reports a comment of a merge request that was deleted. The
258// comment stays in the thread with deleted set and an empty text.
259message CommentDeleted {
260 // Repo is the name of the repository.
261 string repo = 1;
262 // Number is the number of the merge request.
263 int64 number = 2;
264 // Comment is the comment after the deletion.
265 Comment comment = 3;
266}
267
268// CommentResolved reports a comment of a merge request whose resolved state
269// changed.
270message CommentResolved {
271 // Repo is the name of the repository.
272 string repo = 1;
273 // Number is the number of the merge request.
274 int64 number = 2;
275 // Comment is the comment after the change.
276 Comment comment = 3;
277}
278
279// IssueOpened reports a new issue.
280message IssueOpened {
281 // Issue is the new issue, including its repository and number.
282 Issue issue = 1;
283}
284
285// IssueClosed reports a closed issue.
286message IssueClosed {
287 // Issue is the issue after closing, including its repository and number.
288 Issue issue = 1;
289}
290
291// IssueReopened reports a reopened issue.
292message IssueReopened {
293 // Issue is the issue after reopening, including its repository and number.
294 Issue issue = 1;
295}
296
297// IssueCommented reports a new comment on an issue.
298message IssueCommented {
299 // Repo is the name of the repository.
300 string repo = 1;
301 // Number is the number of the issue.
302 int64 number = 2;
303 // Comment is the new comment.
304 IssueComment comment = 3;
305}
306
307// IssueSubmitted reports an issue awaiting moderation. It is delivered only
308// on the "owner" topic, never on "home" or "repo:<name>". It carries no title or body: content never travels in
309// events, read it with IssueService.ListPendingIssues.
310message IssueSubmitted {
311 // Repo is the name of the repository.
312 string repo = 1;
313 // Id is the PendingIssue.id.
314 string id = 2;
315}
316
317// Gap tells the client that events were lost: the requested resume point is
318// older than the server's buffer. It has no fields. The client should reload
319// the state it displays (repositories, refs, merge requests and their
320// comments, issues and their comments, CI runs and their jobs) and carry on
321// with the next events.
322message Gap {}
323
324// RunUpdated reports a CI run that was created or whose status, conclusion or
325// timestamps changed. It is delivered on the "repo:<name>" topic only.
326message RunUpdated {
327 // Run is the run after the change, as of its latest attempt, without jobs.
328 Run run = 1;
329}
330
331// JobUpdated reports a CI job that was created or whose status, conclusion,
332// runner or steps changed. It is delivered on the "repo:<name>" topic only.
333message JobUpdated {
334 // Job is the job after the change, with its steps.
335 RunJob job = 1;
336}
337
338// MirrorFailed reports the start of a failure incident: a transition from ok
339// or disabled into failing or paused. It is sent once per incident, not for
340// each failed attempt nor for failing to paused. Servers with feature "mirror"
341// deliver it on "repo:<name>" and "home", subject to repository visibility. It
342// carries no URL, reason or error detail; read the status for those.
343message MirrorFailed {
344 // Repo is the repository name.
345 string repo = 1;
346 // State is the new mirror state.
347 MirrorState state = 2;
348 // FailureClass is the failure category.
349 string failure_class = 3;
350
351 reserved 4;
352 reserved "reason";
353}
354
355// MirrorRecovered reports a successful sync after failing or paused. Delivery
356// follows MirrorFailed. It carries no URL or error detail.
357message MirrorRecovered {
358 // Repo is the repository name.
359 string repo = 1;
360}