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

Fast pages, required checks on the branch, self-hosted runners, honest incidents1import 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. */
Fast pages, required checks on the branch, self-hosted runners, honest incidents20 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;
41};
42
43export type RunnerGroup = {
44 id: string;
45 name: string;
46 default: boolean;
47 /** Repository names; empty is every repository in the workspace. */
48 repositories: string[];
49 runners: number;
50 updatedAt: string;
51};
52
53/** Shown once. */
54export type RegistrationToken = {
55 token: string;
56 expiresAt: string;
57 workspace: string;
58 repo: string | null;
59 group: string | null;
60 url: string;
61};
62
63export type RunnerSettings = {
64 agentsOnSelfHosted: boolean;
65 agentLabels: string[];
66 forkPullRequests: boolean;
67 /** For a repository: these are its workspace's. */
68 inherited: boolean;
69};
70
71export type RunnersOwner = { repo: RepoPath } | { workspace: string };
72
73export type RunnerSettingsChange = {
74 agents_on_self_hosted?: boolean;
75 agent_labels?: string[];
76 fork_pull_requests?: boolean;
77 inherit?: boolean;
78};
79
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.80/** A workflow job running in one of g1t's sandboxes. Snake case, as `runner_activity` answers. */
81export type CloudJob = { id: string; name: string; run_id: string; repo: string; started_at: string | null };
82
83/** Agent work handed to one of the workspace's own runners, waiting for one or taken. */
84export type HandedOverTask = {
85 id: string;
86 /** The agent run it is; null for work handed over before runs were noted. */
87 run_id: string | null;
88 kind: string;
89 title: string;
90 repo: string;
91 status: "queued" | "in_progress";
92 runner_name: string | null;
93 created_at: string;
94 started_at: string | null;
95};
96
97/** What runs for a workspace now, in g1t's sandboxes and on its own runners (`runner_activity`). */
98export type RunnerActivity = {
99 /** At most `RUNNER_ACTIVITY_LIMIT`, newest first. */
100 cloud_jobs: CloudJob[];
101 cloud_jobs_queued: number;
102 handed_over: HandedOverTask[];
103 self_hosted_jobs_queued: number;
104};
105
106/** The most jobs and tasks `runner_activity` lists of each: `ACTIVITY_LIMIT` in the actions service. */
107export const RUNNER_ACTIVITY_LIMIT = 100;
108
Fast pages, required checks on the branch, self-hosted runners, honest incidents109/** A job that has waited ten minutes or more with no matching runner online. */
110export type StuckJob = { id: string; name: string; runId: string; repo: string; labels: string; queuedAt: string };
111
112export interface RunnersApi {
113 /** The viewer's workspaces' jobs stuck waiting for a self-hosted runner, for Mission control. */
114 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.115 /** What runs for the workspace now, in g1t's sandboxes and handed to its own runners. Owners. */
116 activity(actor: User, workspace: string): Promise<Result<RunnerActivity>>;
Fast pages, required checks on the branch, self-hosted runners, honest incidents117 list(actor: User, owner: RunnersOwner): Promise<Result<Runner[]>>;
118 createToken(actor: User, owner: RunnersOwner, group?: string): Promise<Result<RegistrationToken>>;
119 remove(actor: User, owner: RunnersOwner, id: string): Promise<Result<boolean>>;
120 groups(actor: User, workspace: string): Promise<Result<RunnerGroup[]>>;
121 /** Without `id`, a new group. */
122 setGroup(actor: User, workspace: string, group: { id?: string; name?: string; repositories?: string[] }): Promise<Result<RunnerGroup>>;
123 deleteGroup(actor: User, workspace: string, id: string): Promise<Result<boolean>>;
124 settings(actor: User, owner: RunnersOwner): Promise<Result<RunnerSettings>>;
125 setSettings(actor: User, owner: RunnersOwner, change: RunnerSettingsChange): Promise<Result<RunnerSettings>>;
126}
127
128/**
129 * The runner's container image: `g1t-runner` and the Docker CLI, for
130 * running it in Docker or Kubernetes. Published with each release.
131 */
The runner's image is g1t.sh/flagon-io/g1t-runner, on g1t's own registry, public132export const RUNNER_IMAGE = "g1t.sh/flagon-io/g1t-runner";
Fast pages, required checks on the branch, self-hosted runners, honest incidents133
134/** Where the runner binary is published: `g1t.sh/downloads/runner/<version>/<file>`. */
135export const RUNNER_DOWNLOADS = "https://g1t.sh/downloads/runner";
136
137/** The file for each platform, as published. */
138export const RUNNER_FILES: Record<"linux-x64" | "linux-arm64" | "macos-arm64" | "macos-x64" | "windows-x64", string> = {
139 "linux-x64": "g1t-runner-linux-x64",
140 "linux-arm64": "g1t-runner-linux-arm64",
141 "macos-arm64": "g1t-runner-macos-arm64",
142 "macos-x64": "g1t-runner-macos-x64",
143 "windows-x64": "g1t-runner-windows-x64.exe",
144};