blob: 814ab9b716c513a7c8701030c04bdab63d0dedfb [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/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
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) {};
}
// 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 ;
}
}
// 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;
// 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.status
// - build.status_details
// - build.steps
// - build.summary_markdown
// - build.tags
// - build.infra.buildbucket.agent.output
// - build.infra.buildbucket.agent.purposes
//
// 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: 22.
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.
//
// 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;
}
// A request message for CancelBuild rpc.
message CancelBuildRequest {
// ID of the build to cancel.
int64 id = 1;
// Required. Value for Build.summary_markdown.
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;
// 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;
}
// 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;
}