g1t/crates/contracts/src/work.rs

1,241 lines40,621 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.

Issues and pull requests replace intents and attempts1//! The work service: issues, pull requests, comments and sessions.
Work service in Rust, with RFC 3339 timestamps2//!
3//! Each `*Args` struct is the argument of the method of the same name,
4//! served at `POST /rpc/<method>`.
Issues and pull requests replace intents and attempts5//!
6//! Issues and pull requests share one sequence of numbers per repository,
7//! so `#12` names exactly one of them.
Work service in Rust, with RFC 3339 timestamps8
9use serde::{Deserialize, Serialize};
10
Agents as a team: lifecycle, merge queue, billing and a new shell11use crate::repos::{CompareArgs, RepoPath};
Work service in Rust, with RFC 3339 timestamps12use crate::{User, Viewer};
13
Issues and pull requests replace intents and attempts14/// Labels every repository starts with. Any other label comes into being
15/// the first time it is put on an issue.
16pub const DEFAULT_LABELS: [&str; 5] = ["bug", "feature", "docs", "chore", "question"];
17
18/// `open` or `closed`: the filter on lists of issues and pull requests. An
19/// open pull request is a draft or one ready for review; a closed one was
20/// merged or closed without merging.
Work service in Rust, with RFC 3339 timestamps21#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
22#[serde(rename_all = "lowercase")]
Issues and pull requests replace intents and attempts23pub enum State {
Work service in Rust, with RFC 3339 timestamps24 Open,
Issues and pull requests replace intents and attempts25 Closed,
26}
27
28/// Why an issue was closed.
29#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
30#[serde(rename_all = "snake_case")]
31pub enum IssueReason {
32 /// The work was done. If a pull request did it, `resolved_by` names it.
33 Completed,
34 NotPlanned,
Work service in Rust, with RFC 3339 timestamps35}
36
Issues and pull requests replace intents and attempts37impl IssueReason {
38 pub fn as_str(self) -> &'static str {
39 match self {
40 IssueReason::Completed => "completed",
41 IssueReason::NotPlanned => "not_planned",
42 }
43 }
44}
45
46/// Something that should change in a repository: a bug, a feature, a
47/// question. Opened by a person, an agent or an integration. Pull requests
48/// are made against it; the one that is merged resolves it.
Work service in Rust, with RFC 3339 timestamps49#[derive(Clone, Debug, Serialize, Deserialize)]
50#[serde(rename_all = "camelCase")]
Issues and pull requests replace intents and attempts51pub struct Issue {
Work service in Rust, with RFC 3339 timestamps52 pub id: String,
53 pub repo_id: String,
Issues and pull requests replace intents and attempts54 /// Shown as `#12`.
Work service in Rust, with RFC 3339 timestamps55 pub number: u32,
56 pub title: String,
Issues and pull requests replace intents and attempts57 /// Markdown. Also what an agent is given to work from.
58 pub body: String,
59 pub labels: Vec<String>,
60 /// Commands that must pass for a pull request to be accepted.
Work service in Rust, with RFC 3339 timestamps61 pub checks: Vec<String>,
Issues and pull requests replace intents and attempts62 pub state: State,
63 /// Set when closed.
64 pub reason: Option<IssueReason>,
65 /// The number of the pull request whose merge closed this issue.
66 pub resolved_by: Option<u32>,
Work service in Rust, with RFC 3339 timestamps67 pub author: User,
68 /// RFC 3339.
69 pub created_at: String,
Issues and pull requests replace intents and attempts70 /// RFC 3339.
71 pub updated_at: String,
72 /// RFC 3339.
73 pub closed_at: Option<String>,
74 /// Pull requests made against this issue, in any state.
75 pub pull_count: u32,
76 pub comment_count: u32,
Agents as a team: lifecycle, merge queue, billing and a new shell77 /// Usernames of the people it is assigned to.
78 #[serde(default)]
79 pub assignees: Vec<String>,
80 /// The numbers of the issues that have to be merged before this one is
81 /// worked on.
82 #[serde(default)]
83 pub blocked_by: Vec<u32>,
84 /// Whether a g1t agent takes it as soon as it can: at once, or when
85 /// what it is blocked by has merged.
86 #[serde(default)]
87 pub queued: bool,
88 /// The agent working on it now: the one behind its newest pull request
89 /// that is still in progress in a fork, such as `g1t-agent`.
90 #[serde(default)]
91 pub agent: Option<String>,
Work service in Rust, with RFC 3339 timestamps92}
93
94#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
95#[serde(rename_all = "lowercase")]
Issues and pull requests replace intents and attempts96pub enum PullStatus {
97 /// Still being worked on.
98 Draft,
99 /// Ready for review.
100 Open,
101 Merged,
102 /// Closed without merging.
103 Closed,
Work service in Rust, with RFC 3339 timestamps104}
105
Issues and pull requests replace intents and attempts106impl PullStatus {
Work service in Rust, with RFC 3339 timestamps107 pub fn as_str(self) -> &'static str {
108 match self {
Issues and pull requests replace intents and attempts109 PullStatus::Draft => "draft",
110 PullStatus::Open => "open",
111 PullStatus::Merged => "merged",
112 PullStatus::Closed => "closed",
Work service in Rust, with RFC 3339 timestamps113 }
114 }
115
Issues and pull requests replace intents and attempts116 /// Whether the pull request can still be changed or merged.
Work service in Rust, with RFC 3339 timestamps117 pub fn is_active(self) -> bool {
Issues and pull requests replace intents and attempts118 matches!(self, PullStatus::Draft | PullStatus::Open)
Work service in Rust, with RFC 3339 timestamps119 }
120}
121
122/// Where the agent runs: on g1t's sandboxes, or in someone's own session.
123#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
124#[serde(rename_all = "lowercase")]
Issues and pull requests replace intents and attempts125pub enum Runtime {
Work service in Rust, with RFC 3339 timestamps126 Hosted,
127 External,
128}
129
Pull requests from branches130/// A proposed change. It is made either in a fork created for it, which is
131/// how agents work, or on a branch pushed to the repository itself.
Work service in Rust, with RFC 3339 timestamps132#[derive(Clone, Debug, Serialize, Deserialize)]
133#[serde(rename_all = "camelCase")]
Issues and pull requests replace intents and attempts134pub struct Pull {
Work service in Rust, with RFC 3339 timestamps135 pub id: String,
136 pub repo_id: String,
Issues and pull requests replace intents and attempts137 /// Shown as `#12`.
Work service in Rust, with RFC 3339 timestamps138 pub number: u32,
Issues and pull requests replace intents and attempts139 /// The number of the issue this is for, if any.
140 pub issue: Option<u32>,
141 pub title: String,
142 /// Markdown: what changed and why. Set when marked ready.
143 pub body: Option<String>,
Work service in Rust, with RFC 3339 timestamps144 /// A label for the agent doing the work, e.g. `claude-code`.
145 pub agent: String,
Issues and pull requests replace intents and attempts146 pub runtime: Runtime,
147 pub status: PullStatus,
Pull requests from branches148 /// The fork holding the change, unless it is on a branch.
149 pub fork: Option<RepoPath>,
Work service in Rust, with RFC 3339 timestamps150 /// The fork's repository id.
Pull requests from branches151 pub fork_repo_id: Option<String>,
152 /// The branch of the repository holding the change, unless it is in a
153 /// fork.
154 pub branch: Option<String>,
Work service in Rust, with RFC 3339 timestamps155 pub head_commit: Option<String>,
Issues and pull requests replace intents and attempts156 /// For a merged pull request, what the branch pointed to before the
157 /// merge. Comparing against it shows what the pull request changed.
158 pub merge_base: Option<String>,
159 /// Username of whoever merged it.
160 pub merged_by: Option<String>,
161 /// RFC 3339.
162 pub merged_at: Option<String>,
163 /// Set on a pull request closed because another one for the same issue
164 /// was merged: that one's number.
165 pub superseded_by: Option<u32>,
Acceptance checks in sandboxes, line comments and review verdicts166 /// Where the latest run of the issue's acceptance checks stands, if
167 /// there has been one against the current head.
168 pub check_status: Option<CheckStatus>,
Agents as a team: lifecycle, merge queue, billing and a new shell169 /// The files it changes, as of its latest push.
170 #[serde(default)]
171 pub files: Vec<ChangedFile>,
172 /// Usernames of the people it is assigned to.
173 #[serde(default)]
174 pub assignees: Vec<String>,
175 /// Those whose review was asked for: usernames, and `g1t-agent` when a
176 /// g1t agent was asked.
177 #[serde(default)]
178 pub reviewers: Vec<String>,
Issues and pull requests replace intents and attempts179 pub author: User,
Work service in Rust, with RFC 3339 timestamps180 /// RFC 3339.
181 pub created_at: String,
182 /// RFC 3339.
183 pub updated_at: String,
184}
185
Agents as a team: lifecycle, merge queue, billing and a new shell186/// One file a pull request changes, and by how much.
187#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
188pub struct ChangedFile {
189 pub path: String,
190 pub additions: u32,
191 pub deletions: u32,
192}
193
194/// Another pull request in progress that changes some of the same files.
195/// Two for the same issue are alternatives; two for different issues are
196/// heading for a conflict.
197#[derive(Clone, Debug, Serialize, Deserialize)]
198pub struct Overlap {
199 pub number: u32,
200 pub title: String,
201 /// The number of the issue the other pull request is for.
202 pub issue: Option<u32>,
203 /// The files both change.
204 pub paths: Vec<String>,
205}
206
207impl Pull {
208 /// What to ask the repos service to see what this pull request changes.
209 ///
210 /// A fork is compared as a whole. A branch is compared by name while
211 /// the pull request is open, and by the commit it was merged or closed
212 /// at afterwards, so later pushes to the branch do not change the record.
213 pub fn comparison(&self, viewer: &Viewer) -> CompareArgs {
214 let settled = matches!(self.status, PullStatus::Merged | PullStatus::Closed);
215 let (repo_id, head) = match &self.fork_repo_id {
216 Some(fork) => (fork.clone(), None),
217 None => (
218 self.repo_id.clone(),
219 self.head_commit
220 .clone()
221 .filter(|_| settled)
222 .or_else(|| self.branch.clone()),
223 ),
224 };
225 CompareArgs {
226 repo_id,
227 viewer: viewer.clone(),
228 base: self.merge_base.clone(),
229 head,
230 }
231 }
232}
233
Acceptance checks in sandboxes, line comments and review verdicts234#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
235#[serde(rename_all = "lowercase")]
236pub enum CheckStatus {
237 /// Waiting for a sandbox.
238 Queued,
239 Running,
240 Passed,
241 Failed,
242 /// The checks could not be run at all.
243 Errored,
244}
245
246impl CheckStatus {
247 pub fn as_str(self) -> &'static str {
248 match self {
249 CheckStatus::Queued => "queued",
250 CheckStatus::Running => "running",
251 CheckStatus::Passed => "passed",
252 CheckStatus::Failed => "failed",
253 CheckStatus::Errored => "errored",
254 }
255 }
256}
257
258/// How one acceptance check went.
259#[derive(Clone, Debug, Serialize, Deserialize)]
260#[serde(rename_all = "camelCase")]
261pub struct CheckResult {
262 pub command: String,
263 pub passed: bool,
264 /// Absent when the command was stopped for taking too long.
265 #[serde(default)]
266 pub exit_code: Option<i32>,
267 /// What the command printed, standard output and error together. The
268 /// end of it, when there was a lot.
269 #[serde(default)]
270 pub output: String,
271 #[serde(default)]
272 pub duration_ms: u64,
273}
274
275/// One run of an issue's acceptance checks against a pull request's head,
276/// in a sandbox that holds nothing but that commit.
277#[derive(Clone, Debug, Serialize, Deserialize)]
278#[serde(rename_all = "camelCase")]
279pub struct CheckRun {
280 pub id: String,
281 /// The commit that was checked.
282 pub head_commit: String,
283 pub status: CheckStatus,
284 pub results: Vec<CheckResult>,
285 /// Why the checks could not be run, when `status` is `errored`.
286 pub error: Option<String>,
287 /// RFC 3339.
288 pub created_at: String,
289 /// RFC 3339.
290 pub finished_at: Option<String>,
291}
292
293/// A reviewer's decision on a pull request.
294#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
295#[serde(rename_all = "snake_case")]
296pub enum Verdict {
297 Approve,
298 RequestChanges,
299}
300
301impl Verdict {
302 pub fn as_str(self) -> &'static str {
303 match self {
304 Verdict::Approve => "approve",
305 Verdict::RequestChanges => "request_changes",
306 }
307 }
308}
309
Agents as a team: lifecycle, merge queue, billing and a new shell310/// What an entry in a conversation is.
311#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
312#[serde(rename_all = "lowercase")]
313pub enum CommentKind {
314 /// Something a person or an agent wrote.
315 #[default]
316 Comment,
317 /// Something that happened: an assignment, a review asked for, a close.
318 Event,
319}
320
Acceptance checks in sandboxes, line comments and review verdicts321/// A comment on an issue or a pull request. On a pull request it can sit
322/// on one line of the change, and it can carry a reviewer's verdict.
Issues and pull requests replace intents and attempts323#[derive(Clone, Debug, Serialize, Deserialize)]
324#[serde(rename_all = "camelCase")]
325pub struct Comment {
326 pub id: String,
Agents as a team: lifecycle, merge queue, billing and a new shell327 /// Something a person wrote, or something that happened.
328 #[serde(default)]
329 pub kind: CommentKind,
Issues and pull requests replace intents and attempts330 pub author: User,
Agents as a team: lifecycle, merge queue, billing and a new shell331 /// Markdown. For an event, what its author did, as the rest of a
332 /// sentence that starts with their name: "assigned ana".
Issues and pull requests replace intents and attempts333 pub body: String,
Acceptance checks in sandboxes, line comments and review verdicts334 /// The file commented on, for a comment on a line.
335 pub path: Option<String>,
336 /// The line of that file, as numbered after the change.
337 pub line: Option<u32>,
338 pub verdict: Option<Verdict>,
Issues and pull requests replace intents and attempts339 /// RFC 3339.
340 pub created_at: String,
341}
342
Work service in Rust, with RFC 3339 timestamps343#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
344#[serde(rename_all = "snake_case")]
345pub enum SessionEntryKind {
346 Prompt,
347 Message,
348 ToolCall,
349 ToolResult,
350 Note,
351}
352
Issues and pull requests replace intents and attempts353/// One step of an agent's session: the "why" behind a pull request's commits.
Work service in Rust, with RFC 3339 timestamps354#[derive(Clone, Debug, Serialize, Deserialize)]
355pub struct SessionEntry {
356 pub seq: u32,
357 pub kind: SessionEntryKind,
358 pub text: String,
359 /// For tool calls and results.
360 pub tool: Option<String>,
361 /// The fork's head commit when this entry was recorded, if known.
362 pub commit: Option<String>,
363 /// RFC 3339.
364 pub at: String,
365}
366
367#[derive(Clone, Debug, Serialize, Deserialize)]
368pub struct NewSessionEntry {
369 pub kind: SessionEntryKind,
370 pub text: String,
371 #[serde(default)]
372 pub tool: Option<String>,
373 #[serde(default)]
374 pub commit: Option<String>,
375}
376
377#[derive(Clone, Debug, Serialize, Deserialize)]
Issues and pull requests replace intents and attempts378pub struct IssueDetail {
379 pub issue: Issue,
380 /// Every pull request made against it, oldest first.
381 pub pulls: Vec<Pull>,
382 pub comments: Vec<Comment>,
Work service in Rust, with RFC 3339 timestamps383}
384
385#[derive(Clone, Debug, Serialize, Deserialize)]
Issues and pull requests replace intents and attempts386pub struct PullDetail {
387 pub pull: Pull,
388 /// The issue it is for, if any.
389 pub issue: Option<Issue>,
390 pub comments: Vec<Comment>,
Acceptance checks in sandboxes, line comments and review verdicts391 /// The latest run of the issue's acceptance checks.
392 pub checks: Option<CheckRun>,
Agents as a team: lifecycle, merge queue, billing and a new shell393 /// Other pull requests in progress that change the same files.
394 #[serde(default)]
395 pub overlaps: Vec<Overlap>,
396 /// Whether the branch it would merge into has moved on without it, so
397 /// that it has to catch up before it can merge.
398 #[serde(default)]
399 pub behind: bool,
400 /// Whether a g1t agent is reviewing it right now.
401 #[serde(default)]
402 pub review_pending: bool,
403 /// Where it stands on its way to being merged, for a pull request g1t
404 /// is seeing through. Absent on anyone else's.
405 #[serde(default)]
406 pub lifecycle: Option<Lifecycle>,
407 /// A merge was asked for while it was behind: g1t is bringing it up to
408 /// date and will then land it.
409 #[serde(default)]
410 pub landing: bool,
411 /// Why g1t stopped working on it, if it did: a catch-up that could not
412 /// be completed, for example.
413 #[serde(default)]
414 pub stalled: Option<String>,
415}
416
417/// A step on the way from an assigned issue to a pull request that is ready
418/// to merge. g1t takes each one without being asked.
419#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
420#[serde(rename_all = "snake_case")]
421pub enum Stage {
422 /// The agent is making the change.
423 Working,
424 /// The issue's acceptance checks are running against it.
425 Checking,
426 /// A g1t agent is reviewing it.
427 Reviewing,
428 /// The agent is addressing failed checks or a review.
429 Revising,
430 /// The agent is merging in the branch it would land on, which moved.
431 CatchingUp,
432 /// In the repository's merge queue, being tested with what is ahead of
433 /// it before it lands.
434 Queued,
435 /// Checks passed, reviewed and approved, up to date. A person merges.
436 Ready,
437 /// g1t has stopped and a person has to decide what happens next.
438 NeedsYou,
439}
440
441/// Where a pull request made by a g1t agent stands. See [`Stage`].
442#[derive(Clone, Debug, Serialize, Deserialize)]
443pub struct Lifecycle {
444 pub stage: Stage,
445 /// One sentence saying what is happening, or why it stopped.
446 pub detail: String,
447 /// How many times the agent has been sent back to revise it.
448 pub revisions: u32,
449}
450
451/// `advance`: works out the next step for a pull request g1t is seeing
452/// through and, if there is one to take now, claims it, so that it is
453/// taken once however many times this is called. Called by the runner
454/// service, which carries the step out. Returns `Advance`.
455#[derive(Debug, Serialize, Deserialize)]
456#[serde(rename_all = "camelCase")]
457pub struct AdvanceArgs {
458 pub pull_id: String,
459}
460
461#[derive(Debug, Serialize, Deserialize)]
462#[serde(tag = "action", rename_all = "snake_case")]
463pub enum Advance {
464 /// Nothing to do now: a step is under way, or it is a person's turn.
465 None,
466 /// Have a g1t agent review it.
467 Review { job: LifecycleJob },
468 /// Send the agent back to address `job.feedback`.
469 Revise { job: LifecycleJob },
470 /// Merge in the branch it would land on.
471 CatchUp { job: LifecycleJob },
Work service in Rust, with RFC 3339 timestamps472}
473
Agents as a team: lifecycle, merge queue, billing and a new shell474/// What the runner needs to carry out a step of a pull request's lifecycle.
475#[derive(Debug, Serialize, Deserialize)]
476#[serde(rename_all = "camelCase")]
477pub struct LifecycleJob {
478 pub pull_id: String,
479 pub repo: RepoPath,
480 pub number: u32,
481 /// Who the pull request belongs to. Sandboxes act as them.
482 pub author: User,
483 /// The repository holding the change: its fork, or the repository
484 /// itself for one made on a branch.
485 pub source: RepoPath,
486 /// The branch of the source holding the change; its default branch
487 /// when absent.
488 #[serde(default)]
489 pub branch: Option<String>,
490 pub default_branch: String,
491 pub title: String,
492 pub description: String,
493 pub issue: Option<Issue>,
494 /// For a revision: the failed checks or the review to address.
495 pub feedback: String,
496 /// For a revision: which one this is, from 1.
497 pub round: u32,
498}
499
500/// How a repository wants its pull requests handled. A repository that has
501/// changed nothing has the defaults.
502#[derive(Clone, Debug, Serialize, Deserialize)]
503#[serde(rename_all = "camelCase", default)]
504pub struct RepoSettings {
505 /// Land a g1t agent's pull request without a person once it is ready:
506 /// checks passed and approved as the settings below require.
507 pub auto_merge: bool,
508 /// Refuse to merge a pull request that does not contain the default
509 /// branch's latest commits, so that what merges is what was checked.
510 /// When off, merging one that is behind brings it up to date first.
511 pub require_up_to_date: bool,
512 /// How many approving reviews a pull request needs before it may
513 /// merge. A reviewer who has since asked for changes blocks it.
514 pub required_approvals: u32,
515 /// Whether a g1t agent's approval counts towards `required_approvals`.
516 pub count_agent_approvals: bool,
517 /// Whether a member may merge although the acceptance checks did not
518 /// pass.
519 pub allow_ignoring_checks: bool,
520 /// Whether a g1t agent's pull request is reviewed by a second agent
521 /// without being asked.
522 pub agent_review: bool,
523 /// How many times a g1t agent is sent back to its pull request before
524 /// a person is asked instead.
525 pub max_revisions: u32,
526 /// Merge through a queue: pull requests are tested together with those
527 /// ahead of them, and only a combination that passed reaches the default
528 /// branch.
529 pub merge_queue: bool,
530 /// Username of the member who last changed the settings, if anyone has.
531 pub updated_by: Option<String>,
532 /// RFC 3339.
533 pub updated_at: Option<String>,
534}
535
536impl Default for RepoSettings {
537 fn default() -> Self {
538 RepoSettings {
539 auto_merge: false,
540 require_up_to_date: false,
541 required_approvals: 0,
542 count_agent_approvals: true,
543 allow_ignoring_checks: true,
544 agent_review: true,
545 max_revisions: 2,
546 merge_queue: false,
547 updated_by: None,
548 updated_at: None,
549 }
550 }
551}
552
553/// `update_settings`: replaces a repository's settings. Members of its
554/// workspace only. Returns `Outcome<RepoSettings>`. `get_settings` takes
555/// `ViewArgs` and returns the same.
556#[derive(Debug, Serialize, Deserialize)]
557pub struct UpdateSettingsArgs {
558 pub actor: User,
559 pub repo: RepoPath,
560 /// Who changed them and when are filled in by the service.
561 pub settings: RepoSettings,
562}
563
564/// `catch_up_job`: what the runner needs to bring a pull request up to date
565/// because a merge of it was asked for. Null if none was. Returns
566/// `Option<LifecycleJob>`.
567#[derive(Debug, Serialize, Deserialize)]
568#[serde(rename_all = "camelCase")]
569pub struct CatchUpJobArgs {
570 pub pull_id: String,
571}
572
573/// `stall`: records that a step could not be carried out, so that g1t
574/// stops and a person is asked. Returns `bool`.
575#[derive(Debug, Serialize, Deserialize)]
576#[serde(rename_all = "camelCase")]
577pub struct StallArgs {
578 pub pull_id: String,
579 pub reason: String,
580}
581
582/// `managed_pulls`: ids of the open pull requests g1t is seeing through,
583/// in one repository or in all of them. Returns `Vec<String>`.
584#[derive(Debug, Default, Serialize, Deserialize)]
585#[serde(rename_all = "camelCase")]
586pub struct ManagedPullsArgs {
587 #[serde(default)]
588 pub repo_id: Option<String>,
589}
590
Issues and pull requests replace intents and attempts591/// `open_issue`. Returns `Outcome<Issue>`.
Work service in Rust, with RFC 3339 timestamps592#[derive(Debug, Serialize, Deserialize)]
Issues and pull requests replace intents and attempts593pub struct OpenIssueArgs {
Work service in Rust, with RFC 3339 timestamps594 pub actor: User,
595 pub repo: RepoPath,
596 pub title: String,
597 #[serde(default)]
Issues and pull requests replace intents and attempts598 pub body: String,
599 #[serde(default)]
600 pub labels: Vec<String>,
Work service in Rust, with RFC 3339 timestamps601 #[serde(default)]
602 pub checks: Vec<String>,
603}
604
Issues and pull requests replace intents and attempts605/// `list_issues`, newest first. Returns `Outcome<Vec<Issue>>`.
Work service in Rust, with RFC 3339 timestamps606#[derive(Debug, Serialize, Deserialize)]
Issues and pull requests replace intents and attempts607pub struct ListIssuesArgs {
Work service in Rust, with RFC 3339 timestamps608 pub repo: RepoPath,
609 pub viewer: Viewer,
610 #[serde(default)]
Issues and pull requests replace intents and attempts611 pub state: Option<State>,
612 /// Only issues carrying this label.
613 #[serde(default)]
614 pub label: Option<String>,
Work service in Rust, with RFC 3339 timestamps615}
616
Issues and pull requests replace intents and attempts617/// `list_pulls`, newest first. Returns `Outcome<Vec<Pull>>`.
Work service in Rust, with RFC 3339 timestamps618#[derive(Debug, Serialize, Deserialize)]
Issues and pull requests replace intents and attempts619pub struct ListPullsArgs {
620 pub repo: RepoPath,
621 pub viewer: Viewer,
622 #[serde(default)]
623 pub state: Option<State>,
624}
625
626/// `get_issue` (`Outcome<IssueDetail>`), `get_pull` (`Outcome<PullDetail>`),
627/// `read_session` (`Outcome<Vec<SessionEntry>>`), `list_labels`
628/// (`Outcome<Vec<String>>`) and `counts` (`Outcome<Counts>`). The last two
629/// ignore `number`.
630#[derive(Debug, Serialize, Deserialize)]
631#[serde(rename_all = "camelCase")]
632pub struct ViewArgs {
Work service in Rust, with RFC 3339 timestamps633 pub repo: RepoPath,
Issues and pull requests replace intents and attempts634 #[serde(default)]
Work service in Rust, with RFC 3339 timestamps635 pub number: u32,
636 pub viewer: Viewer,
Issues and pull requests replace intents and attempts637 /// For `read_session`: only entries after this sequence number.
638 #[serde(default)]
639 pub after_seq: u32,
640}
641
642/// How many issues and pull requests are open on a repository.
643#[derive(Debug, Serialize, Deserialize)]
644pub struct Counts {
645 pub issues: u32,
646 pub pulls: u32,
647}
648
649/// `update_issue`: changes whichever fields are given. The author or a
650/// member of the workspace may. Returns `Outcome<Issue>`.
651#[derive(Debug, Serialize, Deserialize)]
652pub struct UpdateIssueArgs {
653 pub actor: User,
654 pub repo: RepoPath,
655 pub number: u32,
656 #[serde(default)]
657 pub title: Option<String>,
658 #[serde(default)]
659 pub body: Option<String>,
660 #[serde(default)]
661 pub labels: Option<Vec<String>>,
Agents as a team: lifecycle, merge queue, billing and a new shell662 /// Usernames of the people it is assigned to; replaces the whole set.
663 /// Assigning it to the g1t agent is the runner's `run`, not this.
664 #[serde(default)]
665 pub assignees: Option<Vec<String>>,
Work service in Rust, with RFC 3339 timestamps666}
667
Issues and pull requests replace intents and attempts668/// `close_issue` and `reopen_issue`. Each returns `Outcome<Issue>`.
Work service in Rust, with RFC 3339 timestamps669#[derive(Debug, Serialize, Deserialize)]
Issues and pull requests replace intents and attempts670pub struct IssueActionArgs {
Work service in Rust, with RFC 3339 timestamps671 pub actor: User,
Issues and pull requests replace intents and attempts672 pub repo: RepoPath,
673 pub number: u32,
674 /// For `close_issue`; `completed` if left out.
675 #[serde(default)]
676 pub reason: Option<IssueReason>,
Work service in Rust, with RFC 3339 timestamps677}
678
Acceptance checks in sandboxes, line comments and review verdicts679/// `add_comment`, on an issue or a pull request. On a pull request it may
680/// name a line of the change, and may carry a verdict; nobody can give a
681/// verdict on their own pull request. Returns `Outcome<Comment>`.
Work service in Rust, with RFC 3339 timestamps682#[derive(Debug, Serialize, Deserialize)]
Issues and pull requests replace intents and attempts683pub struct AddCommentArgs {
Work service in Rust, with RFC 3339 timestamps684 pub actor: User,
Issues and pull requests replace intents and attempts685 pub repo: RepoPath,
686 pub number: u32,
Acceptance checks in sandboxes, line comments and review verdicts687 /// May be empty when approving.
688 #[serde(default)]
Issues and pull requests replace intents and attempts689 pub body: String,
Acceptance checks in sandboxes, line comments and review verdicts690 #[serde(default)]
691 pub path: Option<String>,
692 #[serde(default)]
693 pub line: Option<u32>,
694 #[serde(default)]
695 pub verdict: Option<Verdict>,
Work service in Rust, with RFC 3339 timestamps696}
697
Pull requests from branches698/// `open_pull`. Without `branch`, forks the repo and returns a draft pull
699/// request to push to. With it, opens a pull request, ready for review,
700/// for a branch already pushed to the repo. Returns `Outcome<Pull>`.
Work service in Rust, with RFC 3339 timestamps701#[derive(Debug, Serialize, Deserialize)]
Issues and pull requests replace intents and attempts702pub struct OpenPullArgs {
703 pub actor: User,
704 pub repo: RepoPath,
705 /// The issue this is for.
Work service in Rust, with RFC 3339 timestamps706 #[serde(default)]
Issues and pull requests replace intents and attempts707 pub issue: Option<u32>,
708 /// Defaults to the issue's title; required without an issue.
709 #[serde(default)]
710 pub title: String,
Pull requests from branches711 /// What changed and why. Usually set later, when a draft is marked ready.
712 #[serde(default)]
713 pub body: String,
714 /// A branch of the repository that already holds the change.
715 #[serde(default)]
716 pub branch: Option<String>,
Issues and pull requests replace intents and attempts717 #[serde(default)]
718 pub agent: String,
719 pub runtime: Runtime,
Work service in Rust, with RFC 3339 timestamps720}
721
Issues and pull requests replace intents and attempts722/// `ready_pull`, `close_pull` and `merge_pull`. Each returns `Outcome<Pull>`.
Work service in Rust, with RFC 3339 timestamps723#[derive(Debug, Serialize, Deserialize)]
724#[serde(rename_all = "camelCase")]
Issues and pull requests replace intents and attempts725pub struct PullActionArgs {
Work service in Rust, with RFC 3339 timestamps726 pub actor: User,
Issues and pull requests replace intents and attempts727 pub repo: RepoPath,
728 pub number: u32,
729 /// For `ready_pull`: what changed and why.
Work service in Rust, with RFC 3339 timestamps730 #[serde(default)]
731 pub summary: String,
Issues and pull requests replace intents and attempts732 /// For `merge_pull`: leave the issue open and the other pull requests
733 /// for it untouched, because this one is only part of the work.
734 #[serde(default)]
735 pub keep_issue_open: bool,
Acceptance checks in sandboxes, line comments and review verdicts736 /// For `merge_pull`: merge although the acceptance checks have not
737 /// passed.
738 #[serde(default)]
739 pub ignore_checks: bool,
740}
741
Agents as a team: lifecycle, merge queue, billing and a new shell742/// Where a plan stands.
743#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
744#[serde(rename_all = "lowercase")]
745pub enum PlanStatus {
746 /// An agent is reading the repository and writing it.
747 Planning,
748 /// Written, and waiting for a person to read and apply it.
749 Ready,
750 /// It could not be written.
751 Failed,
752 /// Its issues have been opened.
753 Applied,
754}
755
756/// One issue a plan proposes.
757#[derive(Clone, Debug, Default, Serialize, Deserialize)]
758#[serde(rename_all = "camelCase", default)]
759pub struct PlannedIssue {
760 pub title: String,
761 /// Markdown: what to change, where, and why.
762 pub body: String,
763 pub labels: Vec<String>,
764 /// Commands that must pass once the change is made.
765 pub checks: Vec<String>,
766 /// The files it will most likely change.
767 pub files: Vec<String>,
768 /// The positions, counting from 1, of earlier issues in the plan that
769 /// have to be merged first. An agent writes this as `depends_on`.
770 #[serde(alias = "depends_on")]
771 pub depends_on: Vec<u32>,
772 /// Its number, once the plan has been applied and it was kept.
773 pub number: Option<u32>,
774}
775
776/// An outcome someone wrote, and the issues an agent proposes to get there.
777#[derive(Clone, Debug, Serialize, Deserialize)]
778#[serde(rename_all = "camelCase")]
779pub struct Plan {
780 pub id: String,
781 pub repo_id: String,
782 /// The outcome wanted, as written.
783 pub brief: String,
784 pub status: PlanStatus,
785 /// The agent's account of how it split the work.
786 pub summary: String,
787 pub issues: Vec<PlannedIssue>,
788 /// Why it could not be written, when `status` is `failed`.
789 pub error: Option<String>,
790 pub author: User,
791 /// RFC 3339.
792 pub created_at: String,
793 /// RFC 3339.
794 pub finished_at: Option<String>,
795}
796
797/// `start_plan`: records an outcome to plan for. Members of the
798/// repository's workspace only. Called by the runner service, which starts
799/// the sandbox. Returns `Outcome<PlanJob>`.
800#[derive(Debug, Serialize, Deserialize)]
801pub struct StartPlanArgs {
802 pub actor: User,
803 pub repo: RepoPath,
804 pub brief: String,
805}
806
807/// What a sandbox needs to write a plan.
808#[derive(Debug, Serialize, Deserialize)]
809#[serde(rename_all = "camelCase")]
810pub struct PlanJob {
811 pub plan_id: String,
812 /// Lets the sandbox, and nothing else, report this plan.
813 pub token: String,
814 pub brief: String,
815 pub repo: RepoPath,
816}
817
818/// `report_plan`: the plan a sandbox's agent wrote, or why it could not
819/// write one. Returns `Outcome<bool>`.
820#[derive(Debug, Serialize, Deserialize)]
821#[serde(rename_all = "camelCase")]
822pub struct ReportPlanArgs {
823 pub plan_id: String,
824 pub token: String,
825 #[serde(default)]
826 pub summary: String,
827 #[serde(default)]
828 pub issues: Vec<PlannedIssue>,
829 #[serde(default)]
830 pub error: Option<String>,
831}
832
833/// `get_plan`. Members only. Returns `Outcome<Plan>`. `list_plans` takes
834/// `ViewArgs` and returns `Outcome<Vec<Plan>>`, newest first.
835#[derive(Debug, Serialize, Deserialize)]
836pub struct PlanArgs {
837 pub repo: RepoPath,
838 pub viewer: Viewer,
839 pub id: String,
840}
841
842/// `apply_plan`: opens a plan's issues, each blocked by the ones it depends
843/// on. Members only, and once. Returns `Outcome<Plan>`, its issues now
844/// carrying their numbers.
845#[derive(Debug, Serialize, Deserialize)]
846pub struct ApplyPlanArgs {
847 pub actor: User,
848 pub repo: RepoPath,
849 pub id: String,
850 /// Queue every issue for a g1t agent.
851 #[serde(default)]
852 pub assign: bool,
853 /// The positions, counting from 1, of the issues to open. All of them
854 /// when absent.
855 #[serde(default)]
856 pub keep: Option<Vec<u32>>,
857}
858
859/// `queue_issue`: asks for a g1t agent to take an issue as soon as it can,
860/// or withdraws that. The author or a member may. Returns `Outcome<bool>`.
861#[derive(Debug, Serialize, Deserialize)]
862pub struct QueueIssueArgs {
863 pub actor: User,
864 pub repo: RepoPath,
865 pub number: u32,
866 pub queued: bool,
867}
868
869/// `ready_issues`: issues waiting for a g1t agent that can be given one
870/// now, in one repository or in all. Called by the runner service. Returns
871/// `Vec<ReadyIssue>`.
872#[derive(Debug, Default, Serialize, Deserialize)]
873#[serde(rename_all = "camelCase")]
874pub struct ReadyIssuesArgs {
875 #[serde(default)]
876 pub repo_id: Option<String>,
877}
878
879#[derive(Debug, Serialize, Deserialize)]
880pub struct ReadyIssue {
881 pub repo: RepoPath,
882 pub number: u32,
883 /// Who queued it, on whose say-so the agent works.
884 pub actor: User,
885}
886
887/// `update_pull`: changes who a pull request is assigned to and whose
888/// review is asked for. Each list given replaces the whole set. Whoever
889/// opened it, or a member of the workspace, may. Returns `Outcome<Pull>`.
890#[derive(Debug, Serialize, Deserialize)]
891pub struct UpdatePullArgs {
892 pub actor: User,
893 pub repo: RepoPath,
894 pub number: u32,
895 #[serde(default)]
896 pub assignees: Option<Vec<String>>,
897 /// May include `g1t-agent`. Asking for its review does not by itself
898 /// start one; the runner's `review` does.
899 #[serde(default)]
900 pub reviewers: Option<Vec<String>>,
901}
902
Acceptance checks in sandboxes, line comments and review verdicts903/// `start_checks`: begins a run of the acceptance checks for a pull request
904/// that is ready for review. Called by the runner service, which starts the
905/// sandbox. Returns `Outcome<CheckJob>`.
906#[derive(Debug, Serialize, Deserialize)]
907#[serde(rename_all = "camelCase")]
908pub struct StartChecksArgs {
909 pub pull_id: String,
910}
911
912/// What a sandbox needs to carry out a check run.
913#[derive(Debug, Serialize, Deserialize)]
914#[serde(rename_all = "camelCase")]
915pub struct CheckJob {
916 pub run_id: String,
917 /// Lets the sandbox, and nothing else, report this run's results.
918 pub token: String,
919 pub commands: Vec<String>,
920 /// The repository holding the commit: the fork, or the repository itself.
921 pub source: RepoPath,
922 pub commit: String,
923 /// Who opened the pull request, and so can read its source.
924 pub author: User,
925 /// Username of whoever wrote the checks: the issue's author.
926 pub requested_by: String,
927 pub repo: RepoPath,
928 pub number: u32,
929}
930
931/// `report_checks`: what a sandbox says about its run. With no results and
932/// no error it has started. `skip` forgets the run, for one that will not
933/// be carried out. Returns `Outcome<CheckRun>`.
934#[derive(Debug, Serialize, Deserialize)]
935#[serde(rename_all = "camelCase")]
936pub struct ReportChecksArgs {
937 pub run_id: String,
938 pub token: String,
939 #[serde(default)]
940 pub results: Vec<CheckResult>,
941 #[serde(default)]
942 pub error: Option<String>,
943 #[serde(default)]
944 pub skip: bool,
Work service in Rust, with RFC 3339 timestamps945}
946
Issues and pull requests replace intents and attempts947/// A pull request in progress, with where it lives.
948#[derive(Debug, Serialize, Deserialize)]
949pub struct ActivePull {
950 pub pull: Pull,
951 pub issue: Option<Issue>,
Agents as a team: lifecycle, merge queue, billing and a new shell952 /// Where it stands, for one g1t is seeing through.
953 #[serde(default)]
954 pub lifecycle: Option<Lifecycle>,
Issues and pull requests replace intents and attempts955}
956
957/// `list_active_pulls`: drafts and open pull requests the viewer started,
Agents as a team: lifecycle, merge queue, billing and a new shell958/// most recently active first. Returns `Vec<ActivePull>`. Also
959/// `list_assigned_issues`: open issues assigned to the viewer, most
960/// recently changed first. Returns `Vec<Issue>`.
Work service in Rust, with RFC 3339 timestamps961#[derive(Debug, Serialize, Deserialize)]
962pub struct ViewerArgs {
963 pub viewer: Viewer,
964}
965
966/// `append_session`. Returns `Outcome<Appended>`.
967#[derive(Debug, Serialize, Deserialize)]
968pub struct AppendSessionArgs {
969 pub actor: User,
Issues and pull requests replace intents and attempts970 pub repo: RepoPath,
971 pub number: u32,
Work service in Rust, with RFC 3339 timestamps972 pub entries: Vec<NewSessionEntry>,
973}
974
975#[derive(Debug, Serialize, Deserialize)]
976pub struct Appended {
977 pub count: u32,
978}
Issues and pull requests replace intents and attempts979
Agents as a team: lifecycle, merge queue, billing and a new shell980/// `start_review`: begins a review of a pull request by a g1t agent. Called
981/// by the runner service, which starts the sandbox. Returns
982/// `Outcome<ReviewJob>`.
983#[derive(Debug, Serialize, Deserialize)]
984#[serde(rename_all = "camelCase")]
985pub struct StartReviewArgs {
986 pub pull_id: String,
987}
988
989/// What a sandbox needs to review a pull request.
990#[derive(Debug, Serialize, Deserialize)]
991#[serde(rename_all = "camelCase")]
992pub struct ReviewJob {
993 pub run_id: String,
994 /// Lets the sandbox, and nothing else, report this review.
995 pub token: String,
996 /// The repository holding the commit: the fork, or the repository itself.
997 pub source: RepoPath,
998 pub commit: String,
999 pub repo: RepoPath,
1000 pub default_branch: String,
1001 pub number: u32,
1002 pub title: String,
1003 pub description: String,
1004 /// The issue the pull request is for, which says what it should achieve.
1005 pub issue: Option<Issue>,
1006 /// Who opened the pull request, and so can read its source.
1007 pub author: User,
1008}
1009
1010/// A comment on one line, as a reviewing agent reports it.
1011#[derive(Debug, Serialize, Deserialize)]
1012pub struct ReviewComment {
1013 pub path: String,
1014 #[serde(default)]
1015 pub line: u32,
1016 pub body: String,
1017}
1018
1019/// `report_review`: the review a sandbox's agent wrote, or why it could not
1020/// write one. Returns `Outcome<bool>`.
1021#[derive(Debug, Serialize, Deserialize)]
1022#[serde(rename_all = "camelCase")]
1023pub struct ReportReviewArgs {
1024 pub run_id: String,
1025 pub token: String,
1026 #[serde(default)]
1027 pub verdict: Option<Verdict>,
1028 #[serde(default)]
1029 pub body: String,
1030 #[serde(default)]
1031 pub comments: Vec<ReviewComment>,
1032 /// The model that wrote it, by its public name.
1033 #[serde(default)]
1034 pub model: Option<String>,
1035 #[serde(default)]
1036 pub error: Option<String>,
1037}
1038
Issues and pull requests replace intents and attempts1039/// Lowercases, trims and de-duplicates labels, dropping empty ones.
1040/// Returns `None` if there are too many or one is too long.
1041pub fn normalize_labels(labels: &[String]) -> Option<Vec<String>> {
1042 const MAX_LABELS: usize = 10;
1043 const MAX_LABEL_CHARS: usize = 40;
1044 let mut normalized: Vec<String> = Vec::new();
1045 for label in labels {
1046 let label = label
1047 .split_whitespace()
1048 .collect::<Vec<_>>()
1049 .join(" ")
1050 .to_lowercase();
1051 if label.is_empty() || normalized.contains(&label) {
1052 continue;
1053 }
1054 if label.chars().count() > MAX_LABEL_CHARS {
1055 return None;
1056 }
1057 normalized.push(label);
1058 }
1059 (normalized.len() <= MAX_LABELS).then_some(normalized)
1060}
1061
1062#[cfg(test)]
1063mod tests {
1064 use super::normalize_labels;
1065
1066 fn labels(names: &[&str]) -> Vec<String> {
1067 names.iter().map(|name| (*name).to_owned()).collect()
1068 }
1069
1070 #[test]
1071 fn labels_are_lowercased_trimmed_and_unique() {
1072 assert_eq!(
1073 normalize_labels(&labels(&[" Bug ", "bug", "", "Good First Issue"])),
1074 Some(labels(&["bug", "good first issue"]))
1075 );
1076 }
1077
1078 #[test]
1079 fn too_long_or_too_many_labels_are_refused() {
1080 assert_eq!(normalize_labels(&["x".repeat(41)]), None);
1081 let many: Vec<String> = (0..11).map(|i| format!("label-{i}")).collect();
1082 assert_eq!(normalize_labels(&many), None);
1083 }
1084}
Agents as a team: lifecycle, merge queue, billing and a new shell1085
1086
1087// --- Merge queue ----------------------------------------------------------
1088
1089/// Where a pull request in a merge queue stands.
1090#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
1091#[serde(rename_all = "snake_case")]
1092pub enum QueueState {
1093 /// Waiting for its turn to be tested.
1094 Waiting,
1095 /// Its combined state is being built and checked.
1096 Testing,
1097 /// Its combined state passed; it lands once everything ahead has.
1098 Passed,
1099 /// Its combined state failed, or would not merge. It left the queue.
1100 Failed,
1101 /// On the default branch.
1102 Landed,
1103 /// Taken out of the queue by a person, or closed.
1104 Removed,
1105}
1106
1107impl QueueState {
1108 pub fn as_str(self) -> &'static str {
1109 match self {
1110 QueueState::Waiting => "waiting",
1111 QueueState::Testing => "testing",
1112 QueueState::Passed => "passed",
1113 QueueState::Failed => "failed",
1114 QueueState::Landed => "landed",
1115 QueueState::Removed => "removed",
1116 }
1117 }
1118
1119 /// Still in the queue.
1120 pub fn is_active(self) -> bool {
1121 matches!(
1122 self,
1123 QueueState::Waiting | QueueState::Testing | QueueState::Passed
1124 )
1125 }
1126}
1127
1128/// One pull request's place in a merge queue.
1129#[derive(Clone, Debug, Serialize, Deserialize)]
1130#[serde(rename_all = "camelCase")]
1131pub struct QueueEntry {
1132 pub id: String,
1133 pub number: u32,
1134 pub title: String,
1135 /// Who or what made the pull request, e.g. `g1t-agent`.
1136 pub agent: String,
1137 pub state: QueueState,
1138 /// The pull requests merged ahead of it in the state being tested, in
1139 /// queue order. Empty when it was tested on the default branch alone.
1140 pub ahead: Vec<u32>,
1141 /// The default branch's commit the tested state was built on.
1142 pub base_commit: Option<String>,
1143 /// The tested state: the default branch with everything ahead and this.
1144 pub combined_commit: Option<String>,
1145 /// Why it failed: a merge conflict or what could not be run.
1146 pub error: Option<String>,
1147 /// The checks run against the tested state.
1148 pub results: Vec<CheckResult>,
1149 /// Username of whoever merged it into the queue: a person, or `g1t`.
1150 pub enqueued_by: String,
1151 /// RFC 3339.
1152 pub created_at: String,
1153 /// RFC 3339. When it landed or left.
1154 pub finished_at: Option<String>,
1155}
1156
1157/// A repository's merge queue: what is in it, in order, and what recently
1158/// left it.
1159#[derive(Clone, Debug, Serialize, Deserialize)]
1160#[serde(rename_all = "camelCase")]
1161pub struct QueueView {
1162 /// Whether the repository merges through the queue.
1163 pub enabled: bool,
1164 pub active: Vec<QueueEntry>,
1165 /// Newest first.
1166 pub recent: Vec<QueueEntry>,
1167}
1168
1169/// `queue`: a repository's merge queue. Returns `Outcome<QueueView>`.
1170#[derive(Debug, Serialize, Deserialize)]
1171pub struct QueueArgs {
1172 pub repo: RepoPath,
1173 pub viewer: Viewer,
1174}
1175
1176/// `queue_build`: the next batch to test for a repository, if nothing is
1177/// being tested now. Returns `Vec<QueueJob>`, one per entry, each testing
1178/// the default branch with that entry and everything ahead of it.
1179#[derive(Debug, Serialize, Deserialize)]
1180#[serde(rename_all = "camelCase")]
1181pub struct QueueBuildArgs {
1182 pub repo_id: String,
1183}
1184
1185/// One pull request in a state being tested: where its change is.
1186#[derive(Clone, Debug, Serialize, Deserialize)]
1187#[serde(rename_all = "camelCase")]
1188pub struct QueueStackItem {
1189 pub number: u32,
1190 pub title: String,
1191 /// The repository holding the change: its fork, or the repository.
1192 pub source: RepoPath,
1193 /// The branch of `source` holding it.
1194 pub branch: String,
1195 pub commit: String,
1196}
1197
1198/// What a sandbox needs to build and check one combined state.
1199#[derive(Clone, Debug, Serialize, Deserialize)]
1200#[serde(rename_all = "camelCase")]
1201pub struct QueueJob {
1202 pub entry_id: String,
1203 /// Lets the sandbox, and nothing else, report this state's result.
1204 pub token: String,
1205 pub repo: RepoPath,
1206 pub default_branch: String,
1207 /// The default branch's commit to build on.
1208 pub base_commit: String,
1209 /// Where to push the tested state, in the repository itself.
1210 pub branch: String,
1211 /// The pull requests to merge in, in order; the last is the entry.
1212 pub stack: Vec<QueueStackItem>,
1213 /// Every acceptance check of every pull request in the stack.
1214 pub checks: Vec<String>,
1215 /// The checks of issues already completed: the default branch's
1216 /// contract. One that fails on the base alone is not held against the
1217 /// entry.
1218 #[serde(default)]
1219 pub contract_checks: Vec<String>,
1220 /// Who the sandbox acts as: a member who can push the tested state.
1221 pub actor: User,
1222}
1223
1224/// `report_queue`: a sandbox's result for one combined state. Returns
1225/// `Outcome<QueueState>`.
1226#[derive(Debug, Serialize, Deserialize)]
1227#[serde(rename_all = "camelCase")]
1228pub struct ReportQueueArgs {
1229 pub entry_id: String,
1230 pub token: String,
1231 #[serde(default)]
1232 pub combined_commit: Option<String>,
1233 #[serde(default)]
1234 pub results: Vec<CheckResult>,
1235 /// Set when the state could not be built or checked.
1236 #[serde(default)]
1237 pub error: Option<String>,
1238 /// For a merge conflict: the pull request whose change it collided with.
1239 #[serde(default)]
1240 pub conflict_with: Option<u32>,
1241}