1/*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17syntax = "proto3";
18
19package luci.resultdb.v1;
20
21option go_package = "go.chromium.org/luci/resultdb/proto/v1;resultpb";
22option java_package = "com.android.resultdb.proto";
23option java_multiple_files = true;
24
25// A collection of instructions.
26// Used for step and test result instructions.
27// Instructions may mixed between step and test instructions.
28// This has a size limit of 1MB.
29message Instructions {
30  repeated Instruction instructions = 1;
31}
32
33// Instruction is one failure reproduction instruction for a step or test result.
34// Instruction can have different targets, like "local" or "remote".
35// Instructions are stored in invocation level.
36message Instruction {
37  // ID of the instruction. Required.
38  // It is consumer-defined and is unique within the an invocation.
39  // The tuple (invocation_id, instruction_id) can uniquely identify an instruction.
40  // At this moment, we only has use cases for instruction ID for step instructions,
41  // but we also require test instruction to have ID, for possible features
42  // or enhancements in the future.
43  // Format [a-z][a-z0-9_\-:.]{0,99}
44  // Limit: 100 bytes.
45  string id = 1;
46
47  // Either step or test instruction.
48  InstructionType type = 2;
49
50  // List of instruction for different targets.
51  // There is at most 1 instruction per target.
52  // If there is more than 1, an error will be returned.
53  repeated TargetedInstruction targeted_instructions = 3;
54
55  // Specified the collection of test results that this instruction applies to.
56  // For example, we can target all test results within a child invocation.
57  // The consumer needs to make sure that any test result only has at most 1 instruction.
58  // Otherwise, the behavior is undeterministic.
59  // If no filter is applied, assume this applies to all test results contained
60  // in this invocation and included invocations.
61  // Only applicable for test instructions. This field will be ignored for step instructions.
62  InstructionFilter instruction_filter = 4;
63
64  // This is an output only field, representing the name of the instruction.
65  // Format: invocations/<invocation_id>/instructions/<instruction_id>
66  // If this field is set as input, it will be ignored.
67  string name = 5;
68
69  // The descriptive, human-readable name of the instruction.
70  // It will be showed in the dependency section in MILO.
71  // Limit: 100 bytes.
72  string descriptive_name = 6;
73}
74
75// InstructionFilter specifies the test results that this instruction applies to.
76message InstructionFilter{
77  // TODO (nqmtuan): We may support filter by invocation tags if requested.
78  oneof filter_type {
79    InstructionFilterByInvocationID invocation_ids = 1;
80  }
81}
82
83message InstructionFilterByInvocationID {
84  // Only test results contained in these invocation IDs will be selected.
85  repeated string invocation_ids = 1;
86
87  // Whether the check is recursive (i.e. whether it applies to test results
88  // in included invocation).
89  bool recursive = 2;
90}
91
92
93// Instruction for specific targets.
94// Instruction for different targets may have the same or different dependency
95// and content.
96message TargetedInstruction {
97  // The targets that this instruction is for, like "LOCAL", "REMOTE" or "PREBUILT".
98  // A targeted instruction can only depend on another instruction with the same target.
99  // For example, a "LOCAL" instruction can only depend on another "LOCAL" instruction.
100  repeated InstructionTarget targets = 1;
101
102  // Another instruction that this instruction depends on.
103  // At the moment, one instruction can have at most 1 dependency.
104  // Make this repeated for forward compatibility.
105  repeated InstructionDependency dependencies = 2;
106
107  // The content of the instruction, in markdown format.
108  // Placeholders may be used and will be populated with real
109  // information when displayed in the UI.
110  // This will be limit to 10KB. If the content is longer than 10KB,
111  // an error will be returned.
112  // See go/luci-failure-reproduction-instructions-dd for details.
113  string content = 3;
114}
115
116// Specifies a dependency for instruction.
117// An instruction being depended on needs to be step instruction, not test result instruction.
118// If the dependency cannot be found, or the user does not have the ACL,
119// the dependency chain will stop and Milo will not display the dependency.
120// If a dependency cycle is detected, we will stop showing dependency once we detected the cycle.
121message InstructionDependency {
122  // The invocation ID of the instruction being depended on.
123  // Limit: 100 bytes
124  string invocation_id = 1;
125
126  // The instruction ID of the instruction being depended on.
127  // (invocation_id, instruction_id) uniquely identify an invocation.
128  string instruction_id = 2;
129}
130
131enum InstructionTarget {
132  INSTRUCTION_TARGET_UNSPECIFIED = 0;
133  // For running in a local machine.
134  LOCAL = 1;
135  // For running remotely.
136  REMOTE = 2;
137  // For prebuilt images.
138  PREBUILT = 3;
139}
140
141enum InstructionType {
142  INSTRUCTION_TYPE_UNSPECIFIED = 0;
143  // Instruction for step.
144  STEP_INSTRUCTION = 1;
145  // Instruction for test result.
146  TEST_RESULT_INSTRUCTION = 2;
147}
148