go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/buildbucket/proto/build.proto (about)

     1  // Copyright 2018 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  syntax = "proto3";
    16  
    17  package buildbucket.v2;
    18  
    19  option go_package = "go.chromium.org/luci/buildbucket/proto;buildbucketpb";
    20  
    21  import "google/api/field_behavior.proto";
    22  import "google/protobuf/duration.proto";
    23  import "google/protobuf/timestamp.proto";
    24  import "google/protobuf/struct.proto";
    25  import "go.chromium.org/luci/buildbucket/proto/build_field_visibility.proto";
    26  import "go.chromium.org/luci/buildbucket/proto/builder_common.proto";
    27  import "go.chromium.org/luci/buildbucket/proto/common.proto";
    28  import "go.chromium.org/luci/buildbucket/proto/field_option.proto";
    29  import "go.chromium.org/luci/buildbucket/proto/step.proto";
    30  import "go.chromium.org/luci/buildbucket/proto/task.proto";
    31  import "go.chromium.org/luci/resultdb/proto/v1/invocation.proto";
    32  
    33  // A single build, identified by an int64 ID.
    34  // Belongs to a builder.
    35  //
    36  // RPC: see Builds service for build creation and retrieval.
    37  // Some Build fields are marked as excluded from responses by default.
    38  // Use "mask" request field to specify that a field must be included.
    39  //
    40  // BigQuery: this message also defines schema of a BigQuery table of completed
    41  // builds. A BigQuery row is inserted soon after build ends, i.e. a row
    42  // represents a state of a build at completion time and does not change after
    43  // that. All fields are included.
    44  //
    45  // Next id: 36.
    46  message Build {
    47    // Defines what to build/test.
    48    //
    49    // Behavior of a build executable MAY depend on Input.
    50    // It MAY NOT modify its behavior based on anything outside of Input.
    51    // It MAY read non-Input fields to display for debugging or to pass-through to
    52    // triggered builds. For example the "tags" field may be passed to triggered
    53    // builds, or the "infra" field may be printed for debugging purposes.
    54    message Input {
    55      // Arbitrary JSON object. Available at build run time.
    56      //
    57      // RPC: By default, this field is excluded from responses.
    58      //
    59      // V1 equivalent: corresponds to "properties" key in "parameters_json".
    60      google.protobuf.Struct properties = 1;
    61  
    62      // The Gitiles commit to run against.
    63      // Usually present in CI builds, set by LUCI Scheduler.
    64      // If not present, the build may checkout "refs/heads/master".
    65      // NOT a blamelist.
    66      //
    67      // V1 equivalent: supersedes "revision" property and "buildset"
    68      // tag that starts with "commit/gitiles/".
    69      GitilesCommit gitiles_commit = 2 [ (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
    70  
    71      // Gerrit patchsets to run against.
    72      // Usually present in tryjobs, set by CQ, Gerrit, git-cl-try.
    73      // Applied on top of gitiles_commit if specified, otherwise tip of the tree.
    74      //
    75      // V1 equivalent: supersedes patch_* properties and "buildset"
    76      // tag that starts with "patch/gerrit/".
    77      repeated GerritChange gerrit_changes = 3 [ (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
    78  
    79      // DEPRECATED
    80      //
    81      // Equivalent to `"luci.non_production" in experiments`.
    82      //
    83      // See `Builder.experiments` for well-known experiments.
    84      bool experimental = 5;
    85  
    86      // The sorted list of experiments enabled on this build.
    87      //
    88      // See `Builder.experiments` for a detailed breakdown on how experiments
    89      // work, and go/buildbucket-settings.cfg for the current state of global
    90      // experiments.
    91      repeated string experiments = 6;
    92    }
    93  
    94    // Result of the build executable.
    95    message Output {
    96      reserved 4; // critical, was moved to Build.
    97  
    98      // Arbitrary JSON object produced by the build.
    99      //
   100      // In recipes, use step_result.presentation.properties to set these,
   101      // for example
   102      //
   103      //   step_result = api.step(['echo'])
   104      //   step_result.presentation.properties['foo'] = 'bar'
   105      //
   106      // More docs: https://chromium.googlesource.com/infra/luci/recipes-py/+/HEAD/doc/old_user_guide.md#Setting-properties
   107      //
   108      // V1 equivalent: corresponds to "properties" key in
   109      // "result_details_json".
   110      // In V1 output properties are not populated until build ends.
   111      google.protobuf.Struct properties = 1;
   112  
   113      // Build checked out and executed on this commit.
   114      //
   115      // Should correspond to Build.Input.gitiles_commit.
   116      // May be present even if Build.Input.gitiles_commit is not set, for example
   117      // in cron builders.
   118      //
   119      // V1 equivalent: this supersedes all got_revision output property.
   120      GitilesCommit gitiles_commit = 3;
   121  
   122      // Logs produced by the build script, typically "stdout" and "stderr".
   123      repeated Log logs = 5;
   124  
   125      // Build status which is reported by the client via StartBuild or UpdateBuild.
   126      Status status = 6;
   127      StatusDetails status_details = 7;
   128      // Deprecated. Use summary_markdown instead.
   129      string summary_html = 8 [deprecated = true];
   130      string summary_markdown = 2;
   131    }
   132  
   133    reserved 13; // infra_failure_reason was moved into status_details.
   134    reserved 14; // cancel_reason was moved into status_details.
   135  
   136    // Identifier of the build, unique per LUCI deployment.
   137    // IDs are monotonically decreasing.
   138    int64 id = 1 [ (google.api.field_behavior) = OUTPUT_ONLY,
   139                   (visible_with) = BUILDS_LIST_PERMISSION ];
   140  
   141    // Required. The builder this build belongs to.
   142    //
   143    // Tuple (builder.project, builder.bucket) defines build ACL
   144    // which may change after build has ended.
   145    BuilderID builder = 2 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED,
   146                            (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
   147  
   148    // Information of the builder, propagated from builder config.
   149    //
   150    // The info captures the state of the builder at creation time.
   151    // If any information is updated, all future builds will have the new
   152    // information, while the historical builds persist the old information.
   153    message BuilderInfo {
   154      string description = 1;
   155  
   156      // TODO(crbug.com/1093655): add builder tags.
   157    }
   158    BuilderInfo builder_info = 34 [ (google.api.field_behavior) = OUTPUT_ONLY ];
   159  
   160    // Human-readable identifier of the build with the following properties:
   161    // - unique within the builder
   162    // - a monotonically increasing number
   163    // - mostly contiguous
   164    // - much shorter than id
   165    //
   166    // Caution: populated (positive number) iff build numbers were enabled
   167    // in the builder configuration at the time of build creation.
   168    //
   169    // Caution: Build numbers are not guaranteed to be contiguous.
   170    // There may be gaps during outages.
   171    //
   172    // Caution: Build numbers, while monotonically increasing, do not
   173    // necessarily reflect source-code order. For example, force builds
   174    // or rebuilds can allocate new, higher, numbers, but build an older-
   175    // than-HEAD version of the source.
   176    int32 number = 3 [ (google.api.field_behavior) = OUTPUT_ONLY,
   177                       (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
   178  
   179    // Verified LUCI identity that created this build.
   180    string created_by = 4 [ (google.api.field_behavior) = OUTPUT_ONLY ];
   181  
   182    // Redirect url for the build.
   183    string view_url = 5;
   184  
   185    // Verified LUCI identity that canceled this build.
   186    //
   187    // Special values:
   188    // * buildbucket: The build is canceled by buildbucket. This can happen if the
   189    // build's parent has ended, and the build cannot outlive its parent.
   190    // * backend: The build's backend task is canceled. For example the build's
   191    // Swarming task is killed.
   192    string canceled_by = 23 [ (google.api.field_behavior) = OUTPUT_ONLY ];
   193  
   194    // When the build was created.
   195    google.protobuf.Timestamp create_time = 6
   196        [ (google.api.field_behavior) = OUTPUT_ONLY,
   197          (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
   198    // When the build started.
   199    // Required iff status is STARTED, SUCCESS or FAILURE.
   200    google.protobuf.Timestamp start_time = 7
   201        [ (google.api.field_behavior) = OUTPUT_ONLY,
   202          (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
   203    // When the build ended.
   204    // Present iff status is terminal.
   205    // MUST NOT be before start_time.
   206    google.protobuf.Timestamp end_time = 8
   207        [ (google.api.field_behavior) = OUTPUT_ONLY,
   208          (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
   209    // When the build was most recently updated.
   210    //
   211    // RPC: can be > end_time if, e.g. new tags were attached to a completed
   212    // build.
   213    google.protobuf.Timestamp update_time = 9
   214        [ (google.api.field_behavior) = OUTPUT_ONLY,
   215          (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
   216    // When the cancel process of the build started.
   217    // Note it's not the time that the cancellation completed, which would be
   218    // tracked by end_time.
   219    //
   220    // During the cancel process, the build still accepts updates.
   221    //
   222    // bbagent checks this field at the frequency of
   223    // buildbucket.MinUpdateBuildInterval. When bbagent sees the build is in
   224    // cancel process, there are two states:
   225    //  * it has NOT yet started the exe payload,
   226    //  * it HAS started the exe payload.
   227    //
   228    // In the first state, bbagent will immediately terminate the build without
   229    // invoking the exe payload at all.
   230    //
   231    // In the second state, bbagent will send SIGTERM/CTRL-BREAK to the exe
   232    // (according to the deadline protocol described in
   233    // https://chromium.googlesource.com/infra/luci/luci-py/+/HEAD/client/LUCI_CONTEXT.md).
   234    // After grace_period it will then try to kill the exe.
   235    //
   236    // NOTE: There is a race condition here; If bbagent starts the luciexe and
   237    // then immediately notices that the build is canceled, it's possible that
   238    // bbagent can send SIGTERM/CTRL-BREAK to the exe before that exe sets up
   239    // interrupt handlers. There is a bug on file (crbug.com/1311821)
   240    // which we plan to implement at some point as a mitigation for this.
   241    //
   242    // Additionally, the Buildbucket service itself will launch an asynchronous
   243    // task to terminate the build via the backend API (e.g. Swarming cancellation)
   244    // if bbagent cannot successfully terminate the exe in time.
   245    google.protobuf.Timestamp cancel_time = 32
   246        [ (google.api.field_behavior) = OUTPUT_ONLY,
   247          (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
   248  
   249    // Status of the build.
   250    // Must be specified, i.e. not STATUS_UNSPECIFIED.
   251    //
   252    // RPC: Responses have most current status.
   253    //
   254    // BigQuery: Final status of the build. Cannot be SCHEDULED or STARTED.
   255    Status status = 12 [ (buildbucket.v2.create_build_field_option).field_behavior = OUTPUT_ONLY,
   256                         (visible_with) = BUILDS_LIST_PERMISSION ];
   257  
   258    // Human-readable summary of the build in Markdown format
   259    // (https://spec.commonmark.org/0.28/).
   260    // Explains status.
   261    // Up to 4 KB.
   262    string summary_markdown = 20 [ (buildbucket.v2.create_build_field_option).field_behavior = OUTPUT_ONLY ];
   263  
   264    // Markdown reasoning for cancelling the build.
   265    // Human readable and should be following https://spec.commonmark.org/0.28/.
   266    string cancellation_markdown = 33 [ (buildbucket.v2.create_build_field_option).field_behavior = OUTPUT_ONLY ];
   267  
   268    // If NO, then the build status SHOULD NOT be used to assess correctness of
   269    // the input gitiles_commit or gerrit_changes.
   270    // For example, if a pre-submit build has failed, CQ MAY still land the CL.
   271    // For example, if a post-submit build has failed, CLs MAY continue landing.
   272    Trinary critical = 21 [ (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
   273  
   274    // Machine-readable details of the current status.
   275    // Human-readable status reason is available in summary_markdown.
   276    StatusDetails status_details = 22
   277        [ (buildbucket.v2.create_build_field_option).field_behavior = OUTPUT_ONLY,
   278          (visible_with) = BUILDS_LIST_PERMISSION ];
   279  
   280    // Input to the build executable.
   281    Input input = 15 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   282  
   283    // Output of the build executable.
   284    // SHOULD depend only on input field and NOT other fields.
   285    // MUST be unset if build status is SCHEDULED.
   286    //
   287    // RPC: By default, this field is excluded from responses.
   288    // Updated while the build is running and finalized when the build ends.
   289    Output output = 16 [ (buildbucket.v2.create_build_field_option).field_behavior = OUTPUT_ONLY ];
   290  
   291    // Current list of build steps.
   292    // Updated as build runs.
   293    //
   294    // May take up to 1MB after zlib compression.
   295    // MUST be unset if build status is SCHEDULED.
   296    //
   297    // RPC: By default, this field is excluded from responses.
   298    repeated Step steps = 17 [ (buildbucket.v2.create_build_field_option).field_behavior = OUTPUT_ONLY ];
   299  
   300    // Build infrastructure used by the build.
   301    //
   302    // RPC: By default, this field is excluded from responses.
   303    BuildInfra infra = 18 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   304  
   305    // Arbitrary annotations for the build.
   306    // One key may have multiple values, which is why this is not a map<string,string>.
   307    // Indexed by the server, see also BuildPredicate.tags.
   308    repeated StringPair tags = 19;
   309  
   310    // What to run when the build is ready to start.
   311    Executable exe = 24 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   312  
   313    // DEPRECATED
   314    //
   315    // Equivalent to `"luci.buildbucket.canary_software" in input.experiments`.
   316    //
   317    // See `Builder.experiments` for well-known experiments.
   318    bool canary = 25;
   319  
   320    // Maximum build pending time.
   321    // If the timeout is reached, the build is marked as INFRA_FAILURE status
   322    // and both status_details.{timeout, resource_exhaustion} are set.
   323    google.protobuf.Duration scheduling_timeout = 26;
   324  
   325    // Maximum build execution time.
   326    //
   327    // Not to be confused with scheduling_timeout.
   328    //
   329    // If the timeout is reached, the task will be signaled according to the
   330    // `deadline` section of
   331    // https://chromium.googlesource.com/infra/luci/luci-py/+/HEAD/client/LUCI_CONTEXT.md
   332    // and status_details.timeout is set.
   333    //
   334    // The task will have `grace_period` amount of time to handle cleanup
   335    // before being forcefully terminated.
   336    google.protobuf.Duration execution_timeout = 27;
   337  
   338    // Amount of cleanup time after execution_timeout.
   339    //
   340    // After being signaled according to execution_timeout, the task will
   341    // have this duration to clean up before being forcefully terminated.
   342    //
   343    // The signalling process is explained in the `deadline` section of
   344    // https://chromium.googlesource.com/infra/luci/luci-py/+/HEAD/client/LUCI_CONTEXT.md.
   345    google.protobuf.Duration grace_period = 29;
   346  
   347    // If set, swarming was requested to wait until it sees at least one bot
   348    // report a superset of the build's requested dimensions.
   349    bool wait_for_capacity = 28;
   350  
   351    // Flag to control if the build can outlive its parent.
   352    //
   353    // This field is only meaningful if the build has ancestors.
   354    // If the build has ancestors and the value is false, it means that the build
   355    // SHOULD reach a terminal status (SUCCESS, FAILURE, INFRA_FAILURE or
   356    // CANCELED) before its parent. If the child fails to do so, Buildbucket will
   357    // cancel it some time after the parent build reaches a terminal status.
   358    //
   359    // A build that can outlive its parent can also outlive its parent's ancestors.
   360    bool can_outlive_parent = 30 [ (visible_with) = BUILDS_LIST_PERMISSION ];
   361  
   362    // IDs of the build's ancestors. This includes all parents/grandparents/etc.
   363    // This is ordered from top-to-bottom so `ancestor_ids[0]` is the root of
   364    // the builds tree, and `ancestor_ids[-1]` is this build's immediate parent.
   365    // This does not include any "siblings" at higher levels of the tree, just
   366    // the direct chain of ancestors from root to this build.
   367    repeated int64 ancestor_ids = 31 [
   368      (google.api.field_behavior) = OUTPUT_ONLY,
   369      (visible_with) = BUILDS_LIST_PERMISSION ];
   370  
   371    // If UNSET, retrying the build is implicitly allowed;
   372    // If YES, retrying the build is explicitly allowed;
   373    // If NO, retrying the build is explicitly disallowed,
   374    //   * any UI displaying the build should remove "retry" button(s),
   375    //   * ScheduleBuild using the build as template should fail,
   376    //   * but the build can still be synthesized by SynthesizeBuild.
   377    Trinary retriable = 35;
   378  }
   379  
   380  message InputDataRef {
   381    message CAS {
   382      // Full name of RBE-CAS instance. `projects/{project_id}/instances/{instance}`.
   383      // e.g. projects/chromium-swarm/instances/default_instance
   384      string cas_instance = 1;
   385  
   386      // This is a [Digest][build.bazel.remote.execution.v2.Digest] of a blob on
   387      // RBE-CAS. See the explanations at the original definition.
   388      // https://github.com/bazelbuild/remote-apis/blob/77cfb44a88577a7ade5dd2400425f6d50469ec6d/build/bazel/remote/execution/v2/remote_execution.proto#L753-L791
   389      message Digest {
   390        string hash = 1;
   391        int64 size_bytes = 2;
   392      }
   393  
   394      Digest digest = 2;
   395    }
   396  
   397    message CIPD {
   398      string server = 1;
   399  
   400      message PkgSpec {
   401        // Package MAY include CIPD variables, including conditional variables like
   402        // `${os=windows}`. Additionally, version may be a ref or a tag.
   403        string package = 1;
   404        string version = 2;
   405      }
   406      repeated PkgSpec specs = 2;
   407    }
   408  
   409    oneof data_type {
   410      CAS cas = 1;
   411      CIPD cipd = 2;
   412    }
   413  
   414    // TODO(crbug.com/1266060): TBD. `on_path` may need to move out to be incorporated into a field which captures other envvars.
   415    // Subdirectories relative to the root of `ref` which should be set as a prefix to
   416    // the $PATH variable.
   417    //
   418    // A substitute of `env_prefixes` in SwarmingRpcsTaskProperties field -
   419    // https://chromium.googlesource.com/infra/luci/luci-go/+/0048a84944e872776fba3542aa96d5943ae64bab/common/api/swarming/swarming/v1/swarming-gen.go#1495
   420    repeated string on_path = 3;
   421  
   422    reserved 4; // purpose, replaced by agent.data_purposes.
   423  }
   424  
   425  message ResolvedDataRef {
   426    message Timing {
   427      google.protobuf.Duration fetch_duration = 1;
   428      google.protobuf.Duration install_duration = 2;
   429    }
   430  
   431    message CAS {
   432      // TODO(crbug.com/1266060): potential fields can be
   433      // int64 cache_hits = ?;
   434      // int64 cache_hit_size = ?:
   435      // int64 cache_misses = ?;
   436      // int64 cache_miss_size = ?;
   437      // need more thinking and better to determine when starting writing code
   438      // to download binaries in bbagent.
   439      Timing timing = 1;
   440    }
   441  
   442    message CIPD {
   443      message PkgSpec {
   444        // True if this package wasn't installed because `package` contained a
   445        // non-applicable conditional (e.g. ${os=windows} on a mac machine).
   446        bool skipped = 1;
   447  
   448        string package = 2;  // fully resolved
   449        string version = 3;  // fully resolved
   450  
   451        Trinary was_cached = 4;
   452        Timing timing = 5;  // optional
   453      }
   454  
   455      repeated PkgSpec specs = 2;
   456    }
   457  
   458    // TODO(crbug.com/1266060): if we have local caches here, report if they were cached
   459    // and how big they were when they were mapped in.
   460  
   461    oneof data_type {
   462      CAS cas = 1;
   463      CIPD cipd = 2;
   464    }
   465  }
   466  
   467  // Build infrastructure that was used for a particular build.
   468  message BuildInfra {
   469  
   470    // Buildbucket-specific information, captured at the build creation time.
   471    message Buildbucket {
   472      // bbagent will interpret Agent.input, as well as update Agent.output.
   473      message Agent {
   474        // Source describes where the Agent should be fetched from.
   475        message Source {
   476          message CIPD {
   477            // The CIPD package to use for the agent.
   478            //
   479            // Must end in "/${platform}" with no other CIPD variables.
   480            //
   481            // If using an experimental agent binary, please make sure the package
   482            // prefix has been configured here -
   483            // https://chrome-internal.googlesource.com/infradata/config/+/refs/heads/main/configs/chrome-infra-packages/bootstrap.cfg
   484            string package = 1;
   485  
   486            // The CIPD version to use for the agent.
   487            string version = 2;
   488  
   489            // The CIPD server to use.
   490            string server = 3;
   491  
   492            // maps ${platform} -> instance_id for resolved agent packages.
   493            //
   494            // Will be overwritten at CreateBuild time, should be left empty
   495            // when creating a new Build.
   496            map<string, string> resolved_instances = 4 [ (google.api.field_behavior) = OUTPUT_ONLY ];
   497          }
   498  
   499          oneof data_type {
   500            CIPD cipd = 1;
   501          }
   502          // Other source mechanisms could be added in the future, such as GCS
   503          // CAS or direct-download URLs. These would need to have a map of
   504          // platform -> details.
   505        }
   506        message Input {
   507          // Maps relative-to-root directory to the data.
   508          //
   509          // For now, data is only allowed at the 'leaves', e.g. you cannot
   510          // specify data at "a/b/c" and "a/b" (but "a/b/c" and "a/q" would be OK).
   511          // All directories beginning with "luci." are reserved for Buildbucket's own use.
   512          //
   513          // TODO(crbug.com/1266060): Enforce the above constraints in a later phase.
   514          // Currently users don't have the flexibility to set the parent directory path.
   515          map<string, InputDataRef> data = 1;
   516  
   517          // Maps relative-to-root directory to the cipd package itself.
   518          // This is the CIPD client itself and  should be downloaded first so that
   519          // the packages in the data field above can be downloaded.
   520          map<string, InputDataRef> cipd_source = 2;
   521        }
   522        message Output {
   523          // Maps relative-to-root directory to the fully-resolved ref.
   524          //
   525          // This will always have 1:1 mapping to Agent.Input.data
   526          map<string, ResolvedDataRef> resolved_data = 1;
   527  
   528          Status status = 2;
   529          StatusDetails status_details = 3;
   530          // Deprecated. Use summary_markdown instead.
   531          string summary_html = 4 [deprecated = true];
   532  
   533          // The agent's resolved CIPD ${platform} (e.g. "linux-amd64",
   534          // "windows-386", etc.).
   535          //
   536          // This is trivial for bbagent to calculate (unlike trying to embed
   537          // its cipd package version inside or along with the executable).
   538          // Buildbucket is doing a full package -> instance ID resolution at
   539          // CreateBuild time anyway, so Agent.Source.resolved_instances
   540          // will give the mapping from `agent_platform` to a precise instance_id
   541          // which was used.
   542          string agent_platform = 5;
   543  
   544          // Total installation duration for all input data. Currently only record
   545          // cipd packages installation time.
   546          google.protobuf.Duration total_duration = 6;
   547          string summary_markdown = 7;
   548        }
   549  
   550        // TODO(crbug.com/1297809): for a long-term solution, we may need to add
   551        // a top-level `on_path` array field in the input and read the value from
   552        // configuration files (eg.settings.cfg, builder configs). So it can store
   553        // the intended order of PATH env var. Then the per-inputDataRef level
   554        // `on_path` field will be deprecated.
   555        // Currently, the new BBagent flow merges all inputDataRef-level `on_path`
   556        // values and sort. This mimics the same behavior of PyBB backend in order
   557        // to have the cipd_installation migration to roll out first under a minimal risk.
   558        Input input = 1 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   559        Output output = 2 [ (buildbucket.v2.create_build_field_option).field_behavior = OUTPUT_ONLY ];
   560        Source source = 3 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   561  
   562        enum Purpose {
   563          // No categorized/known purpose.
   564          PURPOSE_UNSPECIFIED = 0;
   565  
   566          // This path contains the contents of the build's `exe.cipd_package`.
   567          PURPOSE_EXE_PAYLOAD = 1;
   568  
   569          // This path contains data specifically for bbagent's own use.
   570          //
   571          // There's a proposal currently to add `nsjail` support to bbagent, and it
   572          // would need to bring a copy of `nsjail` in order to run the user binary
   573          // but we wouldn't necessarily want to expose it to the user binary.
   574          PURPOSE_BBAGENT_UTILITY = 2;
   575        }
   576  
   577        // Maps the relative-to-root directory path in both `input` and `output`
   578        // to the Purpose of the software in that directory.
   579        //
   580        // If a path is not listed here, it is the same as PURPOSE_UNSPECIFIED.
   581        map<string, Purpose> purposes = 4;
   582  
   583        // Cache for the cipd client.
   584        // The cache name should be in the format like `cipd_client_<sha(client_version)>`.
   585        CacheEntry cipd_client_cache = 5;
   586        // Cache for the cipd packages.
   587        // The cache name should be in the format like `cipd_cache_<sha(task_service_account)>`.
   588        CacheEntry cipd_packages_cache = 6;
   589      }
   590  
   591      reserved 4; // field "canary" was moved to Build message.
   592  
   593      // Version of swarming task template. Defines
   594      // versions of kitchen, git, git wrapper, python, vpython, etc.
   595      string service_config_revision = 2;
   596      // Properties that were specified in ScheduleBuildRequest to create this
   597      // build.
   598      //
   599      // In particular, CQ uses this to decide whether the build created by
   600      // someone else is appropriate for CQ, e.g. it was created with the same
   601      // properties that CQ would use.
   602      google.protobuf.Struct requested_properties = 5;
   603  
   604      // Dimensions that were specified in ScheduleBuildRequest to create this
   605      // build.
   606      repeated RequestedDimension requested_dimensions = 6;
   607  
   608      // Buildbucket hostname, e.g. "cr-buildbucket.appspot.com".
   609      string hostname = 7;
   610  
   611      enum ExperimentReason {
   612        // This value is unused (i.e. if you see this, it's a bug).
   613        EXPERIMENT_REASON_UNSET = 0;
   614  
   615        // This experiment was configured from the 'default_value' of a global
   616        // experiment.
   617        //
   618        // See go/buildbucket-settings.cfg for the list of global experiments.
   619        EXPERIMENT_REASON_GLOBAL_DEFAULT = 1;
   620  
   621        // This experiment was configured from the Builder configuration.
   622        EXPERIMENT_REASON_BUILDER_CONFIG = 2;
   623  
   624        // This experiment was configured from the 'minimum_value' of a global
   625        // experiment.
   626        //
   627        // See go/buildbucket-settings.cfg for the list of global experiments.
   628        EXPERIMENT_REASON_GLOBAL_MINIMUM = 3;
   629  
   630        // This experiment was explicitly set from the ScheduleBuildRequest.
   631        EXPERIMENT_REASON_REQUESTED = 4;
   632  
   633        // This experiment is inactive and so was removed from the Build.
   634        //
   635        // See go/buildbucket-settings.cfg for the list of global experiments.
   636        EXPERIMENT_REASON_GLOBAL_INACTIVE = 5;
   637      }
   638  
   639      // This contains a map of all the experiments involved for this build, as
   640      // well as which bit of configuration lead to them being set (or unset).
   641      //
   642      // Note that if the reason here is EXPERIMENT_REASON_GLOBAL_INACTIVE,
   643      // then that means that the experiment is completely disabled and has no
   644      // effect, but your builder or ScheduleBuildRequest still indicated that
   645      // the experiment should be set. If you see this, then please remove it
   646      // from your configuration and/or requests.
   647      map<string, ExperimentReason> experiment_reasons = 8;
   648  
   649      // The agent binary (bbagent or kitchen) resolutions Buildbucket made for this build.
   650      // This includes all agent_executable references supplied to
   651      // the TaskBackend in "original" (CIPD) form, to facilitate debugging.
   652      // DEPRECATED: Use agent.source instead.
   653      map<string, ResolvedDataRef> agent_executable = 9 [deprecated = true];
   654  
   655      Agent agent = 10 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   656  
   657      repeated string known_public_gerrit_hosts = 11;
   658  
   659      // Flag for if the build should have a build number.
   660      bool build_number = 12;
   661    }
   662  
   663    // Swarming-specific information.
   664    //
   665    // Next ID: 10.
   666    message Swarming {
   667      // Describes a cache directory persisted on a bot.
   668      //
   669      // If a build requested a cache, the cache directory is available on build
   670      // startup. If the cache was present on the bot, the directory contains
   671      // files from the previous run on that bot.
   672      // The build can read/write to the cache directory while it runs.
   673      // After build completes, the cache directory is persisted.
   674      // The next time another build requests the same cache and runs on the same
   675      // bot, the files will still be there (unless the cache was evicted,
   676      // perhaps due to disk space reasons).
   677      //
   678      // One bot can keep multiple caches at the same time and one build can request
   679      // multiple different caches.
   680      // A cache is identified by its name and mapped to a path.
   681      //
   682      // If the bot is running out of space, caches are evicted in LRU manner
   683      // before the next build on this bot starts.
   684      //
   685      // Builder cache.
   686      //
   687      // Buildbucket implicitly declares cache
   688      //   {"name": "<hash(project/bucket/builder)>", "path": "builder"}.
   689      // This means that any LUCI builder has a "personal disk space" on the bot.
   690      // Builder cache is often a good start before customizing caching.
   691      // In recipes, it is available at api.buildbucket.builder_cache_path.
   692      //
   693      message CacheEntry {
   694        // Identifier of the cache. Required. Length is limited to 128.
   695        // Must be unique in the build.
   696        //
   697        // If the pool of swarming bots is shared among multiple LUCI projects and
   698        // projects use same cache name, the cache will be shared across projects.
   699        // To avoid affecting and being affected by other projects, prefix the
   700        // cache name with something project-specific, e.g. "v8-".
   701        string name = 1;
   702  
   703        // Relative path where the cache in mapped into. Required.
   704        //
   705        // Must use POSIX format (forward slashes).
   706        // In most cases, it does not need slashes at all.
   707        //
   708        // In recipes, use api.path['cache'].join(path) to get absolute path.
   709        //
   710        // Must be unique in the build.
   711        string path = 2;
   712  
   713        // Duration to wait for a bot with a warm cache to pick up the
   714        // task, before falling back to a bot with a cold (non-existent) cache.
   715        //
   716        // The default is 0, which means that no preference will be chosen for a
   717        // bot with this or without this cache, and a bot without this cache may
   718        // be chosen instead.
   719        //
   720        // If no bot has this cache warm, the task will skip this wait and will
   721        // immediately fallback to a cold cache request.
   722        //
   723        // The value must be multiples of 60 seconds.
   724        google.protobuf.Duration wait_for_warm_cache = 3;
   725  
   726        // Environment variable with this name will be set to the path to the cache
   727        // directory.
   728        string env_var = 4;
   729      }
   730  
   731      // Swarming hostname, e.g. "chromium-swarm.appspot.com".
   732      // Populated at the build creation time.
   733      string hostname = 1 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   734  
   735      // Swarming task id.
   736      // Not guaranteed to be populated at the build creation time.
   737      string task_id = 2 [ (google.api.field_behavior) = OUTPUT_ONLY ];
   738  
   739      // Swarming run id of the parent task from which this build is triggered.
   740      // If set, swarming promises to ensure this build won't outlive its parent
   741      // swarming task (which may or may not itself be a Buildbucket build).
   742      // Populated at the build creation time.
   743      string parent_run_id = 9;
   744  
   745      // Task service account email address.
   746      // This is the service account used for all authenticated requests by the
   747      // build.
   748      string task_service_account = 3;
   749  
   750      // Priority of the task. The lower the more important.
   751      // Valid values are [20..255].
   752      int32 priority = 4;
   753  
   754      // Swarming dimensions for the task.
   755      repeated RequestedDimension task_dimensions = 5;
   756  
   757      // Swarming dimensions of the bot used for the task.
   758      repeated StringPair bot_dimensions = 6;
   759  
   760      // Caches requested by this build.
   761      repeated CacheEntry caches = 7;
   762    }
   763  
   764    // LogDog-specific information.
   765    message LogDog {
   766      // LogDog hostname, e.g. "logs.chromium.org".
   767      string hostname = 1 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   768  
   769      // LogDog project, e.g. "chromium".
   770      // Typically matches Build.builder.project.
   771      string project = 2;
   772  
   773      // A slash-separated path prefix shared by all logs and artifacts of this
   774      // build.
   775      // No other build can have the same prefix.
   776      // Can be used to discover logs and/or load log contents.
   777      string prefix = 3;
   778    }
   779  
   780    // Recipe-specific information.
   781    message Recipe {
   782      // CIPD package name containing the recipe used to run this build.
   783      string cipd_package = 1;
   784  
   785      // Name of the recipe used to run this build.
   786      string name = 2;
   787    }
   788  
   789    // ResultDB-specific information.
   790    message ResultDB {
   791      // Hostname of the ResultDB instance, such as "results.api.cr.dev".
   792      string hostname = 1 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   793  
   794      // Name of the invocation for results of this build.
   795      // Typically "invocations/build:<build_id>".
   796      string invocation = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
   797  
   798      // Whether to enable ResultDB:Buildbucket integration.
   799      bool enable = 3;
   800  
   801      // Configuration for exporting test results to BigQuery.
   802      // This can have multiple values to export results to multiple BigQuery
   803      // tables, or to support multiple test result predicates.
   804      repeated luci.resultdb.v1.BigQueryExport bq_exports = 4;
   805  
   806      // Deprecated. Any values specified here are ignored.
   807      luci.resultdb.v1.HistoryOptions history_options = 5;
   808    }
   809  
   810    // Led specific information.
   811    message Led {
   812      // The original bucket this led build is shadowing.
   813      string shadowed_bucket = 1;
   814    }
   815  
   816    // BBAgent-specific information.
   817    //
   818    // All paths are relateive to bbagent's working directory, and must be delimited
   819    // with slashes ("/"), regardless of the host OS.
   820    message BBAgent {
   821      // BBAgent-specific input.
   822      message Input {
   823        // CIPD Packages to make available for this build.
   824        message CIPDPackage {
   825          // Name of this CIPD package.
   826          //
   827          // Required.
   828          string name = 1;
   829  
   830          // CIPD package version.
   831          //
   832          // Required.
   833          string version = 2;
   834  
   835          // CIPD server to fetch this package from.
   836          //
   837          // Required.
   838          string server = 3;
   839  
   840          // Path where this CIPD package should be installed.
   841          //
   842          // Required.
   843          string path = 4;
   844        }
   845  
   846        repeated CIPDPackage cipd_packages = 1;
   847      }
   848      // Path to the base of the user executable package.
   849      //
   850      // Required.
   851      string payload_path = 1;
   852  
   853      // Path to a directory where each subdirectory is a cache dir.
   854      //
   855      // Required.
   856      string cache_dir = 2;
   857  
   858      // List of Gerrit hosts to force git authentication for.
   859      //
   860      // By default public hosts are accessed anonymously, and the anonymous access
   861      // has very low quota. Context needs to know all such hostnames in advance to
   862      // be able to force authenticated access to them.
   863      repeated string known_public_gerrit_hosts = 3 [deprecated = true];
   864  
   865      // DEPRECATED: Use build.Infra.Buildbucket.Agent.Input instead.
   866      Input input = 4 [deprecated = true];
   867    }
   868  
   869    // Backend-specific information.
   870    message Backend {
   871      // Configuration supplied to the backend at the time it was instructed to
   872      // run this build.
   873      google.protobuf.Struct config = 1;
   874  
   875      // Current backend task status.
   876      // Updated as build runs.
   877      Task task = 2;
   878  
   879      // Caches requested by this build.
   880      repeated CacheEntry caches = 3;
   881  
   882      // Dimensions for the task.
   883      repeated RequestedDimension task_dimensions = 5;
   884  
   885      // Hostname is the hostname for the backend itself.
   886      string hostname = 6;
   887    }
   888  
   889    Buildbucket buildbucket = 1 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   890    Swarming swarming = 2;
   891    LogDog logdog = 3 [ (buildbucket.v2.create_build_field_option).field_behavior = REQUIRED ];
   892    Recipe recipe = 4;
   893    ResultDB resultdb = 5 [ (visible_with) = BUILDS_GET_LIMITED_PERMISSION ];
   894    BBAgent bbagent = 6;
   895    Backend backend = 7;
   896    // It should only be set for led builds.
   897    Led led = 8;
   898  }