// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.devtools.cloudbuild.v1;

import "google/api/annotations.proto";
import "google/longrunning/operations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

option go_package = "google.golang.org/genproto/googleapis/devtools/cloudbuild/v1;cloudbuild";
option java_multiple_files = true;
option java_package = "com.google.cloudbuild.v1";
option objc_class_prefix = "GCB";


// Manages container image build requests in the cloud.
//
// The main concept used by this API is a Build, which describes the location of
// the source to build, how to build the source into a container image, and what
// tag to apply to the built image when it is pushed to Google Container
// Registry.
//
// A user can list previously-requested builds or get builds by their ID to
// determine the status of the build.
service CloudBuild {
  // Starts a build with the specified configuration.
  //
  // The long-running Operation returned by this method will include the ID of
  // the build, which can be passed to GetBuild to determine its status (e.g.,
  // success or failure).
  rpc CreateBuild(CreateBuildRequest) returns (google.longrunning.Operation) {
    option (google.api.http) = { post: "/v1/projects/{project_id}/builds" body: "build" };
  }

  // Returns information about a previously requested build.
  //
  // The Build that is returned includes its status (e.g., success or failure,
  // or in-progress), and timing information.
  rpc GetBuild(GetBuildRequest) returns (Build) {
    option (google.api.http) = { get: "/v1/projects/{project_id}/builds/{id}" };
  }

  // Lists previously requested builds.
  //
  // Previously requested builds may still be in-progress, or may have finished
  // successfully or unsuccessfully.
  rpc ListBuilds(ListBuildsRequest) returns (ListBuildsResponse) {
    option (google.api.http) = { get: "/v1/projects/{project_id}/builds" };
  }

  // Cancels a requested build in progress.
  rpc CancelBuild(CancelBuildRequest) returns (Build) {
    option (google.api.http) = { post: "/v1/projects/{project_id}/builds/{id}:cancel" body: "*" };
  }

  // Creates a new BuildTrigger.
  //
  // This API is experimental.
  rpc CreateBuildTrigger(CreateBuildTriggerRequest) returns (BuildTrigger) {
    option (google.api.http) = { post: "/v1/projects/{project_id}/triggers" body: "trigger" };
  }

  // Gets information about a BuildTrigger.
  //
  // This API is experimental.
  rpc GetBuildTrigger(GetBuildTriggerRequest) returns (BuildTrigger) {
    option (google.api.http) = { get: "/v1/projects/{project_id}/triggers/{trigger_id}" };
  }

  // Lists existing BuildTrigger.
  //
  // This API is experimental.
  rpc ListBuildTriggers(ListBuildTriggersRequest) returns (ListBuildTriggersResponse) {
    option (google.api.http) = { get: "/v1/projects/{project_id}/triggers" };
  }

  // Deletes an BuildTrigger by its project ID and trigger ID.
  //
  // This API is experimental.
  rpc DeleteBuildTrigger(DeleteBuildTriggerRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = { delete: "/v1/projects/{project_id}/triggers/{trigger_id}" };
  }

  // Updates an BuildTrigger by its project ID and trigger ID.
  //
  // This API is experimental.
  rpc UpdateBuildTrigger(UpdateBuildTriggerRequest) returns (BuildTrigger) {
    option (google.api.http) = { patch: "/v1/projects/{project_id}/triggers/{trigger_id}" body: "trigger" };
  }
}

// StorageSource describes the location of the source in an archive file in
// Google Cloud Storage.
message StorageSource {
  // Google Cloud Storage bucket containing source (see
  // [Bucket Name
  // Requirements](https://cloud.google.com/storage/docs/bucket-naming#requirements)).
  string bucket = 1;

  // Google Cloud Storage object containing source.
  //
  // This object must be a gzipped archive file (.tar.gz) containing source to
  // build.
  string object = 2;

  // Google Cloud Storage generation for the object. If the generation is
  // omitted, the latest generation will be used.
  int64 generation = 3;
}

// RepoSource describes the location of the source in a Google Cloud Source
// Repository.
message RepoSource {
  // ID of the project that owns the repo. If omitted, the project ID requesting
  // the build is assumed.
  string project_id = 1;

  // Name of the repo. If omitted, the name "default" is assumed.
  string repo_name = 2;

  // A revision within the source repository must be specified in
  // one of these ways.
  oneof revision {
    // Name of the branch to build.
    string branch_name = 3;

    // Name of the tag to build.
    string tag_name = 4;

    // Explicit commit SHA to build.
    string commit_sha = 5;
  }
}

