blob: b7635cbe1cc1ec9d20d1db055aa4ec2a6f14e2ba [file] [log] [blame]
// Copyright 2020 The Swarming Authors. All rights reserved.
// Use of this source code is governed by the Apache v2.0 license that can be
// found in the LICENSE file.
syntax = "proto3";
package buildbucket.v2;
option go_package = "go.chromium.org/luci/buildbucket/proto;buildbucketpb";
import "google/api/field_behavior.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/struct.proto";
import "google/rpc/status.proto";
import "go.chromium.org/luci/buildbucket/proto/build.proto";
import "go.chromium.org/luci/buildbucket/proto/builder_common.proto";
import "go.chromium.org/luci/buildbucket/proto/common.proto";
import "go.chromium.org/luci/buildbucket/proto/notification.proto";
import "go.chromium.org/luci/common/proto/structmask/structmask.proto";
// Manages builds.
//
// Buildbot: To simplify V1->V2 API transition for clients, buildbucket.v2.Builds
// service has some support for non-LUCI builds. Most of such builds are
// Buildbot builds and this documentation refers to them as such, but they also
// include non-Buildbot non-LUCI builds (e.g. Skia builds).
// See "Buildbot" paragraph in each RPC comment.
service Builds {
// Gets a build.
//
// By default the returned build does not include all fields.
// See GetBuildRequest.mask.
//
// Buildbot: if the specified build is a buildbot build, converts it to Build
// message with the following rules:
// * bucket names are full, e.g. "luci.infra.try". Note that LUCI buckets
// in v2 are shortened, e.g. "try".
// * if a v2 Build field does not make sense in V1, it is unset/empty.
// * step support is not implemented for Buildbot builds.
// Note that it does not support getting a buildbot build by build number.
// Examples: go/buildbucket-rpc#getbuild
//
// GetBuild is good for getting detailed information for a build.
// For use cases that only requires build status checking (e.g. wait for a
// build to complete), please use GetBuildStatus instead.
rpc GetBuild(GetBuildRequest) returns (Build) {};
// Searches for builds.
// Examples: go/buildbucket-rpc#searchbuilds
rpc SearchBuilds(SearchBuildsRequest) returns (SearchBuildsResponse) {};
// Updates a build.
//
// RPC metadata must include "x-buildbucket-token" key with a token
// generated by the server when scheduling the build.
rpc UpdateBuild(UpdateBuildRequest) returns (Build) {};
// Schedules a new build.
// The requester must have at least SCHEDULER role in the destination bucket.
// Example: go/buildbucket-rpc#schedulebuild
rpc ScheduleBuild(ScheduleBuildRequest) returns (Build) {};
// Cancels a build.
// The requester must have at least SCHEDULER role in the destination bucket.
// Note that cancelling a build in ended state (meaning build is not in
// STATUS_UNSPECIFIED, SCHEDULED or STARTED status) will be a no-op and
// directly return up-to-date Build message.
//
// When called, Buildbucket will set the build's cancelTime to "now". It
// will also recursively start the cancellation process for any children of
// this build which are marked as can_outlive_parent=false.
//
// The next time the build checks in (which happens periodically in
// `bbagent`), bbagent will see the cancelTime, and start the cancellation
// process described by the 'deadline' section in
// https://chromium.googlesource.com/infra/luci/luci-py/+/HEAD/client/LUCI_CONTEXT.md.
//
// If the build ends before the build's grace_period, then the final status
// reported from the build is accepted; this is considered 'graceful termination'.
//
// If the build doesn't end within the build's grace_period, Buildbucket will
// forcibly cancel the build.
rpc CancelBuild(CancelBuildRequest) returns (Build) {};
// Executes multiple requests in a batch.
// The response code is always OK.
// Examples: go/buildbucket-rpc#batch
rpc Batch(BatchRequest) returns (BatchResponse) {};
// Creates a new build for the provided build proto.
//
// If build with the given ID already exists, returns ALREADY_EXISTS
// error code.
rpc CreateBuild(CreateBuildRequest) returns (Build) {};
// Synthesizes a build proto.
//
// This RPC is exclusively for generating led builds.
rpc SynthesizeBuild(SynthesizeBuildRequest) returns (Build) {};
// Gets a build's status.
//
// The returned build contains the requested build id or
// (builder + build number), and build status.
//
// It's useful when a user only wants to check the build's status (i.e. wait
// for a build to complete).
rpc GetBuildStatus(GetBuildStatusRequest) returns (Build) {};
// Starts a build.
//
// RPC metadata must include "x-buildbucket-token" key with
// * a BUILD type token generated by the server when it creates a Swarming
// task for the build (builds on Swarming) or
// * a START_BUILD type token generated by the server when it attempts to run
// a backend task (builds on TaskBackend).
//
// Agent must call it before making any UpdateBuild calls.
//
// StartBuild will associate a task with a build if the association is not done
// after RunTaskResponse is returned to buildbucket.
rpc StartBuild(StartBuildRequest) returns (StartBuildResponse) {};
}
// A request message for GetBuild RPC.
message GetBuildRequest {
// Build ID.
// Mutually exclusive with builder and number.
int64 id = 1;
// Builder of the build.
// Requires number. Mutually exclusive with id.
BuilderID builder = 2;
// Build number.
// Requires builder. Mutually exclusive with id.
int32 build_number = 3;
// Fields to include in the response.
//
// DEPRECATED: Use mask instead.
//
// If not set, the default mask is used, see Build message comments for the
// list of fields returned by default.
//
// Supports advanced semantics, see
// https://chromium.googlesource.com/infra/luci/luci-py/+/f9ae69a37c4bdd0e08a8b0f7e123f6e403e774eb/appengine/components/components/protoutil/field_masks.py#7
// In particular, if the client needs only some output properties, they
// can be requested with paths "output.properties.fields.foo".
google.protobuf.FieldMask fields = 100 [deprecated = true];
// What portion of the Build message to return.
//
// If not set, the default mask is used, see Build message comments for the
// list of fields returned by default.
BuildMask mask = 101;
}
// A request message for SearchBuilds RPC.
message SearchBuildsRequest {
// Returned builds must satisfy this predicate. Required.
BuildPredicate predicate = 1;
// Fields to include in the response, see GetBuildRequest.fields.
//
// DEPRECATED: Use mask instead.
//
// Note that this applies to the response, not each build, so e.g. steps must
// be requested with a path "builds.*.steps".
google.protobuf.FieldMask fields = 100 [deprecated = true];
// What portion of the Build message to return.
//
// If not set, the default mask is used, see Build message comments for the
// list of fields returned by default.
BuildMask mask = 103;
// Number of builds to return.
// Defaults to 100.
// Any value >1000 is interpreted as 1000.
int32 page_size = 101;
// Value of SearchBuildsResponse.next_page_token from the previous response.
// Use it to continue searching.
// The predicate and page_size in this request MUST be exactly same as in the
// previous request.
string page_token = 102;
}
// A response message for SearchBuilds RPC.
message SearchBuildsResponse {
// Search results.
//
// Ordered by build ID, descending. IDs are monotonically decreasing, so in
// other words the order is newest-to-oldest.
repeated Build builds = 1;
// Value for SearchBuildsRequest.page_token to continue searching.
string next_page_token = 100;
}
// A request message for Batch RPC.
message BatchRequest {
// One request in a batch.
message Request {
oneof request {
GetBuildRequest get_build = 1;
SearchBuildsRequest search_builds = 2;
ScheduleBuildRequest schedule_build = 3;
CancelBuildRequest cancel_build = 4 ;
GetBuildStatusRequest get_build_status = 5;
}
}
// Requests to execute in a single batch.
//
// * All requests are executed in their own individual transactions.
// * BatchRequest as a whole is not transactional.
// * There's no guaranteed order of execution between batch items (i.e.
// consider them to all operate independently).
// * There is a limit of 200 requests per batch.
repeated Request requests = 1;
}
// A response message for Batch RPC.
message BatchResponse {
// Response a BatchRequest.Response.
message Response {
oneof response {
Build get_build = 1;
SearchBuildsResponse search_builds = 2;
Build schedule_build = 3;
Build cancel_build = 4;
Build get_build_status = 5;
// Error code and details of the unsuccessful RPC.
google.rpc.Status error = 100;
}
}
// Responses in the same order as BatchRequest.requests.
repeated Response responses = 1;
}
// A request message for UpdateBuild RPC.
message UpdateBuildRequest {
// Build to update, with new field values.
Build build = 1;
// Build fields to update.
// See also
// https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#fieldmask
//
// Currently supports only the following path strings:
// - build.output
// - build.output.properties
// - build.output.gitiles_commit
// - build.output.status
// - build.output.status_details
// - build.output.summary_markdown
// - build.status
// - build.status_details
// - build.steps
// - build.summary_markdown
// - build.tags
// - build.infra.buildbucket.agent.output
// - build.infra.buildbucket.agent.purposes
//
// Note, "build.output.status" is required explicitly to update the field.
// If there is only "build.output" in update_mask, build.output.status will not
// be updated.
//
// If omitted, Buildbucket will update the Build's update_time, but nothing else.
google.protobuf.FieldMask update_mask = 2;
// Fields to include in the response. See also GetBuildRequest.fields.
//
// DEPRECATED: Use mask instead.
google.protobuf.FieldMask fields = 100 [deprecated = true];
// What portion of the Build message to return.
//
// If not set, an empty build will be returned.
BuildMask mask = 101;
}
// A request message for ScheduleBuild RPC.
//
// Next ID: 25.
message ScheduleBuildRequest {
// ** STRONGLY RECOMMENDED **.
// A unique string id used for detecting duplicate requests.
// Should be unique at least per requesting identity.
// Used to dedup build scheduling requests with same id within 1 min.
// If a build was successfully scheduled with the same request id in the past
// minute, the existing build will be returned.
string request_id = 1;
// ID of a build to retry as is or altered.
// When specified, fields below default to the values in the template build.
int64 template_build_id = 2;
// Value for Build.builder. See its comments.
// Required, unless template_build_id is specified.
BuilderID builder = 3;
// DEPRECATED
//
// Set "luci.buildbucket.canary_software" in `experiments` instead.
//
// YES sets "luci.buildbucket.canary_software" to true in `experiments`.
// NO sets "luci.buildbucket.canary_software" to false in `experiments`.
Trinary canary = 4;
// DEPRECATED
//
// Set "luci.non_production" in `experiments` instead.
//
// YES sets "luci.non_production" to true in `experiments`.
// NO sets "luci.non_production" to false in `experiments`.
Trinary experimental = 5;
// Sets (or prevents) these experiments on the scheduled build.
//
// See `Builder.experiments` for well-known experiments.
map<string, bool> experiments = 16;
// Properties to include in Build.input.properties.
//
// Input properties of the created build are result of merging server-defined
// properties and properties in this field.
// Each property in this field defines a new or replaces an existing property
// on the server.
// If the server config does not allow overriding/adding the property, the
// request will fail with InvalidArgument error code.
// A server-defined property cannot be removed, but its value can be
// replaced with null.
//
// Reserved property paths:
// ["$recipe_engine/buildbucket"]
// ["$recipe_engine/runtime", "is_experimental"]
// ["$recipe_engine/runtime", "is_luci"]
// ["branch"]
// ["buildbucket"]
// ["buildername"]
// ["repository"]
//
// The Builder configuration specifies which top-level property names are
// overridable via the `allowed_property_overrides` field. ScheduleBuild
// requests which attempt to override a property which isn't allowed will
// fail with InvalidArgument.
//
// V1 equivalent: corresponds to "properties" key in "parameters_json".
google.protobuf.Struct properties = 6;
// Value for Build.input.gitiles_commit.
//
// Setting this field will cause the created build to have a "buildset"
// tag with value "commit/gitiles/{hostname}/{project}/+/{id}".
//
// GitilesCommit objects MUST have host, project, ref fields set.
//
// V1 equivalent: supersedes "revision" property and "buildset"
// tag that starts with "commit/gitiles/".
GitilesCommit gitiles_commit = 7;
// Value for Build.input.gerrit_changes.
// Usually present in tryjobs, set by CQ, Gerrit, git-cl-try.
// Applied on top of gitiles_commit if specified, otherwise tip of the tree.
// All GerritChange fields are required.
//
// Setting this field will cause the created build to have a "buildset"
// tag with value "patch/gerrit/{hostname}/{change}/{patchset}"
// for each change.
//
// V1 equivalent: supersedes patch_* properties and "buildset"
// tag that starts with "patch/gerrit/".
repeated GerritChange gerrit_changes = 8;
// Tags to include in Build.tags of the created build, see Build.tags
// comments.
// Note: tags of the created build may include other tags defined on the
// server.
repeated StringPair tags = 9;
// Overrides default dimensions defined by builder config or template build.
//
// A set of entries with the same key defines a new or replaces an existing
// dimension with the same key.
// If the config does not allow overriding/adding the dimension, the request
// will fail with InvalidArgument error code.
//
// After merging, dimensions with empty value will be excluded.
//
// Note: For the same key dimensions, it won't allow to pass empty and
// non-empty values at the same time in the request.
//
// Note: "caches" and "pool" dimensions may only be specified in builder
// configs. Setting them hear will fail the request.
//
// A dimension expiration must be a multiple of 1min.
repeated RequestedDimension dimensions = 10;
// If not zero, overrides swarming task priority.
// See also Build.infra.swarming.priority.
int32 priority = 11;
// A per-build notification configuration.
NotificationConfig notify = 12;
// Fields to include in the response. See also GetBuildRequest.fields.
//
// DEPRECATED: Use mask instead.
google.protobuf.FieldMask fields = 100 [deprecated = true];
// What portion of the Build message to return.
//
// If not set, the default mask is used, see Build message comments for the
// list of fields returned by default.
BuildMask mask = 101;
// Value for Build.critical.
Trinary critical = 13;
// Overrides Builder.exe in the config.
// Supported subfields: cipd_version.
Executable exe = 14;
// Swarming specific part of the build request.
message Swarming {
// If specified, parent_run_id should match actual Swarming task run ID the
// caller is running as and results in swarming server ensuring that the newly
// triggered build will not outlive its parent.
//
// Typical use is for triggering and waiting on child build(s) from within
// 1 parent build and if child build(s) on their own aren't useful. Then,
// if parent build ends for whatever reason, all not yet finished child
// builds aren't useful and it's desirable to terminate them, too.
//
// If the Builder config does not specify a swarming backend, the request
// will fail with InvalidArgument error code.
//
// The parent_run_id is assumed to be from the same swarming server as the
// one the new build is to be executed on. The ScheduleBuildRequest doesn't
// check if parent_run_id refers to actually existing task, but eventually
// the new build will fail if so.
string parent_run_id = 1;
}
// Swarming specific part of the build request.
Swarming swarming = 15;
// Maximum build pending time.
//
// If set, overrides the default `expiration_secs` set in builder config.
// Only supports seconds precision for now.
// For more information, see Build.scheduling_timeout in build.proto.
google.protobuf.Duration scheduling_timeout = 17;
// Maximum build execution time.
//
// If set, overrides the default `execution_timeout_secs` set in builder config.
// Only supports seconds precision for now.
// For more information, see Build.execution_timeout in build.proto.
google.protobuf.Duration execution_timeout = 18;
// Amount of cleanup time after execution_timeout.
//
// If set, overrides the default `grace_period` set in builder config.
// Only supports seconds precision for now.
// For more information, see Build.grace_period in build.proto.
google.protobuf.Duration grace_period = 19;
// Whether or not this request constitutes a dry run.
//
// A dry run returns the build proto without actually scheduling it. All
// fields except those which can only be computed at run-time are filled in.
// Does not cause side-effects. When batching, all requests must specify the
// same value for dry_run.
bool dry_run = 20;
// Flag to control if the build can outlive its parent.
//
// If the value is UNSET, it means this build doesn't have any parent, so
// the request must not have a head with any BuildToken.
//
// If the value is anything other than UNSET, then the BuildToken for the
// parent build must be set as a header.
// Note: it's not currently possible to establish parent/child relationship
// except via the parent build at the time the build is launched.
//
// If the value is NO, it means that the build SHOULD reach a terminal status
// (SUCCESS, FAILURE, INFRA_FAILURE or CANCELED) before its parent. If the
// child fails to do so, Buildbucket will cancel it some time after the
// parent build reaches a terminal status.
//
// A build that can outlive its parent can also outlive its parent's ancestors.
//
// If schedule a build without parent, this field must be UNSET.
//
// If schedule a build with parent, this field should be YES or NO.
// But UNSET is also accepted for now, and it has the same effect as YES.
// TODO(crbug.com/1031205): after the parent tracking feature is stable,
// require this field to be set when scheduling a build with parent.
Trinary can_outlive_parent = 21;
// Value for Build.retriable.
Trinary retriable = 22;
// Information for scheduling a build as a shadow build.
message ShadowInput {
}
// Input for scheduling a build in the shadow bucket.
//
// If this field is set, it means the build to be scheduled will
// * be scheduled in the shadow bucket of the requested bucket, with shadow
// adjustments on service_account, dimensions and properties.
// * inherit its parent build's agent input and agent source if it has a parent.
ShadowInput shadow_input = 23;
// ResultDB-specific part of build request.
message ResultDB {
// Whether to create the ResultDB invocation for this build as an export
// root. See ResultDB invocation.is_export_root for more information.
//
// By default, only buildbucket builds that do not have a parent are
// defined as an export root, as invocations for child builds are included
// in their parents.
bool is_export_root_override = 1;
}
// ResultDB-specific part of the build request.
ResultDB resultdb = 24;
}
// A request message for CancelBuild RPC.
message CancelBuildRequest {
// ID of the build to cancel.
int64 id = 1;
// Required. Value for Build.cancellation_markdown. Will be appended to
// Build.summary_markdown when exporting to bigquery and returned via GetBuild.
string summary_markdown = 2;
// Fields to include in the response. See also GetBuildRequest.fields.
//
// DEPRECATED: Use mask instead.
google.protobuf.FieldMask fields = 100 [deprecated = true];
// What portion of the Build message to return.
//
// If not set, the default mask is used, see Build message comments for the
// list of fields returned by default.
BuildMask mask = 101;
}
// A request message for CreateBuild RPC.
message CreateBuildRequest {
// The Build to be created.
Build build = 1 [(google.api.field_behavior) = REQUIRED];
// A unique identifier for this request.
// A random UUID is recommended.
// This request is only idempotent if a `request_id` is provided.
string request_id = 2;
// What portion of the Build message to return.
//
// If not set, the default mask is used, see Build message comments for the
// list of fields returned by default.
BuildMask mask = 3;
}
// A request message for SynthesizeBuild RPC.
message SynthesizeBuildRequest {
// ID of a build to use as the template.
// Mutually exclusive with builder.
int64 template_build_id = 1;
// Value for Build.builder. See its comments.
// Required, unless template_build_id is specified.
BuilderID builder = 2;
// Sets (or prevents) these experiments on the synthesized build.
//
// See `Builder.experiments` for well-known experiments.
map<string, bool> experiments = 3;
}
// A request message for StartBuild RPC.
message StartBuildRequest {
// A nonce to deduplicate requests.
string request_id = 1 [(google.api.field_behavior) = REQUIRED];
// Id of the build to start.
int64 build_id = 2 [(google.api.field_behavior) = REQUIRED];
// Id of the task running the started build.
string task_id = 3 [(google.api.field_behavior) = REQUIRED];
}
// A response message for StartBuild RPC.
message StartBuildResponse {
// The whole proto of the started build.
Build build = 1;
// a build token for agent to use when making subsequent UpdateBuild calls.
string update_build_token = 2;
}
// A request message for GetBuildStatus RPC.
message GetBuildStatusRequest {
// Build ID.
// Mutually exclusive with builder and number.
int64 id = 1;
// Builder of the build.
// Requires number. Mutually exclusive with id.
BuilderID builder = 2;
// Build number.
// Requires builder. Mutually exclusive with id.
int32 build_number = 3;
}
// Defines a subset of Build fields and properties to return.
message BuildMask {
// Fields of the Build proto to include.
//
// Follows the standard FieldMask semantics as documented at e.g.
// https://pkg.go.dev/google.golang.org/protobuf/types/known/fieldmaskpb.
//
// If not set, the default mask is used, see Build message comments for the
// list of fields returned by default.
google.protobuf.FieldMask fields = 1;
// Defines a subset of `input.properties` to return.
//
// When not empty, implicitly adds the corresponding field to `fields`.
repeated structmask.StructMask input_properties = 2;
// Defines a subset of `output.properties` to return.
//
// When not empty, implicitly adds the corresponding field to `fields`.
repeated structmask.StructMask output_properties = 3;
// Defines a subset of `infra.buildbucket.requested_properties` to return.
//
// When not empty, implicitly adds the corresponding field to `fields`.
repeated structmask.StructMask requested_properties = 4;
// Flag for including all fields.
//
// Mutually exclusive with `fields`, `input_properties`, `output_properties`,
// and `requested_properties`.
bool all_fields = 5;
// A status to filter returned `steps` by. If unspecified, no filter is
// applied. Otherwise filters by the union of the given statuses.
//
// No effect unless `fields` specifies that `steps` should be returned or
// `all_fields` is true.
repeated Status step_status = 6;
}
// A build predicate.
//
// At least one of the following fields is required: builder, gerrit_changes and
// git_commits.
// If a field value is empty, it is ignored, unless stated otherwise.
message BuildPredicate {
// A build must be in this builder.
BuilderID builder = 1;
// A build must have this status.
Status status = 2;
// A build's Build.Input.gerrit_changes must include ALL of these changes.
repeated GerritChange gerrit_changes = 3;
// DEPRECATED
//
// Never implemented.
GitilesCommit output_gitiles_commit = 4;
// A build must be created by this identity.
string created_by = 5;
// A build must have ALL of these tags.
// For "ANY of these tags" make separate RPCs.
repeated StringPair tags = 6;
// A build must have been created within the specified range.
// Both boundaries are optional.
TimeRange create_time = 7;
// If false (the default), equivalent to filtering by experiment
// "-luci.non_production".
//
// If true, has no effect (both production and non_production builds will be
// returned).
//
// NOTE: If you explicitly search for non_production builds with the experiment
// filter "+luci.non_production", this is implied to be true.
//
// See `Builder.experiments` for well-known experiments.
bool include_experimental = 8;
// A build must be in this build range.
BuildRange build = 9;
// DEPRECATED
//
// If YES, equivalent to filtering by experiment
// "+luci.buildbucket.canary_software".
//
// If NO, equivalent to filtering by experiment
// "-luci.buildbucket.canary_software".
//
// See `Builder.experiments` for well-known experiments.
Trinary canary = 10;
// A list of experiments to include or exclude from the search results.
//
// Each entry should look like "[-+]$experiment_name".
//
// A "+" prefix means that returned builds MUST have that experiment set.
// A "-" prefix means that returned builds MUST NOT have that experiment set
// AND that experiment was known for the builder at the time the build
// was scheduled (either via `Builder.experiments` or via
// `ScheduleBuildRequest.experiments`). Well-known experiments are always
// considered to be available.
repeated string experiments = 11;
// A build ID.
//
// Returned builds will be descendants of this build (e.g. "100" means
// "any build transitively scheduled starting from build 100").
//
// Mutually exclusive with `child_of`.
int64 descendant_of = 12;
// A build ID.
//
// Returned builds will be only the immediate children of this build.
//
// Mutually exclusive with `descendant_of`.
int64 child_of = 13;
}
// Open build range.
message BuildRange {
// Inclusive lower (less recent build) boundary. Optional.
int64 start_build_id = 1;
// Inclusive upper (more recent build) boundary. Optional.
int64 end_build_id = 2;
}