g1t/packages/contracts/src/actions.ts

188 lines5,881 bytesCodeBlame
1import type { User, Viewer } from "./identity";
2import type { RepoPath } from "./repos";
3import type { Result } from "./result";
4
5/**
6 * GitHub Actions workflows, run on g1t as they are. Mirrors
7 * `crates/contracts/src/actions.rs`.
8 */
9
10export type WorkflowNote = {
11 severity: "info" | "warning" | "unsupported";
12 job: string | null;
13 message: string;
14};
15
16/** One `workflow_dispatch` input, as written in the workflow. */
17export type DispatchInput = {
18 description?: string;
19 required?: boolean;
20 default?: string | number | boolean;
21 type?: "string" | "boolean" | "number" | "choice" | "environment";
22 options?: string[];
23};
24
25export type RunStatus = "pending" | "queued" | "in_progress" | "completed";
26export type Conclusion = "success" | "failure" | "cancelled" | "skipped";
27
28export type WorkflowRun = {
29 id: string;
30 workflowId: string;
31 path: string;
32 name: string;
33 title: string;
34 number: number;
35 attempt: number;
36 event: string;
37 ref: string;
38 sha: string;
39 pull: number | null;
40 status: RunStatus;
41 conclusion: Conclusion | null;
42 error: string | null;
43 actor: string | null;
44 createdAt: string;
45 startedAt: string | null;
46 finishedAt: string | null;
47};
48
49export type Workflow = {
50 id: string;
51 path: string;
52 name: string;
53 events: string[];
54 state: "active" | "disabled";
55 error: string | null;
56 notes: WorkflowNote[];
57 dispatch: Record<string, DispatchInput> | null;
58 lastRun: WorkflowRun | null;
59};
60
61export type StepState = {
62 number: number;
63 name: string;
64 status: "queued" | "in_progress" | "completed";
65 conclusion: Conclusion | null;
66 startedAt: string | null;
67 finishedAt: string | null;
68};
69
70export type Annotation = {
71 level: "error" | "warning" | "notice";
72 message: string;
73 title: string | null;
74 file: string | null;
75 line: number | null;
76};
77
78export type Job = {
79 id: string;
80 runId: string;
81 key: string;
82 name: string;
83 needs: string[];
84 /** `calling`: running the reusable workflow it calls, whose jobs follow it. */
85 status: "waiting" | "queued" | "in_progress" | "calling" | "completed";
86 conclusion: Conclusion | null;
87 steps: StepState[];
88 annotations: Annotation[];
89 reason: string | null;
90 startedAt: string | null;
91 finishedAt: string | null;
92 /** Its `runs-on` names self-hosted runners. */
93 selfHosted?: boolean;
94 /** The self-hosted runner that took it, by name. */
95 runner?: string | null;
96};
97
98export type RunDetail = { run: WorkflowRun; jobs: Job[]; notes: WorkflowNote[] };
99
100export type LogChunk = { seq: number; step: number; text: string };
101export type JobLog = { chunks: LogChunk[]; done: boolean };
102
103/**
104 * Who may read a secret or variable: `workflows` (`secrets.*`, `vars.*` in
105 * GitHub Actions) and `deployments` (a deploy build's environment and the
106 * running app's bindings). Agents, checks and the merge queue never read
107 * any.
108 */
109export type SettingReader = "workflows" | "deployments";
110
111/**
112 * One row of secrets and variables, as Vercel lists environment variables:
113 * a key, its type, the environments it applies to and who reads it. A key
114 * may have one row per environment. Secrets' values are never returned.
115 */
116export type Setting = {
117 id: string;
118 name: string;
119 /** `variable` is shown as Config. Config may become a secret, never back. */
120 kind: SettingKind;
121 /** A variable's value. */
122 value: string | null;
123 /** A project's (a repository's belong to its project) or the workspace's. */
124 scope: "project" | "workspace";
125 updatedAt: string;
126 availableTo: SettingReader[];
127 /** The environments it applies to; empty is every environment. */
128 environments: string[];
129 /** A workspace's row: the projects it reaches, by slug; empty is every one. */
130 projects: string[];
131 /** Where to rotate it, or who to ask. */
132 note: string | null;
133 updatedBy: string | null;
134};
135
136/** What saving a row sets beyond its value; left out is unchanged. */
137export type SettingOptions = {
138 /** The row to change; left out, the key's row for every environment. */
139 id?: string;
140 availableTo?: SettingReader[];
141 environments?: string[];
142 /** A workspace's row: project slugs; empty for every one. */
143 projects?: string[];
144 note?: string;
145};
146
147export type SettingsOwner = { repo: RepoPath } | { workspace: string };
148export type SettingKind = "secret" | "variable";
149/** `all` lists both. */
150export type SettingKindFilter = SettingKind | "all";
151
152export type RunsFilter = {
153 workflow?: string;
154 branch?: string;
155 event?: string;
156 pull?: number;
157 sha?: string;
158 limit?: number;
159};
160
161export interface ActionsApi {
162 workflows(repo: RepoPath, viewer: Viewer): Promise<Result<Workflow[]>>;
163 runs(repo: RepoPath, viewer: Viewer, filter?: RunsFilter): Promise<Result<WorkflowRun[]>>;
164 run(repo: RepoPath, viewer: Viewer, id: string): Promise<Result<RunDetail>>;
165 logs(repo: RepoPath, viewer: Viewer, job: string, after?: number): Promise<Result<JobLog>>;
166 dispatch(
167 actor: User,
168 repo: RepoPath,
169 workflow: string,
170 ref: string | undefined,
171 inputs: Record<string, unknown>,
172 ): Promise<Result<WorkflowRun>>;
173 cancel(actor: User, repo: RepoPath, id: string): Promise<Result<WorkflowRun>>;
174 rerun(actor: User, repo: RepoPath, id: string, failedOnly?: boolean): Promise<Result<WorkflowRun>>;
175 setWorkflowEnabled(actor: User, repo: RepoPath, workflow: string, enabled: boolean): Promise<Result<Workflow>>;
176 settings(actor: User, owner: SettingsOwner, kind: SettingKindFilter): Promise<Result<Setting[]>>;
177 /** `value` null keeps an existing entry's default value. */
178 setSetting(
179 actor: User,
180 owner: SettingsOwner,
181 kind: SettingKind,
182 name: string,
183 value: string | null,
184 options?: SettingOptions,
185 ): Promise<Result<Setting>>;
186 /** One row by `id`, or every row of the key. */
187 deleteSetting(actor: User, owner: SettingsOwner, kind: SettingKindFilter, name: string, id?: string): Promise<Result<boolean>>;
188}