// Source describes the location of the source in a supported storage
// service.
message Source {
  // Describes location of source.
  oneof source {
    // If provided, get the source from this location in in Google Cloud
    // Storage.
    StorageSource storage_source = 2;

    // If provided, get source from this location in a Cloud Repo.
    RepoSource repo_source = 3;
  }
}

// BuiltImage describes an image built by the pipeline.
message BuiltImage {
  // Name used to push the container image to Google Container Registry, as
  // presented to `docker push`.
  string name = 1;

  // Docker Registry 2.0 digest.
  string digest = 3;
}

// BuildStep describes a step to perform in the build pipeline.
message BuildStep {
  // The name of the container image that will run this particular build step.
  //
  // If the image is already available in the host's Docker daemon's cache, it
  // will be run directly. If not, the host will attempt to pull the image
  // first, using the builder service account's credentials if necessary.
  //
  // The Docker daemon's cache will already have the latest versions of all of
  // the officially supported build steps
  // ([https://github.com/GoogleCloudPlatform/cloud-builders](https://github.com/GoogleCloudPlatform/cloud-builders)).
  // The Docker daemon will also have cached many of the layers for some popular
  // images, like "ubuntu", "debian", but they will be refreshed at the time you
  // attempt to use them.
  //
  // If you built an image in a previous build step, it will be stored in the
  // host's Docker daemon's cache and is available to use as the name for a
  // later build step.
  string name = 1;

  // A list of environment variable definitions to be used when running a step.
  //
  // The elements are of the form "KEY=VALUE" for the environment variable "KEY"
  // being given the value "VALUE".
  repeated string env = 2;

  // A list of arguments that will be presented to the step when it is started.
  //
  // If the image used to run the step's container has an entrypoint, these args
  // will be used as arguments to that entrypoint. If the image does not define
  // an entrypoint, the first element in args will be used as the entrypoint,
  // and the remainder will be used as arguments.
  repeated string args = 3;

  // Working directory (relative to project source root) to use when running
  // this operation's container.
  string dir = 4;

  // Optional unique identifier for this build step, used in wait_for to
  // reference this build step as a dependency.
  string id = 5;

  // The ID(s) of the step(s) that this build step depends on.
  // This build step will not start until all the build steps in wait_for
  // have completed successfully. If wait_for is empty, this build step will
  // start when all previous build steps in the Build.Steps list have completed
  // successfully.
  repeated string wait_for = 6;

  // Optional entrypoint to be used instead of the build step image's default
  // If unset, the image's default will be used.
  string entrypoint = 7;

  // A list of environment variables which are encrypted using a Cloud KMS
  // crypto key. These values must be specified in the build's secrets.
  repeated string secret_env = 8;

  // List of volumes to mount into the build step.
  //
  // Each volume will be created as an empty volume prior to execution of the
  // build step. Upon completion of the build, volumes and their contents will
  // be discarded.
  //
  // Using a named volume in only one step is not valid as it is indicative
  // of a mis-configured build request.
  repeated Volume volumes = 9;
}

// Volume describes a Docker container volume which is mounted into build steps
// in order to persist files across build step execution.
message Volume {
  // Name of the volume to mount.
  //
  // Volume names must be unique per build step and must be valid names for
  // Docker volumes. Each named volume must be used by at least two build steps.
  string name = 1;

  // Path at which to mount the volume.
  //
  // Paths must be absolute and cannot conflict with other volume paths on the
  // same build step or with certain reserved volume paths.
  string path = 2;
}

// Results describes the artifacts created by the build pipeline.
message Results {
  // Images that were built as a part of the build.
  repeated BuiltImage images = 2;

  // List of build step digests, in order corresponding to build step indices.
  repeated string build_step_images = 3;
}

