| 1 | import type { User } from "./identity"; |
| 2 | import type { RepoPath } from "./repos"; |
| 3 | import 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 | |
| 11 | export type RunnerStatus = "online" | "busy" | "offline"; |
| 12 | |
| 13 | /** What a runner is doing now. */ |
| 14 | export type RunnerWork = { |
| 15 | kind: "workflow" | "agent"; |
| 16 | id: string; |
| 17 | name: string; |
| 18 | repo: string | null; |
| 19 | /** The workflow run the job is in; for `agent` work, the agent run it is, when known. */ |
| 20 | runId: string | null; |
| 21 | startedAt: string | null; |
| 22 | }; |
| 23 | |
| 24 | export 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 | |
| 43 | export 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. */ |
| 54 | export type RegistrationToken = { |
| 55 | token: string; |
| 56 | expiresAt: string; |
| 57 | workspace: string; |
| 58 | repo: string | null; |
| 59 | group: string | null; |
| 60 | url: string; |
| 61 | }; |
| 62 | |
| 63 | export 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 | |
| 71 | export type RunnersOwner = { repo: RepoPath } | { workspace: string }; |
| 72 | |
| 73 | export type RunnerSettingsChange = { |
| 74 | agents_on_self_hosted?: boolean; |
| 75 | agent_labels?: string[]; |
| 76 | fork_pull_requests?: boolean; |
| 77 | inherit?: boolean; |
| 78 | }; |
| 79 | |
| 80 | /** A workflow job running in one of g1t's sandboxes. Snake case, as `runner_activity` answers. */ |
| 81 | export 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. */ |
| 84 | export 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`). */ |
| 98 | export 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. */ |
| 107 | export const RUNNER_ACTIVITY_LIMIT = 100; |
| 108 | |
| 109 | /** A job that has waited ten minutes or more with no matching runner online. */ |
| 110 | export type StuckJob = { id: string; name: string; runId: string; repo: string; labels: string; queuedAt: string }; |
| 111 | |
| 112 | export interface RunnersApi { |
| 113 | /** The viewer's workspaces' jobs stuck waiting for a self-hosted runner, for Mission control. */ |
| 114 | stuck(viewer: User): Promise<StuckJob[]>; |
| 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>>; |
| 117 | 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 | */ |
| 132 | export const RUNNER_IMAGE = "g1t.sh/flagon-io/g1t-runner"; |
| 133 | |
| 134 | /** Where the runner binary is published: `g1t.sh/downloads/runner/<version>/<file>`. */ |
| 135 | export const RUNNER_DOWNLOADS = "https://g1t.sh/downloads/runner"; |
| 136 | |
| 137 | /** The file for each platform, as published. */ |
| 138 | export 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 | }; |