Skip to content
217 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.

Cleanup: clippy is quiet outside billing, the README says g1t, and http-cache-semantics is 4.3.01import type { User } from "./identity";
2import type { RepoPath } from "./repos";
3import type { Result } from "./result";
4
5/**
6 * Self-hosted runners: a workspace's or a repository's own machines, which
7 * run its workflow jobs (and, when it says so, its agents' work) instead of
8 * g1t's sandboxes, at $0. Mirrors `crates/contracts/src/runners.rs`.
9 */
10
11export type RunnerStatus = "online" | "busy" | "offline";
12
13/** What a runner is doing now. */
14export type RunnerWork = {
15 kind: "workflow" | "agent";
16 id: string;
17 name: string;
18 repo: string | null;
The Runners page shows the machines a workspace's agents and workflow jobs run on, in Workspace under Compute: g1t's cloud beside your own runners, what each is running now with a link to it, what's waiting, this month's machine time and its cost (your own runners' free), where agent work and workflow jobs run, adding a runner, and groups; runner_activity in Actions says what runs where, work handed to your runners keeps its agent run, and the self-hosted runners guide says how.19 /** The workflow run the job is in; for `agent` work, the agent run it is, when known. */
Cleanup: clippy is quiet outside billing, the README says g1t, and http-cache-semantics is 4.3.020 runId: string | null;
21 startedAt: string | null;
22};
23
24export type Runner = {
25 id: string;
26 name: string;
27 workspace: string;
28 /** `owner/name` for a repository's own runner; null for the workspace's. */
29 repo: string | null;
30 group: string | null;
31 labels: string[];
32 os: "linux" | "macos" | "windows";
33 arch: "x64" | "arm64";
34 version: string;
35 ephemeral: boolean;
36 status: RunnerStatus;
37 work: RunnerWork | null;
38 lastSeenAt: string | null;
39 createdAt: string;
40 createdBy: string | null;
Merge the runner sandbox: g1t-runner sandbox up makes a person's own computer a self-hosted runner that nothing a job runs can get out of. Linux jobs run in a Linux VM of the runner's own (a WSL 2 distribution with no host mounts, interop or Docker socket on Windows; vfkit on macOS; Sysbox, or QEMU and KVM, on Linux), each in a fresh container under Sysbox inside it; on Windows 11 Pro and up, Windows jobs each run in a Windows Sandbox discarded after the job. Runners report their isolation, and the Runners page shows it.41 /** How it keeps work from its machine, as it last said; null for a runner from before runners said. */
42 isolation?: RunnerIsolation | null;
Cleanup: clippy is quiet outside billing, the README says g1t, and http-cache-semantics is 4.3.043};
44
Merge the runner sandbox: g1t-runner sandbox up makes a person's own computer a self-hosted runner that nothing a job runs can get out of. Linux jobs run in a Linux VM of the runner's own (a WSL 2 distribution with no host mounts, interop or Docker socket on Windows; vfkit on macOS; Sysbox, or QEMU and KVM, on Linux), each in a fresh container under Sysbox inside it; on Windows 11 Pro and up, Windows jobs each run in a Windows Sandbox discarded after the job. Runners report their isolation, and the Runners page shows it.45/**
46 * `nested-container`: a container per job inside the runner's own sandboxed container (or VM).
47 * `vm`: a throwaway VM per job, native to the machine's OS (Windows Sandbox).
48 * `container`: a container per job on a Docker Engine shared with the machine.
49 * `host`: directly on the machine, unsandboxed.
50 */
51export type RunnerIsolation = "nested-container" | "vm" | "container" | "host";
52
Cleanup: clippy is quiet outside billing, the README says g1t, and http-cache-semantics is 4.3.053export type RunnerGroup = {
54 id: string;
55 name: string;
56 default: boolean;
57 /** Repository names; empty is every repository in the workspace. */
58 repositories: string[];
59 runners: number;
60 updatedAt: string;
61};
62
63/** Shown once. */
64export type RegistrationToken = {
65 token: string;
66 expiresAt: string;
67 workspace: string;
68 repo: string | null;
69 group: string | null;
70 url: string;
71};
72
73export type RunnerSettings = {
74 agentsOnSelfHosted: boolean;
75 agentLabels: string[];
76 forkPullRequests: boolean;
77 /** For a repository: these are its workspace's. */
78 inherited: boolean;
79};
80
81export type RunnersOwner = { repo: RepoPath } | { workspace: string };
82
83export type RunnerSettingsChange = {
84 agents_on_self_hosted?: boolean;
85 agent_labels?: string[];
86 fork_pull_requests?: boolean;
87 inherit?: boolean;
88};
89
The Runners page shows the machines a workspace's agents and workflow jobs run on, in Workspace under Compute: g1t's cloud beside your own runners, what each is running now with a link to it, what's waiting, this month's machine time and its cost (your own runners' free), where agent work and workflow jobs run, adding a runner, and groups; runner_activity in Actions says what runs where, work handed to your runners keeps its agent run, and the self-hosted runners guide says how.90/** A workflow job running in one of g1t's sandboxes. Snake case, as `runner_activity` answers. */
91export type CloudJob = { id: string; name: string; run_id: string; repo: string; started_at: string | null };
92
93/** Agent work handed to one of the workspace's own runners, waiting for one or taken. */
94export type HandedOverTask = {
95 id: string;
96 /** The agent run it is; null for work handed over before runs were noted. */
97 run_id: string | null;
98 kind: string;
99 title: string;
100 repo: string;
101 status: "queued" | "in_progress";
102 runner_name: string | null;
103 created_at: string;
104 started_at: string | null;
105};
106
107/** What runs for a workspace now, in g1t's sandboxes and on its own runners (`runner_activity`). */
108export type RunnerActivity = {
109 /** At most `RUNNER_ACTIVITY_LIMIT`, newest first. */
110 cloud_jobs: CloudJob[];
111 cloud_jobs_queued: number;
112 handed_over: HandedOverTask[];
113 self_hosted_jobs_queued: number;
114};
115
116/** The most jobs and tasks `runner_activity` lists of each: `ACTIVITY_LIMIT` in the actions service. */
117export const RUNNER_ACTIVITY_LIMIT = 100;
118
Cleanup: clippy is quiet outside billing, the README says g1t, and http-cache-semantics is 4.3.0119/** A job that has waited ten minutes or more with no matching runner online. */
120export type StuckJob = { id: string; name: string; runId: string; repo: string; labels: string; queuedAt: string };
121
122export interface RunnersApi {
123 /** The viewer's workspaces' jobs stuck waiting for a self-hosted runner, for Mission control. */
124 stuck(viewer: User): Promise<StuckJob[]>;
The Runners page shows the machines a workspace's agents and workflow jobs run on, in Workspace under Compute: g1t's cloud beside your own runners, what each is running now with a link to it, what's waiting, this month's machine time and its cost (your own runners' free), where agent work and workflow jobs run, adding a runner, and groups; runner_activity in Actions says what runs where, work handed to your runners keeps its agent run, and the self-hosted runners guide says how.125 /** What runs for the workspace now, in g1t's sandboxes and handed to its own runners. Owners. */
126 activity(actor: User, workspace: string): Promise<Result<RunnerActivity>>;
Cleanup: clippy is quiet outside billing, the README says g1t, and http-cache-semantics is 4.3.0127 list(actor: User, owner: RunnersOwner): Promise<Result<Runner[]>>;
128 createToken(actor: User, owner: RunnersOwner, group?: string): Promise<Result<RegistrationToken>>;
129 remove(actor: User, owner: RunnersOwner, id: string): Promise<Result<boolean>>;
130 groups(actor: User, workspace: string): Promise<Result<RunnerGroup[]>>;
131 /** Without `id`, a new group. */
132 setGroup(actor: User, workspace: string, group: { id?: string; name?: string; repositories?: string[] }): Promise<Result<RunnerGroup>>;
133 deleteGroup(actor: User, workspace: string, id: string): Promise<Result<boolean>>;
134 settings(actor: User, owner: RunnersOwner): Promise<Result<RunnerSettings>>;
135 setSettings(actor: User, owner: RunnersOwner, change: RunnerSettingsChange): Promise<Result<RunnerSettings>>;
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.136 /** What the person's own desktop app says of its runner, in a workspace they own. */
137 reportDesktop(actor: User, report: DesktopReport): Promise<Result<boolean>>;
138 /** The workspace's desktops, as each app last said. Owners. */
139 desktops(actor: User, workspace: string): Promise<Result<DesktopRunner[]>>;
Cleanup: clippy is quiet outside billing, the README says g1t, and http-cache-semantics is 4.3.0140}
141
142/**
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.143 * The desktop app keeps a runner on a person's computer while it is open.
144 * What it says of that runner (its state, why, and the fix) comes from one
145 * catalogue in the app (apps/desktop/src-tauri/src/runner/diagnosis.rs),
146 * and the site shows it word for word: `closed` is what to show once g1t
147 * is closed on that computer, which the app sends too.
148 */
149export type DesktopDiagnosis = {
150 code: string;
151 tone: "ok" | "working" | "off" | "warning" | "problem";
152 title: string;
153 cause: string | null;
154 fix: string | null;
Merge the desktop app's sandbox: its default runner now starts g1t-runner's sandbox on Windows, macOS and Linux, and says per kind of job (Linux, Windows) what it is doing or why it cannot and how to fix it.155 /** A sandboxed desktop's kinds of job, each with how it is: Linux jobs can run while Windows jobs cannot. */
156 capabilities?: DesktopCapability[];
157};
158
159/** One kind of job a sandboxed desktop runs (`linux`, `windows`, `macos`), as its app says it. */
160export type DesktopCapability = {
161 id: string;
162 /** `Linux jobs`. */
163 label: string;
164 tone: DesktopDiagnosis["tone"];
165 /** `Waiting for jobs`, `Not available`. */
166 title: string;
167 cause: string | null;
168 fix: string | null;
Merge the desktop app's runner: it starts with the app for the signed-in person, sandboxed by default and running nothing where no sandbox is available yet, registers through the site, keeps itself up to date, and says everywhere what it is doing, why it is not, and how to fix it.169};
170
171/** How a desktop runs jobs. */
172export type DesktopBackend = "sandboxed" | "docker" | "host";
173
174export type DesktopReport = {
175 workspace: string;
176 machine: string;
177 backend: DesktopBackend;
178 version: string | null;
179 diagnosis: DesktopDiagnosis;
180 closed: DesktopDiagnosis;
181};
182
183/** One person's computer, as its desktop app last said. */
184export type DesktopRunner = {
185 workspace: string;
186 machine: string;
187 /** Whose computer: their username. */
188 person: string;
189 backend: DesktopBackend;
190 version: string | null;
191 diagnosis: DesktopDiagnosis;
192 closed: DesktopDiagnosis;
193 /** Heard from in the last ten minutes: g1t is open there. */
194 open: boolean;
195 reportedAt: string;
196};
197
198/** The label every desktop app's runner has. */
199export const DESKTOP_LABEL = "desktop";
200
201/**
Cleanup: clippy is quiet outside billing, the README says g1t, and http-cache-semantics is 4.3.0202 * The runner's container image: `g1t-runner` and the Docker CLI, for
203 * running it in Docker or Kubernetes. Published with each release.
204 */
The runner's image is g1t.sh/flagon-io/g1t-runner, on g1t's own registry, public205export const RUNNER_IMAGE = "g1t.sh/flagon-io/g1t-runner";
Cleanup: clippy is quiet outside billing, the README says g1t, and http-cache-semantics is 4.3.0206
207/** Where the runner binary is published: `g1t.sh/downloads/runner/<version>/<file>`. */
208export const RUNNER_DOWNLOADS = "https://g1t.sh/downloads/runner";
209
210/** The file for each platform, as published. */
211export const RUNNER_FILES: Record<"linux-x64" | "linux-arm64" | "macos-arm64" | "macos-x64" | "windows-x64", string> = {
212 "linux-x64": "g1t-runner-linux-x64",
213 "linux-arm64": "g1t-runner-linux-arm64",
214 "macos-arm64": "g1t-runner-macos-arm64",
215 "macos-x64": "g1t-runner-macos-x64",
216 "windows-x64": "g1t-runner-windows-x64.exe",
217};

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