// A build resource in the Container Builder API.
//
// At a high level, a Build describes where to find source code, how to build
// it (for example, the builder image to run on the source), and what tag to
// apply to the built image when it is pushed to Google Container Registry.
//
// Fields can include the following variables which will be expanded when the
// build is created:
//
// - $PROJECT_ID: the project ID of the build.
// - $BUILD_ID: the autogenerated ID of the build.
// - $REPO_NAME: the source repository name specified by RepoSource.
// - $BRANCH_NAME: the branch name specified by RepoSource.
// - $TAG_NAME: the tag name specified by RepoSource.
// - $REVISION_ID or $COMMIT_SHA: the commit SHA specified by RepoSource or
//   resolved from the specified branch or tag.
message Build {
  // Possible status of a build.
  enum Status {
    // Status of the build is unknown.
    STATUS_UNKNOWN = 0;

    // Build is queued; work has not yet begun.
    QUEUED = 1;

    // Build is being executed.
    WORKING = 2;

    // Build finished successfully.
    SUCCESS = 3;

    // Build failed to complete successfully.
    FAILURE = 4;

    // Build failed due to an internal cause.
    INTERNAL_ERROR = 5;

    // Build took longer than was allowed.
    TIMEOUT = 6;

    // Build was canceled by a user.
    CANCELLED = 7;
  }

  // Unique identifier of the build.
  // @OutputOnly
  string id = 1;

  // ID of the project.
  // @OutputOnly.
  string project_id = 16;

  // Status of the build.
  // @OutputOnly
  Status status = 2;

  // Customer-readable message about the current status.
  // @OutputOnly
  string status_detail = 24;

  // Describes where to find the source files to build.
  Source source = 3;

  // Describes the operations to be performed on the workspace.
  repeated BuildStep steps = 11;

  // Results of the build.
  // @OutputOnly
  Results results = 10;

  // Time at which the request to create the build was received.
  // @OutputOnly
  google.protobuf.Timestamp create_time = 6;

  // Time at which execution of the build was started.
  // @OutputOnly
  google.protobuf.Timestamp start_time = 7;

  // Time at which execution of the build was finished.
  //
  // The difference between finish_time and start_time is the duration of the
  // build's execution.
  // @OutputOnly
  google.protobuf.Timestamp finish_time = 8;

  // Amount of time that this build should be allowed to run, to second
  // granularity. If this amount of time elapses, work on the build will cease
  // and the build status will be TIMEOUT.
  //
  // Default time is ten minutes.
  google.protobuf.Duration timeout = 12;

  // A list of images to be pushed upon the successful completion of all build
  // steps.
  //
  // The images will be pushed using the builder service account's credentials.
  //
  // The digests of the pushed images will be stored in the Build resource's
  // results field.
  //
  // If any of the images fail to be pushed, the build is marked FAILURE.
  repeated string images = 13;

  // Google Cloud Storage bucket where logs should be written (see
  // [Bucket Name
  // Requirements](https://cloud.google.com/storage/docs/bucket-naming#requirements)).
  // Logs file names will be of the format `${logs_bucket}/log-${build_id}.txt`.
  string logs_bucket = 19;

  // A permanent fixed identifier for source.
  // @OutputOnly
  SourceProvenance source_provenance = 21;

  // The ID of the BuildTrigger that triggered this build, if it was
  // triggered automatically.
  // @OutputOnly
  string build_trigger_id = 22;

  // Special options for this build.
  BuildOptions options = 23;

  // URL to logs for this build in Google Cloud Logging.
  // @OutputOnly
  string log_url = 25;

  // Substitutions data for Build resource.
  map<string, string> substitutions = 29;

  // Tags for annotation of a Build. These are not docker tags.
  repeated string tags = 31;

  // Secrets to decrypt using Cloud KMS.
  repeated Secret secrets = 32;
}

// Metadata for build operations.
message BuildOperationMetadata {
  // The build that the operation is tracking.
  Build build = 1;
}

// Provenance of the source. Ways to find the original source, or verify that
// some source was used for this build.
message SourceProvenance {
  // A copy of the build's source.storage_source, if exists, with any
  // generations resolved.
  StorageSource resolved_storage_source = 3;

  // A copy of the build's source.repo_source, if exists, with any
  // revisions resolved.
  RepoSource resolved_repo_source = 6;

  // Hash(es) of the build source, which can be used to verify that the original
  // source integrity was maintained in the build. Note that FileHashes will
  // only be populated if BuildOptions has requested a SourceProvenanceHash.
  //
  // The keys to this map are file paths used as build source and the values
  // contain the hash values for those files.
  //
  // If the build source came in a single package such as a gzipped tarfile
  // (.tar.gz), the FileHash will be for the single path to that file.
  // @OutputOnly
  map<string, FileHashes> file_hashes = 4;
}

// Container message for hashes of byte content of files, used in
// SourceProvenance messages to verify integrity of source input to the build.
message FileHashes {
  // Collection of file hashes.
  repeated Hash file_hash = 1;
}

// Container message for hash values.
message Hash {
  // Specifies the hash algorithm, if any.
  enum HashType {
    // No hash requested.
    NONE = 0;

    // Use a sha256 hash.
    SHA256 = 1;
  }

  // The type of hash that was performed.
  HashType type = 1;

  // The hash value.
  bytes value = 2;
}

