pr_01m47d15m3e54sn21z27rpy5n9/packages/contracts/src/events.ts

109 lines4,403 bytesCodeBlame
1/**
2 * Every state change in g1t is published as an event. Services react to
3 * each other through events rather than direct calls, and the same stream
4 * feeds timelines, webhooks and workflows.
5 *
6 * The envelope follows CloudEvents: `type` says what happened, `subject`
7 * says to what, `data` is the type-specific payload.
8 */
9
10import type { Verdict } from "./work";
11export type EventPayloads = {
12 "repo.created": { repoId: string; namespace: string; name: string; isPrivate: boolean };
13 "repo.forked": { repoId: string; sourceRepoId: string; pullId: string };
14 /**
15 * One branch moved by a push. `ref` is the full ref, `after` the commit it
16 * points to now, and `defaultBranch` whether it is the default branch.
17 */
18 "git.push": { repoId: string; ref: string; after: string; defaultBranch: boolean };
19 "issue.opened": { issueId: string; repoId: string; number: number; title: string };
20 "issue.updated": { issueId: string; repoId: string; number: number };
21 /** The people an issue is assigned to changed; `assignees` is the new set. */
22 "issue.assigned": { issueId: string; repoId: string; number: number; assignees: string[] };
23 /** `resolvedBy` is the number of the pull request whose merge closed it. */
24 "issue.closed": {
25 issueId: string;
26 repoId: string;
27 number: number;
28 reason: "completed" | "not_planned";
29 resolvedBy?: number;
30 };
31 "issue.reopened": { issueId: string; repoId: string; number: number };
32 /** `issue` is the number of the issue the pull request is for. */
33 "pull.opened": { pullId: string; repoId: string; number: number; issue?: number; agent: string };
34 "pull.ready": { pullId: string; repoId: string; number: number; issue?: number };
35 /** A push moved the head of a pull request that is ready for review. */
36 "pull.updated": { pullId: string; repoId: string; number: number; issue?: number; commit: string };
37 /** A merge was asked for while the pull request was behind; it has to catch up first. */
38 "pull.merge_requested": { pullId: string; repoId: string; number: number; issue?: number };
39 "pull.closed": { pullId: string; repoId: string; number: number; issue?: number };
40 /** Another agent asked the agent on a pull request, which was not at work, a question or handed it work. */
41 "agent.asked": { pullId: string; repoId: string; number: number; issue?: number };
42 "pull.merged": { pullId: string; repoId: string; number: number; issue?: number; commit: string };
43 /** A run of the acceptance checks finished. `commit` is what was checked. */
44 "checks.completed": {
45 pullId: string;
46 repoId: string;
47 number: number;
48 status: "passed" | "failed" | "errored";
49 commit: string;
50 };
51 /** A g1t agent finished reviewing a pull request; no verdict if it could not. */
52 "review.completed": {
53 pullId: string;
54 repoId: string;
55 number: number;
56 verdict?: "approve" | "request_changes";
57 };
58 /** A repository's merge queue gained, lost or settled an entry. */
59 "queue.changed": { repoId: string };
60 /** `number` is the issue or pull request commented on. */
61 "comment.created": {
62 commentId: string;
63 repoId: string;
64 number: number;
65 /** Set when the comment is on a pull request. */
66 pullId?: string;
67 /** Set when the comment is a review. */
68 verdict?: Verdict;
69 };
70 "session.appended": { pullId: string; repoId: string; number: number; count: number };
71};
72
73export type EventType = keyof EventPayloads;
74
75export type G1tEvent<T extends EventType = EventType> = {
76 [K in T]: {
77 id: string;
78 type: K;
79 /** The service that published it. */
80 source: string;
81 /** RFC 3339. */
82 time: string;
83 /** The repo the event concerns, used to scope timelines and deliveries. */
84 repoId: string | null;
85 /** The user or agent that caused it, if any. */
86 actor: string | null;
87 data: EventPayloads[K];
88 };
89}[T];
90
91/** What a publisher supplies; the bus fills in `id` and `time`. */
92export type NewEvent<T extends EventType = EventType> = {
93 [K in T]: Omit<G1tEvent<K>, "id" | "time">;
94}[T];
95
96export type EventQuery = {
97 repoId?: string;
98 types?: EventType[];
99 /** Return events older than this event id. */
100 before?: string;
101 limit?: number;
102};
103
104/** The event bus and its durable log. */
105export interface EventsApi {
106 publish(events: NewEvent[]): Promise<void>;
107 /** Newest first. */
108 list(query: EventQuery): Promise<G1tEvent[]>;
109}