v0.2.0 43088fd

exec.proto RawHistoryFolder

1// SPDX-License-Identifier: MIT
2
3// Internal wire format between the host process of ermite-runner and the
4// executor running inside a sandbox (vsock in a micro-VM, Unix socket in a
5// container). Frames are length-prefixed on the stream (see frame.go); this file
6// defines the payload. It is internal to ermite-runner: no compatibility is
7// promised between runner versions, which is safe because the host attaches its
8// own executable to every sandbox.
9
10syntax = "proto3";
11
12package ermite.runner.exec.v1;
13
14option go_package = "bnema.dev/ermite-runner/internal/execstream/execpb";
15
16// Frame is the only message on the stream.
17message Frame {
18  oneof body {
19    Hello hello = 1;   // executor -> host, first frame
20    Run run = 2;       // host -> executor, after Hello
21    Output output = 3; // executor -> host
22    Exit exit = 4;     // executor -> host, last frame
23    Cancel cancel = 5; // host -> executor
24    StepStarted step_started = 6;     // executor -> host
25    StepCompleted step_completed = 7; // executor -> host
26    Log log = 8;                      // executor -> host
27    JobResult job_result = 9;         // executor -> host, before Exit
28    StepAnnotations step_annotations = 10; // executor -> host, before the StepCompleted of the step
29    StepSummary step_summary = 11;         // executor -> host, before the StepCompleted of the step
30    ResolveRequest resolve_request = 12;   // executor -> host
31    ResolveResponse resolve_response = 13; // host -> executor, answers a ResolveRequest
32  }
33}
34
35message Hello {
36  string version = 1;  // runner version of the executor
37  string sandbox = 2;  // "vm" or "container"
38  string hostname = 3;
39}
40
41// Run asks the executor to run a script or a job. Without job it is the stub
42// executor of sandbox-check: the script is run with `sh -c`; an empty script
43// means the built-in diagnostics script. With job the executor runs the job
44// like a GitHub Actions runner and reports it with StepStarted, Log,
45// StepCompleted and JobResult frames, then Exit.
46message Run {
47  string script = 1;
48  map<string, string> env = 2;
49  JobSpec job = 3;
50}
51
52// JobSpec is the job to run: the fields of the job that ermite handed to the
53// host process, minus the tokens (the sandbox never sees them).
54message JobSpec {
55  string workflow_path = 1;
56  string workflow_yaml = 2;
57  string job_key = 3;
58  string matrix = 4;   // JSON object
59  string contexts = 5; // JSON object
60  string repo = 6;     // repository name
61  int32 timeout_minutes = 7;
62  string runner_name = 8;
63  string runner_version = 9;
64  // runner_environment is the runner.environment value ("github-hosted" or "self-hosted").
65  string runner_environment = 10;
66  bool debug = 11; // ACTIONS_STEP_DEBUG
67  // deadline_ms is what is left of the job timeout when the host sends this
68  // Run, in milliseconds: the timeout counts from the moment the host received
69  // the job (runner.proto: Job.timeout_minutes), not from the start of the
70  // executor, and booting the sandbox takes time. 0 means "use
71  // timeout_minutes from now".
72  int64 deadline_ms = 12;
73  // send_annotations and send_summaries say that the server keeps annotations
74  // (feature ci.annotations) and step summaries (ci.summaries). The executor
75  // sends StepAnnotations and StepSummary frames only when they are set.
76  bool send_annotations = 13;
77  bool send_summaries = 14;
78}
79
80enum StreamKind {
81  STREAM_KIND_UNSPECIFIED = 0;
82  STREAM_KIND_STDOUT = 1;
83  STREAM_KIND_STDERR = 2;
84}
85
86message Output {
87  StreamKind stream = 1;
88  bytes data = 2;
89  int64 unix_nano = 3;
90}
91
92message Exit {
93  int32 code = 1;
94  string error = 2; // set when the executor failed to run the script at all
95}
96
97// Cancel asks the executor to stop the running script. The executor escalates
98// like the official runner: SIGINT to the script's process group at once,
99// SIGTERM 7.5 s later, SIGKILL 2.5 s after that.
100message Cancel {
101  // reason is for the job log and diagnostics ("cancelled by the user",
102  // "job timeout", ...); it never changes the behaviour.
103  string reason = 1;
104  // kind tells the job executor how the job ends: cancelled, timed out, or
105  // cancelled because the runner shuts down. The stub executor ignores it.
106  CancelKind kind = 2;
107}
108
109enum CancelKind {
110  CANCEL_KIND_UNSPECIFIED = 0; // same as USER
111  CANCEL_KIND_USER = 1;
112  CANCEL_KIND_TIMEOUT = 2;
113  CANCEL_KIND_SHUTDOWN = 3;
114}
115
116// Steps are numbered like GitHub's log: "Set up job" is 1, the steps of the
117// workflow follow, "Complete job" is last.
118message StepStarted {
119  int32 number = 1;
120  string name = 2;
121  int64 unix_nano = 3;
122}
123
124message StepCompleted {
125  int32 number = 1;
126  string name = 2;
127  StepConclusion conclusion = 3;
128  int64 unix_nano = 4;
129  // outcome is steps.<id>.outcome: the result before continue-on-error. It
130  // differs from conclusion only for a failed step with continue-on-error.
131  // UNSPECIFIED means the same as conclusion.
132  StepConclusion outcome = 5;
133}
134
135enum AnnotationLevel {
136  ANNOTATION_LEVEL_UNSPECIFIED = 0;
137  ANNOTATION_LEVEL_NOTICE = 1;
138  ANNOTATION_LEVEL_WARNING = 2;
139  ANNOTATION_LEVEL_FAILURE = 3;
140}
141
142// Annotation is one ::notice, ::warning or ::error (or a problem matcher
143// match), masked. The host validates every field again before it sends them.
144message Annotation {
145  AnnotationLevel level = 1;
146  string title = 2;
147  string message = 3;
148  string file = 4; // relative to the repository when the file is in it
149  int32 start_line = 5;
150  int32 end_line = 6;
151  int32 start_column = 7;
152  int32 end_column = 8;
153}
154
155// StepAnnotations is the complete list of the annotations of a step (the ones
156// the runner keeps: at most 10 per level), replacing any earlier list of that
157// step. Annotations of the steps inside a composite action are those of the
158// step of the workflow that uses it.
159message StepAnnotations {
160  int32 step = 1;
161  repeated Annotation annotations = 2;
162}
163
164// StepSummary is the masked content of GITHUB_STEP_SUMMARY after a step, at
165// most 1 MiB.
166message StepSummary {
167  int32 step = 1;
168  string markdown = 2;
169}
170
171enum StepConclusion {
172  STEP_CONCLUSION_UNSPECIFIED = 0;
173  STEP_CONCLUSION_SUCCESS = 1;
174  STEP_CONCLUSION_FAILURE = 2;
175  STEP_CONCLUSION_CANCELLED = 3;
176  STEP_CONCLUSION_SKIPPED = 4;
177  STEP_CONCLUSION_TIMED_OUT = 5; // jobs only
178}
179
180// Log is one line of the job log, without terminator, valid UTF-8. A line of
181// more than 64 KiB is cut by the executor into pieces at character boundaries;
182// every piece but the first has continued set (the AppendLog rule).
183message Log {
184  int32 step = 1;
185  int64 unix_nano = 2;
186  string text = 3;
187  bool continued = 4;
188}
189
190// JobResult is the outcome of the job; Exit follows.
191message JobResult {
192  StepConclusion conclusion = 1;
193  map<string, string> outputs = 2;
194  string error = 3;
195  bool runner_shutdown = 4;
196}
197
198// ResolveRequest asks the host to resolve actions with RunnerService.
199// ResolveActions: the job token stays in the host, so the executor cannot call
200// it. The executor sends one per level of composite actions (the runner's own
201// "one more round per level") and waits for the ResolveResponse with the same id.
202message ResolveRequest {
203  int64 id = 1;
204  repeated string uses = 2; // "owner/repo[/path]@ref", at most 100
205}
206
207// ResolveResponse answers a ResolveRequest. error is set when the call itself
208// failed (the executor fails the job); actions has one entry per uses otherwise.
209message ResolveResponse {
210  int64 id = 1;
211  string error = 2;
212  repeated ResolvedAction actions = 3;
213}
214
215// ResolvedAction mirrors ermite.ResolvedAction (the token is a secret: the
216// executor masks it).
217message ResolvedAction {
218  string ref = 1;
219  string name_with_owner = 2;
220  string path = 3;
221  string resolved_sha = 4;
222  string tarball_url = 5;
223  string token = 6;
224  string source = 7;
225  string error = 8;
226  // auth_origin (scheme://host[:port], as the sandbox reaches it) is the only
227  // origin the token may be sent to; empty means the token is never sent. The
228  // host sets it for archives served by the ermite server, from its own
229  // configuration, never from the URL alone.
230  string auth_origin = 9;
231}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 4

Tags 11

↑↓ moveenter openesc close