event.go RawHistoryFolder
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package domain
4
5import (
6 "fmt"
7 "regexp"
8 "time"
9)
10
11// ZeroOID is the object ID that stands for "no object" in a ref update.
12const ZeroOID = "0000000000000000000000000000000000000000"
13
14// RefUpdate is one ref change of a push, as Git reports it to the hooks.
15type RefUpdate struct {
16 // Old is the previous object ID, ZeroOID when the ref is created.
17 Old string
18 // New is the new object ID, ZeroOID when the ref is deleted.
19 New string
20 // Ref is the full ref name, such as refs/heads/main.
21 Ref string
22}
23
24var oidRE = regexp.MustCompile(`^[0-9a-f]{40}$`)
25
26// maxRefLen bounds a ref name.
27const maxRefLen = 4096
28
29// NewRefUpdate validates the parts of a ref update as Git reports them: two
30// 40-digit lowercase hexadecimal object IDs (sha1) and a non-empty ref name.
31func NewRefUpdate(oldOID, newOID, ref string) (RefUpdate, error) {
32 if !oidRE.MatchString(oldOID) || !oidRE.MatchString(newOID) {
33 return RefUpdate{}, fmt.Errorf("invalid object id in the update of %q", ref)
34 }
35 if ref == "" || len(ref) > maxRefLen {
36 return RefUpdate{}, fmt.Errorf("invalid ref name %q", ref)
37 }
38 return RefUpdate{Old: oldOID, New: newOID, Ref: ref}, nil
39}
40
41// IsCreate reports whether the update creates the ref.
42func (u RefUpdate) IsCreate() bool { return u.Old == ZeroOID }
43
44// IsDelete reports whether the update deletes the ref.
45func (u RefUpdate) IsDelete() bool { return u.New == ZeroOID }
46
47// Event is something that happened in the forge, published on the event bus.
48type Event interface {
49 // EventKind names the kind of event.
50 EventKind() string
51}
52
53// RepoCreated is published when a repository comes into being.
54type RepoCreated struct {
55 Repo RepoName
56 Visibility Visibility
57 At time.Time
58}
59
60// EventKind implements Event.
61func (RepoCreated) EventKind() string { return "repo.created" }
62
63// RepoUpdated is published when the metadata of a repository, or its default
64// branch, changed. The new state is read from the repository.
65//
66// The visibility fields tell who could read the repository before and after
67// the change, and CreatedAt tells which repository of that name it was (a
68// name can be deleted and created again): the event stream decides who may be
69// told from them.
70type RepoUpdated struct {
71 Repo RepoName
72 At time.Time
73 // Visibility is the visibility after the change, Previous the one before.
74 Visibility, Previous Visibility
75 // CreatedAt is the creation time of the repository.
76 CreatedAt time.Time
77}
78
79// EventKind implements Event.
80func (RepoUpdated) EventKind() string { return "repo.updated" }
81
82// RepoDeleted is published after a repository was deleted. It records the
83// visibility the repository had, which decides who may be told.
84type RepoDeleted struct {
85 Repo RepoName
86 Visibility Visibility
87 At time.Time
88 // CreatedAt is the creation time of the repository that was deleted.
89 CreatedAt time.Time
90}
91
92// EventKind implements Event.
93func (RepoDeleted) EventKind() string { return "repo.deleted" }
94
95// PushEvent is published after a push has been accepted.
96//
97// It carries the visibility and the creation time of the repository as read
98// when the push was recorded, so the event stream does not read them later,
99// when the repository may have changed or been recreated. A zero CreatedAt
100// means the repository was unknown: the event is not delivered.
101type PushEvent struct {
102 Repo RepoName
103 Updates []RefUpdate
104 At time.Time
105 // Visibility is the visibility of the repository at publish time.
106 Visibility Visibility
107 // CreatedAt is the creation time of the repository that was pushed to.
108 CreatedAt time.Time
109}
110
111// EventKind implements Event.
112func (PushEvent) EventKind() string { return "repo.pushed" }
113
114// MergeRequestOpened is published when a merge request is opened.
115type MergeRequestOpened struct {
116 MergeRequest MergeRequest
117 At time.Time
118 // Visibility and CreatedAt are those of the repository when the event
119 // was published, like PushEvent's.
120 Visibility Visibility
121 CreatedAt time.Time
122}
123
124// EventKind implements Event.
125func (MergeRequestOpened) EventKind() string { return "mr.opened" }
126
127// MergeRequestMerged is published when a merge request was merged, before the
128// PushEvent of the target branch.
129type MergeRequestMerged struct {
130 MergeRequest MergeRequest
131 At time.Time
132 Visibility Visibility
133 CreatedAt time.Time
134}
135
136// EventKind implements Event.
137func (MergeRequestMerged) EventKind() string { return "mr.merged" }
138
139// MergeRequestClosed is published when a merge request was closed without
140// merging.
141type MergeRequestClosed struct {
142 MergeRequest MergeRequest
143 At time.Time
144 Visibility Visibility
145 CreatedAt time.Time
146}
147
148// EventKind implements Event.
149func (MergeRequestClosed) EventKind() string { return "mr.closed" }
150
151// MergeRequestReady is published when a draft merge request was marked ready
152// for review: its title lost the draft prefix.
153type MergeRequestReady struct {
154 MergeRequest MergeRequest
155 At time.Time
156 Visibility Visibility
157 CreatedAt time.Time
158}
159
160// EventKind implements Event.
161func (MergeRequestReady) EventKind() string { return "mr.ready" }
162
163// CommentAdded is published when a comment was added to a merge request.
164type CommentAdded struct {
165 Repo RepoName
166 Number int64
167 Comment Comment
168 At time.Time
169 Visibility Visibility
170 CreatedAt time.Time
171}
172
173// EventKind implements Event.
174func (CommentAdded) EventKind() string { return "mr.comment_added" }
175
176// IssueOpened is published when an issue is opened.
177type IssueOpened struct {
178 Issue Issue
179 At time.Time
180 // Visibility and CreatedAt are those of the repository when the event
181 // was published, like PushEvent's.
182 Visibility Visibility
183 CreatedAt time.Time
184}
185
186// EventKind implements Event.
187func (IssueOpened) EventKind() string { return "issue.opened" }
188
189// IssueClosed is published when an issue was closed.
190type IssueClosed struct {
191 Issue Issue
192 At time.Time
193 Visibility Visibility
194 CreatedAt time.Time
195}
196
197// EventKind implements Event.
198func (IssueClosed) EventKind() string { return "issue.closed" }
199
200// IssueReopened is published when a closed issue was reopened.
201type IssueReopened struct {
202 Issue Issue
203 At time.Time
204 Visibility Visibility
205 CreatedAt time.Time
206}
207
208// EventKind implements Event.
209func (IssueReopened) EventKind() string { return "issue.reopened" }
210
211// IssueCommented is published when a comment was added to an issue.
212type IssueCommented struct {
213 Repo RepoName
214 Number int64
215 Comment IssueComment
216 At time.Time
217 Visibility Visibility
218 CreatedAt time.Time
219}
220
221// EventKind implements Event.
222func (IssueCommented) EventKind() string { return "issue.commented" }
223
224// IssueSubmitted is published when an anonymous submission awaits moderation.
225// It carries no content, and is delivered to the owner topic only: never to
226// home or to a repository topic.
227type IssueSubmitted struct {
228 Repo RepoName
229 ID PendingIssueID
230 At time.Time
231}
232
233// EventKind implements Event.
234func (IssueSubmitted) EventKind() string { return "issue.submitted" }
235
236// IssuePendingRemoved is published when a pending submission is rejected, so
237// the other open inboxes drop it. Like IssueSubmitted it carries no content
238// and is delivered to the owner topic only.
239type IssuePendingRemoved struct {
240 Repo RepoName
241 ID PendingIssueID
242 At time.Time
243}
244
245// EventKind implements Event.
246func (IssuePendingRemoved) EventKind() string { return "issue.pending_removed" }
247
248// CommentEdited is published when the text of a note was edited.
249type CommentEdited struct {
250 Repo RepoName
251 Number int64
252 Comment Comment
253 At time.Time
254 Visibility Visibility
255 CreatedAt time.Time
256}
257
258// EventKind implements Event.
259func (CommentEdited) EventKind() string { return "mr.comment_edited" }
260
261// CommentDeleted is published when the text of a note was deleted.
262type CommentDeleted struct {
263 Repo RepoName
264 Number int64
265 Comment Comment
266 At time.Time
267 Visibility Visibility
268 CreatedAt time.Time
269}
270
271// EventKind implements Event.
272func (CommentDeleted) EventKind() string { return "mr.comment_deleted" }
273
274// CommentResolved is published when a thread was resolved or reopened.
275type CommentResolved struct {
276 Repo RepoName
277 Number int64
278 Comment Comment
279 At time.Time
280 Visibility Visibility
281 CreatedAt time.Time
282}
283
284// EventKind implements Event.
285func (CommentResolved) EventKind() string { return "mr.comment_resolved" }
286
287// MergeRequestMergeability is published when the mergeability of an open merge
288// request changed.
289type MergeRequestMergeability struct {
290 Repo RepoName
291 Number int64
292 Mergeability Mergeability
293 At time.Time
294 Visibility Visibility
295 CreatedAt time.Time
296}
297
298// EventKind implements Event.
299func (MergeRequestMergeability) EventKind() string { return "mr.mergeability" }
300
301// EventGap tells a subscriber that it missed events because it was too slow;
302// it must refresh its whole view.
303type EventGap struct{}
304
305// EventKind implements Event.
306func (EventGap) EventKind() string { return "gap" }
307
308// MirrorFailed is published when a mirror enters failing or paused (transitions only).
309type MirrorFailed struct {
310 Repo RepoName
311 State MirrorState
312 Class MirrorFailureClass
313 At time.Time
314 Visibility Visibility
315 CreatedAt time.Time
316}
317
318func (MirrorFailed) EventKind() string { return "mirror.failed" }
319
320// MirrorRecovered is published when a failing or paused mirror succeeds again.
321type MirrorRecovered struct {
322 Repo RepoName
323 At time.Time
324 Visibility Visibility
325 CreatedAt time.Time
326}
327
328func (MirrorRecovered) EventKind() string { return "mirror.recovered" }