g1t/crates/contracts/src/actions.rs

318 lines9,781 bytesCodeBlame

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 two: running workflows1//! The actions service: GitHub Actions workflows, run on g1t as they are.
2//!
3//! A repository's `.github/workflows/*.yml` are read from the commit an
4//! event is about (the default branch for issues, schedules and manual
5//! runs). Each workflow an event starts becomes a run; each job of the run
6//! (one per matrix combination) runs in a sandbox once the jobs it needs
7//! have finished. Jobs report their steps and logs back as they go, and a
8//! run on a pull request's head is a status on that pull request.
9//!
10//! Secrets and variables belong to a repository or to its workspace; a
11//! repository's override its workspace's of the same name. Secret values
12//! are sealed at rest and never returned.
13//!
14//! Mirrors `packages/contracts/src/actions.ts`.
15
16use serde::{Deserialize, Serialize};
17use serde_json::Value;
18
19use crate::repos::RepoPath;
20use crate::{User, Viewer};
21
22/// A note on something in a workflow that runs differently on g1t.
23#[derive(Clone, Debug, Serialize, Deserialize)]
24#[serde(rename_all = "camelCase")]
25pub struct WorkflowNote {
26 /// `info`, `warning` or `unsupported`.
27 pub severity: String,
28 pub job: Option<String>,
29 pub message: String,
30}
31
32#[derive(Clone, Debug, Serialize, Deserialize)]
33#[serde(rename_all = "camelCase")]
34pub struct Workflow {
35 pub id: String,
36 /// `.github/workflows/ci.yml`.
37 pub path: String,
38 pub name: String,
39 /// The events that start it, such as `push` and `pull_request`.
40 pub events: Vec<String>,
41 /// `active`, or `disabled` when a member turned it off.
42 pub state: String,
43 /// Why the file cannot be used, if it cannot.
44 pub error: Option<String>,
45 pub notes: Vec<WorkflowNote>,
46 /// `on.workflow_dispatch.inputs` as written, when it can be run by hand.
47 pub dispatch: Option<Value>,
48 pub last_run: Option<WorkflowRun>,
49}
50
51#[derive(Clone, Debug, Serialize, Deserialize)]
52#[serde(rename_all = "camelCase")]
53pub struct WorkflowRun {
54 pub id: String,
55 pub workflow_id: String,
56 pub path: String,
57 /// The workflow's name.
58 pub name: String,
59 /// `run-name`, or what started it: a commit's subject, a pull request's title.
60 pub title: String,
61 /// Counts the workflow's runs: 1, 2, 3…
62 pub number: u64,
63 pub attempt: u64,
64 /// The GitHub event: `push`, `pull_request`, `schedule`…
65 pub event: String,
66 #[serde(rename = "ref")]
67 pub git_ref: String,
68 pub sha: String,
69 /// The pull request it ran for, if any.
70 pub pull: Option<u32>,
71 /// `queued`, `in_progress` or `completed`.
72 pub status: String,
73 /// When completed: `success`, `failure`, `cancelled` or `skipped`.
74 pub conclusion: Option<String>,
75 /// Why it could not start, such as a workflow file that does not read.
76 pub error: Option<String>,
77 /// Username of whoever caused it.
78 pub actor: Option<String>,
79 pub created_at: String,
80 pub started_at: Option<String>,
81 pub finished_at: Option<String>,
82}
83
84#[derive(Clone, Debug, Default, Serialize, Deserialize)]
85#[serde(rename_all = "camelCase")]
86pub struct StepState {
87 /// From 1.
88 pub number: u32,
89 pub name: String,
90 /// `queued`, `in_progress` or `completed`.
91 pub status: String,
92 /// `success`, `failure`, `cancelled` or `skipped`.
93 pub conclusion: Option<String>,
94 pub started_at: Option<String>,
95 pub finished_at: Option<String>,
96}
97
98/// A message a step left with `::error::`, `::warning::` or `::notice::`.
99#[derive(Clone, Debug, Default, Serialize, Deserialize)]
100#[serde(rename_all = "camelCase")]
101pub struct Annotation {
102 /// `error`, `warning` or `notice`.
103 pub level: String,
104 pub message: String,
105 pub title: Option<String>,
106 pub file: Option<String>,
107 pub line: Option<u32>,
108}
109
110#[derive(Clone, Debug, Serialize, Deserialize)]
111#[serde(rename_all = "camelCase")]
112pub struct Job {
113 pub id: String,
114 pub run_id: String,
115 /// Its key under `jobs:`.
116 pub key: String,
117 /// With its matrix combination: `test (ubuntu-latest, 20)`.
118 pub name: String,
119 pub needs: Vec<String>,
120 /// `queued`, `waiting` (for the jobs it needs), `in_progress` or `completed`.
121 pub status: String,
122 pub conclusion: Option<String>,
123 pub steps: Vec<StepState>,
124 pub annotations: Vec<Annotation>,
125 /// Why it did not run, or what stopped it.
126 pub reason: Option<String>,
127 pub started_at: Option<String>,
128 pub finished_at: Option<String>,
129}
130
131#[derive(Clone, Debug, Serialize, Deserialize)]
132#[serde(rename_all = "camelCase")]
133pub struct RunDetail {
134 pub run: WorkflowRun,
135 pub jobs: Vec<Job>,
136 /// The workflow's notes, as of the run's commit.
137 pub notes: Vec<WorkflowNote>,
138}
139
140#[derive(Clone, Debug, Serialize, Deserialize)]
141#[serde(rename_all = "camelCase")]
142pub struct LogChunk {
143 pub seq: u64,
144 /// The step it belongs to, from 1; 0 for the job's setup.
145 pub step: u32,
146 pub text: String,
147}
148
149#[derive(Clone, Debug, Serialize, Deserialize)]
150#[serde(rename_all = "camelCase")]
151pub struct JobLog {
152 pub chunks: Vec<LogChunk>,
153 /// Whether the job has finished, so no more will come.
154 pub done: bool,
155}
156
157/// A secret's or variable's name, and for a variable its value.
158#[derive(Clone, Debug, Serialize, Deserialize)]
159#[serde(rename_all = "camelCase")]
160pub struct Setting {
161 pub name: String,
162 /// Variables only; secrets are never returned.
163 pub value: Option<String>,
164 /// `repository` or `workspace`.
165 pub scope: String,
166 pub updated_at: String,
167}
168
169// --- Methods ---------------------------------------------------------------
170
171/// `workflows`. Returns `Outcome<Vec<Workflow>>`.
172#[derive(Debug, Serialize, Deserialize)]
173pub struct WorkflowsArgs {
174 pub repo: RepoPath,
175 pub viewer: Viewer,
176}
177
178/// `runs`: newest first. Returns `Outcome<Vec<WorkflowRun>>`.
179#[derive(Debug, Serialize, Deserialize)]
180pub struct RunsArgs {
181 pub repo: RepoPath,
182 pub viewer: Viewer,
183 /// A workflow's id or file name.
184 #[serde(default)]
185 pub workflow: Option<String>,
186 #[serde(default)]
187 pub branch: Option<String>,
188 #[serde(default)]
189 pub event: Option<String>,
190 /// The pull request's number.
191 #[serde(default)]
192 pub pull: Option<u32>,
193 #[serde(default)]
194 pub sha: Option<String>,
195 #[serde(default)]
196 pub limit: Option<u32>,
197}
198
199/// `run`. Returns `Outcome<RunDetail>`.
200#[derive(Debug, Serialize, Deserialize)]
201pub struct RunArgs {
202 pub repo: RepoPath,
203 pub viewer: Viewer,
204 pub id: String,
205}
206
207/// `logs`: a job's log after `after`. Returns `Outcome<JobLog>`.
208#[derive(Debug, Serialize, Deserialize)]
209pub struct LogsArgs {
210 pub repo: RepoPath,
211 pub viewer: Viewer,
212 pub job: String,
213 #[serde(default)]
214 pub after: u64,
215}
216
217/// `dispatch`: run a workflow that has `workflow_dispatch`. Members only.
218/// Returns `Outcome<WorkflowRun>`.
219#[derive(Debug, Serialize, Deserialize)]
220pub struct DispatchArgs {
221 pub actor: User,
222 pub repo: RepoPath,
223 /// A workflow's id or file name.
224 pub workflow: String,
225 /// A branch or tag; the default branch when absent.
226 #[serde(default, rename = "ref")]
227 pub git_ref: Option<String>,
228 #[serde(default)]
229 pub inputs: serde_json::Map<String, Value>,
230}
231
232/// `cancel` and `rerun` (all jobs, or with `failed_only` the ones that did
233/// not succeed). Members only. Returns `Outcome<WorkflowRun>`.
234#[derive(Debug, Serialize, Deserialize)]
235pub struct RunActionArgs {
236 pub actor: User,
237 pub repo: RepoPath,
238 pub id: String,
239 #[serde(default)]
240 pub failed_only: bool,
241}
242
243/// `set_workflow_enabled`. Members only. Returns `Outcome<Workflow>`.
244#[derive(Debug, Serialize, Deserialize)]
245pub struct SetWorkflowEnabledArgs {
246 pub actor: User,
247 pub repo: RepoPath,
248 pub workflow: String,
249 pub enabled: bool,
250}
251
252/// Whose secrets or variables: a repository's, or with only `workspace`,
253/// a workspace's.
254#[derive(Clone, Debug, Serialize, Deserialize)]
255pub struct SettingsOwner {
256 #[serde(default)]
257 pub repo: Option<RepoPath>,
258 #[serde(default)]
259 pub workspace: Option<String>,
260}
261
262/// `settings`: the secrets (`kind: secret`) or variables (`kind: variable`)
263/// of a repository, with its workspace's, or of a workspace. Members only.
264/// Returns `Outcome<Vec<Setting>>`.
265#[derive(Debug, Serialize, Deserialize)]
266pub struct SettingsArgs {
267 pub actor: User,
268 #[serde(flatten)]
269 pub owner: SettingsOwner,
270 pub kind: String,
271}
272
273/// `set_setting`: add or replace one. A repository's need a member; a
274/// workspace's an owner. Returns `Outcome<Setting>`.
275#[derive(Debug, Serialize, Deserialize)]
276pub struct SetSettingArgs {
277 pub actor: User,
278 #[serde(flatten)]
279 pub owner: SettingsOwner,
280 pub kind: String,
281 pub name: String,
282 pub value: String,
283}
284
285/// `delete_setting`. Returns `Outcome<bool>`.
286#[derive(Debug, Serialize, Deserialize)]
287pub struct DeleteSettingArgs {
288 pub actor: User,
289 #[serde(flatten)]
290 pub owner: SettingsOwner,
291 pub kind: String,
292 pub name: String,
293}
294
295/// `job_spec` and `job_report`: the sandbox running a job, with the job's
296/// own token. `report` is one of:
297/// `{"kind": "step", "number", "status", "conclusion"}`,
298/// `{"kind": "log", "step", "text"}`,
299/// `{"kind": "annotation", "level", "message", "title", "file", "line"}`,
300/// `{"kind": "done", "conclusion", "outputs", "reason"}`.
301#[derive(Debug, Serialize, Deserialize)]
302pub struct JobCallArgs {
303 pub job: String,
304 pub token: String,
305 #[serde(default)]
306 pub report: Value,
307}
308
309/// What the runner needs to start a job's sandbox.
310#[derive(Debug, Serialize, Deserialize)]
311#[serde(rename_all = "camelCase")]
312pub struct StartJobArgs {
313 pub job: String,
314 pub token: String,
315 pub repo: RepoPath,
316 /// Minutes before the job is stopped.
317 pub timeout_minutes: u32,
318}