// Secret pairs a set of secret environment variables containing encrypted
// values with the Cloud KMS key to use to decrypt the value.
message Secret {
  // Cloud KMS key name to use to decrypt these envs.
  string kms_key_name = 1;

  // Map of environment variable name to its encrypted value.
  //
  // Secret environment variables must be unique across all of a build's
  // secrets, and must be used by at least one build step. Values can be at most
  // 1 KB in size. There can be at most ten secret values across all of a
  // build's secrets.
  map<string, bytes> secret_env = 3;
}

// Request to create a new build.
message CreateBuildRequest {
  // ID of the project.
  string project_id = 1;

  // Build resource to create.
  Build build = 2;
}

// Request to get a build.
message GetBuildRequest {
  // ID of the project.
  string project_id = 1;

  // ID of the build.
  string id = 2;
}

// Request to list builds.
message ListBuildsRequest {
  // ID of the project.
  string project_id = 1;

  // Number of results to return in the list.
  int32 page_size = 2;

  // Token to provide to skip to a particular spot in the list.
  string page_token = 3;

  // The raw filter text to constrain the results.
  string filter = 8;
}

// Response including listed builds.
message ListBuildsResponse {
  // Builds will be sorted by create_time, descending.
  repeated Build builds = 1;

  // Token to receive the next page of results.
  string next_page_token = 2;
}

// Request to cancel an ongoing build.
message CancelBuildRequest {
  // ID of the project.
  string project_id = 1;

  // ID of the build.
  string id = 2;
}

// Configuration for an automated build in response to source repository
// changes.
message BuildTrigger {
  // Unique identifier of the trigger.
  //
  // @OutputOnly
  string id = 1;

  // Human-readable description of this trigger.
  string description = 10;

  // Template describing the types of source changes to trigger a build.
  //
  // Branch and tag names in trigger templates are interpreted as regular
  // expressions. Any branch or tag change that matches that regular expression
  // will trigger a build.
  RepoSource trigger_template = 7;

  // Template describing the Build request to make when the trigger is matched.
  oneof build_template {
    // Contents of the build template.
    Build build = 4;

    // Path, from the source root, to a file whose contents is used for the
    // template.
    string filename = 8;
  }

  // Time when the trigger was created.
  //
  // @OutputOnly
  google.protobuf.Timestamp create_time = 5;

  // If true, the trigger will never result in a build.
  bool disabled = 9;

  // Substitutions data for Build resource.
  map<string, string> substitutions = 11;
}

// Request to create a new BuildTrigger.
message CreateBuildTriggerRequest {
  // ID of the project for which to configure automatic builds.
  string project_id = 1;

  // BuildTrigger to create.
  BuildTrigger trigger = 2;
}

// Returns the BuildTrigger with the specified ID.
message GetBuildTriggerRequest {
  // ID of the project that owns the trigger.
  string project_id = 1;

  // ID of the BuildTrigger to get.
  string trigger_id = 2;
}

// Request to list existing BuildTriggers.
message ListBuildTriggersRequest {
  // ID of the project for which to list BuildTriggers.
  string project_id = 1;
}

// Response containing existing BuildTriggers.
message ListBuildTriggersResponse {
  // BuildTriggers for the project, sorted by create_time descending.
  repeated BuildTrigger triggers = 1;
}

// Request to delete a BuildTrigger.
message DeleteBuildTriggerRequest {
  // ID of the project that owns the trigger.
  string project_id = 1;

  // ID of the BuildTrigger to delete.
  string trigger_id = 2;
}

// Request to update an existing BuildTrigger.
message UpdateBuildTriggerRequest {
  // ID of the project that owns the trigger.
  string project_id = 1;

  // ID of the BuildTrigger to update.
  string trigger_id = 2;

  // BuildTrigger to update.
  BuildTrigger trigger = 3;
}

// Optional arguments to enable specific features of builds.
message BuildOptions {
  // Specifies the manner in which the build should be verified, if at all.
  enum VerifyOption {
    // Not a verifiable build. (default)
    NOT_VERIFIED = 0;

    // Verified build.
    VERIFIED = 1;
  }

  // Specifies the behavior when there is an error in the substitution checks.
  enum SubstitutionOption {
    // Fails the build if error in substitutions checks, like missing
    // a substitution in the template or in the map.
    MUST_MATCH = 0;

    // Do not fail the build if error in substitutions checks.
    ALLOW_LOOSE = 1;
  }

  // Requested hash for SourceProvenance.
  repeated Hash.HashType source_provenance_hash = 1;

  // Requested verifiability options.
  VerifyOption requested_verify_option = 2;

  // SubstitutionOption to allow unmatch substitutions.
  SubstitutionOption substitution_option = 4;
}
