Skip to content
432 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs1import 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
Merge branch 'worktree-agent-a3abfcce648e87dca'25/**
26 * `action_required`: a pull request's run from outside, waiting for someone
27 * with the Write role to approve it. `waiting`: its jobs are held by an
28 * environment's protection rules (a run's detail says so; lists do not).
29 */
30export type RunStatus = "pending" | "action_required" | "queued" | "in_progress" | "waiting" | "completed";
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs31export type Conclusion = "success" | "failure" | "cancelled" | "skipped";
32
33export type WorkflowRun = {
34 id: string;
35 workflowId: string;
36 path: string;
37 name: string;
38 title: string;
39 number: number;
40 attempt: number;
41 event: string;
42 ref: string;
43 sha: string;
44 pull: number | null;
45 status: RunStatus;
46 conclusion: Conclusion | null;
47 error: string | null;
48 actor: string | null;
49 createdAt: string;
50 startedAt: string | null;
51 finishedAt: string | null;
52};
53
54export type Workflow = {
55 id: string;
56 path: string;
57 name: string;
58 events: string[];
59 state: "active" | "disabled";
60 error: string | null;
61 notes: WorkflowNote[];
62 dispatch: Record<string, DispatchInput> | null;
63 lastRun: WorkflowRun | null;
64};
65
66export type StepState = {
67 number: number;
68 name: string;
69 status: "queued" | "in_progress" | "completed";
70 conclusion: Conclusion | null;
71 startedAt: string | null;
72 finishedAt: string | null;
73};
74
75export type Annotation = {
76 level: "error" | "warning" | "notice";
77 message: string;
78 title: string | null;
79 file: string | null;
80 line: number | null;
81};
82
83export type Job = {
84 id: string;
85 runId: string;
86 key: string;
87 name: string;
88 needs: string[];
Merge branch 'worktree-agent-a3abfcce648e87dca'89 /**
90 * `calling`: running the reusable workflow it calls, whose jobs follow it.
91 * `pending`: held by its environment's protection rules; `reason` says for what.
92 */
93 status: "waiting" | "pending" | "queued" | "in_progress" | "calling" | "completed";
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs94 conclusion: Conclusion | null;
95 steps: StepState[];
96 annotations: Annotation[];
97 reason: string | null;
98 startedAt: string | null;
99 finishedAt: string | null;
Merge branch 'worktree-agent-a3abfcce648e87dca'100 /** The environment it names, once its needs are done. */
101 environment?: string | null;
Fast pages, required checks on the branch, self-hosted runners, honest incidents102 /** Its `runs-on` names self-hosted runners. */
103 selfHosted?: boolean;
104 /** The self-hosted runner that took it, by name. */
105 runner?: string | null;
Merge Actions runs: summaries, attempts and re-runs, graceful cancel, log downloads, badges (actions 0009)106 /** Cancelled, and running its `if: always()` and `cancelled()` steps and post steps before it ends. */
107 cancelling?: boolean;
A run opens on its summary: what triggered it, its status, duration and artifacts, a graph of its jobs (what needs what, matrices folded, called workflows boxed, deploys with their address), annotations, and each job's summary; the job list groups the same way108 /** Where its deployment is (`environment.url`), for a job that deploys and says; the current attempt's only. */
109 environmentUrl?: string | null;
110 /** For a job that calls a reusable workflow: that workflow's file. Its jobs' keys are this job's key, `/`, their own. */
111 uses?: string | null;
Merge Actions runs: summaries, attempts and re-runs, graceful cancel, log downloads, badges (actions 0009)112};
113
114/** One attempt of a run: the first, or a re-run. */
115export type RunAttempt = {
116 attempt: number;
117 status: RunStatus;
118 conclusion: Conclusion | null;
119 /** Who started it: whoever caused the run, then whoever re-ran it. */
120 actor: string | null;
121 /** It ran with debug logging. */
122 debug: boolean;
123 startedAt: string | null;
124 finishedAt: string | null;
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs125};
126
Merge Actions runs: summaries, attempts and re-runs, graceful cancel, log downloads, badges (actions 0009)127/** What a job's steps wrote to `$GITHUB_STEP_SUMMARY`, in Markdown, masked. */
128export type JobSummary = { jobId: string; name: string; steps: { step: number; markdown: string }[] };
129
130/** A job's whole log, to download. `omitted`: left out of a run's logs that grew too large. */
131export type JobLogText = {
132 jobId: string;
133 name: string;
134 steps: StepState[];
135 chunks: LogChunk[];
136 done: boolean;
137 omitted?: boolean;
138};
139
Merge branch 'worktree-agent-a3abfcce648e87dca'140export type RunDetail = {
141 run: WorkflowRun;
142 jobs: Job[];
143 notes: WorkflowNote[];
144 /** For a pull request's run from outside: whether it waits for, or had, approval. */
145 approval?: RunApproval | null;
146 /** The environments whose protection rules hold its jobs, this attempt. */
147 pendingDeployments?: PendingDeployment[];
Merge Actions runs: summaries, attempts and re-runs, graceful cancel, log downloads, badges (actions 0009)148 /** Every attempt, oldest first, the one shown (`run.attempt`) included. */
149 attempts?: RunAttempt[];
Merge branch 'worktree-agent-a3abfcce648e87dca'150};
151
152export type RunApproval = {
153 state: "required" | "approved";
154 /** Why it waits, in words. */
155 reason: string;
156 approvedBy: string | null;
157};
158
159/** One person or team who may approve an environment's jobs. */
160export type EnvironmentReviewer = { type: "user" | "team"; name: string };
161
162/** A branch or tag pattern an environment takes deployments from. */
163export type BranchPattern = { name: string; type: "branch" | "tag" };
164
165/** The most reviewers an environment may have. */
166export const MAX_ENVIRONMENT_REVIEWERS = 6;
167/** The longest wait timer, in minutes (30 days). */
168export const MAX_WAIT_MINUTES = 43_200;
169
170/**
171 * An environment and its protection rules. Jobs naming it with
172 * `environment:` wait until the rules let them through, and only then get
173 * its secrets.
174 */
175export type Environment = {
176 /** Lowercase. */
177 name: string;
178 reviewers: EnvironmentReviewer[];
179 preventSelfReview: boolean;
180 waitMinutes: number;
181 /** `protected`: branches the rules protect; `selected`: `branchPatterns`. */
182 branchPolicy: "all" | "protected" | "selected";
183 branchPatterns: BranchPattern[];
184 adminsBypass: boolean;
185 /** Whether it has rules saved; false for one only named by a workflow or a secret. */
186 protected: boolean;
187 updatedAt: string | null;
188 updatedBy: string | null;
189};
190
191/** What changes an environment's rules; left out is unchanged. */
192export type EnvironmentChange = Partial<
193 Pick<Environment, "reviewers" | "preventSelfReview" | "waitMinutes" | "branchPolicy" | "branchPatterns" | "adminsBypass">
194>;
195
196/** An environment holding a run's jobs, and where its rules stand. */
197export type PendingDeployment = {
198 environment: string;
199 state: "waiting" | "approved" | "rejected";
200 needsReview: boolean;
201 /** When its wait timer lets its jobs start. */
202 waitUntil: string | null;
203 reviewers: EnvironmentReviewer[];
204 /** The jobs it holds, by name. */
205 jobs: string[];
206 /** Whether the viewer may approve or reject it now. */
207 canReview: boolean;
208 reviewedBy: string | null;
209 comment: string | null;
210 reviewedAt: string | null;
211};
212
213/** Which pull requests' runs wait for approval, least strict first. */
214export const APPROVAL_POLICIES = ["first_time_contributors", "outside_contributors", "all_external_contributors"] as const;
215export type ApprovalPolicy = (typeof APPROVAL_POLICIES)[number];
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs216
Merge branch 'worktree-agent-a3abfcce648e87dca'217/** A repository's choices for its workflows. */
218export type ActionsSettings = {
219 /**
220 * What a workflow without `permissions:` gets. Unchosen, a repository made
221 * before restricted tokens keeps `write`; a newer one takes its
222 * workspace's default. Never more than `maxPermissions`.
223 */
224 defaultPermissions: "read" | "write";
225 /** Whether the repository chose it. */
226 defaultChosen: boolean;
227 /** The most the workspace lets a repository's default be. */
228 maxPermissions: "read" | "write";
229 approvalPolicy: ApprovalPolicy;
230 /** "Allow g1t Actions to create and approve pull requests". */
231 canApprovePullRequests: boolean;
232 /** Whether the workspace lets its repositories turn that on. */
233 workspaceAllowsPullRequests: boolean;
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts234 /**
235 * Who may use the repository's actions and reusable workflows while it is
236 * private: only itself (`none`), or private repositories of its workspace
237 * (`organization`). A public repository's are anyone's.
238 */
239 accessLevel: ActionsAccessLevel;
Merge branch 'worktree-agent-a3abfcce648e87dca'240};
241
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts242/** Settings, Actions, Access. */
243export const ACTIONS_ACCESS_LEVELS = ["none", "organization"] as const;
244export type ActionsAccessLevel = (typeof ACTIONS_ACCESS_LEVELS)[number];
245
Merge branch 'worktree-agent-a3abfcce648e87dca'246/** What changes a repository's choices; `inherit` unchooses its default. */
247export type ActionsSettingsChange = {
248 defaultPermissions?: "read" | "write" | "inherit";
249 approvalPolicy?: ApprovalPolicy;
250 canApprovePullRequests?: boolean;
Merge Actions: cross-repo workflows and actions, release and deployment triggers, step timeouts251 accessLevel?: ActionsAccessLevel;
Merge branch 'worktree-agent-a3abfcce648e87dca'252};
253
254/** A workspace's policy for its repositories' job tokens. */
255export type WorkspaceActionsSettings = {
256 /** What a repository made from now on gets by default. */
257 defaultPermissions: "read" | "write";
258 /** The most any repository's default may be. */
259 maxPermissions: "read" | "write";
260 canApprovePullRequests: boolean;
261};
262
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs263export type LogChunk = { seq: number; step: number; text: string };
264export type JobLog = { chunks: LogChunk[]; done: boolean };
265
Secrets and variables: one list, rows per environment, for workflows and deployments266/**
267 * Who may read a secret or variable: `workflows` (`secrets.*`, `vars.*` in
268 * GitHub Actions) and `deployments` (a deploy build's environment and the
269 * running app's bindings). Agents, checks and the merge queue never read
270 * any.
271 */
272export type SettingReader = "workflows" | "deployments";
273
274/**
275 * One row of secrets and variables, as Vercel lists environment variables:
276 * a key, its type, the environments it applies to and who reads it. A key
277 * may have one row per environment. Secrets' values are never returned.
278 */
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs279export type Setting = {
Secrets and variables: one list, rows per environment, for workflows and deployments280 id: string;
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs281 name: string;
Secrets and variables: one list, rows per environment, for workflows and deployments282 /** `variable` is shown as Config. Config may become a secret, never back. */
283 kind: SettingKind;
284 /** A variable's value. */
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs285 value: string | null;
Projects: what a workspace builds and runs, first on every page286 /** A project's (a repository's belong to its project) or the workspace's. */
287 scope: "project" | "workspace";
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs288 updatedAt: string;
Secrets and variables: one list, rows per environment, for workflows and deployments289 availableTo: SettingReader[];
290 /** The environments it applies to; empty is every environment. */
291 environments: string[];
Projects: what a workspace builds and runs, first on every page292 /** A workspace's row: the projects it reaches, by slug; empty is every one. */
293 projects: string[];
Secrets and variables: one list, rows per environment, for workflows and deployments294 /** Where to rotate it, or who to ask. */
295 note: string | null;
296 updatedBy: string | null;
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs297};
298
Secrets and variables: one list, rows per environment, for workflows and deployments299/** What saving a row sets beyond its value; left out is unchanged. */
300export type SettingOptions = {
301 /** The row to change; left out, the key's row for every environment. */
302 id?: string;
303 availableTo?: SettingReader[];
304 environments?: string[];
Projects: what a workspace builds and runs, first on every page305 /** A workspace's row: project slugs; empty for every one. */
306 projects?: string[];
Secrets and variables: one list, rows per environment, for workflows and deployments307 note?: string;
308};
309
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs310export type SettingsOwner = { repo: RepoPath } | { workspace: string };
311export type SettingKind = "secret" | "variable";
Secrets and variables: one list, rows per environment, for workflows and deployments312/** `all` lists both. */
313export type SettingKindFilter = SettingKind | "all";
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs314
315export type RunsFilter = {
316 workflow?: string;
317 branch?: string;
318 event?: string;
319 pull?: number;
320 sha?: string;
321 limit?: number;
322};
323
324export interface ActionsApi {
325 workflows(repo: RepoPath, viewer: Viewer): Promise<Result<Workflow[]>>;
326 runs(repo: RepoPath, viewer: Viewer, filter?: RunsFilter): Promise<Result<WorkflowRun[]>>;
Merge Actions runs: summaries, attempts and re-runs, graceful cancel, log downloads, badges (actions 0009)327 /** The latest attempt, or an earlier one. */
328 run(repo: RepoPath, viewer: Viewer, id: string, attempt?: number): Promise<Result<RunDetail>>;
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs329 logs(repo: RepoPath, viewer: Viewer, job: string, after?: number): Promise<Result<JobLog>>;
Merge Actions runs: summaries, attempts and re-runs, graceful cancel, log downloads, badges (actions 0009)330 /** The job summaries of an attempt (the latest by default), jobs without one left out. */
331 summaries(repo: RepoPath, viewer: Viewer, id: string, attempt?: number): Promise<Result<JobSummary[]>>;
332 /** A job's whole log, any attempt's, by the id the run gave the job. */
333 jobLogText(repo: RepoPath, viewer: Viewer, job: string): Promise<Result<JobLogText>>;
334 /** Every job's whole log for an attempt, to download as one archive. */
335 runLogs(repo: RepoPath, viewer: Viewer, id: string, attempt?: number): Promise<Result<JobLogText[]>>;
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs336 dispatch(
337 actor: User,
338 repo: RepoPath,
339 workflow: string,
340 ref: string | undefined,
341 inputs: Record<string, unknown>,
342 ): Promise<Result<WorkflowRun>>;
Merge Actions runs: summaries, attempts and re-runs, graceful cancel, log downloads, badges (actions 0009)343 /** Running jobs clean up first; `force` (or cancelling a run that is cancelling) stops them outright. */
344 cancel(actor: User, repo: RepoPath, id: string, force?: boolean): Promise<Result<WorkflowRun>>;
345 /** A new attempt: every job, the failed ones, or `job` and what needs it; `debug` for debug logging. */
346 rerun(
347 actor: User,
348 repo: RepoPath,
349 id: string,
350 failedOnly?: boolean,
351 options?: { job?: string; debug?: boolean },
352 ): Promise<Result<WorkflowRun>>;
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs353 setWorkflowEnabled(actor: User, repo: RepoPath, workflow: string, enabled: boolean): Promise<Result<Workflow>>;
Secrets and variables: one list, rows per environment, for workflows and deployments354 settings(actor: User, owner: SettingsOwner, kind: SettingKindFilter): Promise<Result<Setting[]>>;
355 /** `value` null keeps an existing entry's default value. */
356 setSetting(
357 actor: User,
358 owner: SettingsOwner,
359 kind: SettingKind,
360 name: string,
361 value: string | null,
362 options?: SettingOptions,
363 ): Promise<Result<Setting>>;
364 /** One row by `id`, or every row of the key. */
365 deleteSetting(actor: User, owner: SettingsOwner, kind: SettingKindFilter, name: string, id?: string): Promise<Result<boolean>>;
Merge branch 'worktree-agent-a3abfcce648e87dca'366 /** Lets a pull request's run from outside start. Write role. */
367 approveRun(actor: User, repo: RepoPath, id: string): Promise<Result<WorkflowRun>>;
368 pendingDeployments(repo: RepoPath, viewer: Viewer, id: string): Promise<Result<PendingDeployment[]>>;
369 /** Approves or rejects the jobs `environments` hold (every waiting one when empty). */
370 reviewDeployments(
371 actor: User,
372 repo: RepoPath,
373 id: string,
374 state: "approved" | "rejected",
375 environments?: string[],
376 comment?: string,
377 ): Promise<Result<PendingDeployment[]>>;
378 actionsSettings(repo: RepoPath, viewer: Viewer): Promise<Result<ActionsSettings>>;
379 /** Admin role. Left out is unchanged. */
380 setActionsSettings(actor: User, repo: RepoPath, change: ActionsSettingsChange): Promise<Result<ActionsSettings>>;
381 /** Members. */
382 workspaceActionsSettings(workspace: string, viewer: Viewer): Promise<Result<WorkspaceActionsSettings>>;
383 /** Owners. Left out is unchanged. */
384 setWorkspaceActionsSettings(
385 actor: User,
386 workspace: string,
387 change: Partial<WorkspaceActionsSettings>,
388 ): Promise<Result<WorkspaceActionsSettings>>;
389 /** Every environment the repository's rules, secrets, workflows or jobs name. */
390 environments(repo: RepoPath, viewer: Viewer): Promise<Result<Environment[]>>;
391 /** Admin role. */
392 setEnvironment(actor: User, repo: RepoPath, name: string, change: EnvironmentChange): Promise<Result<Environment>>;
393 deleteEnvironment(actor: User, repo: RepoPath, name: string): Promise<Result<boolean>>;
Actions: OIDC tokens, the toolkit's cache and artifact services, and artifacts in R2394 /** A repository's artifacts, newest first, or one run's. */
395 artifacts(repo: RepoPath, viewer: Viewer, filter?: { run?: string; name?: string; page?: number; per_page?: number }): Promise<Result<ArtifactList>>;
396 /** One artifact by id, or by run and name, with a token to download it for a few minutes. */
397 artifactDownload(repo: RepoPath, viewer: Viewer, by: { id?: number; run?: string; name?: string }): Promise<Result<ArtifactBlob>>;
398 /** Needs the Write role. */
399 deleteArtifact(actor: User, repo: RepoPath, id: number): Promise<Result<Artifact>>;
400 /** How long the repository keeps artifacts; with `days`, sets it (Maintain). */
401 artifactRetention(repo: RepoPath, viewer: Viewer, days?: number): Promise<Result<ArtifactRetention>>;
GitHub Actions on g1t, part three: .g1t/workflows, the pages, the docs402}
Actions: OIDC tokens, the toolkit's cache and artifact services, and artifacts in R2403
404/**
405 * A workflow run's artifact, kept in R2 for its retention days. Mirrors
406 * `g1t_contracts::actions::Artifact` (which travels in `snake_case`).
407 */
408export type Artifact = {
409 id: number;
410 name: string;
411 size: number;
412 /** `sha256:<hex>`, when the uploader said. */
413 digest: string | null;
414 /** `zip`, or `tgz` for one an older runner sent. */
415 format: string;
416 run_id: string;
417 job_id: string;
418 repo_id: string;
419 expired: boolean;
420 created_at: string;
421 updated_at: string;
422 expires_at: string;
423 head_branch?: string | null;
424 head_sha?: string | null;
425};
426
427export type ArtifactList = { total_count: number; artifacts: Artifact[] };
428
429/** An artifact, where it is, and a signed token for the API's `/actions/toolkit/blobs/{blob}`. */
430export type ArtifactBlob = { artifact: Artifact; object: string; blob: string };
431
432export type ArtifactRetention = { days: number; maximum_allowed_days: number };

This file's history is long; its oldest lines are credited to the oldest commit read.